PI

라즈베리파이 3B+ 4B 아두이노 시리얼통신 (UART - Tx, Rx 핀 사용)

밍디 ٩(ˊ ᗜˋ*)و 2020. 1. 24. 19:48

++ 아두이노 코드와 파이코드 시험 끝나면 추가하겠슴당

 

이 글은

http://leaqua.mulple.com/?p=607

 

아두이노와 라즈베리 파이의 UART(serial) 통신

라즈베리파이와  아두이노 사이의 통신에는 SPI, I2C , UART 등을 사용할수 있습니다. 그중에 제일 만만한? UART(Serial) 을 테스트 해보았습니다. 같은 전압의 IO핀을 사용하면 바로 결선해서 사용하면 간단해 지겠지만 아두이노의 입출력 핀 전압 5V 와 라즈베리파이의 GPIO 의 입출력 핀전압 3.3V 의 차이 때문에 직접적인 결선은 문제가 있어서 회로구성이 불가피 해집니다. UART 통신하는 회로의 구성에도 여러가지가 있습니다. MOSF

leaqua.mulple.com

https://arsviator.blogspot.com/2016/07/methods-of-connecting-raspberry-pi-and.html

 

라즈베리 파이와 아두이노를 시리얼 포트로 연결하는 방법들 (Methods of connecting Raspberry Pi and Arduino using serial port)

라즈베리 파이와 아두이노를 시리얼 포트로 통신을 할 수 있도록 연결하는 방법을 소개한다. 가장 쉬운 방법은 라즈베리 파이의 USB 포트에 아두이노를 USB케이블로 연결하는 것이다. 이 경우는 라즈베리 파이에서 아두이노 IDE로 스케치를 작...

arsviator.blogspot.com

 

https://canorus.github.io/2018/11/28/raspbian-%EB%B2%84%EC%A0%84-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0/

 

Raspbian 버전 확인하기 · Fabulam Canor

라즈베리 파이에서 Raspbian을 사용하면서 간간이 설치된 운영체제의 버전을 확인할 필요가 있었다. 주로 버그 리포팅이나 포럼에 도움을 구할 때지만, 간단한 macOS 버전도 헷갈리기 시작하는 입장에서 릴리즈 날짜를 일일이 기억하는 건 벅찬 일이었다. 커널 버전은 말할 것도 없고. 때문에 Raspbian의 릴리즈 데이트와 커널 버전을 확인하는 방법을 기록해 둔다. 커널 버전 확인하기 커널 버전은 uname -a 로 확인할 수 있다. cat /proc/v

canorus.github.io

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/3048를 참고하여 작성.

 

[IoT 네트워크와 서비스 강좌] # 2-2 서버-센서장치 시리얼 통신 | Hard Copy Arduino

 

www.hardcopyworld.com

https://blog.naver.com/hahav000/221322904700

 

라즈베리파이3 B+ 시리얼 통신(serial)

안녕하세요 하하입니다.라즈베리파이 기본세트(라즈베리파이3B+ + 전원어댑터 + hdmi케이블 + 케이스 + 방...

blog.naver.com

http://blog.prettymay.com/220672172975

 

라즈베리파이3 HAT - 라즈베리파이와 아두이노의 결혼 Rpino

NULSOM Inc. (Make something out of null)http://www.nulsom.com늘솜(주) Nul...

blog.naver.com

https://pinocc.tistory.com/185

 

[라즈베리파이] UART 사용 설정 및 테스트

라즈베리파이에서 UART 를 사용하는 방법에 대해서 정리하였다. 참고 : http://spellfoundry.com/sleepy-pi/setting-arduino-ide-raspbian/ 라즈베리파이 Pin 확인 라즈베리파이 Pin Map : (https://pinout.xyz/pi..

pinocc.tistory.com

 

를 참고하여 공부하고 작성. 다들 성공하시길.

 

 

시리얼통신에는

 

1. 아두이노랑 라즈베리파이랑 USB로 연결하는 USB 통신

2. Tx,Rx 핀을 이용한 방법이 있는데

 

Tx, Rx 핀 쓰는게 더 멋있으니까 두번째 방법을 써보도록 하자.

 

라즈베리파이에 설치된 OS 버전 별로 설정방법이 다르니까 주의
버전 순서는 Whezzy(7) → Jessie(8) → Stretch(9) → Buster(10)

 

자신의 OS버전을 확인하고 싶다면 터미널창에 

$ cat /etc/os-release

 

짜잔

 

라즈베리파이 3B+ 4B 아두이노 시리얼통신


0. 결선


아두이노 핀 전압은 5V 고 라즈베리파이 GPIO 핀은 3.3V 라서

 

RPI Rx → 아두이노 Tx 는  (O) 직접 연결해도 문제 없음

근데 반대로

아두이노 Rx → RPI Tx (X) 직접적으로 결선하면 문제가 될 수 있다고 하네요.

 

그 말 듣고 전압분배를 했더니 안되고 걍 다이렉트로 연결하니까 그제서야 됩니다.

라즈베리파이의 내부 풀업저항이 충분히 커버쳐줘서 그렇다는데 저는 전자과가 아니라서 잘 모르겠습니다 (◍´▽`◍) 암튼

 

라즈베리파이에 gpio readall 명령어를 치면

$ gpio readall

 

라즈베리파이 핀맵이 나오는데

(3B, 3B+, 4B 는 핀맵이 모두 같아요)

 

오른쪽에 보이는 TxD 가 tx, RxD가 rx 핀입니다.

저기 보이는 TxD에 아두이노의 RX핀, RxD에는 아두이노 TX핀을 꽂으면 됩니당

 

그럼 아두이노에서 tx, rx는 무슨 핀인가??

 

https://www.arduino.cc/reference/en/language/functions/communication/serial/

아두이노에서 사용하는 공식적인 rx, tx 핀은 0 (D0)번과 1 (D1)번핀인데

이 핀은 아두이노가 컴퓨터와 시리얼통신

이 시리얼 통신

을 하는 핀과 같습니당

 

그래서 아두이노 전원을 PC의 USB로 공급받고 있을 때는 이미 PC와 시리얼통신을 하는거라 이 때는 이 핀이 동작하지 않습니다

 

그래서 직접 코드로 지정해줘야합니다

 

아두이노에서 'tx, rx를 사용한 시리얼통신' 코드를 짤때는 SoftwareSerial 클래스를 사용합니다.

/* arduino에서 사용하는 코드입니다 라즈베리파이 코드 아님 */

/* SoftwareSerial raspberrySerial(rxPin, txPin); */
SoftwareSerial raspberrySerial(2, 3);

 

아두이노에서는 SoftwareSerial 객체 생성 때 생성자로 집어넣는

앞 숫자가 아두이노의 rx핀이되고 뒷 숫자가 아두이노의 tx핀이 됩니다.

보통은 2,3번 핀을 사용합니다

 

아두이노 rx핀 (2) - 라즈베리파이 tx핀

아두이노 tx핀 (3) - 라즈베리파이 rx핀

 

연결하면 이런모습

 

1. cmdline.txt 수정


수정하기 전에 먼저 백업.

$ sudo cp /boot/cmdline.txt /boot/cmdline_backup.txt

 

백업한 다음 cmdline 을 수정

$ sudo vi /boot/cmdline.txt 

cmdline.txt의 내용은 라즈비안 버전마다 비슷하면서도 다 다름

enable 부터 console=tty1 사이의 빨간글씨를 지우면 됩니다.

 

 

 

아래는 (2019-04-08-raspbian-stretch) 의 cmdline.txt 내용입니다.

[3B+ Stretch] 

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=55333470-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

 

rootwait 뒤는 따로 설정한 내용입니다.

 

 

아래는 (2019-09-26-raspbian-buster) 의 cmdline.txt 내용입니다. 

[4B Buster ]

console=serial0, 115200 console=tty1 root=PARTUUID=d9b3f436-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

 

rootwait 뒤는 따로 설정한 내용입니다.

 

2. Serial Login 비활성화


 

systemd control 명령으로

$ sudo systemctl stop serial-getty@ttyAMA0.service
$ sudo systemctl disable serial-getty@ttyAMA0.service

 

RPI 3 에서는 UART 디바이스 정보가 바뀌어서 아래와 같이 설정하면 된댔는데

$ sudo systemctl stop serial-getty@ttyS0.service
$ sudo systemctl disable serial-getty@ttyS0.service

출처: https://pinocc.tistory.com/185 [땅뚱 창고]

3. raspi-config 수정

$ sudo raspi-config

[3B+ Stretch] 

5. interfacing option 선택

P6. Serial 선택

시리얼 포트로 다른 시리얼 기기 통신하는데 사용하기 위해 No 선택

[4B Buster ] 

 

5. interfacing option 선택

P6. Serial 선택

 

시리얼 포트로 다른 시리얼 기기 통신하는데 사용하기 위해 No 선택

No를 선택하면 창이 하나가 더뜨는데

여기서는 Yes 선택

 

4. config 파일 수정


config.txt 파일을 수정한다.

$ sudo vi /boot/config.txt

 

 UART를 사용하기위해 맨 마지막줄에 enable_uart = 1 을 추가하자.

enable_uart=1

 

3B+부터는 블루투스 기능이 들어오면서 UART사용되는 부분이 서로 겹쳐지기 때문에 블루투스가 켜져있으면 동작을 안한다고함.

블루투스 기능을 꺼주자

dtoverlay=pi3-disable-bt

 

 

[3B+ Stretch] 

수정한 config.txt

 

 

4B에는 아래 추가.

dtoverlay=uartx

 

저장 후 터미널에서

$ sudo systemctl disable hciuart

그리고

$ sudo reboot

 

 

5. 테스트


 

먼저 파이 내부에서 UART 통신이 잘 되는지 확인해보자

파이의 Tx와 Rx를 직접 연결해 루프백테스트

아래는 루프백 테스트 코드. 출처는 https://embejied.tistory.com/40

 

[라즈베리파이] wiringPi를 이용한 시리얼통신

라즈베리파이에서 시리얼통신(RS232)을 해보자. wiringPi에서 시리얼통신 라이브러리도 만들어놨다. 약간의 설정만 하고 사용하기만 하면 된다. 먼저 라즈베리파이에서 다음과 같이 설정해준다. 먼저 /boot/cmdlin..

embejied.tistory.com

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <wiringPi.h>
#include <wiringSerial.h>

int main ()
{
  int fd ;
  int count ;
  unsigned int nextTime ;

  if ((fd = serialOpen ("/dev/ttyAMA0", 115200)) < 0)  // 두번째 인자값이 보레이트 설정
  {
    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;                   
    return 1 ;
  }
//
  if (wiringPiSetup () == -1)
  {
    fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
    return 1 ;
  }

  nextTime = millis () + 300 ;

  for (count = 0 ; count < 256 ; )
  {
    if (millis () > nextTime)
    {
      printf ("\nOut: %d: ", count) ;
      fflush (stdout) ;
      serialPutchar (fd, count) ; // 데이터 전송해주는 함수
      nextTime += 300 ;
      ++count ;
    }

    delay (3) ;

    while (serialDataAvail (fd))
    {
      printf (" -> %3d", serialGetchar (fd)) ;  // 데이터 받는 함수
      fflush (stdout) ;
    }
  }

  printf ("\n") ;
  return 0 ;
}

 

 

실행결과

 

숫자가 잘뜨면 성공입니다.

 

 

 

짝짝짝짝