使用 Pyserial 延迟读取时 Arduino 串行缓冲区泛滥

问题描述

我正在从事一个项目,其中 RFID-RC522 阅读器读取 RFID 卡,将读取的数字拉入,然后通过串行中继输出代码如下:

#include <SPI.h>
#include <RFID.h>
#define SS_PIN 10
#define RST_PIN 9

RFID rfid(SS_PIN,RST_PIN);
String rfidCard;
void setup() {
  Serial.begin(9600);
  //Serial.println("Starting the RFID Reader...");
  SPI.begin();
  rfid.init();
}
void loop() {
  if (rfid.isCard()) {
    if (rfid.readCardSerial()) {
      rfidCard = (String(rfid.serNum[0]) + String(rfid.serNum[1]) + String(rfid.serNum[2]) +  String(rfid.serNum[3]));
      Serial.print(rfidCard);
    }
    rfid.halt();
  }
}

那部分效果很好。在python方面,以下代码在我的电脑上运行并读取一切正常:

import serial
import time
connected = False
#This port below is specific to my usb port I think
port = '/dev/cu.usbserial-14620'
baud = 9600


serial_port = serial.Serial(port,baud,timeout=0)

while True:

   reading = serial_port.readline().decode()
   if reading != '':
         print(reading)

因此,当我将 RFID 阅读器插入我的 arduino Nano,并将 Nano 插入我的计算机并运行 Python 代码时,最终结果是:当我将 RFID 卡放在阅读器上时,它会连续打印数字,当我把它拉开时,它什么也没打印。看起来像这样:

786179181
786179181
786179181
786179181
786179181
786179181

正是我想要的。

这就是问题开始的地方。我想在python脚本中引入一段时间,它不会读取任何内容。一种延迟,其中 RFID 阅读器基本上不可用。这段代码是我试图获得的效果的最小可重现示例:

i = 5

while i > 0:
   print(i)
   time.sleep(1)
   i-=1

当我在串行初始化行之前添加代码时,它会打印从 5 到 1 的倒计时,然后打开端口并开始读取和打印。但是看起来如果我在倒计时结束之前将卡放在读卡器上,它会将它读取的所有内容添加到缓冲区中,然后在允许端口再次打印后立即将其全部发送出去。对我来说最奇怪的是它实际上开始循环发送垃圾邮件,即使我把卡拿走也是如此。从现在开始,arduino 现在陷入了垃圾数据的这种状态——即使我终止了 python 脚本并重新运行它,并且没有将任何卡放在读卡器上,它仍然在无限循环中向旧数据发送垃圾邮件.它看起来更像这样,有时会堆叠成一行:

786179181786179181786179181786179181
786179181
786179181786179181786179181786179181786179181

我尝试过使用 flush()reset_input_buffer()reset_output_buffer() 之类的命令,但它们似乎没有做我想要的,或者我可能不完全了解如何他们工作。我不完全确定我的问题是出在 arduino 代码输出还是 Python 代码输入上。

解决方法

好的,我可以使用以下方法使其工作。

在 arduino 中,写入代码仅在它从 python 接收到一些东西时才执行:

#include <SPI.h>
#include <RFID.h>
#define SS_PIN 10
#define RST_PIN 9

RFID rfid(SS_PIN,RST_PIN);
String rfidCard;
void setup() {
  Serial.begin(9600);
  SPI.begin();
  rfid.init();
}
void loop() {
  if (rfid.isCard()) {
    if (rfid.readCardSerial()) {
      if (Serial.available()){
        rfidCard = (String(rfid.serNum[0]) + String(rfid.serNum[1]) + String(rfid.serNum[2]) +  String(rfid.serNum[3]));
        Serial.println(rfidCard);
      }
    }
    rfid.halt();
  }
}

在python中,只有当我想接收数据时,即延迟过去后,它才会将数据发送到arduino:

import serial
import time


port = '/dev/cu.usbserial-14620'
baud = 9600

serial_port = serial.Serial(port,baud,timeout=1)

i = 5

while i > 0:

   print(i)
   time.sleep(1)
   i-=1 

while True:

   serial_port.write(b'1') 

   try:

      reading = serial_port.readline().decode().rstrip()
      print(reading)

   except:

      pass

这具有一次打印一行数据而无需任何收集的缓冲区数据的预期效果。

感谢大家的帮助!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...