Objetivo y caso de uso
Qué construirás: Un sistema avanzado de inventario RFID utilizando Arduino Uno R4 WiFi y el lector MFRC522, integrado con MQTT para la gestión de datos en tiempo real.
Para qué sirve
- Gestión de inventario en tiempo real mediante la lectura de etiquetas RFID.
- Notificaciones automáticas de cambios en el inventario a través de MQTT.
- Control de acceso a áreas restringidas mediante identificación RFID.
- Visualización de datos de inventario en aplicaciones web o móviles.
Resultado esperado
- Lectura de hasta 100 etiquetas RFID por minuto.
- Latencia de respuesta del sistema inferior a 200 ms al enviar datos al broker MQTT.
- Actualización del estado del inventario en la interfaz de usuario en menos de 5 segundos.
- Consumo de energía del sistema inferior a 200 mA durante la operación.
Público objetivo: Desarrolladores y técnicos en IoT; Nivel: Avanzado
Arquitectura/flujo: Arduino Uno R4 WiFi con MFRC522 conectado a la red WiFi, enviando datos a un broker MQTT y recibiendo actualizaciones para el control de LEDs WS2812B.
Nivel: Avanzado
Prerrequisitos
Sistema operativo y entorno probado
- Ubuntu 22.04.3 LTS (x86_64)
- Alternativas compatibles:
- Windows 11 23H2 (x64) con drivers USB nativos (WinUSB). No requiere drivers CH340/CP210x para Arduino Uno R4 WiFi.
- macOS 13 Ventura o superior (Apple Silicon o Intel).
Toolchain exacta
- Arduino CLI 0.35.3
- Core/Paquete de placas: Arduino UNO R4 Boards (FQBN: arduino:renesas_uno:unor4wifi) versión 1.0.6
- Compilador incluido en el core (arm-none-eabi-gcc provisto por el paquete arduino:renesas_uno 1.0.6)
- Bibliotecas Arduino (versiones exactas):
- WiFiS3 1.5.5
- ArduinoMqttClient 0.1.8
- MFRC522 1.4.11 (miguelbalboa/MFRC522)
- Adafruit NeoPixel 1.12.0
- ArduinoJson 6.21.3
- SPI (incluida en el core)
Requisitos de red y broker
- Red WiFi de 2.4 GHz con DHCP, SSID y contraseña conocidos.
- Broker MQTT accesible (por ejemplo Mosquitto 2.x) en la red local sin TLS para simplificar la puesta en marcha inicial:
- Host: 192.168.1.50 (ajusta a tu caso)
- Puerto: 1883
- Sin autenticación (o usuario/clave si tu broker lo exige; lo cubrimos más adelante).
- Cliente de validación en PC:
- mosquitto-clients (para mosquitto_pub y mosquitto_sub).
Materiales
- 1 × Arduino Uno R4 WiFi (modelo exacto: UNO R4 WiFi — Renesas RA4M1 + co-procesador ESP32-S3 para conectividad).
- 1 × Módulo RFID MFRC522 (versión con regulador a 3.3 V y adaptación de nivel incluida; a menudo etiquetado “RC522 SPI Module”).
- 1 × Tira de LEDs WS2812B (8 a 16 LEDs es suficiente para el caso práctico).
- 1 × Resistencia 330 Ω (en serie con la línea de datos de la tira WS2812B).
- 1 × Condensador electrolítico 1000 µF / 6.3 V o superior (entre +5 V y GND de la tira LED, polarizado).
- 1 × Fuente de 5 V externa con suficiente corriente para la tira LED (recomendado 2 A para margen).
- Cables Dupont macho-hembra, protoboard opcional.
- Tarjetas/llaveros RFID tipo MIFARE Classic (13.56 MHz) compatibles con MFRC522.
Nota sobre compatibilidad eléctrica:
– El MFRC522 es un dispositivo de 3.3 V. Se recomienda un módulo con regulador y adaptación de nivel integrada. Si tu módulo no tiene adaptación de nivel, usa un convertidor de nivel (bidireccional) para las líneas SPI desde el UNO R4 (5 V) hacia el MFRC522 (3.3 V). La línea MISO (3.3 V) suele ser aceptada por entradas de 5 V como “alto” lógico, pero mantén buenas prácticas y verifica tu módulo.
Preparación y conexión
Conexiones físicas (Arduino Uno R4 WiFi + MFRC522 + WS2812B)
Tabla de cableado:
| Componente | Señal/Pin en módulo | Pin en Arduino Uno R4 WiFi | Notas |
|---|---|---|---|
| MFRC522 | SDA (SS) | D10 | Selección de esclavo SPI (SS) |
| MFRC522 | SCK | D13 | SPI SCK (cabecera ICSP replicada) |
| MFRC522 | MOSI | D11 | SPI MOSI |
| MFRC522 | MISO | D12 | SPI MISO |
| MFRC522 | RST | D9 | Reset del lector |
| MFRC522 | 3.3V | 3.3V | Alimentación del lector (no uses 5 V) |
| MFRC522 | GND | GND | Referencia |
| WS2812B | DIN | D6 (a través de 330 Ω) | Línea de datos con resistencia serie |
| WS2812B | +5V | 5V (fuente externa) | Alimenta desde fuente externa de 5 V si >10 LEDs |
| WS2812B | GND | GND común | Debe compartir GND con el Arduino |
| WS2812B | — | Condensador 1000 µF entre +5V y GND | Protege contra picos de arranque |
Recomendaciones:
– Conecta primero GND común entre la fuente de 5 V, la tira WS2812B y el Arduino. Luego conecta +5 V a la tira. Finalmente la línea DIN con su resistencia de 330 Ω.
– Mantén cortos los cables de datos del WS2812B y del bus SPI.
Preparación del entorno de compilación (Arduino CLI)
1) Instala Arduino CLI 0.35.3 (Linux):
– Descarga desde https://github.com/arduino/arduino-cli/releases
– Copia el binario arduino-cli a /usr/local/bin y dale permisos de ejecución.
2) Inicializa Arduino CLI (si no lo usaste antes):
– arduino-cli config init
3) Actualiza índices e instala el core para UNO R4 WiFi:
– arduino-cli core update-index
– arduino-cli core install arduino:renesas_uno@1.0.6
4) Instala bibliotecas:
– arduino-cli lib install «WiFiS3@1.5.5»
– arduino-cli lib install «ArduinoMqttClient@0.1.8»
– arduino-cli lib install «MFRC522@1.4.11»
– arduino-cli lib install «Adafruit NeoPixel@1.12.0»
– arduino-cli lib install «ArduinoJson@6.21.3»
5) Verifica que el FQBN esté disponible:
– arduino-cli board listall | grep -i unor4wifi
– Debe listar: arduino:renesas_uno:unor4wifi
6) Permisos de puerto serie en Linux (si es necesario):
– sudo usermod -a -G dialout $USER
– Cierra sesión/inicia sesión.
Código completo
En este caso práctico implementaremos:
– Conexión WiFi (WiFiS3) y MQTT (ArduinoMqttClient).
– Lectura RFID (MFRC522 por SPI), detección de UIDs y “debounce”.
– Lógica de “inventory” simple: toggle check-in/check-out por UID.
– Publicación de eventos JSON en MQTT bajo un topic con el device_id derivado de la MAC.
– Feedback visual con WS2812B: estados de conexión, publicación y resultado de lectura.
Estructura de archivos recomendada:
- rfid-inventory-mqtt/
- rfid-inventory-mqtt.ino
- secrets.h (no subir a repositorios públicos)
- secrets.h.example (plantilla)
secrets.h.example (cópialo a secrets.h y rellena tus credenciales)
#pragma once
// WiFi
#define WIFI_SSID "TuSSID"
#define WIFI_PASS "TuPasswordWiFi"
// MQTT
#define MQTT_HOST "192.168.1.50"
#define MQTT_PORT 1883
// Si tu broker exige autenticación, rellena; si no, deja strings vacíos.
#define MQTT_USER ""
#define MQTT_PASSWD ""
rfid-inventory-mqtt.ino
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Adafruit_NeoPixel.h>
#include <ArduinoJson.h>
#include "secrets.h"
// -------------------- Configuración de pines --------------------
constexpr uint8_t PIN_SS = 10; // MFRC522 SDA/SS
constexpr uint8_t PIN_RST = 9; // MFRC522 RST
constexpr uint8_t PIN_PIX = 6; // WS2812B DIN
constexpr uint16_t NUM_PIX = 12; // Ajusta a tu tira (>=8 es suficiente)
// -------------------- Objetos globales -------------------------
MFRC522 rfid(PIN_SS, PIN_RST);
Adafruit_NeoPixel pixels(NUM_PIX, PIN_PIX, NEO_GRB + NEO_KHZ800);
// WiFi y MQTT
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
// -------------------- Utilidades de LEDs -----------------------
void pixelsFill(uint8_t r, uint8_t g, uint8_t b, uint8_t brightness=50) {
pixels.setBrightness(brightness);
for (uint16_t i = 0; i < NUM_PIX; i++) {
pixels.setPixelColor(i, pixels.Color(r,g,b));
}
pixels.show();
}
void pixelsFlash(uint8_t r, uint8_t g, uint8_t b, int times=2, int on_ms=120, int off_ms=60) {
for (int i=0; i<times; i++) {
pixelsFill(r,g,b,80);
delay(on_ms);
pixelsFill(0,0,0,0);
delay(off_ms);
}
}
// -------------------- Gestión de inventario --------------------
struct ItemEntry {
String uid;
bool present;
uint32_t lastSeenMs;
};
constexpr size_t MAX_ITEMS = 64;
ItemEntry items[MAX_ITEMS];
size_t itemsCount = 0;
int findItemIndex(const String& uid) {
for (size_t i=0; i<itemsCount; i++) {
if (items[i].uid == uid) return (int)i;
}
return -1;
}
bool upsertItemToggle(const String& uid, uint32_t nowMs, bool& outPresent) {
int idx = findItemIndex(uid);
if (idx < 0) {
if (itemsCount >= MAX_ITEMS) return false; // sin espacio
items[itemsCount] = {uid, true, nowMs}; // primera vez => check-in
outPresent = true;
itemsCount++;
return true;
} else {
// "Debounce": ignora si se vuelve a leer el mismo UID demasiado pronto
if (nowMs - items[idx].lastSeenMs < 1500) {
outPresent = items[idx].present;
return false; // no se publica
}
items[idx].present = !items[idx].present;
items[idx].lastSeenMs = nowMs;
outPresent = items[idx].present;
return true;
}
}
// -------------------- WiFi/MQTT helpers ------------------------
String deviceId;
String baseTopic;
void deriveDeviceId() {
byte mac[6];
WiFi.macAddress(mac);
char buf[32];
snprintf(buf, sizeof(buf), "unor4wifi-%02X%02X%02X", mac[3], mac[4], mac[5]);
deviceId = String(buf);
baseTopic = "inventory/" + deviceId;
}
bool ensureWiFi() {
if (WiFi.status() == WL_CONNECTED) return true;
pixelsFill(0,0,60,60); // azul: intentando conexión WiFi
Serial.print("Conectando a WiFi SSID=");
Serial.println(WIFI_SSID);
WiFi.disconnect();
int status = WiFi.begin(WIFI_SSID, WIFI_PASS);
unsigned long t0 = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
if (millis() - t0 > 15000) {
Serial.println("\nTimeout WiFi. Reintentando...");
return false;
}
}
Serial.println("\nWiFi conectado.");
Serial.print("IP: "); Serial.println(WiFi.localIP());
pixelsFlash(0, 80, 0, 2); // verde breve
return true;
}
bool ensureMQTT() {
if (mqttClient.connected()) return true;
if (!ensureWiFi()) return false;
pixelsFill(60,60,0,60); // amarillo: conectando MQTT
mqttClient.setId(deviceId);
mqttClient.setKeepAliveInterval(60);
mqttClient.setCleanSession(true);
Serial.print("Conectando a MQTT: ");
Serial.print(MQTT_HOST); Serial.print(":"); Serial.println(MQTT_PORT);
bool auth = (String(MQTT_USER).length() > 0);
bool ok = false;
if (auth) {
ok = mqttClient.connect(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASSWD);
} else {
ok = mqttClient.connect(MQTT_HOST, MQTT_PORT);
}
if (!ok) {
Serial.print("Fallo MQTT, code=");
Serial.println(mqttClient.connectError());
pixelsFlash(80,0,60,2); // magenta: fallo
return false;
}
// Publicamos LWT manual (opcional) o un online marker:
String onlineTopic = baseTopic + "/status";
mqttClient.beginMessage(onlineTopic);
mqttClient.print("{\"status\":\"online\"}");
mqttClient.endMessage();
Serial.println("MQTT conectado.");
pixelsFlash(0, 80, 0, 2); // verde breve
return true;
}
String uidToHexString(MFRC522::Uid *uid) {
char buf[3*10] = {0}; // hasta 10 bytes UID (normal 4/7)
String s;
for (byte i = 0; i < uid->size; i++) {
snprintf(buf, sizeof(buf), "%02X", uid->uidByte[i]);
s += buf;
if (i < uid->size - 1) s += ":";
}
return s;
}
bool publishEvent(const String& uid, bool present) {
if (!ensureMQTT()) return false;
// Construimos el JSON con ArduinoJson (buffer fijo)
StaticJsonDocument<256> doc;
doc["device_id"] = deviceId;
doc["event"] = present ? "checkin" : "checkout";
doc["uid"] = uid;
doc["ts_ms"] = millis();
doc["rssi"] = WiFi.RSSI();
String topic = baseTopic + "/events";
String payload;
serializeJson(doc, payload);
Serial.print("Publicando en ");
Serial.print(topic);
Serial.print(": ");
Serial.println(payload);
pixelsFill(60, 40, 0, 70); // ámbar: publicando
bool ok = mqttClient.beginMessage(topic);
if (!ok) return false;
mqttClient.print(payload);
mqttClient.endMessage();
pixelsFlash(0, 80, 0, 1); // verde: OK
return true;
}
// -------------------- Setup y loop ------------------------------
void setup() {
Serial.begin(115200);
while (!Serial) { ; }
pixels.begin();
pixelsFill(0, 0, 0, 0);
Serial.println("rfid-inventory-mqtt | UNO R4 WiFi + MFRC522 + WS2812B");
// SPI + RFID
SPI.begin();
rfid.PCD_Init(PIN_SS, PIN_RST);
byte v = rfid.PCD_ReadRegister(MFRC522::VersionReg);
Serial.print("MFRC522 VersionReg: 0x"); Serial.println(v, HEX);
// WiFi/MQTT
if (!ensureWiFi()) {
Serial.println("WiFi no disponible al inicio; se reintentará en loop.");
}
deriveDeviceId();
ensureMQTT();
// Indicador listo
pixelsFlash(0, 0, 80, 2); // azul: listo
}
void loop() {
// Mantener MQTT
if (mqttClient.connected()) {
mqttClient.poll();
} else {
// Reintentos espaciados
static unsigned long lastTry = 0;
if (millis() - lastTry > 5000) {
ensureMQTT();
lastTry = millis();
}
}
// Lectura de tarjetas
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
delay(10);
return;
}
String uid = uidToHexString(&rfid.uid);
uint32_t nowMs = millis();
bool present = false;
bool changed = upsertItemToggle(uid, nowMs, present);
if (!changed) {
// Evento ignorado por debounce; parpadeo corto azul
pixelsFlash(0,0,60,1,60,40);
} else {
// Feedback: verde check-in, rojo check-out
if (present) {
pixelsFlash(0, 80, 0, 2, 100, 60);
} else {
pixelsFlash(80, 0, 0, 2, 100, 60);
}
if (!publishEvent(uid, present)) {
Serial.println("Error publicando evento.");
pixelsFlash(80,0,60,2); // magenta: error
}
}
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}
Breve explicación por bloques:
– Conectividad:
– ensureWiFi(): maneja la conexión WiFi y timeouts (15 s), con feedback en LEDs.
– ensureMQTT(): establece la sesión MQTT (keepalive 60 s, clean session), publica un mensaje de “online” y usa el topic base inventory/
– RFID:
– Inicializa SPI y MFRC522; lee UID; convierte a string hex “AA:BB:CC:DD”.
– Aplica “debounce” de 1.5 s por UID para evitar múltiples eventos al mismo tag.
– Inventario:
– upsertItemToggle(): primera lectura de un UID ⇒ check-in; siguiente ⇒ check-out; se guarda un arreglo de hasta 64 entradas.
– LEDs:
– Azul: intentando conectar o listo; Verde: éxito; Rojo: check-out; Ámbar: publicación; Magenta: error.
– MQTT:
– Publica JSON con device_id, event, uid, ts_ms y rssi en inventory/
Compilación/flash/ejecución
Asumimos que estás en el directorio padre y vas a crear la carpeta del sketch.
1) Crea la estructura del proyecto:
mkdir -p ~/proyectos/rfid-inventory-mqtt
cd ~/proyectos/rfid-inventory-mqtt
# Crea los archivos
printf '%s\n' '#pragma once' \
'#define WIFI_SSID "TuSSID"' \
'#define WIFI_PASS "TuPasswordWiFi"' \
'#define MQTT_HOST "192.168.1.50"' \
'#define MQTT_PORT 1883' \
'#define MQTT_USER ""' \
'#define MQTT_PASSWD ""' > secrets.h
# (Luego edita secrets.h con tus credenciales reales)
2) Guarda el contenido de rfid-inventory-mqtt.ino en este directorio.
3) Instala core y librerías (si no lo hiciste antes):
arduino-cli core update-index
arduino-cli core install arduino:renesas_uno@1.0.6
arduino-cli lib install "WiFiS3@1.5.5"
arduino-cli lib install "ArduinoMqttClient@0.1.8"
arduino-cli lib install "MFRC522@1.4.11"
arduino-cli lib install "Adafruit NeoPixel@1.12.0"
arduino-cli lib install "ArduinoJson@6.21.3"
4) Conecta el Arduino Uno R4 WiFi por USB y localiza el puerto:
arduino-cli board list
# Ejemplo de salida:
# Port Type Board Name FQBN
# /dev/ttyACM0 Serial Port (USB) Uno R4 WiFi arduino:renesas_uno:unor4wifi
5) Compila:
arduino-cli compile --fqbn arduino:renesas_uno:unor4wifi ~/proyectos/rfid-inventory-mqtt
6) Sube el firmware:
arduino-cli upload -p /dev/ttyACM0 --fqbn arduino:renesas_uno:unor4wifi ~/proyectos/rfid-inventory-mqtt
7) Abre el monitor serie (115200 baudios):
arduino-cli monitor -p /dev/ttyACM0 -c 115200
8) Instala cliente MQTT en tu PC (si no lo tienes):
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y mosquitto-clients
Validación paso a paso
1) Verifica la secuencia de LEDs al encender:
– Azul fijo/parpadeo: intentando conectarse al WiFi/MQTT.
– Dos destellos verdes: conectado correctamente.
2) Verifica en el monitor serie (arduino-cli monitor):
– Debes ver algo como:
– rfid-inventory-mqtt | UNO R4 WiFi + MFRC522 + WS2812B
– MFRC522 VersionReg: 0x92 (u otro valor válido)
– Conectando a WiFi SSID=…
– WiFi conectado. IP: 192.168.1.123
– Conectando a MQTT: 192.168.1.50:1883
– MQTT conectado.
3) Suscríbete a los eventos desde tu PC:
mosquitto-sub -h 192.168.1.50 -t "inventory/unor4wifi-+/events" -v
# Alternativamente, tras ver el device_id exacto en el monitor, suscríbete a:
# mosquitto-sub -h 192.168.1.50 -t "inventory/unor4wifi-ABCD12/events" -v
4) Acerca una tarjeta/llavero RFID al MFRC522:
– Espera ver en consola serial la UID leída y “Publicando…” con el payload.
– En la suscripción MQTT, deberías ver algo como:
– inventory/unor4wifi-ABCD12/events {«device_id»:»unor4wifi-ABCD12″,»event»:»checkin»,»uid»:»DE:AD:BE:EF»,»ts_ms»:123456,»rssi»:-57}
– Un segundo toque con la misma tarjeta (pasados ~1.5 s) debe alternar “checkout”.
5) Verifica feedback de LEDs:
– Check-in: destellos verdes.
– Check-out: destellos rojos.
– Publicación: breve ámbar.
– Error de publicación: magenta.
6) Consulta el estado del dispositivo:
mosquitto_sub -h 192.168.1.50 -t "inventory/unor4wifi-+/status" -v
# Debe haber publicado {"status":"online"} tras conectar.
7) (Opcional) Prueba autenticación si tu broker lo requiere:
mosquitto_sub -h 192.168.1.50 -u tuuser -P tuclave -t "inventory/+/events" -v
# Asegúrate de haber rellenado MQTT_USER y MQTT_PASSWD en secrets.h y recompilado.
8) Estresa el sistema con varias UID y verifica la lógica:
– Pasa 3–5 tarjetas diferentes.
– Comprueba que cada una alterna entre check-in/check-out en cada lectura separada por >1.5 s.
– Observa que el array de items crece hasta MAX_ITEMS (64 por defecto).
Troubleshooting
1) El monitor serie no muestra nada / no ves el puerto:
– Verifica el cable USB (de datos, no solo carga).
– En Linux, añade tu usuario a dialout: sudo usermod -a -G dialout $USER y reinicia sesión.
– Ejecuta arduino-cli board list para confirmar /dev/ttyACM0.
– Prueba otro puerto USB. En Windows, revisa el Administrador de dispositivos (COMx).
2) Error al compilar: FQBN incorrecto o core no instalado:
– Asegúrate de usar exactamente: –fqbn arduino:renesas_uno:unor4wifi
– Instala el core: arduino-cli core install arduino:renesas_uno@1.0.6
– Repite arduino-cli core update-index si falla la descarga.
3) El MFRC522 no detecta tarjetas:
– Revisa que alimentas el módulo con 3.3 V (no 5 V).
– Comprueba el cableado SPI: SDA→D10, SCK→D13, MOSI→D11, MISO→D12, RST→D9 y GND común.
– Verifica que tu módulo posee adaptación de nivel o usa un level shifter para las señales desde el UNO R4 (5 V).
– Acerca la tarjeta a 2–3 cm. Observa el VersionReg: 0x91/0x92 suelen ser válidos; 0x00 o 0xFF indican wiring o alimentación incorrecta.
4) WS2812B parpadea errático o no enciende:
– Asegura GND común entre fuente de 5 V, Arduino y tira.
– Coloca la resistencia serie de 330 Ω en DIN y el condensador de 1000 µF entre +5 V y GND.
– Si la tira tiene más de 60 LEDs, alimenta por ambos extremos.
– Reduce el brillo (pixels.setBrightness) al probar.
5) No conecta a WiFi:
– Confirma SSID/clave en secrets.h.
– Asegura red 2.4 GHz habilitada (algunos AP mezclan 2.4/5 GHz con el mismo SSID; puede funcionar, pero confirma).
– Acerca el equipo al AP; revisa saturación de canal; verifica que el DHCP entrega IP.
6) No conecta a MQTT:
– Revisa que el broker esté accesible desde tu máquina (ping, telnet 1883).
– Si el broker requiere usuario/clave, rellena MQTT_USER/MQTT_PASSWD y recompila.
– En Mosquitto, revisa listeners y ACLs (listener 1883 0.0.0.0).
– Comprueba que no haya doble NAT o firewall bloqueando.
7) Publicación falla intermitente:
– Observa el RSSI en payload; si < -80 dBm, mejora la señal WiFi.
– Aumenta keepalive o reintentos en ensureMQTT(); reduce la frecuencia de publicaciones si hay mucha carga.
8) El sketch reinicia o se cuelga:
– Evita alimentar la tira WS2812B desde el 5 V del Arduino si supera ~8–10 LEDs; usa fuente externa.
– Revisa consumo total y calidad de la fuente 5 V (mínimo 1–2 A para 16 LEDs con brillo alto).
– Disminuye el tamaño de JSON si sospechas presión de memoria (ArduinoJson 256 B estático; ajusta si amplías campos).
Mejoras/variantes
- Seguridad MQTT (TLS):
- Usa un listener TLS en tu broker (8883) y certificados.
-
ArduinoMqttClient puede trabajar sobre WiFiSSLClient (siempre que WiFiS3 soporte TLS en tu versión). Implica gestionar certificados y memoria.
-
Persistencia de inventario:
- Guarda el estado en la memoria flash (EEPROM emulada) en el UNO R4 tras cada cambio.
-
Carga el estado al inicio para no perderlo tras reinicio.
-
NTP/RTC y timestamps absolutos:
- Sincroniza hora vía NTP y usa timestamps POSIX en “ts_ms” en lugar de millis(), aprovechando el RTC del UNO R4 WiFi.
-
Publica timezone y drift si necesitas auditoría precisa.
-
Comandos vía MQTT:
-
Suscríbete a inventory/
/cmd para: - reset: limpiar inventario.
- status: publicar resumen de items presentes.
- led:
: feedback visual remoto.
-
Lote/batching:
-
Agrupa varios eventos en un JSON array si lees muchas tarjetas en ráfaga, para reducir overhead de MQTT.
-
QoS y Retained:
- Ajusta QoS si tu broker/consumidor lo requiere.
-
Publica retained en status online/offline para facilitar descubrimiento.
-
Identificación de artículos:
- Mantén un diccionario UID→SKU/Descripción en el consumidor MQTT (servidor) o descarga una tabla al dispositivo vía comandos.
Checklist de verificación
- [ ] He instalado Arduino CLI 0.35.3 correctamente y puedo ejecutar arduino-cli version.
- [ ] He instalado el core arduino:renesas_uno@1.0.6 y verifico el FQBN arduino:renesas_uno:unor4wifi.
- [ ] He instalado las bibliotecas exactas: WiFiS3 1.5.5, ArduinoMqttClient 0.1.8, MFRC522 1.4.11, Adafruit NeoPixel 1.12.0, ArduinoJson 6.21.3.
- [ ] He cableado el MFRC522 a D10/D13/D11/D12/D9 y lo alimento a 3.3 V; GND común.
- [ ] He cableado la tira WS2812B al pin D6 con resistencia serie 330 Ω, condensador 1000 µF entre +5 V/GND, y fuente de 5 V adecuada con GND común.
- [ ] He creado secrets.h con mis credenciales WiFi y parámetros del broker MQTT.
- [ ] El sketch compila y se sube con: arduino-cli upload -p /dev/ttyACM0 –fqbn arduino:renesas_uno:unor4wifi.
- [ ] El monitor serie muestra IP asignada y conexión MQTT exitosa.
- [ ] Puedo suscribirme con mosquitto-sub a inventory/unor4wifi-+/events y recibo eventos JSON de check-in/checkout al acercar tarjetas.
- [ ] Los LEDs muestran: verde al check-in, rojo al check-out, ámbar al publicar, magenta si hay error.
Con lo anterior, habrás implementado un flujo completo “rfid-inventory-mqtt” con el modelo exacto Arduino Uno R4 WiFi + MFRC522 + WS2812B, usando Arduino CLI, core y librerías en versiones concretas, y con una validación reproducible ponta a punta desde el hardware hasta el topic MQTT.
Encuentra este producto y/o libros sobre este tema en 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.



