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

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

ただいまの
回答率

90.53%

  • Python

    7884questions

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

  • シリアルポート

    45questions

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

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

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 356

 前提・実現したいこと

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

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

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

 該当のソースコード

import serial

ser = 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)  

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

ser.write(b"F3\n\r") #F3は機器の制御コマンド

ser.close()  

 試したこと

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追記
オシロの波形です。

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+2

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/06 16:20

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

    キャンセル

  • 2018/07/06 16:27

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

    キャンセル

  • 2018/07/06 16:33

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

    コントロールラインは見ていませんが、考えてみます。

    キャンセル

  • 2018/07/06 16:34

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

    キャンセル

  • 2018/07/06 16:35

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

    キャンセル

  • 2018/07/06 16:37

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

    キャンセル

check解決した方法

+1

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

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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

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

ser.open()

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/06 16:27

    ありがとうございます。ご指摘の方法でおこなうと、Port already openとなります。
    上の行の宣言のみでポートは開くようです。

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

    としてもスクリプトでは装置は反応しませんでした。

    キャンセル

  • 2018/07/06 16:31

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

    キャンセル

  • 2018/07/06 16:35

    ありがとうございます。ご指摘のとおりですね。逆にしてもスクリプトでは動きませんでした。
    (コマンドプロンプトでは問題なく動く)

    F3はファンクションキーではなく、文字列になります。

    キャンセル

  • 2018/07/06 16:40

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

    キャンセル

  • 2018/07/06 16:44

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

    キャンセル

  • 2018/07/06 16:53

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

    キャンセル

  • 2018/07/06 16:59

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

    キャンセル

  • 2018/07/06 17:01

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

    キャンセル

  • 2018/07/06 17:07

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

    キャンセル

  • 2018/07/06 17:53

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

    キャンセル

  • 2018/07/06 17:58

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

    キャンセル

  • 2018/07/06 18:01

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

    キャンセル

  • 2018/07/09 08: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ロジアナが届くので、これで観察したいと思います。

    キャンセル

  • 2018/07/09 17:24

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

    キャンセル

  • 2018/07/10 15:18 編集

    ありがとうございます。ご提案の方法を試しましたが、結果は変わりませんでした。

    オシロでも波形を見まして、USB-シリアル基板を出る信号については差がないことがわかりました。
    となればUSB-SCSI変換基板の入力信号があやしいなぁとプローブを当てていたら基板から煙が…
    どこかをショートさせてしまったようです。

    USB-SCSI変換基板を再度入手して確認しようと思います。
    重ねてありがとうございました。

    キャンセル

+1

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

ser.open
ser.rtscts=False
ser.dsrdtr=False
ser.rts=False
ser.dtr=False

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/09 15:48

    ありがとうございます。
    上記コードをデジタルマルチメーターの制御命令のすぐ上に入れて実行してみましたが、ファイルに保存したスクリプトでは、やはり装置が反応しませんでした。

    ちょっと気になってきたのは、上の補足情報で書いたようにコマンドプロンプトからの実行では実行後に「4」と出力されるのですが、ファイルに保存したスクリプトの実行後には何も表示されないのです...

    キャンセル

  • 2018/07/09 15:51

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

    キャンセル

  • 2018/07/09 15:54

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

    キャンセル

  • 2018/07/09 17:20 編集

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

    キャンセル

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

  • ただいまの回答率 90.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    7884questions

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

  • シリアルポート

    45questions

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