Caso práctico: fichaje RFID en SD con Arduino UNO

Caso práctico: fichaje RFID en SD con Arduino UNO — hero

Objetivo y caso de uso

Qué construirás: Un prototipo de hardware independiente que lee etiquetas RFID pasivas, obtiene la hora actual de un reloj de tiempo real (RTC) de precisión y registra el evento (UID y marca de tiempo) en un archivo CSV en una tarjeta microSD.

Por qué es importante / Casos de uso

  • Seguimiento de asistencia de estudiantes: Automatiza el registro en el aula mediante toques de tarjetas de identificación, eliminando pasar lista manualmente.
  • Registro de acceso a equipos de laboratorio: Proporciona un registro de auditoría sin conexión de quién usó exactamente una máquina específica y a qué hora.
  • Reloj de control de empleados: Actúa como un sistema básico de entrada/salida para pequeños talleres donde no hay conectividad de red disponible.
  • Auditoría de seguridad: Demuestra los principios fundamentales de los sistemas de control de acceso físico registrando los intentos de entrada en una puerta o portón.

Resultado esperado

  • Inicialización exitosa de los componentes del bus SPI compartido (microSD y RFID) y los componentes I2C (RTC).
  • Salida del monitor serie mostrando los UID de las tarjetas detectadas y las marcas de tiempo en tiempo real (latencia de lectura < 100ms).
  • Creación de un archivo ATTEND.CSV en la tarjeta microSD que contenga entradas de registro separadas por comas y con el formato adecuado.

Audiencia: Desarrolladores de sistemas embebidos y makers; Nivel: Intermedio

Arquitectura/flujo: Toque de etiqueta RFID → Lector RFID SPI → Microcontrolador → Obtención de marca de tiempo RTC I2C → Adición a CSV en microSD SPI

Nota educativa de validación

Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. El validador comprobó los bloques de código, la estructura del artículo, los comandos copiables y la coherencia con el catálogo de dispositivos soportados.

Evidencia de validación publicada

  • Resultado automático: PASS.
  • Estructura parseada: 3 apartados, 5 tablas y 2 bloques de código detectados antes de publicar.
  • Código comprobado: 2 Arduino/arduino-cli compile.
  • Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo y los stacks no soportados bloquean la publicación.
  • Hallazgos del informe: sin hallazgos bloqueantes.

Esta validación confirma compatibilidad sintáctica y de herramientas para el material publicado, pero no sustituye la prueba física sobre tu hardware, cableado y entorno exactos.

Nota educativa de seguridad

Este proyecto construye un prototipo educativo destinado al aprendizaje de la integración de hardware, el uso compartido del bus SPI y el registro de datos. No es un sistema de control de acceso seguro. Las etiquetas MIFARE Classic utilizadas comúnmente con el MFRC522 tienen vulnerabilidades criptográficas bien documentadas y

Diagrama de bloques conceptual

Vista de alto nivel: qué entra, qué procesa cada bloque y qué sale del sistema.

Arquitectura funcional

Toque de etiqueta RFID

Lector RFID SPI

Microcontrolador

Obtención de marca de tiempo RTC I2C

Adición a CSV en microSD SPI

Flujo conceptual de señales y responsabilidades entre bloques del dispositivo.

Ruta de validación

Sketch

arduino-cli compile

Upload

Prueba funcional

Resumen conceptual de las herramientas usadas para comprobar el material publicado.

Requisitos previos

Para completar con éxito este tutorial, necesitas:
* Comprensión básica de la programación en C++ y la estructura de un sketch de Arduino (setup() y loop()).
* Familiaridad con la comunicación serie y la lectura de las salidas del monitor serie.
* Una computadora con el arduino-cli (Interfaz de línea de comandos de Arduino) instalado y agregado al path de tu sistema.
* Una tarjeta microSD (32GB o menor) formateada en FAT32.
* Un cable USB Tipo-A a Tipo-B para programar y alimentar el Arduino UNO.

Materiales

  • Arduino UNO R3 (ATmega328P) + módulo RFID MFRC522 + módulo microSD SPI + RTC DS3231 (Hardware objetivo exacto).
  • Etiquetas o tarjetas RFID pasivas (13.56 MHz, compatibles con MFRC522, típicamente MIFARE Classic).
  • Protoboard y cables puente premium macho-macho y macho-hembra.
  • Tarjeta microSD (formateada en FAT32).

Configuración/Conexión

Este proyecto requiere un cableado cuidadoso porque dos módulos diferentes (el MFRC522 y el módulo microSD) deben compartir el único bus SPI de hardware del Arduino. El bus SPI utiliza líneas compartidas para datos (MOSI, MISO) y reloj (SCK), pero requiere pines de selección de chip (CS) únicos para cada dispositivo. El RTC DS3231 utiliza el bus I2C, que opera en pines separados.

Advertencia de distribución de energía

  • MFRC522: Debe ser alimentado con 3.3V. Aplicar 5V al pin VCC del MFRC522 lo dañará.
  • Módulo microSD: La mayoría de los módulos microSD estándar para Arduino tienen un regulador de voltaje y un cambiador de nivel integrados. Estos deben ser alimentados con 5V.
  • DS3231: Puede operar de manera segura a 5V.

Tablas de cableado

1. Módulo RFID MFRC522 (Bus SPI 1 – Lógica 3.3V)

Pin MFRC522Pin Arduino UNO R3Función / Nota
3.3V3.3VCRÍTICO: No conectar a 5V
RSTPin 9Control de reinicio
GNDGNDTierra común
IRQSin conectarNo se usa en esta implementación de sondeo
MISOPin 12Master In Slave Out (SPI compartido)
MOSIPin 11Master Out Slave In (SPI compartido)
SCKPin 13Reloj serie (SPI compartido)
SDA (CS)Pin 10Selección de chip para RFID

2. Módulo de Tarjeta MicroSD (Bus SPI 2 – Lógica 5V)

Pin MicroSDPin Arduino UNO R3Función / Nota
VCC5VAlimentación para el regulador integrado
GNDGNDTierra común
MISOPin 12Master In Slave Out (SPI compartido)
MOSIPin 11Master Out Slave In (SPI compartido)
SCKPin 13Reloj serie (SPI compartido)
CSPin 4Selección de chip para tarjeta SD

3. Módulo RTC DS3231 (Bus I2C)

Pin DS3231Pin Arduino UNO R3Función / Nota
VCC5VAlimentación
GNDGNDTierra común
SDAPin A4Datos I2C
SCLPin A5Reloj I2C

Código validado

El proyecto utiliza dos archivos de código separados. El primero es un sketch de utilidad para configurar la fecha y hora actuales en tu RTC DS3231. El segundo es la aplicación principal de registro de asistencia.

Sketch de utilidad: set_rtc_time.ino

Ejecuta este sketch una vez para programar el RTC con la hora de compilación actual de tu computadora.

/*
 * Utility: Set DS3231 RTC Time
 * This sketch sets the RTC to the date & time the sketch was compiled.
 */

#include <Wire.h>
#include <RTClib.h>

RTC_DS3231 rtc;

void setup() {
  Serial.begin(9600);
  while (!Serial) { delay(10); } // Wait for serial console

  Serial.println("Initializing RTC...");

  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC. Check wiring.");
    while (1) { delay(10); } // Halt
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
  }

  // Set the RTC to the date & time this sketch was compiled
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  Serial.println("RTC time has been successfully updated!");
  Serial.print("Current time set to: ");

  DateTime now = rtc.now();
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.println(now.second(), DEC);

  Serial.println("You can now flash the main attendance logger sketch.");
}

void loop() {
  // Nothing to do here
}

Aplicación principal: attendance_logger.ino

Este es el firmware principal del prototipo. Inicializa el bus SPI compartido, gestiona los pines de selección de chip, sondea tarjetas RFID y añade registros a la tarjeta SD.

Vista pública parcial del archivo validado. El código completo se muestra a miembros y en PDF/Print.

/*
 * Project: RFID Attendance SD Logger
 * Target: Arduino UNO R3 + MFRC522 + MicroSD + DS3231
 * Description: Reads RFID tag UIDs, fetches timestamp from RTC, 
 *              and logs the data to ATTEND.CSV on the SD card.
 */

#include <SPI.h>
#include <MFRC522.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>

// --- Pin Definitions ---
#define SD_CS_PIN    4
#define RFID_CS_PIN  10
#define RFID_RST_PIN 9

// --- Object Instantiation ---
MFRC522 mfrc522(RFID_CS_PIN, RFID_RST_PIN);
RTC_DS3231 rtc;

// --- Global Variables ---
const char* logFileName = "ATTEND.CSV";

void setup() {
  // Initialize serial communications
  Serial.begin(9600);
  while (!Serial) { delay(10); } // Wait for serial port to connect

  Serial.println(F("--- RFID Attendance Logger Initialization ---"));

  // 1. Initialize SPI Bus
  SPI.begin();

  // 2. Initialize DS3231 RTC (I2C)
  if (!rtc.begin()) {
    Serial.println(F("ERROR: Couldn't find RTC."));
    while (1) { delay(10); }
  }
  if (rtc.lostPower()) {
    Serial.println(F("WARNING: RTC lost power. Time may be inaccurate."));
  } else {
    Serial.println(F("RTC initialized successfully."));
  }

  // 3. Initialize MicroSD Card (SPI)
  // Disable RFID SPI temporarily to ensure clean SD init
  pinMode(RFID_CS_PIN, OUTPUT);
  digitalWrite(RFID_CS_PIN, HIGH); 

  Serial.print(F("Initializing SD card..."));
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println(F("ERROR: SD card initialization failed!"));
    Serial.println(F("Check formatting (FAT32), wiring, and CS pin."));
    while (1) { delay(10); } // Halt if SD fails
  }
  Serial.println(F("SD card initialized."));

  // Write CSV Header if file doesn't exist
  if (!SD.exists(logFileName)) {
    File dataFile = SD.open(logFileName, FILE_WRITE);
    if (dataFile) {
      dataFile.println(F("Timestamp,UID"));
      dataFile.close();
      Serial.println(F("Created new ATTEND.CSV with headers."));
    } else {
      Serial.println(F("ERROR: Could not create file on SD card."));
    }
// ...

🔒 Este contenido es premium. Con la suscripción mensual (7 días gratis) podrás desbloquear el material didáctico completo y el pack PDF listo para imprimir.🔓 Desbloquéalo — 7 días gratis
/*
 * Project: RFID Attendance SD Logger
 * Target: Arduino UNO R3 + MFRC522 + MicroSD + DS3231
 * Description: Reads RFID tag UIDs, fetches timestamp from RTC, 
 *              and logs the data to ATTEND.CSV on the SD card.
 */

#include <SPI.h>
#include <MFRC522.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>

// --- Pin Definitions ---
#define SD_CS_PIN    4
#define RFID_CS_PIN  10
#define RFID_RST_PIN 9

// --- Object Instantiation ---
MFRC522 mfrc522(RFID_CS_PIN, RFID_RST_PIN);
RTC_DS3231 rtc;

// --- Global Variables ---
const char* logFileName = "ATTEND.CSV";

void setup() {
  // Initialize serial communications
  Serial.begin(9600);
  while (!Serial) { delay(10); } // Wait for serial port to connect

  Serial.println(F("--- RFID Attendance Logger Initialization ---"));

  // 1. Initialize SPI Bus
  SPI.begin();

  // 2. Initialize DS3231 RTC (I2C)
  if (!rtc.begin()) {
    Serial.println(F("ERROR: Couldn't find RTC."));
    while (1) { delay(10); }
  }
  if (rtc.lostPower()) {
    Serial.println(F("WARNING: RTC lost power. Time may be inaccurate."));
  } else {
    Serial.println(F("RTC initialized successfully."));
  }

  // 3. Initialize MicroSD Card (SPI)
  // Disable RFID SPI temporarily to ensure clean SD init
  pinMode(RFID_CS_PIN, OUTPUT);
  digitalWrite(RFID_CS_PIN, HIGH); 

  Serial.print(F("Initializing SD card..."));
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println(F("ERROR: SD card initialization failed!"));
    Serial.println(F("Check formatting (FAT32), wiring, and CS pin."));
    while (1) { delay(10); } // Halt if SD fails
  }
  Serial.println(F("SD card initialized."));

  // Write CSV Header if file doesn't exist
  if (!SD.exists(logFileName)) {
    File dataFile = SD.open(logFileName, FILE_WRITE);
    if (dataFile) {
      dataFile.println(F("Timestamp,UID"));
      dataFile.close();
      Serial.println(F("Created new ATTEND.CSV with headers."));
    } else {
      Serial.println(F("ERROR: Could not create file on SD card."));
    }
  }

  // 4. Initialize MFRC522 RFID (SPI)
  mfrc522.PCD_Init();
  // Optional: Increase antenna gain if tags are hard to read
  // mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  Serial.println(F("MFRC522 initialized successfully."));

  Serial.println(F("--- System Ready. Waiting for RFID tags ---"));
}

void loop() {
  // Look for new RFID cards
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Get Current Time from RTC
  DateTime now = rtc.now();

  // Format Timestamp: YYYY-MM-DD HH:MM:SS
  char timeBuffer[20];
  snprintf(timeBuffer, sizeof(timeBuffer), "%04d-%02d-%02d %02d:%02d:%02d",
           now.year(), now.month(), now.day(),
           now.hour(), now.minute(), now.second());

  // Format UID to Hex String
  String uidString = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (mfrc522.uid.uidByte[i] < 0x10) {
      uidString += "0";
    }
    uidString += String(mfrc522.uid.uidByte[i], HEX);
  }
  uidString.toUpperCase();

  // Print to Serial Monitor
  Serial.print(F("Scanned: "));
  Serial.print(timeBuffer);
  Serial.print(F(" | UID: "));
  Serial.println(uidString);

  // Log to SD Card
  File dataFile = SD.open(logFileName, FILE_WRITE);
  if (dataFile) {
    dataFile.print(timeBuffer);
    dataFile.print(F(","));
    dataFile.println(uidString);
    dataFile.close();
    Serial.println(F(" -> Logged to SD card successfully."));
  } else {
    Serial.println(F(" -> ERROR: Failed to open ATTEND.CSV for writing."));
  }

  // Halt PICC to prevent reading the same card repeatedly in a single tap
  mfrc522.PICC_HaltA();
  // Stop encryption on PCD
  mfrc522.PCD_StopCrypto1();

  // Brief delay to prevent rapid-fire multiple reads
  delay(1000); 
}

Comandos de compilación/flasheo/ejecución

Utiliza arduino-cli para compilar y subir tu código.

Tabla de referencia de comandos

TareaComando
Actualizar índice de corearduino-cli core update-index
Instalar core AVRarduino-cli core install arduino:avr
Instalar dependenciasarduino-cli lib install "MFRC522" "RTClib" "SD"
Compilar sketcharduino-cli compile --fqbn arduino:avr:uno <Sketch_Folder>
Subir al UNOarduino-cli upload --fqbn arduino:avr:uno --port <PORT> <Sketch_Folder>
Monitor seriearduino-cli monitor --port <PORT> --config baudrate=9600

Flujo de trabajo numerado

  1. Encuentra tu puerto: Conecta el Arduino UNO a tu computadora. Ejecuta arduino-cli board list para identificar el <PORT> (ej., COM3 en Windows, /dev/ttyACM0 en Linux).
  2. Instala las bibliotecas: Asegúrate de que las bibliotecas de terceros requeridas estén instaladas:
    arduino-cli lib install "MFRC522" "RTClib" "SD"
  3. Configura la hora del RTC:
    • Guarda el primer bloque de código en una carpeta llamada set_rtc_time.
    • Compilar: arduino-cli compile --fqbn arduino:avr:uno set_rtc_time
    • Subir: arduino-cli upload --fqbn arduino:avr:uno --port <PORT> set_rtc_time
    • Monitor: arduino-cli monitor --port <PORT> --config baudrate=9600 para verificar que se configuró la hora.
  4. Flashea el registrador principal:
    • Guarda el segundo bloque de código en una carpeta llamada attendance_logger.
    • Compilar: arduino-cli compile --fqbn arduino:avr:uno attendance_logger
    • Subir: arduino-cli upload --fqbn arduino:avr:uno --port <PORT> attendance_logger
    • Monitor: arduino-cli monitor --port <PORT> --config baudrate=9600 para ver el sistema en vivo.

Validación paso a paso

Utiliza estos puntos de control mientras monitoreas la salida serie para asegurarte de que tu prototipo sea completamente funcional.

  1. Punto de control: Inicialización del RTC
    • Acción: Reinicia el Arduino y observa el monitor serie.
    • Observación esperada: El monitor imprime «RTC initialized successfully.»
    • Condición de éxito: El sistema no se detiene con «ERROR: Couldn’t find RTC.»
  2. Punto de control: Montaje de la tarjeta SD
    • Acción: Continúa observando el monitor serie durante el arranque.
    • Observación esperada: El monitor imprime «Initializing SD card…» seguido de «SD card initialized.»
    • Condición de éxito: El sistema monta con éxito el sistema de archivos FAT32 y no se detiene.
  3. Punto de control: Inicialización del módulo RFID
    • Acción: Observa los mensajes de arranque finales.
    • Observación esperada: El monitor imprime «MFRC522 initialized successfully.» y «— System Ready. Waiting for RFID tags —«.
    • Condición de éxito: Ambos dispositivos SPI (SD y RFID) se han inicializado sin causar conflictos en el bus.
  4. Punto de control: Escaneo y registro de etiquetas
    • Acción: Toca la antena del MFRC522 con una etiqueta RFID de 13.56 MHz.
    • Observación esperada: El monitor serie muestra «Scanned: [Fecha/Hora] | UID: [Cadena Hexadecimal]» seguido de » -> Logged to SD card successfully.»
    • Condición de éxito: El UID coincide con tu tarjeta, la marca de tiempo es precisa y la escritura en la SD reporta éxito.
  5. Punto de control: Verificación de datos CSV
    • Acción: Apaga el Arduino, retira la tarjeta microSD y léela en tu computadora.
    • Observación esperada: Existe un archivo llamado ATTEND.CSV. Al abrirlo, se revela una fila de encabezado (Timestamp,UID) y una fila por cada toque de tarjeta.
    • Condición de éxito: Los datos están correctamente separados por comas y son legibles para un humano en una aplicación de hoja de cálculo.

Solución de problemas

SíntomaCausa probableSolución
Couldn't find RTCProblema de cableado I2C.Verifica que SDA esté en A4 y SCL en A5. Asegúrate de que el módulo tenga 5V y GND.
SD card initialization failed!Formato incorrecto o pin CS.Asegúrate de que la tarjeta SD esté formateada en FAT32 (no exFAT ni NTFS). Verifica que CS esté conectado al Pin 4.
La SD falla solo cuando el RFID está conectadoConflicto MISO SPI (módulos SD económicos).Algunos módulos SD no liberan la línea MISO cuando su CS está en ALTO. Intenta alimentar el módulo SD desde una fuente de 5V separada o añade un búfer triestado a la línea MISO de la SD.
El RFID no detecta tarjetasFuente de alimentación o cableado SPI.Asegúrate de que el VCC del MFRC522 sea 3.3V, NO 5V. Verifica MOSI (11), MISO (12), SCK (13), SDA (10) y RST (9).
La marca de tiempo se reinicia a 2000-01-01Batería del RTC agotada.Reemplaza la batería CR2032 en el módulo DS3231 y vuelve a ejecutar el sketch set_rtc_time.

Mejoras

Una vez que el registrador básico esté funcionando, considera estas mejoras temáticas para un prototipo más robusto:

  • Mecanismos de retroalimentación para el usuario:
    • Añade un zumbador piezoeléctrico para proporcionar un «pitido» audible tras un escaneo y registro exitosos.
    • Integra un LED bicolor (verde para un registro exitoso, rojo para un error de la tarjeta SD) para que el dispositivo pueda usarse sin un monitor serie conectado.
  • Gestión e integridad de datos:
    • Implementa un sistema de rotación diaria de archivos (ej., LOG_1024.CSV para el 24 de octubre) para evitar que un solo archivo CSV se vuelva demasiado grande para analizarlo rápidamente.
    • Añade una base de datos de UID conocidos en la memoria flash del Arduino (usando PROGMEM) para rechazar tarjetas desconocidas y registrar solo usuarios autorizados.
  • Energía e implementación:
    • Añade una rutina de modo de suspensión para apagar los periféricos SPI y poner el ATmega328P a dormir cuando no haya ninguna tarjeta presente, despertando mediante una interrupción de hardware (si usas un módulo RFID diferente que soporte el despertar por IRQ).

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Cuál es el objetivo principal del prototipo de hardware descrito?




Pregunta 2: ¿Qué componente se utiliza para obtener la hora actual en el prototipo?




Pregunta 3: ¿En qué formato se registran los eventos (UID y marca de tiempo) en la tarjeta microSD?




Pregunta 4: ¿Cuál de los siguientes es un caso de uso mencionado para este proyecto?




Pregunta 5: ¿Qué ventaja ofrece el sistema para talleres pequeños según el texto?




Pregunta 6: ¿Qué tipo de etiquetas RFID lee el prototipo construido?




Pregunta 7: ¿Qué bus de comunicación comparten la tarjeta microSD y el módulo RFID en este prototipo?




Pregunta 8: ¿Qué protocolo de comunicación utiliza el componente del reloj de tiempo real (RTC)?




Pregunta 9: ¿Qué beneficio aporta este sistema en el registro de acceso a equipos de laboratorio?




Pregunta 10: Según el resultado esperado, ¿qué información se debe mostrar en la salida del monitor serie?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio