14

pyserialを使用してデータをarduinoに送信しようとしています。しかし、COMポートを開くと、DTRが低く設定され、ボードがリセットされます。ただし、2つのボタンを1秒間押し続けて、シリアル受信モードにする必要があるように、arduinoコードを設定しています。可能であれば、arduinoの起動時にシリアル入力を行う必要はありません。

どうやら、serialWin32.pyファイルを変更して、次の行を変更できます。

self._dtrState = win32.DTR_CONTROL_ENABLE

に:

self._dtrState = win32.DTR_CONTROL_DISABLE

しかし、Pythonスクリプトでこれを直接無効にする方法はありますか?また、すべてのシステムでこれを行う必要があります。このスクリプトを使用するためだけに、基本のシリアル構成を変更するように強制したくはありません。

シリアルポートは次のように開かれます。

 com = serial.Serial(port, baud, timeout=1);

更新:最終的に、セットアップに適したソリューションを見つけました。常にシリアルデータを処理する必要がなかったので、デバイスをシリアル受信モードにしたときにのみ、arduino自体からのシリアル接続のリセットを無効にする方法を見つけました。

多くの投稿では、5Vとリセットの間に約100オームの抵抗を配置することでDTRリセットを無効にできると述べています。しかし、私はこれが永続的なものになることを望んでいませんでした。そこで、代わりにPD5とリセットの間に抵抗を配置しました。次に、ソフトウェアで:

void setup() {
    //.......
    DDRD &= ~(_BV(PD5)); //Set PD5 as input initially
    PORTD |= (_BV(PD5)); //Set high
    //.......
}

inline void setResetDisable(bool state)
{
  if(state)
    DDRD |= (_BV(PD5)); //Set PD5 as output to put 5V on reset line
  else
    DDRD &= ~(_BV(PD5)); //set back to input mode
}

したがって、シリアルモードにしたい場合は、setResetDisable(true)を呼び出します。これにより、100オームの抵抗とリセットピンに5Vがスローされ、DTRがそれをローに引き下げてチップをリセットするのを防ぎます:)次に、setResetDisable(false)を呼び出します。 )チップを通常どおりにプログラムできるように、シリアルモードを終了するとき。

4

5 に答える 5

15

次のように、ポートを開く前にDTRを無効にできる必要があります。

com = serial.Serial()
com.port = port
com.baudrate = baud
com.timeout = 1
com.setDTR(False)
com.open()

ただし、Windows上のpyserial(2.6)の現在のリリースでこれを行うと、次の例外がスローされます。

..., line 315, in setDTR
ValueError: Attempting to use a port that is already open

これは、ソースの最新バージョンである2011年12月29日のSVNリビジョン445で修正されたバグのようです(http://pyserial.svn.sourceforge.net/viewvc/pyserial/trunk/pyserial/serial/serialwin32を参照)。 py?view = log)コメント付き:

Win32で開く前にsetRTS、setDTRを許可(初期状態を設定するため)、ドキュメントの更新

2.6リリースを見逃した可能性があるようです(2011年11月2日にアップロードされました:https ://pypi.python.org/pypi/pyserialを参照)。

さらに、( serialposix.py内の)setDTR()for POSIXの現在の実装を見ると、このバグは修正されておらず、ポートが開いていない場合は例外がスローされるため、クロスプラットフォームソリューションはありそうにありません。

于 2013-03-18T14:21:17.013 に答える
6

DTRを無効にしても機能しません。
ser.dtr = None
(Linux 4.4.0 x86_64 / Python 2.7.12 / PySerial 3.4)

しかし、これは機能します:

import serial
import termios

port = '/dev/ttyACM0'
f = open(port)
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
f.close()
se = serial.Serial()
se.baudrate = 115200
se.port = port
print 'dtr =', se.dtr
se.open()

ここで見つけました。

于 2017-08-03T04:49:05.453 に答える
2

あなたが説明する方法は、私が見たこの問題の最も一般的な解決策のようです-したがって、より単純なソフトウェアベースの解決策はないと思います。もちろん、を使用してDTR回線の状態を手動で変更することもできますがser.setDTR(level)、Arduinoの自動リセットの場合は特にこれを試していません。シリアルポートを開いた直後に回線を切り替えるだけでも、十分な速度が得られない可能性があります。リセットを防ぎます。

私が利用できる他のオプションは、ハードウェアでのArduinoの自動リセットを防ぐこと(ここを参照)、または最初にシリアル接続を行った後にArduinoを再起動できるようにコードを少し変更することです。シリアル受信モードを手動でトリガーして、Arduinoから初期信号を送信し、データを受信する準備ができたことを示します。または、スクリプトにpySerialライブラリの変更バージョンを含めることもできます。

于 2013-03-18T13:37:26.477 に答える
0

これは古いトピックですが、現在、シリアルデータをarduinoに送信するプログラムに取り組んでいます。これは私にとって確実に機能するラインです:

ser = serial.Serial(port = 'COM4', baudrate = 115200, timeout = 0.1, dsrdtr=None)

注:引数は「dsrdtr」であり、パラメーターは「False」ではなく「None」です。

テスト済み:Python 3.8.8、anaconda 3(2021.05)、pyserial 3.5 Arduino Mega2560、MKR WiFi 1010、Wemos Mega2560 + ESP8266

于 2021-12-01T17:52:48.863 に答える
-2

これがソフトウェアソリューションです。私はしばらくの間それを自分で使用していて、それは魅力のように機能します。

ser = serial.Serial("/dev/ttyUSB0", 115200, timeout=1)
ser.setDTR(False)
time.sleep(0.5)

睡眠はトリッキーな部分であり、それなしでは機能しないことに注意してください

于 2013-08-28T22:02:19.597 に答える