Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Arduino串行半双工:Arduino读取以前的串行输入,而不是当前输入_Python_Arduino_Serial Port_Rfid_Spi - Fatal编程技术网

Python Arduino串行半双工:Arduino读取以前的串行输入,而不是当前输入

Python Arduino串行半双工:Arduino读取以前的串行输入,而不是当前输入,python,arduino,serial-port,rfid,spi,Python,Arduino,Serial Port,Rfid,Spi,我正在使用Python 3.7.5和最新版本的串行库。我正试图通过python和arduino制作一个RFID认证设备。用户必须扫描连接到arduino的RFID中的ID,arduino必须将UID发送到python软件。在我的笔记本电脑中,一个线程正在监听串行数据。它检查UID,如果允许,则发送“O”,如果不允许,则发送“X”。在arduino中,如果有数据通过串口发送,程序将等待,然后检查输入是否为“O”。如果RX为“O”,则LED必须为绿色,否则为红色 我的问题是,当我第一次扫描正确的ui

我正在使用Python 3.7.5和最新版本的串行库。我正试图通过python和arduino制作一个RFID认证设备。用户必须扫描连接到arduino的RFID中的ID,arduino必须将UID发送到python软件。在我的笔记本电脑中,一个线程正在监听串行数据。它检查UID,如果允许,则发送“O”,如果不允许,则发送“X”。在arduino中,如果有数据通过串口发送,程序将等待,然后检查输入是否为“O”。如果RX为“O”,则LED必须为绿色,否则为红色

我的问题是,当我第一次扫描正确的uid时,它会变成绿色,没问题。如果我扫描另一个正确的uid,它会再次变为绿色,没有问题。如果我扫描了一个不正确的uid,它会变成绿色,但在我的python代码中它应该是红色的。然后如果我扫描一个正确的uid,它会变成红色,而is应该是绿色。我尝试向arduino和python添加延迟,以等待前一个输入清除,并尝试在传输后刷新,但没有成功

tl;博士 arduino延迟一次uid扫描输出结果,我不知道还能做什么。

Python:

# Reads data from the serial monitor without interrupting the main thread

from serial import Serial
import time
from threading import Thread

class SerialListener:
    def __init__(self, baudrate=9600, timeout=1):
        try:
            self.ser = Serial('/dev/ttyACM0', baudrate, timeout=timeout)
        except:
            self.ser = Serial('/dev/ttyACM1', baudrate, timeout=timeout)

        self.stopped = False
        self.paused = False
        self.stream = ''
        time.sleep(1) # Wait for serial buffer to reset

    def start(self):
        Thread(target=self.update, args=()).start()
        return self

    def update(self):
        if not self.paused:
            while True:
                if self.stopped:
                    self.ser.close()
                    print("Serial Thread Stopped")
                    print("Serial Port Closed")
                    break
                try:
                    self.stream = self.ser.readline().decode('utf-8')
                except:
                    self.stream = self.ser.readline().decode('ascii')
                self.stream = self.stream.rstrip()

    def stop(self):
        self.stopped = True

    def pause(self):
        self.paused = True

    def flush(self):
        self.ser.flush()

    def readDistance(self):
        try:
            return float(self.stream)
        except:
            return -1   # Returns -1 if there is an error in reading

    def readRFID(self):
        return self.stream

    def write(self, msg):
        self.ser.write(msg.encode())

if __name__ == "__main__": # FOR DEBUGGING ONLY
    uno = SerialListener().start()
    uno.flush()
    print("Serial Started")
    uid = ''
    while True:
        uid = uno.readRFID()
        if uid is not '':
            uno.flush()
            time.sleep(0.1)
            if uid == "5BEE9F0D":
                uno.write('O')
                print("SHOULD BE GREEN")
            else:
                uno.write('X')
                print("SHOULD BE RED")
            print(uid)

    uno.stop()
阿杜伊诺:

#include <MFRC522.h>
#define GREEN_LED 6
#define RED_LED 7
#define BUZZER 8

MFRC522 rfid(10, 9);

unsigned long timer = 0;
bool readStatus = false;

void setup() {
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  for(int i = 0; i < 10; i++)
    Serial.write('\n');
  delay(5);
  digitalWrite(RED_LED, HIGH);
}

void loop() {
  while(!readStatus){
    if(rfid.PICC_IsNewCardPresent()){
      if(rfid.PICC_ReadCardSerial()){
        byte uid[rfid.uid.size];
        if((millis() - timer) > 1000){
          for(int i = 0; i < rfid.uid.size; i++)
            uid[i] = rfid.uid.uidByte[i];

          for(int i = 0; i < sizeof(uid); i++){
            if(uid[i] < 0x10)
              Serial.print('0');

            Serial.print(uid[i], HEX);
          }
          Serial.println();
          readStatus = true;
          timer = millis();
        }
        Serial.flush();
      }
    }
  }

  if(readStatus){
    while(!Serial.available());

    char rx = 'X';

    while(Serial.available()){
      rx = Serial.read();
    }

    if(rx == 'O'){
    digitalWrite(GREEN_LED, HIGH);
    digitalWrite(RED_LED, LOW);
    tone(BUZZER, 2500);
    delay(100);
    noTone(BUZZER);
    readStatus = false;
    }
    else{
      digitalWrite(RED_LED, LOW);
      digitalWrite(GREEN_LED, LOW);
      tone(BUZZER, 1000);
      delay(50);
      noTone(BUZZER);
      delay(30);
      tone(BUZZER, 1000);
      delay(50);
      noTone(BUZZER);
      digitalWrite(RED_LED, HIGH);
      readStatus = false;
    }
  }
}

好的,我通过修改pyserial中的超时并在读取之间添加1秒延迟来解决这个问题

问题是,由于我如何设置条件,pyserial多次写入序列

while True:
    uid = uno.readRFID()
    if uid is not '':
        uno.flush()
        time.sleep(0.1)
        if uid == "5BEE9F0D":
            uno.write('O')
            print("SHOULD BE GREEN")
        else:
            uno.write('X')
            print("SHOULD BE RED")
        print(uid)
由于我设置的超时为1,PySerial将继续读取UID,直到超时。这将导致uid在一秒钟内不等于“”,并将不必要地多次向串行端口发送数据

在Arduino中,它只从缓冲区读取字符的一个字节,读取后,从缓冲区中删除所读取的内容。然而,python并不是只向序列发送1个字符,而是多次发送。这就是为什么Arduino在读取前一个缓冲区中的字符而不是python发送到序列号的新字符时输出错误的原因

为了解决这个问题,我将超时设置得更小,以便在达到超时后清除串行输入。不要将超时值设置得太低,否则可能无法读取数据

def __init__(self, baudrate=9600, timeout=0.5):
其次,我在主线程上添加了从串行读取之间的延迟

uid = ''
while True:
    while uid is '':
        uid = uno.readRFID()
    time.sleep(0.1)

    if uid == "5BEE9F0D":
        uno.write('O')
    else:
        uno.write('X')
    print(uid)
    time.sleep(1)
    uid = ''

Arduino中的代码工作正常,所以我没有改变这一点,唯一的问题是python代码本身。

“Arduino延迟一次uid扫描输出结果”--不,您没有提供任何证据,但您偶尔会看到错误的响应,例如,“it”应为绿色,而“it”则为红色。然后得出结论,这个错误的响应是由于“延迟”造成的。这不是因为延迟,我的意思是arduino从python读取之前的读数,而不是最近发送给arduino的读数。作为比较,它是这样的:pythonda=O;serialData=X;数字写入(LED、串行数据);serialData=pythonda;。换句话说,它输出前一个串行输入,而不是当前的串行输入。python读取SPI,当它接收到的UID时,它检查UID是否被允许。在本例中,我们将ID A定义为允许的,以便python通过SPI向arduino发送“O”。Arduino什么也不做,直到它从python接收到串行数据,然后出现“O”。由于接收到的数据为“O”,led将变为绿色。现在回到扫描,重复所有过程,但这次扫描ID B和python发送“X”,但在arduino中,RX显然是“O”。遗憾的是,我无法同时查看两个串行监视器来检查uno接收到的内容“换句话说,它输出的是以前的串行输入,而不是当前的串行输入。”--什么是“它”?您在哪里报告“当前串行输入”是什么?支持你主张的证据在哪里?你的Arduino逻辑不健全<代码>如果(rx=='O')。。。else是有问题的,因为它在执行操作之前不会验证输入的一个案例。顺便说一句,SPI不是“串行端口”。嗯,我认为这一定是因为python多次写入串行端口,因为条件设置为uid为“”时。很抱歉,我忘了提到这一点,但是python在没有收到任何信息之前会多次读取uid。一定是因为这个原因,我认为解决这个问题就能解决问题。我现在正在试。
uid = ''
while True:
    while uid is '':
        uid = uno.readRFID()
    time.sleep(0.1)

    if uid == "5BEE9F0D":
        uno.write('O')
    else:
        uno.write('X')
    print(uid)
    time.sleep(1)
    uid = ''