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

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

新規登録して質問してみよう
ただいま回答率
85.48%
シリアルポート

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

Python

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

Q&A

解決済

4回答

10553閲覧

Pythonのシリアル通信で機器が制御できない

dinosauria123

総合スコア25

シリアルポート

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

Python

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

0グッド

0クリップ

投稿2018/07/06 07:13

編集2018/07/10 06:24

前提・実現したいこと

Pythonからの機器のシリアル制御

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

WinPythonのコマンドプロンプトでは装置が制御できるが、スクリプト(.py)にして実行させると装置が反応しなくなる

該当のソースコード

Python

1import serial 2 3ser = serial.Serial(port="COM5", baudrate=115200, bytesize=8, parity="N", stopbits=1, timeout=None, xonxoff=False, rtscts=False, write_timeout=None, dsrdtr=False, inter_byte_timeout=None, exclusive=None) 4 5ser.close 6time.sleep(1) 7ser.open 8 9ser.write(b"F3\n\r") #F3は機器の制御コマンド 10 11ser.close() 12

試したこと

ser.write(b"F3\n\r") の前後にtime.sleepを入れて実行のタイミングを変えてみたが、装置は反応しなかった。

Linux上のPythonでも試したが、装置は反応しなかった。

baudrateを変えても装置は反応しなかった。

シリアルポートの出力を見ると文字列は出力できている。改行コードか?
VBでは動いていて、vbcrlfを改行コードに使っている。

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

WinPython3.6.5

この話と似ています(Python2.5ですが)

http://d.hatena.ne.jp/kinneko/20070926/p3

コマンドプロンプトからの実行、装置が動きます

コマンドプロンプトからの実行、装置が動きます。最後に「4」が出力されます。

2018.7.9追記
ロジアナでコマンドプロンプトとスクリプトの出力を見てみましたが、全く同じでした。(ますますわからなくなりました...)

装置の構成について詳しく書くと、制御PCからUSBケーブルを変換回路を介して装置のSCSIに繋いでいます。USBーSCSI変換回路はシリアル入出力となっています。

PC =>USBケーブル =>USBーSCSI変換回路 =>SCSIデジタルマルチメーター

出力信号をモニタする時はUSBシリアル変換回路を介してみています。

PC =>USBケーブル =>USBシリアル変換回路 =>USBロジアナ(モニタ用PC)

コマンドライン実行
コマンドライン実行

スクリプトファイル実行
スクリプトファイル実行

なにか大ポカをしていないか心配ですが....

2018.7.10追記
オシロの波形です。

コマンドライン実行
コマンドライン実行

スクリプトファイル実行
スクリプトファイル実行

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

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

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

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

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

guest

回答4

0

自己解決

解決しました!非常に恥ずかしい話なのですが、原因は「ポートのOPEN命令から装置制御命令までの待ち時間が短すぎた」でした。

VBで動いていたのはポートのOPENから実際の装置の操作まで数秒以上の空きがある
(プログラム上では見えなくて、人間が操作するのに時間がかかっている)ためでした。

VBではコマンド入力後500msで反応があったので、ポートのオープンもその程度待てば大丈夫
と思っていたのですが、実際にはその数倍の時間が必要だったことに気づかなかったのでした...

原因に気づいたきっかけは、コマンドプロンプトに一行ではなく、プログラム全部を一気にコピペ
して実行させたら装置が反応しなかったことでした。コマンドプロンプトでうまくいっていたのも、
人間がコピペするのに数秒かかっていた(この時間がプログラムでsleepさせるのと等価だった)
ためでした。

凡ミスで回答者の方の貴重なお時間を浪費させてしまい、申し訳ありませんでした。
大変恥ずかしいのですが、他山の石となれば幸いです。

投稿2018/07/11 02:52

dinosauria123

総合スコア25

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

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

0

まずは別PCにシリアルポートをつないで、Teratermなどで実際にデータが送信されているか見てみればどうでしょうか

投稿2018/07/06 07:18

y_waiwai

総合スコア87774

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

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

dinosauria123

2018/07/06 07:20

ありがとうございます。それは試してみていて、制御コマンドの文字列は送られているようでした。 改行コードかもしれません。VisualBasicでは制御できていて、改行コードはvbcrlfです。
y_waiwai

2018/07/06 07:27

なら、動くものと動かないもの、それぞれデータを見て違いがないか見てみる、また、シリアルポートのコントロールラインの状態によって送信できる/できないの判定をしてる場合があるので、そこらへんチェックしてみることでしょうか。(提示されたコード上ではちゃんとなってるようですが)
dinosauria123

2018/07/06 07:33

ありがとうございます。シリアルコンソール上の文字の出力では、スクリプトで送っても、コマンドプロンプトから送っても違いがみえません。 コントロールラインは見ていませんが、考えてみます。
dinosauria123

2018/07/06 07:34

これは、オシロでチェック、となりますかね。
y_waiwai

2018/07/06 07:35

オシロでチェックできるなら、その装置につないで送信データを見てみましょう
dinosauria123

2018/07/06 07:37

コマンド入力の前後に非表示文字が何かありそうですね。ありがとうございます。 ちょっと大変そうですが…
guest

0

明示的に制御線を無効にするとか

python

1ser.open 2ser.rtscts=False 3ser.dsrdtr=False 4ser.rts=False 5ser.dtr=False

投稿2018/07/09 06:37

ozwk

総合スコア13521

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

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

dinosauria123

2018/07/09 06:48

ありがとうございます。 上記コードをデジタルマルチメーターの制御命令のすぐ上に入れて実行してみましたが、ファイルに保存したスクリプトでは、やはり装置が反応しませんでした。 ちょっと気になってきたのは、上の補足情報で書いたようにコマンドプロンプトからの実行では実行後に「4」と出力されるのですが、ファイルに保存したスクリプトの実行後には何も表示されないのです...
ozwk

2018/07/09 06:51

それは別にwriteの戻り値をprint()すれば出てくるんじゃないですかね?
dinosauria123

2018/07/09 06:54

ありがとうございます。必ず標準出力に出力するというわけではないのですね。
mather

2018/07/09 08:21 編集

僕の方のコメントでも書いているのですが、「4」は書き込まれたバイト数です。機器からの応答ではありません。
guest

0

python

1ser.close 2time.sleep(1) 3ser.open

この部分、関数を参照しているだけで呼び出し(実行)してませんよね?正しくはこうなるのでは。

python

1ser.open()

投稿2018/07/06 07:23

mather

総合スコア6753

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

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

dinosauria123

2018/07/06 07:27

ありがとうございます。ご指摘の方法でおこなうと、Port already openとなります。 上の行の宣言のみでポートは開くようです。 ser.close() time.sleep(1) ser.open() としてもスクリプトでは装置は反応しませんでした。
mather

2018/07/06 07:31

ところで、CRLFを改行として送ってるんですよね? \r = CR \n = LF なので\n\r ではなくて \r\n だと思うんです。 あと、F3ってF3キーのことではなくて文字列でいいんですよね?
dinosauria123

2018/07/06 07:35

ありがとうございます。ご指摘のとおりですね。逆にしてもスクリプトでは動きませんでした。 (コマンドプロンプトでは問題なく動く) F3はファンクションキーではなく、文字列になります。
mather

2018/07/06 07:40

む。「Port already openとなります」ということは既にポートは開いているので、close, open は必要ないのでは。 serial.Serial() の後すぐに ser.write() を実行してみてはいかがでしょうか。
dinosauria123

2018/07/06 07:44

ありがとうございます。そのようにスクリプトを改善してみましたが、やはりスクリプトからは装置が反応しません。コマンドプロンプトでPython立ち上げて、直に入れると動くのですが…
mather

2018/07/06 07:53

コマンドプロンプトでの入出力の内容をそのまま質問に追記することは可能ですか?
dinosauria123

2018/07/06 07:59

はい、上に画像を追加しましたのでご参照ください。
dinosauria123

2018/07/06 08:01

家に帰りますので、お返事は来週になります…ありがとうございます!
mather

2018/07/06 08:07

コンソールに表示されてる '4' はシリアルポートからの応答値ではなくて、書き込んだバイト数です。 https://pythonhosted.org/pyserial/pyserial_api.html#serial.Serial.write ser.writeの返り値を print などで表示しても同じ結果になると思いますし、応答されたデータをチェックする場合はser.readも必要かと思います。 「装置が動いた」というのはどうやって判断しているんでしょうか?
dinosauria123

2018/07/06 08:53

ありがとうございます。装置はデジタルマルチメーターでして、この測定レンジ等をシリアル接続したパソコンから切り替えられるかどうかで判断しています。
mather

2018/07/06 08:58

なるほど。 参考までに「VBでは動いていて」という部分のコードが見てみたいですね。
dinosauria123

2018/07/06 09:01

了解です。こちらは来週の回答となります。 重ねてありがとうございます!
dinosauria123

2018/07/08 23:34

VBですとこれで動いています。ラジオボタンを選択するとデジタルマルチメーターのレンジが変わる、というやつです。 ''' Private Sub RadioButton1_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged 'シリアルポートをオープンしていない場合、処理を行わない. If SerialPort1.IsOpen = False Then MsgBox("シリアルポートが開いていません") Return End If SerialPort1.Write("F1") Threading.Thread.Sleep(500) SerialPort1.Write(vbCrLf) Threading.Thread.Sleep(500) End Sub ''' 今日アマゾンから1000円USBロジアナが届くので、これで観察したいと思います。
mather

2018/07/09 08:24

コマンドプロンプトで書いた内容をそのまま書いてみればどうでしょうか。open, close は最終行も含めてすべてコメントアウトして実行してみてください。
dinosauria123

2018/07/10 06:26 編集

ありがとうございます。ご提案の方法を試しましたが、結果は変わりませんでした。 オシロでも波形を見まして、USB-シリアル基板を出る信号については差がないことがわかりました。 となればUSB-SCSI変換基板の入力信号があやしいなぁとプローブを当てていたら基板から煙が… どこかをショートさせてしまったようです。 USB-SCSI変換基板を再度入手して確認しようと思います。 重ねてありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問