라즈베리파이와 아두이노의 시리얼 통신 방법은 여러가지가 있다.
그 방법들에 대해 정리해 보겠다.
1.라즈베리파이의 USB포트에 아두이노 직결
별 다른 회로 구성이 필요 없는것이 장점이다.
하지만 라즈베리파이에서 USB포트로 출력해주는 전류량이 한정적이기 때문에 아두이노에 많은 회로가 연결 될 경우 전력이 부족 할 수 있다.
별 다른 회로가 없고 시리얼 통신이 중요하거나, 되는지 확인하는 방법으로만 추천한다.
나는 라즈베리파이에서 파이썬으로 시리얼 통신을 테스트 할 예정인데, 해당 파이썬 코드가 제대로 동작하는지 조차 정확히 모르기 때문에 이 방법으로 가장 간단하게 이 방법으로 테스트를 해 보았다.
먼저 PC와 아두이노를 연결하여 아두이노에 밑의 코드를 업로드한다.
String income = "";
void setup()
{
Serial.begin(9600); // Baudrate을 9600으로 시리얼 통신.
}
void loop()
{
while (Serial.available())
{ // 시리얼에 읽을 값이 있으면
income += (char)Serial.read(); // income안에 해당 내용 저장
}
if (income != 0)
{ // income에 내용이 있으면
Serial.print(income); // 시리얼에 해당 내용 전송
income = ""; // 전송한 income내용 초기화
}
delay(10);
}
이후 라즈베리파이의 USB에 아두이노를 연결하고 dmesg|tail 이라고 입력하면
pi@raspberrypi:~ $ dmesg|tail
[ 34.378626] cfg80211: (57000000 KHz - 66000000 KHz @ 2160000 KHz), (N/A, 4000 mBm), (N/A)
[ 35.855151] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[ 56.763364] usb 1-1.2: new full-speed USB device number 5 using dwc_otg
[ 56.877459] usb 1-1.2: New USB device found, idVendor=2341, idProduct=0043
[ 56.877486] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
[ 56.877503] usb 1-1.2: Manufacturer: Arduino (www.arduino.cc)
[ 56.877519] usb 1-1.2: SerialNumber: 7543932383535101B091
[ 56.913620] cdc_acm 1-1.2:1.0: ttyACM0: USB ACM device
[ 56.914771] usbcore: registered new interface driver cdc_acm
[ 56.914789] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
이런 결과가 보이는데, 중간에 ttyACM0: USB ACM device 라는 것이 보인다.
아두이노가 ttyACM0으로 연결이 되어 있다는 것.
다른 강좌에서는 python-serial 을 설치하는 과정이 있었다.
하지만 현재 버전에서는 굳이 설치하지 않았음에도 정상적으로 동작하였다. 따라서 별 다른 이상이 없다면 나는 설치하지 않고 진행하겠다.
이제 터미널에서 python 을 입력하여 인터프리터방식으로 동작의 진행을 살펴보자.
pi@raspberrypi:~ $ python
Python 2.7.9 (default, Mar 8 2015, 00:52:26)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
ttyACM0의 경우 아두이노와 라즈베리파이의 연결 횟수나 비정상적 close 횟수에 따라 바뀌는 경우가 있으니 위의 포트번호 확인 방법을 통해 정상적인 포트 번호를 입력하기 바란다.
>>> import serial
>>> ser = serial.Serial("/dev/ttyACM0",9600)
>>>
이상이 없을 경우 아무런 반응 없이 위와 같은 화면이 된다.
또 다시 다른점이 있는데, 다른 강좌에서는 ser.open() 을 통해 시리얼을 오픈해주는 과정이 있다. 하지만 내 버전에서는
>>> ser.open()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 271, in open
raise SerialException("Port is already open.")
serial.serialutil.SerialException: Port is already open.
와 같이 포트가 이미 열려있다는 에러 메세지가 나온다. 아마 위의 명령어 만으로 자동으로 오픈이 되는듯 하다.
이후 바로 write 테스트를 해보자.
>>> ser.writelines("Hi Everyone")
>>>
write함수와 writelines 함수가 있는데 아마 끝에 줄바꿈문자가 포함되냐 안되냐의 차이인것 같다.
또한 write함수를 사용시 전송한 글자수가 표시되는 반면, writelines 함수는 아무 반응이 없다.
write함수 사용시 끝에 '\n'을 붙여주어 문장이 끝났음을 표시해주는게 좋겠다.
>>> ser.readlines()
['Hi Everyone']
>>>
2. 아두이노의 디지털 포트 이용방법
이 방법은 아주 잘 설명 된 페이지를 참고하였다. (영문) https://oscarliang.com/raspberry-pi-and-arduino-connected-serial-gpio/
하지만 역시 지금 버전에는 하지 않아도 되는 사항이 많고, 해야되는 사항도 있다.
특히 raspbian jessie 버전에서는 /etc/inittab 파일이 없으며, /boot/cmdline.txt 파일 내용도 조금 다르다.
따라서 내가 따로 정리를 다시 하겠다.
또한 유의해야 할 사항이 있는데, 아두이노 우노에서는 TXRX라고 써있는 핀이 D0,D1 핀 뿐인데, 이 핀은 아두이노가 컴퓨터와 UART 통신을 하는 핀과 동일하다.
따라서 아두이노의 전원을 PC의 USB선으로 공급하고 있다면 이미 PC와 시리얼 통신을 하고 있는 상황이 되기에 핀이 동작하지 않는다.
아래의 참고2 그림과 같이 배선을 하고 싶다면 아두이노의 전원을 외부 전원을 사용하여야만 한다.
또는 레오나르도나, 메가2560을 쓴다던지, 아니면 아두이노의 하드웨어 시리얼이 아닌 소프트웨어 시리얼을 통해 구현하여야 한다.
(소프트웨어 시리얼에 대한 코드는 여유가 생긴다면 올리겠다)
나의 경우는 아두이노 전원 인가는 외부 전원을 통하였고, 아래 참고2 그림과 같이 배선이 되어있다.
아두이노는 5v의 신호를 사용하고 라즈베리파이는 3.3v를 사용하기 때문에 바로 직결하면 정상적으로 동작하지 않는다.
따라서 신호를 변환해줘야 하는데, logic level converter 를 사용하던지, 저항을 사용하여 임시적으로 약 3.3v의 신호를 만들어 사용해야 한다.
나는 갖고있는 로직 레벨 컨버터가 없어서 저항을 이용한 voltage divider를 사용하겠다.
참고1) 로직 레벨 컨버터 사용 시 회로 구성
참고2)볼테이지 디바이더 사용시 회로 구성
참고) Voltage Divider Calculator - https://www.abelectronics.co.uk/tools/resistor-voltage-divider.aspx#
위 볼테이지 디바이더 사이트에서 대충 계산을 해 보았는데, R2쪽에는 R1저항의 약 2배인 저항을 달아주면 대충 값이 맞는다.
위 사진상의 저항도 약 2배의 값이다. (R2 = GND쪽)
여태까지는 라즈베리파이2를 가지고 진행을 했는데, 라즈베리파이3 에서는 방법이 다르다.
먼저 /boot/config.txt 파일을 열고 가장 마지막 부분에 이 두줄이 추가되어야 한다.
출처 - http://raspberrypi.stackexchange.com/questions/45570/how-do-i-make-serial-work-on-the-raspberry-pi3
core_freq=250
enable_uart=1
이제 라즈비안 제시에서 다른 점 때문에 해주어야 하는 부분이 등장한다. (출처 - http://blog.prettymay.com/220672172975)
먼저 /boot/cmdline.txt 파일을 수정한다.
sudo nano /boot/cmdline.txt
기본값은
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=$
이와 같은데 console=serial0,115200 부분을 삭제해주어야 한다.
따라서 수정된 cmdline.txt의 값은
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=$
이렇게 되어야 한다.
그후 라즈베리파이를 재부팅 한번 해준다.
이후 위의 1번 방법의 python 이용 방법과 같지만, 이번에는 시리얼 포트가 ttyAMA0이 되겠다. 따라서 실행은 다음과 같다.
pi@raspberrypi:~ $ python
Python 2.7.9 (default, Mar 8 2015, 00:52:26)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
>>> ser.writelines("Hi everyone")
>>> ser.readlines()
['Hi everyone']
>>>
정상 구동이 되는것을 확인 할 수 있다.
자신에게 필요한 방법으로 구현을 하면 되겠다. 추가적인 상황이 발생한다면 계속 자료를 수정하겠다.
'개발 > Embedded' 카테고리의 다른 글
라즈베리파이 Node.js 최신버전 설치 (0) | 2016.09.08 |
---|---|
포토 커플러 SG-2BC 올바른 사용법 (1) | 2016.08.09 |
Fritzing 설치와 사용법 (0) | 2016.08.09 |
라즈베리파이 OS 설치부터 기본 설정까지 (4) | 2016.07.19 |
라즈베리파이 초기 설치를 위한 자료들 (0) | 2016.07.15 |