임베디드/아두이노

[아두이노] 파이썬으로 제어하기

아두이노

 기본적으로 아두이노는 시리얼 통신(UART)을 통해 제어하게 된다. 즉, 파이썬에서도 시리얼 통신을 하게 되면 아두이노를 충분히 제어할 수 있다. 

 단, 하드웨어 코딩은 아두이노 IDE로 해야 한다.

 

흐름도

 

※ 기본적인 통신 방법은 시리얼 통신이다.

 

파이썬

 시리얼 통신

 파이썬으로 시리얼 통신을 하려면, 관련 모듈(pyserial)을 설치해야 한다.

 

pyserial/pyserial

Python serial port access library. Contribute to pyserial/pyserial development by creating an account on GitHub.

github.com

PyPI 명령어는 'python -m pip install pyserial'이다.

 

 파이썬에서 데이터 보내기

파이썬으로 사용자에게 입력받은 값을 토대로 13번 led핀을 on/off 해보자.

 

 아두이노 IDE 코드

int input_data;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  while(Serial.available())
  {
    input_data = Serial.read();
  }

  if(input_data == '1')
  {
    digitalWrite(13, HIGH); // led_on
  }
  else if(input_data == '0')
  {
    digitalWrite(13, LOW); // led_off
  }
}

 

 파이썬 코드

import serial
import time

# 'COM3' 부분에 환경에 맞는 포트 입력
ser = serial.Serial('COM3', 9600)

while True:
    if ser.readable():
        val = input()

        if val == '1':
            val = val.encode('utf-8')
            ser.write(val)
            print("LED TURNED ON")
            time.sleep(0.5)

        elif val == '0':
            val = val.encode('utf-8')
            ser.write(val)
            print("LED TURNED OFF")
            time.sleep(0.5)

 

※ 바이트 단위로 인코딩해서 아두이노에 넘겨줘야 정상적으로 작동한다.

참고로 아두이노 내에서 data type 크기가 보통 사용하는 data type 보다 작다.

https://thmuses.wordpress.com/2014/01/05/arduino-variable-types/

 

 

 파이썬으로 데이터 입력받기

파이썬에 아두이노로부터 받은 값을 입력받아 출력해보자.

 

 아두이노 IDE 코드

int output_data = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(output_data++);
  delay(500); // delay 500ms
}

 

 파이썬 코드

import serial
import time

# 'COM3' 부분에 환경에 맞는 포트 입력
ser = serial.Serial('COM3', 9600)

while True:
    if ser.readable():
        val = ser.readline()
        print(val.decode()[:len(val)-1])  # 넘어온 데이터 중 마지막 개행문자 제외

※ 데이터 받을 때도 디코딩 과정을 해줘야 정상적으로 출력된다.