라즈베리파이3 UART 통신 질문드립니다.



  • 라즈비안 jessie 3월 이후버전 설치하고 UART로 데이터 주고받으려는데,
    라즈베리파이3에서 블루투스가 UART GPIO를 사용한대서 그냥은 안된다고 하더라구요.
    그래서 구글링해서 miniuart로 사용하게큼해서 serial로 putty를 통한 원격접속은 잘 됩니다.
    그러고 본격적으로 uart 통신을 테스트를 하려했습니다.
    윈도우 노트북에서 serial 테스트 프로그램에서 문자열을 보내고 파이3에서 termios이용해서 read하고 출력하는데 뭔가 잘안되는군요.
    처음 연결해서 hello라는 문자열을 보내면 파이는 출력하지도 않고 hellooooooooooooooooooooooooo… 이렇게해서 4 * 2048 bytes 정도 보내구요. 이거 무시하고 계속 hello를 보내면 몇초간은 파이가 hello를 잘 받아서 출력하는데 몇초후에 갑자기 윈도우 노트북 쪽에
    Raspbian GNU/Linux8 raspberrypi ttyAMA0
    raspberrypi login:
    원격접속 ack메시지를 보내더군요… serial 프로그램에서는 엔터문자를 포함해서보내니까 로그인도 됩니다…
    왜 이런현상이 나타나는걸까요. uart 통신 처음으로 해보는거라서 당황스럽네요.
    uart 코드는 아래처럼 썼습니다.

    struct termios s;
    fd=open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
    s.c_iflag = IGNPAR | ICRNL;
    s.c_oflag=0; s.c_lfalg=0; s.c_cflag=0; s.c_cflag=B115200 | CS8 | CREAD | CLOCAL;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd,TCSANOW,&s);
    while(1){
    res=read(fd,buf,48);
    if(res>0){
    printf("%s\n",buf);
    }
    fflush(stdout);
    }
    close(fd);
    

  • Global Moderator

    @이두호 안녕하십니까… 산딸기마을 이장 나무꾼 입니다.

    두호님과 비슷한 현상을 겪고 있는 글을 찾아 공유합니다.

    http://stackoverflow.com/questions/17254923/raspberry-pi-uart-program-in-c-using-termios-receives-garbage-rx-and-tx-are-con

    추가로 현재의 터미널 통신속도 설정은 제대로 되어 있는지도 한번 쯤 확인해 보시는 것도 좋으실듯 합니다.

    이 외에 다른 현상이 있으시다면 추가 댓글 바랍니다.



  • 터미널 통신속도는 115200으로 고정시켜놔서 문제가 되진 않는거 같습니다.
    여러번 테스트 해본결과 양쪽으로 데이터 전송을 문제가 없는데,
    Serial통신 프로그램이 자꾸 serial연결로 login shell을 여는 것 같습니다.
    코드를 아래처럼 바꿨더니 helloooooooooooooooo… 이렇게 발생했던 문제는 안생기는데
    여전히 Serial통신 프로그램이 login shell을 여네요…
    라즈베리파이3 세팅은 제가 라즈비안을 9월에 다운받았기 때문에 3월 18일 이후 OS를 위한 세팅 방법으로 진행했습니다.

    [라즈베리파이3 Serial 통신 세팅 참조]
    http://www.briandorey.com/post/Raspberry-Pi-3-UART-Boot-Overlay-Part-Two

    [사용된 설정 코드]
    fd=open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY | _ONONBLOCK);
    fcntl(fd,F_SETFL,O_RDWR);
    cfmakeraw(&serial);
    cfsetispeed(&serial,B115200);
    cfsetospeed(%serial,B115200);
    serial.c_cflag |= (CLOCAL | CREAD);
    serial.c_cflag &= ~PARENB;
    serial.c_cflag &= ~CSTOPB;
    serial.c_cflag &= ~CSIZE;
    serial.c_cflag |= CS8;
    serial.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    serial.c_oflag &= ~OPOST;
    serial.c_cc[VMIN]=0;
    serial.c_cc[VTIME]=10;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW | TCSAFLUSH, &serial);



  • 그리고 혹시 제가 쓰레드를 사용해서
    fd를 전역변수로 설정하고 쓰레드 열기전에 설정 다해주고
    쓰레드 2개 열어서 write용 함수 부분과 read용 함수 부분을 따로 만들어 돌리게큼 만들었는데
    이 부분이 문제가 된건 아니겠죠?


답변을 위해 로그인하기