Pythonでシリアル通信!Arduinoに文字列を送って、Arduinoから文字列を受け取る!
シリアル通信でLチカしたプログラムをアップデート。Arduinoに特定の文字列を送ると、それに対応した返答を返すというもの。
RS232Cを備える測定器をリモートコントロールするための練習プログラム。
greenhornprofessional.hatenablog.com
結果
Pyhtonから送りたい文字列を標準入力で入力すると、Arduinoから意図したとおりの返答を受け取れている。
送受信は30~40msで完了している。この数字が妥当なのか?などの深堀はまた今度。
また、送信する文字列の末尾にセミコロンをつけていない場合は時間が増える。これはArduino側 Serial.readStringUnitl()
がセミコロンを待つようにしているためで、これのタイムアウト(恐らく1sec)が影響している。
<= abc; 計測開始 送信完了:0.008sec => Input is abc => Return is ABC 受信完了:0.037sec <= abc 計測開始 送信完了:0.010sec => Input is abc => Return is ABC 受信完了:1.020sec <= ddd; 計測開始 送信完了:0.009sec => Input is ddd => N/A 受信完了:0.033sec
プログラム
Arduino側
void setup(){ Serial.begin(115200); } void loop(){ if(Serial.available()>0){ String input = Serial.readStringUntil(';'); Serial.print("Input is "); Serial.println(input); if(strcmp(input.c_str(), "abc") == 0){ Serial.println("Return is ABC"); }else if(strcmp(input.c_str(), "def") == 0){ Serial.println("Return is DEF"); }else{ Serial.println("N/A"); } } }
Python側
#SimpleSerial_003.py import serial from time import sleep import time def decoder(byte): str_array = [] str_array = byte.decode().rstrip('\r\n').split('\r\n') for i in str_array: print("=>",i) def main(): ser = serial.Serial('COM3', 115200, timeout=0.1) sleep(2) command = input() print("<=", command) t0 = time.time() print("計測開始") ser.write(bytes(command, encoding='ascii')) ser.flush() t1 = time.time() print("送信完了:{:.3f}sec".format(t1 - t0)) while True: if ser.in_waiting > 0: data = ser.read_all() break decoder(data) t2 = time.time() print("受信完了:{:.3f}sec".format(t2 - t1)) ser.close() if __name__ == '__main__': main()
コメント:今回のプログラムではser.flush()
は時間に寄与せず。
参考サイト
Serial.readStringUntil()
を紹介している
【prog】Arduino・シリアルで文字列受信するには:ゆうがたの「特にコレと言って」 - ブロマガ
文字列を比較するためのstrcmp
の紹介。コレ結構重要。
【C言語入門】文字列を比較する方法(strcmp、strncmp) | 侍エンジニアブログ
strからchar*に変換する方法。コレもかなり重要。
【C++入門】string型⇔char*型に変換する方法まとめ | 侍エンジニアブログ