1. 파이시리얼(pyserial) : 파이썬 시리얼통신 모듈

 먼저 pyserial을 소개하도록 하겠다. pyserial은 시리얼 통신을 하기 위한 파이썬 모듈이다. 만약 winPython 을 사용한다면 pyserial 이 기본으로 설치되어 있다. ( 처음에는 이 사실도 모르다가 따로 설치를 해야 하겠거니 짐작하고 한참을 헤맸었다. ) 따라서 바로 import 하면 사용할 수 있다.  주의할 점은 모듈명은 pyserial이 아니라 그냥 serial 이라는 것이다.


>>> import serial


일단 아두이노를 연결하면 윈도우 장치관리자에서 COM포트 번호를 확인할 수 있다. 아두이노 우노를 연결하고 내 컴퓨터의 예를 보면 아래와 같이 'COM22'번으로 잡혀있다.



먼저 시리얼 통신 객체를 생성하여야하는데 serial 모듈에 있는 Serial 클래스 (즉, serial.Serial 클래스이다.)를 이용하면 된다. 생성자의 정의는 다음과 같다.


class serial.Serial

__init__(
    port=None,
    baudrate=9600,
    bytesize=EIGHTBITS,
    parity=PARITY_NONE,
    stopbits=STOPBITS_ONE,
    timeout=None,
    xonxoff=False,
    rtscts=False,
    writeTimeout=None,
    dsrdtr=False,
    interCharTimeout=None
)


입력 인수들:


  • port - 장치명. 윈도우즈에서는 'COM0', 'COM1' 등이다.

  • baudrate - 보레이트(baud rate) 예를 들면 9600, 115200 등.

  • parity - 패리티비트. FIVEBITS, SIXBITS, SEVENVITS, EIGHTBITS 등이 가능하다.

  • stopbit - 정지비트. STOPBITS_ONE , STOPBITS_ONE_POINT_FIVE , STOPBITS_TWO 등이 가능하다.

  • timeout - 수신 시간 제한 설정

  • xonxoff - 소프트웨어 흐름 제어를 설정

  • rtscts - 하드웨어(RTS/CTS) 흐름 제어 설정

  • dsrdtr - 하드웨어(DSR/DTR) 흐름 제어 설정

  • writeTimeout - 송신 시간 제한 설정

  • interCharTimeout


예외 발생


  • ValueError - 입력 변수값에 오류가 있을 경우 발생

  • SerialException - 시리얼 통신 장치에 오류가 있을 경우 발생


이것을 보면 포트 정도만 지정해 주어도 기본적으로 생성이 되는 것을 알 수 있다. 포트는 'COM22'와 같이 문자열로 넘겨주어야 한다. 포트명을 특정해 주면 즉시 장치와 연결이 open된다. 시리얼통신 장치를 다 사용하였다면 obj.close() 를 호출하여 반드시 닫아주어야 한다.




Posted by 살레시오
,

2. 아두이노로부터 수신 실험

 실험을 위해서 다음과 같은 간단한 프로그램을 아두이노 우노에 다운로드 하였다. 이 프로그램은 전원이 켜지면(또는 리셋 버튼을 누르면) "Hello python." 이라는 문자열을 보낸다.


void setup() {
   Serial.begin(9600);
   Serial.println("Hello python.");
}

void loop() {
}


그리고 파이썬에서 Serial 객체의 인스턴스를 다음과 같이 생성한다.


>>> ard = serial.Serial('COM22')


이렇게 하면 ard 변수에 Serial 클래스의 인스턴스가 생성된다. 이제 이 변수를 이용해서 아두이노에서 보내는 값을 읽어들일수 있다.


>>> obj = ard.readline()
>>> obj
b'Hello python.\r\n'


아두이노 쪽에서 println()함수를 썼기 때문에 끝에 \r\n 두 개의 개행 제어 문자가 붙어서 넘어왔다.


 한 가지 주의할 것은 Serial.readlin() 함수의 반환 객체가 문자열이 아니라 bytes 라는 파이썬 객체로서 각각의 문자의 아스키코드 바이트 값의 배열이라는 점이다. 이것을 파이썬 문자열(string)로 변환하려면 bytes.decode()함수를 이용하면 된다.


>>> str = obj[:-2].decode()
>>> str
'Hello python.'


이제 str 변수에 아두이노로 부터 전송된 문자열이 정확히 저장되었다. 여기서 obj[:-2] 와 같이 인덱싱을 한 것은 \r\n 두 문자를 제외하기 위한 것이다.





Posted by 살레시오
,

3. 두 번째 실험 : 송신


  이번에는 파이썬에서 값을 송신하면 그에 따라서 아두이노의 LED를 점멸시키는 예제를 해 보겠다. 파이썬에서 데이터를 쓰는 함수로 Serial.write() 함수가 있는데 전송할 바이트 데이터를 리스트나 튜플로 묶어서 넘겨주면 된다. 반환값은 전송한 데이터의 바이트 수이다. 예를 들면 다음과 같다.


-------------------------------------------------------------------------

>>> ard.write( [0] ) # 0이라는 데이터를 전송한다.

>>> ard.write( [10, 150, 255] ) # 10,150,255를 차례로 전송한다.

>>> ard.write( 123 ) # 예외 발생!

-------------------------------------------------------------------------


전송되는 데이터는 바이트 데이터이므로 0~255 사이의 정수여야 하며 마지막 예와 같이 리스트나 튜플이 아니라면 예외가 발생함을 유의하여야 한다.


만약 문자열을 한꺼번에 전송하고 싶다면 encode() 라는 문자열 내장 함수를 이용하면 된다. 이 함수는 파이썬 문자열을 아스키값의 bytes 배열로 변환시켜준다.


-------------------------------------------------------------------------

>>> ard.write( 'Hello arduino.\r\n'.encode() )

-------------------------------------------------------------------------


이 명령은 'H' 부터 맨 마지막 '\n' 까지 14개의 문자의 아스키코드를 차례로 전송한다.


이제 실험을 위해서 아두이노에 다음과 같은 프로그램을 작성하여 다운로드 했다.



아두이노 프로그램 : 전원이 켜지면(또는 리셋 버튼을 누르면) "Hello python." 이라는 문자열을 보낸다. 그리고 데이터가 들어오면 0값이면 LED를 끄고 아니라면 켠다.

-------------------------------------------------------------------------

void setup() {

Serial.begin(9600);

Serial.println("Hello python.");

pinMode(LED_BUILTIN, OUTPUT);

}


void loop() {

if( Serial.available() )

digitalWrite(LED_BUILTIN, Serial.read());

}

-------------------------------------------------------------------------


이제 ard.write([0]) 이라고 명령을 내리면 LED가 꺼지고 ard.write([1])이라고 하면 LED가 켜지는 것을 다음과 같이 확인할 수 있다. 




위 동영상을 보면 1을 쓰면 LED가 켜지고 0을 쓰면 꺼지는 것을 볼 수 있다.


Posted by 살레시오
,