Slow response via Serial Communication

Hello!
So, I recently started using Arduino Nano because I had a fantastic project I wanted to test out.
To get RFID data to my server and respond with the proper sound on the output buzzer, I used serial communication with the Arduino on my Raspberry Pi.

/*
 * -----------------------------------------------------------------------------------------
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 *
 * More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
 */

#include <SPI.h>
#include <MFRC522.h>
 
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

#define GREEN_LED 8
#define YELLOW_LED 7
#define RED_LED 6

byte nuidPICC[4];
int buzzerPin = 2;

void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void ReadRFID(){
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;

  if ( ! mfrc522.PICC_ReadCardSerial())
    return;
  
  if (mfrc522.uid.uidByte[0] != nuidPICC[0] || mfrc522.uid.uidByte[1] != nuidPICC[1] || mfrc522.uid.uidByte[2] != nuidPICC[2] || mfrc522.uid.uidByte[3] != nuidPICC[3] ) {

    // Store NUID into nuidPICC array
    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = mfrc522.uid.uidByte[i];
    }
    printHex(mfrc522.uid.uidByte, mfrc522.uid.size);
    Serial.println();
  } else {
    Serial.write("Card read previously.\n");
  }
}

void Version(){
  Serial.write("version\n");
}

void SerialParser(void) {
  char readChar[64];
  Serial.readBytesUntil(33,readChar,64);
  String read_ = String(readChar);
  //Serial.println(readChar);
  int idx1 = read_.indexOf('%');
  int idx2 = read_.indexOf('$');
  // separate command from associated data
  String cmd = read_.substring(1,idx1);
  String data = read_.substring(idx1+1,idx2);
  
  ReadRFID();
  if (cmd == "version") {
    Version();
  } else if (cmd == "success"){
    digitalWrite(GREEN_LED, HIGH);
    tone(buzzerPin, 440, 1000);
  } else if (cmd == "failed") {
    digitalWrite(RED_LED, HIGH);
    for (int i = 0; i < 2; i = i + 1) {
      tone(buzzerPin, 261, 500);
      delay(1000);
    }
  } else if (cmd == "offline") {
    digitalWrite(YELLOW_LED, HIGH);
    for (int i = 0; i < 3; i = i + 1) {
      tone(buzzerPin, 349, 500);
      delay(1000);
    }
  } else if (cmd == "idle"){
    delay(1000);
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(RED_LED, LOW);
    digitalWrite(YELLOW_LED, LOW);
  }
}

void setup() {
  Serial.begin(38400);
  SPI.begin();          // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  SerialParser();
}

Python Communication

import re
import itertools
import platform
import requests
import serial
import time
from serial.tools import list_ports
if platform.system() == 'Windows':
    import winreg
else:
    import glob

URL = "http://127.0.0.1:6969/api/v1/rfid"

def internet_connection():
    try:
        requests.get('http://1.1.1.1/') #Python 3.x
        return True
    except: return False

def enumerate_serial_ports():
    path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
    try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)
    except WindowsError: raise Exception

    for i in itertools.count():
        try:
            val = winreg.EnumValue(key, i)
            yield (str(val[1]))  # , str(val[0]))
        except EnvironmentError: break


def build_cmd_str(cmd, args=None):
    if args: args = '%'.join(map(str, args))
    else: args = ''
    return "@{cmd}%{args}$!".format(cmd=cmd, args=args)

def get_version(sr):
    cmd_str = build_cmd_str("version")
    try:
        sr.write(cmd_str.encode())
        sr.flush()
    except Exception: return None
    return sr.readline().decode().strip()

def find_port(baud, timeout):
    if platform.system() == 'Windows': ports = enumerate_serial_ports()
    elif platform.system() == 'Darwin': ports = [i[0] for i in list_ports.comports()]
    else: ports = glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*")
    for p in ports:
        print('[+] Found {0}, testing...'.format(p))
        try: sr = serial.Serial(p, baud, timeout=timeout)
        except (serial.serialutil.SerialException, OSError) as e:
            print(str(e))
            continue
        time.sleep(2)
        version = get_version(sr)
        if version != 'version':
            print('[+] Bad version {0}. This is not a Shrimp/Arduino!'.format(version))
            sr.close()
            continue
        print('[+] Using port {0}.'.format(p))
        if sr:
            return sr
    return None

def send_cmd(sr, cmd):
    cmd_str = build_cmd_str(cmd).encode()
    try:
        sr.write(cmd_str)
        sr.flush()
    except Exception: return None
    return sr.readline().decode().strip()

class IO_RFID():
    def __init__(self, baud=38400):
        self.baud = baud
        self.serial = find_port(self.baud, timeout=1)

    def read_tag(self):
        with self.serial as serial:
            regex = r'[0-9A-F]{2} [0-9A-F]{2} [0-9A-F]{2} [0-9A-F]{2}'
            while True:
                line = serial.readline().decode().strip()
                if re.match(regex, line):
                    tag = line.split(" ")[::-1]
                    tag = ''.join(tag)
                    tag = int(tag, 16)
                    print(f"[+] TAG: {tag}")
                    if internet_connection():
                        try:
                            response = requests.get(URL, params={"rfid": tag})
                            if response.json()['status_code'] == 3:
                                send_cmd(self.serial, "success")
                                send_cmd(self.serial, "idle")
                            elif response.json()['status_code'] in [1, 2, 4, 5, 6, 7, 8]:
                                send_cmd(self.serial, "failed")
                                send_cmd(self.serial, "idle")
                            elif response.json()['status_code'] == 9:
                                send_cmd(self.serial, "offline")
                                send_cmd(self.serial, "idle")
                        except:
                            send_cmd(self.serial, "offline")
                            send_cmd(self.serial, "idle")    
                    else:
                        send_cmd(self.serial, "offline")
                        send_cmd(self.serial, "idle")
if __name__ == '__main__':
    obj = IO_RFID(38400)
    obj.read_tag()

And?

When I put the RFID card, it responds around a minute later.

What is "it"? Have you tested the Arduino/Python communication separately to be sure it is responding properly and timely? Surely you can indicate when the Arduino sends and when the Python receive. When the Python send and when the Arduino receives. Are they both delayed by 1 minute?

1 Like

Hello abirabedinkhan

Welcome to the worldbest Arduino forum ever.

I assume that you have written the programme by yourself, then it is quite easy to find the error.

There's a trick to figuring out why something isn't working:

Use a logic analyzer to see what happens.
Put Serial.print statements at various places in the code to see the values of variables and determine whether they meet your expectations.

Have a nice day and enjoy coding in C++.

Only the Arduino responds min later but sometimes it responds instantly.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.