0

I'm working on a project where an RFID-RC522 reader reads an RFID card, pulls that read number in, and relays in out via serial. The code for that is as follows:

#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();
  }
}

That part works great. On the python side, the following code runs on my computer and reads everything in fine:

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)

So the end result when I plug in the RFID reader to my arduino Nano, and the Nano into my computer, and run the Python code is: When I put an RFID card up to the reader, it continuously prints the number, and when I pull it away, it prints nothing. Looks like this:

786179181
786179181
786179181
786179181
786179181
786179181

Exactly what I want.

Here's where the problems start. I want to introduce a period of time in the python script where it won't read anything. A sort of delay where the RFID reader is essentially not useable. This code is a minimally reproducible example of the effect I'm trying to get:

i = 5

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

When I add this code right before the Serial initialization line, it prints a countdown from 5 to 1, and then opens the port and starts reading and printing. But it looks like if I place the card on the reader before the countdown is up, it adds all that it reads to a buffer, and then spams it all at once, once the port is allowed to print again. What's most strange to me is that it actually begins to spam it in a loop, even when I take the card away. And from here on out, the arduino is now stuck in this state of spamming the data - even if I terminate the python script and rerun it, and dont put any card up to the reader, it's still spamming that old data in an infinite loop. It Looks more like this, stacking into one line at times:

786179181786179181786179181786179181
786179181
786179181786179181786179181786179181786179181

I've tried using commands like flush(), reset_input_buffer(), and reset_output_buffer(), but they don't seem to do what I want, or maybe I don't completely understand how they work. I'm not entirely sure if my problem lies in the arduino code output or the python code input.

9
  • It's been awhile, but isn't there some kind of input flow control like in the old XON-XOFF RS232 protocol supported? Commented Jul 21, 2021 at 22:34
  • Add delay to your Arduino code, not in the python code. or you could add the logic where if the card is continuously present, only send the data to python once. Commented Jul 22, 2021 at 1:33
  • @martineau I have no idea what that is but I will look into it, thanks for the idea Commented Jul 22, 2021 at 2:25
  • @hcheung unfortunately I need the delay in my python code, as it is acting as the "master" program. It's not actually going to be a fixed time delay, but rather an event driven delay, depending on other factors. The time delay was a simple way to recreate the problem. For your second idea, I really need it to continuously read, because whether or not the card is currently on the reader is part of what determines what I do with that data, if that makes sense Commented Jul 22, 2021 at 2:29
  • From what you described, you don't need the delay in python, you need to make your python code non-blocking. On the Arduino side, not to send data over serial doesn't mean not continuously reading, it is two different different things. You can also send the state (card-present) along with the reading to the python code as well if it help python code to know what's going on. Commented Jul 22, 2021 at 2:36

1 Answer 1

0

Alright, I was able to get this to work using the following methods.

In the arduino, the write code only executes if it's receiving something from 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();
  }
}

In python, it sends data to the arduino only when I want to receive data back, i.e., after the delay has passed:

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

This has the desired effect of printing one line of data at a time without any collected buffer data.

Thank you everyone for you assistance!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.