概要
Pythonで画像認識した結果をCANで別のツールに伝えるためにPySerialを使いたく、試しにArduinoとのシリアル通信を実験した結果をメモした。
実験1(Python2Auduino)
内容:Jupyterから1のbyte情報をArduinoに送り、Arduinoがそれを受け取りLEDを点灯する
■Auduino側
serial.c
#define LED_PIN 8
//シリアル通信(PC⇔Arduino)
char data;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
LED_ON();
delay(1000);
LED_OFF();
}
void loop(){
if (Serial.available() > 0) {
data = Serial.read();
if(data == '1'){
LED_ON();
}
else{
LED_OFF();
}
}
}
void LED_ON(void){
digitalWrite(LED_PIN, HIGH);
}
void LED_OFF(void){
digitalWrite(LED_PIN, LOW);
}
■python側
serial.py
import serial
import time
num = 0
ser = serial.Serial()
ser.port = "COM4" #PortはAuduinoを挿す度に変わるから、毎回確認
ser.baudrate = 9600
ser.setDTR(False)
ser.open()
while True:
ser.write(b'1')
time.sleep(1)
ser.write(b'0')
time.sleep(1)
num += 1
if num == 10:
break
ser.close()
■結果
LED点灯消灯を繰り返すことができた。
実験2(Auduino2Python)
内容:Auduinoから周期的にある情報をPythonへ送り続ける
■Auduino側
serial.c
//シリアル通信(PC⇔Arduino)
#define RX_buf_Size 24
#define TX_buf_Size 24
char RX_buffer[RX_buf_Size];
char TX_buffer[TX_buf_Size];
int RX_numdata=0;
const short int TX_IntervalTime=1000;//通信周期
unsigned long TX_PrevTime;//timeの前回実行時刻記録
unsigned long CurrTime=0;//グローバルタイム
void setup() {
Serial.begin(9600);
while(Serial.read() >= 0){} //clear serialbuffer
}
void loop(){
CurrTime = millis();//システム起動時間を取得
F_Serial_RX();
if((CurrTime - TX_PrevTime) >= TX_IntervalTime ){
F_Serial_TX2();
TX_PrevTime = CurrTime;
}
}
void F_Serial_TX2(void){
int bytesSent = Serial.write("33");
delay(1);
}
■python側
serial.py
import serial
import time
num = 0
ser = serial.Serial()
ser.port = "COM4" #デバイスマネージャでArduinoのポート確認
ser.baudrate = 9600 #Arduinoと合わせる
ser.setDTR(False) #DTRを常にLOWにしReset阻止
ser.timeout=0 #Buffer溜まる待つ時間
ser.open() #COMポートを開く
while True:
if ser.in_waiting > 1: #Bufferにあるデーターサイズを確認してから読み取り
data = ser.read_all() #読み取りと同時にBufferをクリアしてくれる
if data:
rec_str = data.decode('utf-8')
print(rec_str)
■結果
Auduino側から送られてきた33の数値が受け取れていることがわかる
宿題
信頼度の高い送受信はまだまだこれで十分とは言えないから、通信の合図、CRCチェックなども検討しながら、作って行く必要があります。