Rfid: scelta tipo di dati

Salve,
mi sto accingendo ad usare i miei cari moduli rdm630 per la lettura di tag rfid a 125 khz.
Il tutto dovrà interfacciarsi con Arduino (logico, altrimenti non starei qui a scrivere....ehehheheh) e una SD shield.

In pratica dato l'alto numero di Tag tra cui cercare la presenza o meno del tag "strisciato" ho pensato di salvare sulla SD in un file di testo l'elenco di TAG consentiti....e fin qui nessun problema. (Anzi a dirla tutta più che un problema la mia è una curiosità da condividere....).

Ora le operazioni da fare sono le seguenti:
1)Leggi il TAG
2)Apri e scorri il file SD e per ogni riga letta (i vari codici RFID sono all'inizio di ogni riga) confronta con il TAG letto.
3)Se trovi il TAG allora fai questo altrimenti....etc...

E ora vengo al dunque:
in rete ho visto diversi sketch per l'rfid e il codice del TAG viene gestito in molti modi diversi:
1)come array di 6 Byte
2)come array di 12 char (a volte anche 14)
3)come Stringa
penso di avere un minimo di comprensione sulle differenti dimensioni dell'una o altra scelta, e la facilità di gestione dell'una o dell'altra

Se dovessi gestire l'array di Tag nella memoria di Arduino (senza quindi la SD) farei una scelta soprattutto dettata sull'occupazione di memoria a scapito forse di codice + complicato (confronto tra i diversi byte, piuttosto che un strcmp con le stringhe).

dovendo invece gestire 2 sole variabili (e cioè valore letto dall'rfid e valore letto dall'sd) voi cosa utilizzereste?
io mi sono posto la domanda ragionando su:
necessità di fare il check (funzione Xor forse più semplice su byte che su stringhe)
necessità di confronto (forse più comodo strcmp che confronto byte a byte)
necessità di stampa del TAG su LCD

Grazie...

P.s: appena messo insieme un po' di codice lo sottoporrò in questo post.

Quanti tag devi gestire?

al momento un 100...
ma nella soluzione adottata (SD) mi sono posto nell'ottica di non avere limiti magari anche 1000...
e poi in questo modo, una volta preparato il file con i TAG posso condividerlo anche su più postazioni di controllo.
Con scelte quali gestione memoria interna o eeprom invece dovrei procedere al caricamento manuale per ogni postazione.

perchè questa domanda?

Se devi mettere le mani dentro al file da PC (per controllare i codici o aggiungerne) allora conviene stringa da 12

perchè questa domanda?

Proprio per valutare il tipo di memoria necessaria e, soprattutto, il metodo con cui memorizzare i dati.

Mi spiego meglio: per memorizzare un vettore di 1000 elementi di 12 byte occorrono almeno 12KB (una inezia per una SD) ma ricercare un valore nell'ambito di questo vettore può richiedere del tempo.

Se l'applicazione è "time critical" devi adottare delle tecniche dicotomiche per ridurre i tempi di accesso alla memoria.

Ti consiglio di usare la memoria eeprom
Con arduino uno puoi memorizzare fino a 256 tag mentre con la mega arrivi a 1024 tag

É molto più facile da gestire. Anche la lettura e la comparazione sono più veloci rispetto alla gestione su sd

matrix_77:
dovendo invece gestire 2 sole variabili (e cioè valore letto dall'rfid e valore letto dall'sd) voi cosa utilizzereste?

Di che dimensioni di dati stiamo parlando?
Quanti byte?

Se dai un occhio qua :

http://forum.arduino.cc/index.php?topic=198711.msg1466488#msg1466488

io farei un cosa del genere :

byte value1Block[] = { 1,2,3,4,  5,6,7,8, 9,10,11,12,  13,14,15,16,   valueBlockA,~valueBlockA,valueBlockA,~valueBlockA };

il primo blocco lo userei per identificare il livello ( 0-255 ) dell utente :

SuperAdmin : 4
Admin : 3
User : 2
Guest : 1

il secondo blocco ( 0-255) per il gruppo

Amministrazione : 3
Professore : 2
Alunno : 1

e i restanti per gli utenti partendo dall'ultimo
per avere una cosa tipo questa :

byte value1Block[] = { 4,3,0,0,  0,0,0,0, 0,0,0,0,  0,0,0,1,   valueBlockA,~valueBlockA,valueBlockA,~valueBlockA };

Cosi appena inizi a leggere potresti avere :

SuperAdmin.txt - xml
Admin.txt - xml

Quindi se il primo blocco a valore quattro apri "SuperAdmin.txt"

  • scorro il file e cerco #amministrazione
  • inizio a leggere gli ID utenti
  • controlla se hai il numero del TAG
  • imposto l'autentificazione

Scrivere in eprom l'ultimo id di carta generata cosi da
non aver mai un id identico , e cosi da essere sicuro
di leggere velocemente i dati e non dover scorrere per
scrivere un tag l SD

cosi non deve aprire e leggere un file contente tutti gli utenti ma inizierebbe a scremare ..

in piu aggiungerei tipo al blocco 3 un numero generato casuale che chiamerei the magic number in modo tale che anche se qualcuno volesse provare a clonarti la carta dovrebbe trovare l'id dell utente il suo permesso e il suo gruppo e il numero magico ..

quindi e tutto rilevabile ma il numero magico che e compreso tra 0-255 impostando un blocco per un massimo di tre tentativi per poi fermare la lettura della carta per cinque minuti .. impiegerebbe :

(256minuti / 3tentativi ) = 85.3 prova da fare X 5 minuti = 426 minuti / 60 minuti : 7 ore e quel ...

e vero che con un po di fortuna potrebbe trovare il numero magico 10 ..
quindi inserirei una black list che dopo tre tentativi la tua carta viene bannata e deve essere in attesa dell admin ..

Potresti comunque sempre fare tutto cio appoggiandoti ad un database MYSQL
Leggi il TAG invi la richiesta

127.0.0.1/login.php?Request=Login&Id=000001110101

Apre il Db legge confronta

e in un iframe carica la pagina :

192.168.1.201/Arduino=responseOK

Arduino se legge "Arduino" fara quello che vuoi che faccia ..

in questo modo potrai avere anche una potenza per fare controlli e statistiche sugli utenti ..

Buona Fortuna

Ciao!, ti chiedo giusto un chiarimento:

127.0.0.1/login.php?Request=Login&Id=000001110101
Apre il Db legge confronta qui tutto chiaro...

e in un iframe carica la pagina :
Code:
192.168.1.201/Arduino=responseOK

come mai utilizzi un IP completamente diverso? perchè non può stare nella stessa rete Arduino e Server?

thanks :slight_smile:

allora, per l'uso di memoria do per scontato che NON vuoi caricare tutti i tag in memoria, infatti la cosa mi pare che sia chiara quando dici:

Apri e scorri il file SD e per ogni riga letta (i vari codici RFID sono all'inizio di ogni riga) confronta con il TAG letto.

sul file di testo puoi avere millemila tag, ma tu terrai in memoria solo l'utimo letto.. comodo!

in rete ho visto diversi sketch per l'rfid e il codice del TAG viene gestito in molti modi diversi:

secondo la codifica ascii, 1 byte == 1 char. i TAG rfid sono solitamente caratteri ASCII che corrispondono a lettere e numeri, quindi leggibili; proprio per questo io usere un array di
char[] (per far capire che sono valori stapabili e leggibili tranquillamente da un essere umano, acnhe se a livello codice, sempre secondo charset ascii, non cambia nulla da fare byte[])
La classe String la puoi udare, io personalmente la eviterei.
Poi usa tranquillamente la strcmp, però ricordati di aggiungere il carattere di fine stringa '\0'!! :slight_smile:

Per la dimensione... beh dipende dai tuoi RFID. Quelli che ho io sono a 12 caratteri se non erro. (e sinceramente pensavo fosse standard così)

Poi direi di lasciare perdere la EEPROM, se hai la SD è millemila volte più semplice e comodo caricare i dati o modificarli

ora invece parliamo di ottimizzazione:
se hai 1000 rfid è assai dispensioso cercarli uno a uno nel file. Sopratutto perchè arduino non lavora con la SD a full speed, ma moolto più lentamente.

Mettiamo caso che per ogni rfid vuoi salvare alcuni dati, tipo nome e cognome che sono di lunghezza variabile, io farei un file che per nome ha il TAG. Poi basta cercare di aprire un file in sola lettura, se ha successo la tag esiste (e si può procedere), se falisce la tag non esiste
(
FAT32:
Maximum number of files on disk: 268,435,437
Maximum number of files in a single folder: 65,534
)
immagino che la ricerca del file avvenga con la ricerda dioctomatica come esposto al prossimo punto, altrimenti puoi organizzare per cartelle; visto che di sonlito le prime X cifre sono QUASI sempre uguali, le usi come nomi delle cartelle, che poi a loro volta conterranno i file, o olteriori cartelle, vedi tu)

se invece abbiamo solo il tag rfid, e magari dei dati a lunghezza fissa allora procederei così:
calcioliamo la lunghezza delle righe. Quando carichiamo i dati nel file, li carichiamo ordinati alfabeticamente.
poi leggi il primo e l'ultimo rfid. Se è nell'intervallo prosegui: prendi il tag a metà file; vedi in che metà è compreso, prendi quella mettà etc....
In tal modo il tempo di ricerca anichè essere O(n) è O(ln(n))

Poi, se come dice tex_industries ti appoggi su un server DB, allora NON fare nulla lato arduino se non leggere la carta, inviare una richiesta al DB (che poi passi per una get a una pagina PHP o per la seriale o un programma ad-hoc o quel che vuoi poco importa), e il db oltre che loggare effettua anche una bella (ed ottimizzata) SELECT e restituisce un ok o un ko (con eventuale codice di errore) all'arduino.

dopo finisco ma intanto :

127.0.0.1

equivale a

localhost

ovvero la macchina in qui utilizzi il web server

se la tua macchina avvesse l'indirizzo 192.168.1.201
se la vuoi far raggiungere dagli altri sulla rete utlizzi l'ip

se invece stai facendo delle prove e inutile che ogni volta scopri che indirizzo a il tuo pc e usi localhost:porta oppure 127.0.0.1:porta

la porta devi inserirla solo nel caso in qui non usi quella di default ovvero la 80 .

Buon Divertimento