Lector de barras + RFID RC522

Hola yo tengo un problema para que funcione el lector de codigo de barras ( que conectado a un arduino uno mediante un usb host shield) con el RFID RC522, el problema mas detallado es que cuando funciona el RFID no funciona el lector y viceversa. En el programa tambien esta conectado una pantalla lcd 16x2 con i2c.
A continuacion procedere a poner el programa que me da error

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <hidboot.h>
#include <hiduniversal.h>
#include <SPI.h>
#include <MFRC522.h>

// Definiciones de botones
#define BOTON_INICIO 6
#define BOTON_FIN 7

// Definiciones de la pantalla LCD y lector RFID
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define RST_PIN  9    // Pin para reset del RC522
#define SS_PIN  8    // Pin 8 para SS (SDA) del RC522
MFRC522 mfrc522(SS_PIN, RST_PIN); 

String DataBarcode;       // Almacena el código de barras leído
bool x = false;           // Variable para indicar si el código está completo
bool listaActiva = false; // Variable para controlar si la lista está activa
bool accesoSolicitado = false; // Control de acceso

String materiales[2] = {"", ""}; // Array para los 2 materiales visibles en pantalla

class KbdRptParser : public KeyboardReportParser {
    void PrintKey(uint8_t mod, uint8_t key);

  protected:
    void OnControlKeysChanged(uint8_t before, uint8_t after);
    void OnKeyDown(uint8_t mod, uint8_t key);
    void OnKeyUp(uint8_t mod, uint8_t key);
    void OnKeyPressed(uint8_t key);
};

byte ActualUID[4]; //almacenará el código del Tag leído
byte Usuario1[4]= {0xE6, 0x25, 0x37, 0xD5}; //código del usuario 1
byte Usuario2[4]= {0x85, 0xD2, 0xAE, 0x75}; //código del usuario 2

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) {
  uint8_t c = OemToAscii(mod, key);  // Convierte a ASCII
  if (c) {
    OnKeyPressed(c);  // Envía la tecla presionada
  }
}

void KbdRptParser::OnKeyPressed(uint8_t key) {
  if (key == 0x0D) {    // Si se presiona Enter (0x0D en ASCII)
    x = true;           // Señala que se completó la lectura del código
  } else {
    DataBarcode += (char)key;  // Agrega el carácter al código de barras
  }
}

USB Usb;
HIDUniversal Hid(&Usb);
KbdRptParser Prs;

// Lista de códigos de barras y materiales
const int numMateriales = 3;
String codigos[numMateriales] = {"1145", "1146", "1147"};
String nombresMateriales[numMateriales] = {"Martillo", "Destornillador", "Pie metalico"};

// Función para buscar el material asociado al código de barras
String obtenerMaterial(String codigo) {
  for (int i = 0; i < numMateriales; i++) {
    if (codigo == codigos[i]) {
      return nombresMateriales[i];
    }
  }
  return "Material desconocido";
}

// Función de comparación de UID de usuarios
boolean compareArray(byte array1[], byte array2[]) {
  for (int i = 0; i < 4; i++) {
    if (array1[i] != array2[i]) return false;
  }
  return true;
}

// Verificación de acceso por RFID
void verificarAcceso() {
  lcd.setCursor(0, 0);
  lcd.print("Ingresar tarjeta");

  if (mfrc522.PICC_IsNewCardPresent()) {
  if (mfrc522.PICC_ReadCardSerial()) {
    Serial.println("Tarjeta detectada");
   Serial.print(F("Card UID: "));
      for (byte i = 0; i < mfrc522.uid.size; i++) {
        Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(mfrc522.uid.uidByte[i], HEX);   
        ActualUID[i] = mfrc522.uid.uidByte[i];          
      }
      Serial.println(); // Salto de línea para mejor lectura
      
      // Comparamos los UID para determinar si es uno de nuestros usuarios  
      if(compareArray(ActualUID,Usuario1)){
                    Serial.println("Acceso concedido... Bienvenido profesora Muras");
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print("Acceso");
                    lcd.setCursor(0, 1);
                    lcd.print("Concedido");
                    delay (2000);
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print("Bienvenido");
                    lcd.setCursor(0, 1);
                    lcd.print("profesor Muras");
                    accesoSolicitado = true;
                
                  }
                  
                  else if(compareArray(ActualUID,Usuario2)){
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print("Acceso");
                    lcd.setCursor(0, 1);
                    lcd.print("Concedido");
                    delay (2000);
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print("Bienvenido");
                    lcd.setCursor(0, 1);
                    lcd.print("profesor Teran");
                    accesoSolicitado = true;
                  }
                 } 
                 else {
                    Serial.println("Error al leer tarjeta");
                    Serial.println("Acceso denegado...");
                    lcd.clear();
                    lcd.setCursor(0, 0);
                    lcd.print("Acceso");
                    lcd.setCursor(0, 1);
                    lcd.print("Denegado...");
                    
                  }
      }
      delay(2000);
      lcd.clear();
      lcd.print("Inicie lectura");
      mfrc522.PICC_HaltA();
    }
    
// Configuración inicial
void setup() {
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();

  pinMode(BOTON_INICIO, INPUT_PULLUP);
  pinMode(BOTON_FIN, INPUT_PULLUP);

  lcd.setCursor(0, 0);
  lcd.print("Presiona inicio");

  SPI.begin();              // Inicializar SPI
  mfrc522.PCD_Init();       // Inicializar lector MFRC522
  Serial.println("Control de acceso:");
}

// Función para mostrar los materiales en pantalla
void actualizarPantalla() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(materiales[0]);
  lcd.setCursor(0, 1);
  lcd.print(materiales[1]);
}

// Bucle principal
void loop() {
  Usb.Task();
  if (!accesoSolicitado) {
    verificarAcceso();
    return;
  }

  // Botón de inicio
  if (digitalRead(BOTON_INICIO) == LOW && !listaActiva && accesoSolicitado == true) {
    listaActiva = true;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Lectura activa");
    delay(500);
  }

  // Botón de fin
  if (digitalRead(BOTON_FIN) == LOW && listaActiva) {
    listaActiva = false;
    accesoSolicitado = false; // Restablecer acceso para nueva autorización
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Esperando acceso...");
  }

  // Si la lista está activa y se lee un código de barras
  if (x && listaActiva == true) {
    String material = obtenerMaterial(DataBarcode);
    materiales[0] = materiales[1];
    materiales[1] = material;

    actualizarPantalla();

    // Resetea variables
    x = false;
    DataBarcode = "";
  }
}

Supuestamente escuche que el problema puede deberse a que ambos utilizan SPI por lo tanto asigne diferentes pines SS para cada uno siendo 8 para el RFID y 10 para el usb host shield. Ademas de que cuando comento Usb.Task() el RFID funciona bien y cuando no lo comento es el lector de barras el que funciona.
Tambien probe por separado con dos programas diferentes que pondre a continuacion:

Para el lector de barras con pantalla lcd con i2c

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <hidboot.h>
#include <hiduniversal.h>
#include <SPI.h>

// Definiciones de botones
#define BOTON_INICIO 2
#define BOTON_FIN 3

// Definiciones de la pantalla LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Dirección I2C y tamaño de la pantalla (16x2)

String DataBarcode;  // Almacena el código de barras leído
bool x = false;      // Variable para indicar si el código está completo
bool listaActiva = false; // Variable para controlar si la lista está activa

String materiales[2] = {"", ""}; // Array para los 2 materiales visibles en pantalla

class KbdRptParser : public KeyboardReportParser {
    void PrintKey(uint8_t mod, uint8_t key);

  protected:
    void OnControlKeysChanged(uint8_t before, uint8_t after);
    void OnKeyDown(uint8_t mod, uint8_t key);
    void OnKeyUp(uint8_t mod, uint8_t key);
    void OnKeyPressed(uint8_t key);
};

// Función para manejar las teclas presionadas
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) {
  uint8_t c = OemToAscii(mod, key);  // Convierte a ASCII
  if (c) {
    OnKeyPressed(c);  // Envía la tecla presionada
  }
}

void KbdRptParser::OnKeyPressed(uint8_t key) {
  if (key == 0x0D) {    // Si se presiona Enter (0x0D en ASCII)
    x = true;           // Señala que se completó la lectura del código
  } else {
    DataBarcode += (char)key;  // Agrega el carácter al código de barras
  }
}

// Inicialización del USB
USB Usb;
HIDUniversal Hid(&Usb);
KbdRptParser Prs;

// Lista de códigos de barras y materiales relacionados
const int numMateriales = 3; // Número de materiales a definir
String codigos[numMateriales] = {"1145", "1146", "1147"}; // Ejemplo de códigos de barras
String nombresMateriales[numMateriales] = {"Martillo", "Destornillador", "pie metalico"}; // Nombres de los materiales

// Función para buscar el material asociado al código de barras
String obtenerMaterial(String codigo) {
  for (int i = 0; i < numMateriales; i++) {
    if (codigo == codigos[i]) {
      return nombresMateriales[i];  // Devuelve el nombre del material
    }
  }
  return "Material desconocido"; // Si no se encuentra el código
}

// Configuración inicial
void setup() {
  Serial.begin(115200);
  lcd.init();          // Inicializa la pantalla LCD
  lcd.backlight();     // Enciende la retroiluminación

  pinMode(BOTON_INICIO, INPUT_PULLUP); // Botón de inicio (con resistencia interna)
  pinMode(BOTON_FIN, INPUT_PULLUP);    // Botón de fin (con resistencia interna)

  lcd.setCursor(0, 0);
  lcd.print("Presiona inicio");

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
    return;
  }

  Hid.SetReportParser(0, &Prs);
}

// Función para desplazamiento en la pantalla
void actualizarPantalla() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(materiales[0]); // Material 1 en la primera línea
  lcd.setCursor(0, 1);
  lcd.print(materiales[1]); // Material 2 en la segunda línea
}

// Bucle principal
void loop() {
  Usb.Task();

  // Detecta el botón de inicio
  if (digitalRead(BOTON_INICIO) == LOW && !listaActiva) {
    listaActiva = true;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Lectura activa");
    delay(500);
  }

  // Detecta el botón de fin
  if (digitalRead(BOTON_FIN) == LOW && listaActiva) {
    listaActiva = false;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Lectura finalizada");
    delay(1000);
    lcd.clear();
    lcd.print("Presiona inicio");
    return;
  }

  // Si la lista está activa y se lee un código de barras
  if (x && listaActiva) {
    // Buscar el material relacionado con el código de barras
    String material = obtenerMaterial(DataBarcode);

    // Mueve los materiales en la lista
    materiales[0] = materiales[1];        // El material de la segunda línea pasa a la primera
    materiales[1] = material;             // El nuevo material en la segunda línea
    
    actualizarPantalla();  // Actualiza la pantalla LCD con el desplazamiento

    // Resetea las variables para el siguiente código
    x = false;
    DataBarcode = "";
  }
}

void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {}
void KbdRptParser::PrintKey(uint8_t mod, uint8_t key) {}
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) {}

Para el RFID RC522

#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
  

#define RST_PIN  9    //Pin 9 para el reset del RC522
#define SS_PIN  8   //Pin 10 para el SS (SDA) del RC522
MFRC522 mfrc522(SS_PIN, RST_PIN); ///Creamos el objeto para el RC522



void setup() {
  lcd.init();                      
  lcd.backlight();
  Serial.begin(9600); //Iniciamos La comunicacion serial
  SPI.begin();        //Iniciamos el Bus SPI
  mfrc522.PCD_Init(); // Iniciamos el MFRC522
  Serial.println("Control de acceso:");
}

byte ActualUID[4]; //almacenará el código del Tag leído
byte Usuario1[4]= {0xE6, 0x25, 0x37, 0xD5} ; //código del usuario 1
byte Usuario2[4]= {0x85, 0xD2, 0xAE, 0x75} ; //código del usuario 2
void loop() {
  // Revisamos si hay nuevas tarjetas  presentes
  lcd.setCursor(0, 0);
  lcd.print("Ingresar");
  lcd.setCursor(0, 1);
  lcd.print("Tarjeta");
  if ( mfrc522.PICC_IsNewCardPresent()) 
        {  
      //Seleccionamos una tarjeta
            if ( mfrc522.PICC_ReadCardSerial()) 
            {
                  // Enviamos serialemente su UID
                  Serial.print(F("Card UID:"));
                  for (byte i = 0; i < mfrc522.uid.size; i++) {
                          Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
                          Serial.print(mfrc522.uid.uidByte[i], HEX);   
                          ActualUID[i]=mfrc522.uid.uidByte[i];          
                  } 
                  lcd.setCursor(0,0);
                    lcd.print("                ");
                    lcd.setCursor(0,1);
                    lcd.print("                ");              
                  //comparamos los UID para determinar si es uno de nuestros usuarios  
                  if(compareArray(ActualUID,Usuario1)){
                    Serial.println("Acceso concedido... Bienvenido profesora Ramos");
                    
                    lcd.setCursor(0, 0);
                    lcd.print("Acceso");
                    lcd.setCursor(0, 1);
                    lcd.print("Concedido");
                    delay (2000);
                    lcd.setCursor(0,0);
                    lcd.print("                ");
                    lcd.setCursor(0,1);
                    lcd.print("                ");
                    lcd.setCursor(0, 0);
                    lcd.print("Bienvenido");
                    lcd.setCursor(0, 1);
                    lcd.print("profesor Javier");
                
                  }
                  
                  else if(compareArray(ActualUID,Usuario2)){
                    
                    lcd.setCursor(0, 0);
                    lcd.print("Acceso");
                    lcd.setCursor(0, 1);
                    lcd.print("Concedido");
                    delay (2000);
                    lcd.setCursor(0,0);
                    lcd.print("                ");
                    lcd.setCursor(0,1);
                    lcd.print("                ");
                    lcd.setCursor(0, 0);
                    lcd.print("Bienvenido");
                    lcd.setCursor(0, 1);
                    lcd.print("profesor Teran");
                    
                  }
                  else{
                    Serial.println("Acceso denegado...");
               
                    lcd.setCursor(0, 0);
                    lcd.print("Acceso");
                    lcd.setCursor(0, 1);
                    lcd.print("Denegado...");
                    
                  }
                  // Terminamos la lectura de la tarjeta tarjeta  actual
                  mfrc522.PICC_HaltA();
                    delay (2000);
                    lcd.setCursor(0,0);
                    lcd.print("                ");
                    lcd.setCursor(0,1);
                    lcd.print("                ");
            }
      
  }
}

//Función para comparar dos vectores
 boolean compareArray(byte array1[],byte array2[])
{
  if(array1[0] != array2[0])return(false);
  if(array1[1] != array2[1])return(false);
  if(array1[2] != array2[2])return(false);
  if(array1[3] != array2[3])return(false);
  return(true);
}

En el primer código falta iniciar el USB en setup()

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
    return;
  }

Parece que no prestaste atención al código de ejemplo, solo copiaste y pegaste.

Moderador
Todo bien posteado pero sin querer olvidaste algo que será beneficioso como práctica presente y futura.
Postea siempre además de los códigos, el error (se postea igual que el código, con etiquetas) que tienes porque ahí está el problema. Claramente hoy no lo ves, pero con el tiempo lograrás identificar que lo que ahi se informa permite resolverlo rápidamente.
Si no pones el error, nosotros debemos cargar tu código y agregar las librerías solo para reproducir tu mismo error.

Tenlo presente.

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