Pyserial 在读取串行数据之前读取空字节

问题描述 投票:0回答:1

我有一个 Arduino 通过串行端口输出字符 0 - 9

void setup() {

  Serial.begin(9600);

}

void loop() {

  for(int i = 0; i < 10; i++){

    Serial.print(i);
    delay(200);

  }

}

我正在使用以下Python代码在PC上接收数据,

import serial

usbport = 'COM3'
ser     = serial.Serial(usbport, 9600, timeout=1)

count = 0
while ser.in_waiting < 1 and count < 5:
    
    p = ser.read(10)
    p = p.decode()
    print(p, type(p))
    count += 1
    
ser.close()

每当串行通信启动时,Arduino 都会重置(在本例中这很好),但我注意到 Python 代码总是在读取串行数据之前拾取一个空字节。

输出示例,

 <class 'str'>
0123456789 <class 'str'>
0123456789 <class 'str'>
0123456789 <class 'str'>
0123456789 <class 'str'>

总是这样,有人知道为什么吗?

还有一个奖励点,谁能告诉我为什么我必须放

while ser.in_waiting < 1
才能让它工作,而不仅仅是
while ser.in_waiting

pyserial
1个回答
0
投票

空字节是因为串口连接的原因。一般来说,如果您向 arduino 添加一些代码,这样它会在发送命令时启动该过程:

void setup() {
  Serial.begin(9600);
}

void loop() {
  // Wait for a command from the serial port
  while (!Serial.available()) {
    // Do nothing until a command is received
  }

  // Read the command from the serial port
  String command = Serial.readStringUntil('\n');

  // Check if the received command is "start"
  if (command == "start") {
    // Start sending numbers 0-9
    for (int i = 0; i < 10; i++) {
      Serial.print(i);
      delay(200);
    }
  }
}

在这种情况下,当您向arduino端口写入

"start\n".encode()
时,它将开始循环过程一次。

此外,我通常在使用端口之前先flushInput和flushOutput,专门为了避免这样的事情:

usbport = 'COM3'
ser = serial.Serial(usbport, 9600, timeout=1)
time.sleep(1) # sleep to give enough time for the arduino to initialize
ser.flushInput() # flush input
ser.flushOutput() # flush output

现在,您可以使用您的代码,并添加以下命令:

count = 0 # init count
ser.write("start\n".encode()) # write the command to start
while ser.in_waiting < 1 and count < 5:
    p = ser.read(10)
    p = p.decode()
    print(p, type(p))
    count += 1
ser.close()

另外,关于你的最后一个问题,使用

ser.in_waiting < 1
,你正在检查输入缓冲区中是否少于一个字节,这相当于检查缓冲区是否为空。 IE。如果你只检查
!ser.in_waiting
,那就更明确了。

© www.soinside.com 2019 - 2024. All rights reserved.