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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Q&A

解決済

3回答

4255閲覧

シリアル通信で続けて2つのデータの送信を試みるが、1つ目しか送信されない

suhsuu

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

0グッド

0クリップ

投稿2018/09/06 15:10

前提・実現したいこと

ラズパイから複数のデータをシリアル通信によってPCへ送信したいが、下記のような問題が生じています。
コードのどの部分に不都合があるのかわかりません。

発生している問題・エラーメッセージ

ラズパイ側、PC側のそれぞれで各コードを実行すると、一つ目の”105”しかPCに転送されない。(”107”の値がPC側で出力されない)

該当のソースコード

Python3

1 2ラズパイ側 3# -*- coding: utf-8 -*- 4import serial 5 6# 文字列をシリアル送信 \n区切りで 7def stamp_to_pc(stamp_string="hello"): 8 port = serial.Serial( 9 port = "/dev/ttyS0", 10 baudrate=115200, 11 parity = serial.PARITY_NONE, 12 stopbits = serial.STOPBITS_ONE, 13 bytesize = serial.EIGHTBITS, 14 timeout = 0 15 ) 16 print(stamp_string) 17 stamp_string = stamp_string + "\n" 18 stamp_bytes = stamp_string.encode('utf-8') #文字列をバイト型に変換 19 print(stamp_bytes) 20 21 port.write(stamp_bytes) 22 port.close() 23 24height_size = 105 #この値をPCに送りたい 25width_size = 107 #この値をPCに送りたい 26 27height_stamp_string = str(height_size) 28stamp_to_pc(height_stamp_string) 29width_stamp_string = str(width_size) 30stamp_to_pc(width_stamp_string) 31 32 33PC側 34# -*- coding: utf-8 -*- 35import serial 36 37# 文字列をシリアル受信 \n区切りで 38def stamp_receive(): 39 ser = serial.Serial( 40 port = "COM6", 41 baudrate=115200, 42 parity = serial.PARITY_NONE, 43 stopbits = serial.STOPBITS_ONE, 44 bytesize = serial.EIGHTBITS, 45 timeout = None 46 ) 47 stamp_bytes = ser.readline() #\nまで受信 48 stamp_str = stamp_bytes.rstrip().decode("UTF-8") #バイト型を文字列変数に変換 49 50 ser.close() 51 return stamp_str 52 53height_size_str = stamp_receive() 54height_size = int(height_size_str) 55print(height_size) 56 57width_size_str = stamp_receive() 58width_size = int(width_size_str) 59print(width_size) 60

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

余計かとは思いますが・・

初期化→送信→閉じる、を毎回やってることになりますね、非効率的です。プロのエンジニアの立場から見て、これは「正常に送受信できている」とは言えません。

とりあえず手っ取り早く1回きりのデモができればいいんであればまぁいいのかと思います。
継続的に安定して動作するものを作りたいのか、あるいは効率を求めるならよろしくないです。

他の方からも指摘されてますが、てっとり早く動かせたらいいにしても、根本的な原理が理解できてないと、きちんと動くものは絶対作れないですね。それで本当にいいですか?って思います。まぁ伝わらないだろうなぁとは思いますが。

投稿2018/09/07 15:37

yutakau8255

総合スコア99

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

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

suhsuu

2018/09/07 21:45

おっしゃる通り手っ取り早くデモできるようにと作っています。 しかし、そうはいっても、何回もデモを繰り返すことになると思います。また、初心者とはいえ、いや、むしろ初心者であるからこそ、本来あるべき姿を学びあるべきように作りたいと思っております。 修正すべき点として具体的には、初期化動作は一度だけにすべきなのですね。一方、ポートの開閉は送信のたびに行うべきなのでしょか?それとも、ポートも開けっ放し? アドバイスして頂けると助かります。
yutakau8255

2018/09/08 04:39

初期化もポートオープン・クローズも一度だけでよいはずです。 初期化した際にはIOポートの設定がされますので、シリアルピンに余計な信号が出る可能性があります。 ポートオープン、クローズでは送受信のバッファがクリアされます。その時にバッファに入っていたデータは消えますので、トラブルのもとです。
suhsuu

2018/09/09 07:03

なるほど。勉強になります。 続けて別のデータを送受信させたくて、万が一、前のデータがバッファに残っていると困るのでクリアさせたいという場合は、reset_input_buffer()やreset_output_buffer()を使うべきということでしょうか。
yutakau8255

2018/09/09 12:48

reset_input_bufferなど、バッファをクリアするコマンドもあるかと思いますが、そのクリアした直後にデータが受信されることもあり得るわけですよね?向こうがいつデータを送ってこようとも、「前のデータがバッファに残っていると困る」ことが無い設計をするのが、本筋と思います。
suhsuu

2018/09/11 21:05

コメントありがとうございます。 「前のデータがバッファに残っていると困る」ことが無い設計というのがどのような設計なのかを知りたいです。お手数でなければ、具体例を教えてもらえないでしょうか?コードそのものではなく、具体例のコードが記載されたページなどを知らせて頂くなどでも構いません。よろしくお願いします。
yutakau8255

2018/09/11 22:43

「前のデータがバッファに残っていると困る」のは、suhsuuさんが書かれたコメントです。
guest

0

stamp_receive 関数では、シリアルの初期設定を行ってreadlineしてますが、
初期設定した時点でシリアルポートの受信バッファはクリアされてしまいます

2行分受信していたとしても、2行目の初期設定で受信データはクリアされ、受信できません。

シリアルポートの初期設定はプログラム開始時1回だけ実行するようにしましょう

投稿2018/09/06 22:30

y_waiwai

総合スコア87774

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

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

suhsuu

2018/09/06 22:36

送信が2つ立て続けに来て、1つ受信しあとバッファがクリアされるから2つ目が受信されないということですね。
y_waiwai

2018/09/11 23:17

なんか勘違いされてる蝶ですが、なんでいちいち初期設定したいんでしょうか。 通話が終わったからスマホの電源を切る、電話が来るはずだから電源を入れる、という使い方してるとまずい、というのは理解できるでしょうか?
guest

0

自己解決

ラズパイ側コードにて、
2つのシリアル送信の間に以下のようにtime.sleep(1)を入れると正常に送受信できました。

height_stamp_string = str(height_size)
stamp_to_pc(height_stamp_string)

time.sleep(1)

width_stamp_string = str(width_size)
stamp_to_pc(width_stamp_string)

投稿2018/09/06 22:33

suhsuu

総合スコア15

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

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

y_waiwai

2018/09/07 14:48

それでいいの?
suhsuu

2018/09/07 21:47

初学者なもので、どこがいけないのか理解しておりませんでした。 上記の方が指摘されていることが懸念されている点でしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問