質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

28435閲覧

pythonでのシリアル通信が上手くいかない

lefirea

総合スコア17

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2017/02/08 08:44

編集2017/02/08 09:26

###前提・実現したいこと
pythonを使って、Arduinoとシリアル通信がしたい

###発生している問題・エラーメッセージ
シリアル通信のタイムアウト時間を1秒未満に設定すると上手く通信できない。
serial.readline()で返ってくるデータが空のみ。

###該当のソースコード

python

1import serial 2 3def serial_get(comm,check,Next): #serial_get(送信するコマンド、返ってくるコマンド、次のフェイズ番号) 4 global fase #フェイズ番号 5 global err #エラーカウント 6 7 ser.write(bytes(comm)) #コマンド送信 8 9 read=ser.readline() #コマンド受信 10 while read: 11 print('read=',read,end='') #受信データ表示 12 13 """ 受信データ比較 """ 14 if((check in read)==True): #受信成功 15 err=0 #エラーカウントリセット 16 fase=Next #フェイズ進行 17 return True #受信成功 18 19 elif (('err' in read)==True): #エラーが返ってきたら 20 err=0 21 fase=2 22 return 'error' 23 24 else: #受信失敗 25 err+=1 #エラーカウント増加 26 if fase==0 and err>=100 : #エラーカウント既定値到達 27 err=0 #エラーカウントリセット 28 fase=2 #フェイズを飛ばす 29 return False #受信失敗 30 31 read=ser.readline() #コマンド受信 32 33with serial.Serial('COM3',9600,timeout=1) as ser: #シリアル通信設定。ポートCOM3、通信速度9600、タイムアウト最大1秒 34 while fase==0: #開始信号待ち 35 serial_fase=serial_get('start/','ok',1) #arduino待ち 36 if(serial_fase==True): #arduinoから応答があった 37 print('ok start...\n') 38 break; 39 elif(serial_fase==False): #arduinoから応答がなかった 40 print('\n 1st error\n') 41 break; 42 43 (以下略)

Arduino側のソースコードは以下のコードです。

Arduino

1char data[128]; 2int count=0; 3float a[4]; 4char*tp; 5int flag=0; 6int i; 7 8void reset_arr(); 9 10void setup() { 11 // put your setup code here, to run once: 12 Serial.begin(9600); 13 memset(data,'\0',128); 14} 15 16void loop() { 17 // put your main code here, to run repeatedly: 18 while (Serial.available() > 0){ 19 data[count]=Serial.read(); 20 if(data[count]=='/' || data[count]=='\0'){ 21 data[count]='\0'; 22 count=0; 23 break; 24 } 25 else if(count>=127){ 26 count=0; 27 break; 28 } 29 else { 30 count++; 31 } 32 delayMicroseconds(1025); //1.025[ms] 33 } 34 35 if( (strstr(data,"start")) != NULL){ 36 Serial.println("ok go"); 37 flag=1; 38 reset_arr(); 39 } 40 41 else if( (strstr(data,",")) != NULL){ 42 for(i=0;i<4;i++){ 43 if(i==0){ 44 a[i]=atof( strtok(data,",") ); 45 } 46 else { 47 a[i]=atof( strtok(NULL,",") ); 48 } 49 Serial.println(a[i]); 50 } 51 52 Serial.println("end"); 53 flag=0; 54 reset_arr(); 55 } 56 57 else if(data[0]!='\0'){ 58 Serial.println("error"); 59 reset_arr(); 60 } 61} 62 63void reset_arr(){ 64 for(i=0;i<sizeof(data);i++){ 65 data[i]='\0'; 66 } 67}

###試したこと
baudrateの値を変えてみたり、parityなどのオプション(?)も設定したりしたが変わらなかった。
baudrateの値はArduino と揃えてある。
タイムアウトの時間を減らしていったところ、0.9秒まではちゃんと動作することが確認できた。

###補足情報(言語/FW/ツール等のバージョンなど)
win10 64bitでAnaconda2を使用。

parityなどの設定で参考にしたのは以下のページです。
https://yoheikoga.github.io/2016/08/14/serial-communication-by-python/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2017/02/08 09:16

Arduino側ソース(read後sleep有無など)も提示したほうが回答えられやすいと思います。
guest

回答1

0

ベストアンサー

すみません。
pythonのserialモジュールでの正しい通信方法(blocking)について以前調査したのですが
結局正解が見つかりませんでした。

「こうすればいけるかも」という程度で参考にしてください。

Python

1# 方法1 : 私が使っているコード 2data = ser.read(1) 3n = ser.inWaiting() 4if n: data = data + ser.read(n) 5 6# 方法2 : 公式サンプル miniterm での例 7# https://github.com/pyserial/pyserial/blob/master/serial/tools/miniterm.py 8data = ser.read(ser.in_waiting or 1) 9 10# 方法3 : 末尾"\r\n"あるので、単純に以下でよいかも 11data = ser.readline()

識者の回答を待ちたいと思います。

投稿2017/02/08 09:55

can110

総合スコア38234

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lefirea

2017/02/08 12:30

回答ありがとうございます! 教えていただいた方法を試してみましたが、結果変わりませんでした…。
lefirea

2017/02/11 10:32

返信ありがとうございます。 その方法を試したところ、上手く動きました! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問