PySerial没有和Arduino说话

时间:2011-11-16 09:51:47

标签: python windows serial-port arduino pyserial

我已经编写了一些代码来模拟我正在使用的一些硬件并将其上传到Arduino板。这段代码有效。我知道这一点,因为我得到了HyperTerminal的预期响应。

但是,当我尝试使用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()

注意:Arduino上的代码在对命令的响应结束时发回\r\n

超级终端配置:

COM4 configuration in HyperTerminal

修改

我发现如果我将超时增加到10秒并在发送任何内容之前添加sp.readline(),那么我会得到对这两个命令的响应。

PySerial与Arduino或USB RS-232端口之间通常有多长时间的硬件握手?

4 个答案:

答案 0 :(得分:4)

无法验证这一点,但可能是您在那里有任何数据之前尝试阅读,因此您没有得到回复。

要对此进行测试,您可以尝试并轮询,直到有数据

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

修改

当您打开串行连接时,Arduino将重置,启动期间写入的任何数据都可能会进入天堂。在进行任何读/写操作之前,您可以使用2秒钟的休眠时间(无法找到确切的时间,可能会有所不同)。

或者你可以写信给它,直到你收到回复,在你得到回报之后你开始做“真正的工作”。

答案 1 :(得分:2)

暂时我正在使用解决方法。我已将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()

答案 2 :(得分: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板。

答案 3 :(得分:0)

您可以使用兼容的库SerialTransfer.hpySerialTransfer在Python和Arduino板之间轻松强大地进行连接和通信。这些库使用开始/结束标记,循环冗余检查,一致的开销字节填充和动态有效载荷长度来自动打包和解析串行数据包。

SerialTransfer.h可通过Arduino IDE的库管理器安装,而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);
  }
}