Serial arduino lento

Acabo de realizar un proyecto en el que tengo unos 20 arduinos nano, cada uno de ellos con un RFID rc522, conectados mediante RS485 a una raspberry pi, la cual tiene una base de datos SQL.
Los arduinos leen el UID de la tarjeta, la mandan al la raspberry, que consulta si existe ese UID en la base de datos y luego mandan el OK o el KO al terminal de nuevo.
Cuando hay pocas personas pasando las tarjetas no hay problemas ya que desde que se pasa la tarjeta hasta que da el OK o KO pasan unos pocos milisegundos
Pero en las "horas punta" en las que muchísimas personas pasan sus tarjetas en cada arduino ese tiempo puede demorar casi 1 segundo, o incluso no obtener respuesta.
He comprobado que la velocidad de cada consulta es de milisegundos, y que la raspberry devuelve al serial el comando de Ok o KO al instante, así que ese no es el cuello de botella.

#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN  9    //Pin 9 para el reset del RC522
#define SS_PIN  10   //Pin 10 para el SS (SDA) del RC522
MFRC522 mfrc522(SS_PIN, RST_PIN); //Creamos el objeto para el RC522

const int mydireccion = 101;
const int EnTxPin =  2;  // HIGH:TX y LOW:RX
const int Buzzer = 8;
const int LEDR = 5;
const int LEDG = 6;
const int LEDB = 7;
int TPING = 5000; //tiempo entre ping y ping
int TLED1 = 30;  // tiempo que esta el LED Azul
int TLED2 = 500; // tiempo led verde
int TLED3 = 500; //Tiempo led rojo
int INICIO = 3000; //Tiempo led azul inicio
unsigned long tiempoAnterior = 0;  //guarda tiempo de referencia para comparar



void setup() {
  
  SPI.begin();        //Iniciamos el Bus SPI
  mfrc522.PCD_Init(); // Iniciamos  el MFRC522
  
  Serial.begin(115200);
  
  pinMode(Buzzer , OUTPUT);
  pinMode(LEDR , OUTPUT);
  pinMode(LEDG , OUTPUT);
  pinMode(LEDB , OUTPUT);
  pinMode(EnTxPin, OUTPUT);
  digitalWrite(EnTxPin, LOW); //RS485 como receptor
  digitalWrite(Buzzer , LOW);
  digitalWrite(LEDR , HIGH);
  digitalWrite(LEDG , HIGH);
  digitalWrite(LEDB , LOW);
  delay(1000);
  digitalWrite(LEDB , HIGH);
  digitalWrite(LEDG , LOW);
  delay(1000);
  digitalWrite(LEDG , HIGH);
  digitalWrite(LEDR , LOW);
  delay(1000);
  digitalWrite(LEDR , HIGH);
  
       
}


void(* resetFunc) (void) = 0; //declare reset function @ address 0

void loop() {
  // Revisamos si hay nuevas tarjetas  presentes
  
  
  if(millis()-tiempoAnterior>=TPING){
       digitalWrite(EnTxPin, HIGH);
       tiempoAnterior=millis();
       Serial.print("I");
       Serial.print(",");
       Serial.print(mydireccion);
       Serial.print(",");
       Serial.print("P");
       Serial.print(",");
       Serial.print("F"); //fin de trama
       Serial.println();
       Serial.flush(); //Esperamos hasta que se envíen los datos
       digitalWrite(EnTxPin, LOW); //RS485 como receptor             
       }
  
  
  if ( mfrc522.PICC_IsNewCardPresent()) 
      {  
        //Seleccionamos una tarjeta
        if ( mfrc522.PICC_ReadCardSerial()) 
          {
            // Enviamos serialemente su UID
            digitalWrite(EnTxPin, HIGH);
            Serial.print("I");
            Serial.print(",");
            Serial.print(mydireccion);
            Serial.print(",");
            Serial.print("C");
            Serial.print(",");
            Serial.print(mfrc522.uid.uidByte[0], HEX);
            Serial.print(mfrc522.uid.uidByte[1], HEX);
            Serial.print(mfrc522.uid.uidByte[2], HEX);
            Serial.print(mfrc522.uid.uidByte[3], HEX);
            Serial.print(",");
            Serial.print("F"); //fin de trama
            Serial.println();
            Serial.flush(); //Esperamos hasta que se envíen los datos
            digitalWrite(EnTxPin, LOW); //RS485 como receptor             
          } 
      } 
                          // Terminamos la lectura de la tarjeta  actual
                          mfrc522.PICC_HaltA();
                  
  if(Serial.available()>0)
    {
      char valor = Serial.read();
      switch (valor){
        
        case 'R':
        resetFunc();
        break;   
        
        case 'I':
        int direccion=Serial.parseInt(); //recibimos la direccion 
        if(direccion==mydireccion) //Si direccion es la nuestra
            {
              char comando=Serial.read();
              switch (comando){
                case 'P':
                digitalWrite(LEDB , LOW);
                delay(1);
                digitalWrite(LEDB , HIGH);
                break;
                
                case 'V':
                digitalWrite(LEDG , LOW);
                digitalWrite(Buzzer , HIGH);
                delay(100);
                digitalWrite(LEDG , HIGH);
                digitalWrite(Buzzer , LOW);
                break;
                
                case 'X':
                digitalWrite(LEDR , LOW);
                digitalWrite(Buzzer , HIGH);
                delay(500);
                digitalWrite(LEDR , HIGH);
                digitalWrite(Buzzer , LOW);
                break;

                case 'R':
                resetFunc();
                break; 
              } 
            }
        break;    
         
      }
             
   }
}

Es como si los arduinos tardaran en asimilar las respuestas cuando hay muchos datos seguidos en la malla

¿Alguna ayuda?

parseInt () tiene un tiempo de espera de 1 s, que podría estar relacionado.

        int direccion = Serial.parseInt(); //recibimos la direccion

Sugeriría estudiar Serial Input Basics para manejar esto

también debe agregar {} cuando usa una variable local en un switch/case

case 'I':
  { // <===== !!!
        int direccion=Serial.parseInt(); //recibimos la direccion 
        if(direccion==mydireccion) //Si direccion es la nuestra
            {
     ...
  } // <======== !!
 break;

Me queda una duda con el "ping".
¿Lo necesitas exactamente cada 5 segundos?
Imagino que "ping" genera una respuesta del master
¿Qué sucede si justo antes de enviar los datos de tarjeta se envía el "ping"?

¿Y si reinicias tiempoAnterior también luego de enviar los datos de la tarjeta?
Así tu "ping" se envía cada 5 segundos pero a partir de los 5 segundos de leída una tarjeta.
Si esto fuese posible, cambiaría el orden de las sentencias, primero haría el manejo de la tarjeta luego el del "ping", así el "ping" no podría interferir con el manejo de tarjetas

Saludos

Moderador:
No abras mas hilos del mismo tema, tus 20 esclavos mas el Raspi, okay?
Voy a unir los hilos porque estas cometiendo una falta grave a las normas. Posteos cruzados multiples.
Los temas que consideres cerrados me respondes por privado.

Muchas gracias por las recomendaciones, las tendré en cuenta. El ping lo puse a 5 segundos por poner, sin motivo en especial, y sirve para que el master de respuesta y saber que el esclavo tiene comunicación.

Efectivamente, el parselnt() hacia lenta la letura de la malla.
solucionado poniendo en el setup un Serial.setTimeout de unos 10 o 15 milisegundos y luego poniendo un Serial.readString y cambiando los switch por unos cuantos if

Doy el tema por solucionado

bien hecho

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