Control de stock almacén y pedidos por RFID

Hola Chicas/os.

OJO, NOVATO !!!
Debo advertir que no soy en absoluto experto ni en C, ni en Arduino, ni en RFID, al contrario, soy NOVAtuino.

No es nada nuevo, es lo mismo que se viene haciendo con códigos de barras, pero por RFID.
Obviamente al utilizar esta tecnología, tendremos el equivalente a lo que hacemos con las barras, pero con mil aplicaciones más.
En la red, he encontrado muchos códigos pero te obligan a tener números pre-guardados y los compara con la tarjeta rfid que presentes. Están pensados para control de usuarios, horarios de trabajadores, etc, etc.

Mi intención es plantear un hardware/software que permita controlar unitariamente los productos que tenemos en un almacén o tienda por RFID.

Igualmente, al hacer un paquete con varios de esos productos para su envío, poder controlar y restar del stock, cada producto que sale unitariamente.
Cuando digo unitariamente, no me refiero a la referencia, sino al individuo concreto y único.
Si somos un almacén de martillos y recibimos de fabrica 1000 martillos iguales, podremos diferenciar cada uno de ellos con un numero UID exclusivo e irrepetible.
O bien el fabricante ya les ha pegado una etiqueta RFID a cada uno o lo haremos nosotros.
Antes de colocarlos en las estanterías del almacén, colocaríamos cada etiqueta y les pasaríamos un lector de mano a cada martillo. O a la etiqueta antes de pegársela.

Simultáneamente, nuestro hardware de mano, irá enviando esos UID a un pc con Excel via….por ejemplo un módulo RF433 o similar. Tendremos un archivo en el PC con la lista de martillos recién llegados y almacenados. Ej. 31/12/2019 – 16:40 PM – UID: 4121254547854 más otros 999 UID diferentes…Seguidos o random.

Cuando un cliente nos pide 10 martillos, los cogemos del almacén, les leemos los UID con el hardware de mano y enviamos esa lista a otro Excel.
En el PC, un soft sencillo descuenta los 10 martillos y nos quedan 990 en almacén.
Por otro lado, cuando un cliente nos devuelva un martillo defectuoso, leeremos el UID, sabremos si lo vendimos nosotros y cuando.

Las etiquetas RFID permiten además del UID, escribir información dentro. Por ejemplo, referencia del producto, URL, nombre de a qué mayorista se le ha vendido o cualquier texto que podrá ser leído posteriormente y está oculto a personas normales.

Imaginemos, que vendemos a mayoristas. Nos devuelven un producto y al leer el TAG sabemos a quien se lo vendimos. Por experiencia comercial de muchos años, se que se ven cosas muy raras. Los clientes no siempre dicen “true”….
Luego cada cual, puede añadir a esta implementación, las opciones que desee, orientadas a su actividad.

Al menos para empezar, yo he utilizado los siguientes artículos:

Con estos sencillos dispositivos ya he empezado a jugar y lo más importante, a aprender.

Para los productos que yo utilizo, necesitaba etiquetas adhesivas lo más pequeñas posibles.
Empecé jugando con las primeras que encontré entre mis muestras olvidadas que resultaron ser MIFARE CLASSIC, pero eran demasiado grandes, de hecho, no son etiquetas, sino llaveritos de unos 30mm, no aptos para introducir en mis productos, estas tienen 4 bytes. Para empezar a jugar, leer y escribir sirven.

Pedí a una tienda online rápida unas que además de ser adhesivas, son de 25mm, para mis propósitos, perfecto. Descubro más tarde que no se le puede cambiar el UID…Lo veré más detenidamente. Son MIFARE ULTRALIGHT y vienen con un UID de 18 dígitos dec y todos diferentes. 7 bytes. Puede servir, pero lo ideal es poder asignar una numeración propia.

Tampoco quería una frecuencia muy extendida en otros productos y por ello, aunque todo es cambiable, utilizo 13.56 MHz.

El hard se conecta de la siguiente manera: (Mas el buzzer a GND y Pin3) +LCD Como conectar LCD I2C

Para primeras lecturas de tags, podemos utilizar la propia librería MFRC522, el ejemplo ReadNUID. Abrimos el monitor Serial, acercamos un TAG Classic y nos dice:

PICC type: MIFARE 1KB
A new card has been detected.
The NUID tag is:
In hex:  DE B1 FA 06
In dec:  222 177 250 06

Sin embargo, el otro TAG, MIFARE ULTRALIGHT no lo lee:

PICC type: MIFARE Ultralight or Ultralight C
Your tag is not of type MIFARE Classic.
PICC type: MIFARE Ultralight or Ultralight C
Your tag is not of type MIFARE Classic.

Para este TAG MIFARE ULTRALIGHT, vamos a usar el ejemplo rfid_read_personal_data y nos mostrará la información del TAG.

Read personal data on a MIFARE PICC:
Card Detected:**
Card UID: 04 75 7D 22 D3 63 80
Card SAK: 00
PICC type: MIFARE Ultralight or Ultralight C

Ahí tenemos el UID único de esa etiqueta en HEX de 7 bytes. En este otro código simple que he hecho/copiado/modificado sin usar el LCD, lo muestra en el serial en DEC y el numero seguido para poderlo utilizar como numero entero, sería algo así:

Card UID: 41171253421199128

Lo que es lo mismo:

HEX:04  75   7D   22  D3 63  80
DEC : 4 117 125  34 211 99 128

Este código es muy básico solo para leer en decimal. Algunos amigos del foro me han sugerido otros, pero hay muchos. Este es uno de ellos:

#include <SPI.h>
  #include <MFRC522.h>
  #define RST_PIN         9         
  #define SS_PIN          10         

  MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

  byte readCard[4];

void setup() {

  pinMode(3, OUTPUT);
   
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  //mfrc522.PCD_DumpVersionToSerial();  // descomenta y te mostrará más info del TAG
  Serial.println(F("Aproxime TAG"));
  
}

void loop() {
  // Look for new cards
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
  {
  Serial.print("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], DEC);
      
      


  digitalWrite(3, HIGH);
  delay(10);
  digitalWrite (3, LOW);
  delay(20);
  digitalWrite(3, HIGH);
  delay(10);
  digitalWrite (3, LOW);
  
    }
  Serial.println();
  mfrc522.PICC_HaltA(); 
  //delay(5000);
  }
}

Ahora viene como pasar estos números leídos a excel. Lo tengo verde aunque se que es fácil.

Solo hay que descargar un software que manda los datos en vez de al monitor serial, a una hoja excel.

Archivo del software para pasar de serial a excel

Enlace donde se explica como pasar datos de arduino a excel

Iré subiendo avances y por supuesto que se aceptan correcciones y opiniones.
Insisto que soy novatuino, estos códigos son adaptaciones de copia y pega que he ido buscando y encontrando.

Por cierto, antes dije que en MIFARE ULTRALIGHT no se podía cambiar el UID. Hay una web que creo haber leido que si se puede, con PROXmark 3 Esta.

Feliz 7E4 amigos.

Hola chicas/os.

Y aquí tengo un boceto de código que ya escribe el numero de TAG en en serial, en el LCD y pretende hacerlo en excel. Digo pretende porque todavía no muestra los dígitos decimales como debiera. De hecho me los muestra en numero científico en vez de decimal. Cada vez tengo que cambiar formato de celda en e excel y elegir numero y 0 decimales. Aun así, En vez de mostrar 041171253421199128, muestra 041171253421199100. Por algún motivo los dos últimos marcan 00 en vez de 28.

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#include <LiquidCrystal_I2C.h>

  MFRC522 mfrc522(SS_PIN, RST_PIN);   
  LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  
int content = 0;////////////////////////////////////////////

 
void setup() 
{
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  pinMode(3, OUTPUT);
  SPI.begin();     
  mfrc522.PCD_Init();   
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);

  Serial.print("Aproxime un TAG");
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(1,0);
  lcd.print("Aproxime un TAG");
  

  Serial.println("LABEL,Date,Time,content");///////////////////////////////////////////////////////////


}
void loop() 
{

  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }

  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }

  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
    content.concat(String(mfrc522.uid.uidByte[i], DEC));
  }

////////////////////////////////


      Serial.print("DATA,DATE,TIME,");//send the Name to excel
      //Serial.print(",");
      Serial.println(content); //send the Number to excel
////////////////////////////////



  digitalWrite(3, HIGH);
  delay(50);
  digitalWrite (3, LOW);
  delay(50);
  digitalWrite(3, HIGH);
  delay(50);
  digitalWrite (3, LOW);
  
  lcd.clear();
  lcd.setCursor(1,1);
  lcd.print("TAG Numero: ");
  lcd.setCursor(1,2);
  lcd.print(content);
  content.toUpperCase();

 //Serial.print("Card UID: ");
 //Serial.println(content);


  
  delay(1000);
   
  }

Saludos

Con el ejemplo Dumpinfo de la misma librería podemos ver que hay en la memoria de los TAGS:

Esto es una MIFARE CLASSIC:

Firmware Version: 0x92 = v2.0
Scan PICC to see UID, SAK, type, and data blocks...
Card UID: DE B1 FA 07
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
  15     63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         62   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         61   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         60   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  14     59   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         58   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         57   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         56   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  13     55   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         54   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         53   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         52   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  12     51   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         50   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         49   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         48   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  11     47   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         46   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         45   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         44   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
  10     43   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         42   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         41   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         40   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   9     39   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         38   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         37   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         36   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   8     35   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         34   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         33   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         32   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   7     31   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         30   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         29   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         28   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   6     27   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         26   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         25   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         24   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   5     23   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         22   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         21   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         20   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   4     19   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         18   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         17   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         16   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   3     15   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         14   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         13   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
         12   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   2     11   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
         10   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          9   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          8   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   1      7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          4   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
   0      3   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
          2   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          1   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
          0   DE B1 FA 07  92 08 04 00  62 63 64 65  66 67 68 69  [ 0 0 0 ]

En la linea 0 está el UID de 4 bytes.

Aqui debajo una MIFARE ULTRALIGHT

Firmware Version: 0x92 = v2.0
Scan PICC to see UID, SAK, type, and data blocks...
Card UID: 04 75 7D 22 D3 63 80
Card SAK: 00
PICC type: MIFARE Ultralight or Ultralight C
Page  0  1  2  3
  0   04 75 7D 84
  1   22 D3 63 80
  2   12 48 00 00
  3   E1 10 12 00
  4   01 03 A0 0C
  5   34 03 00 FE
  6   48 45 4C 4C
  7   4F 20 50 45
  8   50 45 21 20
  9   3B 2D 29 00
 10   00 00 00 00
 11   00 00 00 00
 12   00 00 00 00
 13   00 00 00 00
 14   00 00 00 00
 15   00 00 00 00

El UID de 7 bytes en las 3 primeras posiciones (Page 0) y las 4 de la Page 1.

Mi primer código para leer TAGS, sacado de alguna web que no recuerdo fué este que es diferente al anterior y también funciona.
Por si alguien lo prefiere, lee CLASSIC y ULTRALIGHT:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#include <LiquidCrystal_I2C.h>

  MFRC522 mfrc522(SS_PIN, RST_PIN);  
  LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display


 
void setup()
{
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  pinMode(3, OUTPUT);//buzzer
  SPI.begin();    
  mfrc522.PCD_Init();  
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);

  Serial.println("Esperando UID: ");
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(1,0);
  lcd.print("Aproxime una Tarjeta");
  

}
void loop()
{

  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }

  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
    content.concat(String(mfrc522.uid.uidByte[i], DEC));
  }

  digitalWrite(3, HIGH);//Al detectar RFID 13,56 MHz suena buzzer
  delay(50);
  digitalWrite (3, LOW);
  delay(50);
  digitalWrite(3, HIGH);
  delay(50);
  digitalWrite (3, LOW);
  
  lcd.clear();
  lcd.setCursor(1,1);
  lcd.print("UID: ");
  lcd.setCursor(1,2);
  lcd.print(content);
  content.toUpperCase();

 Serial.print("Card UID: ");
 Serial.println(content);


  
  delay(1000);
  
  }

En un post anterior el amigo #IgnoranteAbsoluto me sujirió algunos cambios para que igualemente muestre el UID en decimal y hacerlo más simple:

Esto es lo que me sugiere sobre este código:

DOMPA, he visto que parece que tratas de convertir el UID a su valor en decimal (base 10), con las lineas de código:

for (byte i = 0; i < mfrc522.uid.size; i++)  {
        content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
        content.concat(String(mfrc522.uid.uidByte[i], DEC));
    }

Pero eso no obtiene su valor decimal. Así que aquí tienes dos funciones que te permiten convertir el UID a su valor en decimal (has de guardarlo y/o tratarlo con variables de tipo unsingned long) y una función que te convierte el valor decimal en un UID. Esto te sirve tanto para mostrar los valores en decimal, como para hacer lo del incremento. Para lo del incremento lo único que has de hacer es convertir el UID en decimal (unsigned long), incrementar el valor y volverlo a convertir un el UID. Ejemplo de incrementar en uno newUid con las dos funciones:

Las dos funciones son:

unsigned long convierteUidEnEntero(const void *uid) {
  unsigned long valor = 0;
  for (int i = 0; i < 4; i++) {
    valor = (valor << 8) | ((byte *)uid)[i];
  }
  return valor;
}

void convierteEnteroEnUid(unsigned long valor, const void *uid) {
  for (int i = 3; i >= 0; i--) {
    ((byte *)uid)[i] = valor;
    valor >>= 8;
  }
}

Con esas dos funciones en vez de hacer:

 String content= "";
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
    content.concat(String(mfrc522.uid.uidByte[i], DEC));
  }

Basta con poner:

 String content = convierteUidEnEntero(mfrc522.uid.uidByte);

Cada cual que elija el código que mejor se ajuste a sus necesidades.

Saludos

Para los TAGS MIFARE CLASSIC a los que les queramos cambiar el numero UID, el amigo #surbite ha hecho una importante aportación.

Con este código, cada vez que pasemos un TAG (al menos un CLASSIC), les grabará un numero de UID diferente +1.

//Conexiones de RFID-RC522 para UNO:
// 3,3V -> 3,3V
// GND -> GND
// SDA(SS) -> 10
// SCK -> 13
// MOSI -> 11
// MOSOI -> 12
// RST -> 9

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN   9     // Configurable, see typical pin layout above
#define SS_PIN    10    // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance


#define NEW_UID {0xDE, 0xB1, 0xFA, 0x07}// Set your new UID here!

union tagname
{
	unsigned long a;
	unsigned char Uid[8];
};

union tagname tag;

MFRC522::MIFARE_Key key;

void setup() {
  Serial.begin(9600);  // Initialize serial communications with the PC
  while (!Serial);     // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
 
  SPI.begin();         // Init SPI bus
  mfrc522.PCD_Init();  // Init MFRC522 card
  Serial.println(F("Atención, cuando acerque el TAG al lector, se programará el nuevo UID!"));

  // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
  for (byte i = 0; i < 6; i++) {
      key.keyByte[i] = 0xFF;
  }
	//assign an integer number
	tag.a = 0xDEB1FA07; // tu Uid
}

void loop() {
 
  char i; //for loop counter
  char buffer[60];

  // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. And if present, select one.
  if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
 
   
  Serial.print(F("UID: "));
  for (byte i = 0; i < mfrc522.uid.size; i++) {
      Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], DEC);
  }
  Serial.println();
 
 
  // Comienzo con el número indicado en el setup
  sprintf(buffer, "Numero entero: %lu\r\nNúmero hex   : %lX",tag.a,tag.a);
  Serial.println(buffer);
  Serial.print("     en bytes : ");
	
  for(i=3;i>=0;i--) {
		  sprintf(buffer,"%02X ",tag.Uid[i]);
      Serial.print(buffer);
  }
 
  if ( mfrc522.MIFARE_SetUid(tag.Uid, (byte)4, true) ) {
   
  }
 
  // Halt PICC and re-select it so DumpToSerial doesn't get confused
  mfrc522.PICC_HaltA();
  if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
      return;
  }
  // Set new UID
  tag.a++;
  delay(2000);
}

Ojo, esto cambia el UID solo con pasar la tarjeta TAG por el lector RC522, no va a pedir permiso.

A diferencia de algunos codigos encontrados por la red que escriben información en texto o números en la rajeta RFId sin cambiar el UID, este lo cambia en la linea 0, o sea en la linea del UID.

Ideal para marcar productos con nuestra propia numeración correlativa. Ponemos el numero de partida en HEX y desde ahí sumara +1 a cada tag que acerquemos al lector.

Aun no sé como cambiarle el UID a las ULTRALIGHT.

Saludos

Hola Chicas/os.

Ahora misto estoy atascado con la lectura de los UID en excel.

Utilizo este código:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
#include <LiquidCrystal_I2C.h>

  MFRC522 mfrc522(SS_PIN, RST_PIN);   
  LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  
int content = 0;////////////////////////////////////////////
 
void setup() 
{
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  pinMode(3, OUTPUT);
  SPI.begin();     
  mfrc522.PCD_Init();   
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);

  Serial.print("Aproxime un TAG");
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(1,0);
  lcd.print("Aproxime un TAG");
  
//////////
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Date,Time,RFID UID");
  delay(1000);
/////////

}
void loop() 
{

  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }

  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }

  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
    content.concat(String(mfrc522.uid.uidByte[i], DEC));
  }

////////////////////////////////
     Serial.println( (String) "DATA,DATE,TIME," + content );
////////////////////////////////

  digitalWrite(3, HIGH);
  delay(50);
  digitalWrite (3, LOW);
  delay(50);
  digitalWrite(3, HIGH);
  delay(50);
  digitalWrite (3, LOW);
  
  lcd.clear();
  lcd.setCursor(1,1);
  lcd.print("TAG Numero: ");
  lcd.setCursor(1,2);
  lcd.print(content);
  content.toUpperCase();

 //Serial.print("Card UID: ");
 //Serial.println(content);


  
  delay(1000);
   
  }

El caso es que en LCD y Serial me muestra bien el UID tanto MIFAREE CLASSIC como ULTRALIGHT (4 y 7 Bytes).

Sin embargo en excel con PLX-DAQ, para empezar los UID me los muestra tal que así:

Date	Time	RFID UID
01/01/2020	8:37:15 PM	2.42168E+11
01/01/2020	8:37:18 PM	4.11713E+16
01/01/2020	8:37:21 PM	4.15735E+14

Tengo que boton derecho, formato de celda, numero y decimales 0. Así parece que muestra bien en decimal…Cada vez que subo el codigo, tengo que volver a hacer lo mismo.

Por otro lado, los UID cortos de las CLASSIC o una ULTRALIGHT los muestra correctamente igual que en LCD y serial.

Pero los UID largos de otras ULTRALIGHT, en vez de terminar en 128 que es lo correcto, me los muestra terminados en 100. Creo que es culpa de excel, pero alguien sabe porqué ???

Date Time RFID UID Leido Numero UID Correcto
01/01/2020 8:41:01 PM 415735263238132 415735263238132 OK Ultralight
01/01/2020 8:41:35 PM 242168177220 242168177220 OK Classic
01/01/2020 8:41:38 PM 41171253421199100 41171253421199128 MAL Ultralight
01/01/2020 8:41:40 PM 41251253421199100 41251253421199128 MAL Ultralight
01/01/2020 8:41:44 PM 4491243421199120 4491243421199128 MAL Ultralight
01/01/2020 8:41:48 PM 2170443179 2170443179 OK Classic

Entiendo que al mostrarlo bien en LCD y en Serial, será problema de excel ???

A alguien le ha pasado ???

Gracias y feliz 2020

Hola

Ya encontré el motivo…Ahora me falta la solución.

Al recibir un numero de 18 dígitos, Excel interpreta que es un numero científico y por lo tanto como mostraba en el post anterior.

Incluso escribiendo a mano en excel un numero tan largo, al presionar entero, lo muestra así:

4.15735E+14

He descubierto en la red, que para que lo muestre como un numero normal, hay que anteponer un " o una coma , delante del numero.

la cuestión es como decírselo a arduino.

Serial.println(content);

A esta linea como antepones un " antes del numero ???

Bueno, no sé si es una forma muy ortodoxa pero lo he solucionado con formato de celda/texto.
Al fin y al cabo, estos numeros en principio no deben ser sumados en excel ni usar ninguna formula con ellos.

Para listar productos en almacén, creo que sirve.

Las funciones quedan así de momento…

Esto en el setup

Serial.println("CLEARDATA");
  Serial.println("CLEARSHEET");
  Serial.println("LABEL,Date,Time,RFID UID");
  delay(1000);

Y esto en el loop:

 Serial.println( (String) "DATA,DATE,TIME," + content );
     Serial.println(content);

Saludos.

Por falta de conocimiento como NOVATino, faltan varias fases y perfeccionarlas.

  • Leer/escribir nuevo UID en MIFARE CLASSIC - Hecho
  • Leer MIFARE ULTRALIGHT - Hecho
  • Mostrar en LCD, Serial y excel los dos tipos de tags - Hecho
  • Cambiar UID en MIFARE ULTRALIGHT - Pendiente
  • Enviar UID leidos via RF433 - Pendiente
  • Mejorar distancia de lectura - Pendiente
  • Escribir datos en MIFARE ULTRALIGHT - Pendiente

Se agradece ayuda al respecto, tanto para mejorar lo hecho como para sugerir lo pendiente.

Saludos.

Arduino no puede mostrar tantos digitos porque el mayor número que muestra es un unsigned long o sea 2³² = 4.294.967.296 asi que mas de 10 digitos no puedes representar o creo que no. La forma mas simple es imprimirlos como cadena de caracteres cosa que para Serial.println digamos que da igual.
Asi que lees el valor y si viene como cadena o String no lo conviertas a número, preséntantalo asi.

Hola Surbyte.

El código del post #5 ya lo muestra. Son números de 18 dígitos.
De hecho los muestra en LCD, Serial y ya en excel también.

Te refieres a eso ???

Esta imagen es el resultado de una lectura de MIFARE ULTRALIGHT con codigo del post #5.

En HEX sería: 04 75 7D 22 D3 63 80

Hola Chicas/os.

Aunque en un principio dije que solo quería utilizar los números de los UID de estos TAGs ULTRALIGHT, dejo aquí un código, que permite escribir texto pero no cambiar el UID. (Que es mi intención)

#include <SPI.h>
  #include <MFRC522.h>
 
 
  #define SS_PIN          10
  #define RST_PIN         9

  MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
  MFRC522::StatusCode status; //variable to get card status
 
  byte buffer[18];  //data transfer buffer (16+2 bytes data+CRC)
  byte size = sizeof(buffer);

  uint8_t pageAddr = 0x06;  //In this example we will write/read 16 bytes (page 6,7,8 and 9).
                            //Ultraligth mem = 16 pages. 4 bytes per page. 
                            //Pages 0 to 4 are for special functions.           
 
void setup() {
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card 
  Serial.println(F("Sketch has been started!"));
  memcpy(buffer,"HOLA PEPE! ;-)",16);
}

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

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

  // Write data ***********************************************
  for (int i=0; i < 4; i++) {
    //data is writen in blocks of 4 bytes (4 bytes per page)
    status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer[i*4], 4);
    if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Read() failed: "));
      Serial.println(mfrc522.GetStatusCodeName(status));
      return;
    }
  }
  Serial.println(F("MIFARE_Ultralight_Write() OK "));
  Serial.println();


  // Read data ***************************************************
  Serial.println(F("Reading data ... "));
  //data in 4 block is readed at once.
  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Read() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.print(F("Readed data: "));
  //Dump a byte array to Serial
  for (byte i = 0; i < 16; i++) {
    Serial.write(buffer[i]);
  }
  Serial.println();

  mfrc522.PICC_HaltA();

}

Veréis que en el setup, he escrito HOLA PEPE.
Tras subir este código y pasar el TAG por el lector, escribirá el texto.
Si usamos el ejemplo DumpInfo, nos dará la lectura con sus 16 paginas y 4 bytes:

Firmware Version: 0x92 = v2.0
Scan PICC to see UID, SAK, type, and data blocks...
Card UID: 04 75 7D 22 D3 63 80
Card SAK: 00
PICC type: MIFARE Ultralight or Ultralight C
Page  0  1  2  3
  0   04 75 7D 84
  1   22 D3 63 80
  2   12 48 00 00
  3   E1 10 12 00
  4   01 03 A0 0C
  5   34 03 00 FE
  6   48 4F 4C 41
  7   20 50 45 50
  8   45 21 20 3B
  9   2D 29 00 0D
 10   00 00 00 00
 11   00 00 00 00
 12   00 00 00 00
 13   00 00 00 00
 14   00 00 00 00
 15   00 00 00 00

04 75 7D 22 D3 63 80 son los 7 bytes del UID. El 84 de la cuarta posición es el BCC que desconozco su significado.
Luego en la linea 6,7 y 8 está el texto HOLAespacioPEPE 48 4F 4C 41 20 50 45 50 45 en código HEX que hay que pasar a asci. Para los muy novatinos, 48hex = 72dec = H en asci.

De momento no me sirve para nada, pero es divertido.
Saludos