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