8
  • Python バージョン: 2.6.6
  • PySerialバージョン: 2.5
  • Arduino ボード: Duemilanove 328

使用しているハードウェアをシミュレートするコードをいくつか作成し、Arduino ボードにアップロードしました。このコードは機能します。ハイパーターミナルから期待どおりの応答が得られるので、これはわかっています。

ただし、PySerial を使用して接続しようとすると、接続はエラーになりませんが、送信したコマンドに応答がありません。

これはなぜでしょうか?

Python コード

import serial

def main():
    sp = serial.Serial()
    sp.port = 'COM4'
    sp.baudrate = 19200
    sp.parity = serial.PARITY_NONE
    sp.bytesize = serial.EIGHTBITS
    sp.stopbits = serial.STOPBITS_ONE
    sp.timeout = 0.5
    sp.xonxoff = False
    sp.rtscts = False
    sp.dsrdtr = False

    sp.open()

    sp.write("GV\r\n".encode('ascii'))
    value = sp.readline()
    print value
    sp.write("GI\r\n".encode('ascii'))
    value = sp.readline()
    print value

    sp.close()
 
if __name__ == "__main__":
    main()

\r\n注意: Arduino のコードは、コマンドへの応答の最後に送り返します。

ハイパーターミナル構成:

ハイパーターミナルでの COM4 構成

編集

タイムアウトを 10 秒に増やし、sp.readline()何かを送信する前に a を追加すると、両方のコマンドに対する応答が得られることがわかりました。

PySerial と Arduino または USB RS-232 ポート間のハードウェア ハンドシェイクは通常どのくらいの時間ですか?

4

5 に答える 5

5

これを確認することはできませんが、そこにデータが存在する前に読み取ろうとして、応答がない可能性があります。

これをテストするには、データが存在するまでポーリングを試みることができます

value = None
while not value:
   value = sp.readline()
print value

編集

Arduino は、シリアル接続を開くとリセットされます。起動中に書き込まれたデータは、ビット天国に行く可能性があります。読み取り/書き込みを行う前に、2 秒間スリープを使用することができます (正確な所要時間はわかりませんが、いずれにせよ変化する可能性があります)。

または、応答が返されるまで書き込みを行うこともできます。応答が返された後は、「実際の作業」を開始します。

于 2011-11-16T10:40:55.047 に答える
3

当分の間、私は回避策を使用しています。timeoutを1.5 秒に設定しreadline、最初の書き込みの前に呼び出しを入れました。

したがって、Python コードは次のようになります。

import serial

def main():
    sp = serial.Serial()
    sp.port = 'COM4'
    sp.baudrate = 19200
    sp.parity = serial.PARITY_NONE
    sp.bytesize = serial.EIGHTBITS
    sp.stopbits = serial.STOPBITS_ONE
    sp.timeout = 1.5 #1.5 to give the hardware handshake time to happen
    sp.xonxoff = False
    sp.rtscts = False
    sp.dsrdtr = False

    sp.open()

    sp.readline() #to give the hardware handshake time to happen

    sp.write("GV\r\n".encode('ascii'))
    value = sp.readline()
    print value
    sp.write("GI\r\n".encode('ascii'))
    value = sp.readline()
    print value

    sp.close()

if __name__ == "__main__":
    main()
于 2011-11-16T16:52:24.907 に答える
2

私も最近この問題に遭遇しましたが、これが私の解決策です:

import serial

ser = serial.Serial(4, timeout=2)
ser.setRTS(True)
ser.setRTS(False)
while 1:
    line = ser.readline()
    print(line)
ser.close

これにより、Arduinoボードが正常にリセットされることがわかりました。

于 2012-07-04T02:37:27.360 に答える
1

Arduino がリセットされ、ブートローダーが新しいファームウェアのリッスンを開始するため、ポートを開いた後に遅延を追加します。その時点で何かが送信された場合、MCU はブートローダーでスタックしたままになります。遅延により、ブートローダーがタイムアウトします。

sp.open()
time.sleep(2) # 2 seconds or possibly a bit less
sp.write("blahblah")
于 2016-08-16T13:24:23.737 に答える
0

互換性のあるライブラリSerialTransfer.hおよびpySerialTransferを使用して、Python ボードと Arduino ボードの間で簡単かつ堅牢に接続および通信できます。これらのライブラリは、開始/終了マーカー、巡回冗長検査、一貫したオーバーヘッド バイト スタッフィング、動的ペイロード長を使用して、シリアル パケットを自動的にパケット化し、解析します。

SerialTransfer.h は Arduino IDE の Libraries Manager からインストールでき、pySerialTrasnfer は pip インストール可能です。

例の Python:

from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM13')

        link.txBuff[0] = 'h'
        link.txBuff[1] = 'i'
        link.txBuff[2] = '\n'

        link.send(3)

        while not link.available():
            if link.status < 0:
                print('ERROR: {}'.format(link.status))

        print('Response received:')

        response = ''
        for index in range(link.bytesRead):
            response += chr(link.rxBuff[index])

        print(response)
        link.close()

    except KeyboardInterrupt:
        link.close()

Arduino の例:

#include "SerialTransfer.h"
#include <SoftwareSerial.h>


SoftwareSerial mySerial(2, 3); // RX, TX
SerialTransfer myTransfer;


void setup()
{
  Serial.begin(115200);
  mySerial.begin(9600);
  myTransfer.begin(mySerial);
}

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';

  myTransfer.sendData(3);
  delay(100);

  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}
于 2020-02-10T00:07:48.463 に答える