Salve a tutti ragazzi, ho un quesito da porvi, praticamente ho realizzato un controllo accessi con sensore RFID ID-20 ed ho bisogno di verificare chi entra e a che ora memorizzando sulla eeprom il numero della scheda letta, orario e data e prevedendo una cancellazione automatica dopo 48 ore...per l'orario ho già previsto un modulo RTC con relativa batteria di backup, DS1307 e quarzo...per quanto riguarda la lettura, viene inviata ad un chip standalone di arduino tramite porta seriale....spero che riusciate ad aiutarmi...grazie 1000...ciaoooo
praticamente hai gia' fatto tutto...
come prevedi di leggere i dati sulla eeprom ?
Seriale.. ethernet
Qual'è la domanda?
Grazie innanzi tutto per le risposte....in pratica non ho mai scritto e letto sulla EEPROM, ed è questo appunto il mio problema, i dati vengono dalla seriale...(pin 0, 1 di arduino) non appena arduino riconosce il dato sulla seriale deve poter salvare sulla EEPROM il numero di carta RFID letta e relativa data e ora...e poi prevedere un'autocancellazione dopo 48 ore...la domanda esattamente è: come faccio?...ho cercato un pò in giro...ma non sono riuscito a capire moltissimo...ovviamente devo inizializzare la libreria EEPROM.h e fin qui ok... poi per fargli salvare ciò che è stato letto come posso fare?... premetto che il codice della RFID si presenta nel seguente modo: esempio 26 65 0F 44 09 28... cioè quello che realmente non sono riuscito a capire è quanto spazio ho in ogni cella della eeprom? come riesco a salvare i 6 byte se ogni cella contiene massimo 1 byte? come faccio a memorizzare l'identificativo sopra con ora e data e poi a richiamarli??...l'unica cosa che so è che si usa EEPROM.write per scrivere e EEPROM.read per leggere....penso che per la lettura non ci sia problema...mi è sembrata facile...è la scrittura che non riesco a comprendere...
Ciao peppe91 ti sconsiglio di usare la eeprom interna perchè a forza di scriverla e riscriverla finisci per rovinarla perchè ha un numero limitato di scritture anche se tante. Prevedi nel tuo programma di cambiare cella ogni tanto oppure usa una memoria esterna i2c così ti basta cambiare chip e via. Meglio ancora usare una FRAM della ditta ramtron. Costa un pò di più ed è in smd ma non si rovina con l'utilizzo.
ciao peppe91,
da quello che dici dovresti scrivere 12 byte per ogni accesso. I primi 6 contengono (giorno, mese, anno, ora, minuti, secondi - un byte per ciascuno); i secondi 6 contengono l'ID del chip RFID.
Mantieni una variabile che ti indica quanti accessi hai già memorizzato. A questo punto troverai i dati del primo accesso tra i bytes 0-11, quello del secondo tra i bytes 12-23... e genericamente, quelli dell'n-esimo tra i bytes [i*12, i*12 + 11] dove la i parte da 0 (il primo accesso ha indice 0).
Ti ribadisco però quello che ti hanno già suggerito. La EEPROM ha un numero di cicli di scrittura "limitato" e rischi di esaurirli in breve tempo. Inoltre, tale memoria non è grandissima (1KB per arduino UNO e 4KB per arduino MEGA). Nel primo caso riesci a memorizzare circa 85 accessi, nel secondo circa 341 che in 48 ore potrebbero essere pochi.
Oltre alla FRAM potresti anche considerare l'uso di una SD.
peppe91:
quanto spazio ho in ogni cella della eeprom?
1 byte, 8 bit.
come riesco a salvare i 6 byte se ogni cella contiene massimo 1 byte?
Usi 6 byte. Usi cioè un "taglio" consono al quantitativo di dati da salvare.
come faccio a memorizzare l'identificativo sopra con ora e data e poi a richiamarli??...
Organizzi i dati secondo uno schema come ti ha spiegato vittorio68.
l'unica cosa che so è che si usa EEPROM.write per scrivere e EEPROM.read per leggere....penso che per la lettura non ci sia problema...mi è sembrata facile...è la scrittura che non riesco a comprendere...
Ad EEPROM.write passi l'indirizzo ed il valore da scrivere.
Ovviamente dovendo scrivere più byte, userai un puntatore al blocco di byte. Ogni blocco sarà composto da n byte.
Mettiamo che il tuo blocco sia di 12 byte, il 1° blocco parte da 0 e termina ad 11. Il 2° blocco parte da 12 e termina a 23 ecc..
Grazie a tutti per le risposte....per la eeprom esterna dispongo di alcune 24c64 che sono i2c da 64Kb...per quanto riguarda i byte sono riuscito a capire....quello che ancora non capisco è la tecnica di memorizzazione....mettiamo caso che il programma legga la carta RFID con il comando readCard, e per l'orario ho dichiarato ora, minuti, secondi, giorno, mese, anno, per scrivere i dati sulla eeprom cosa dovrei fare?
EEPROM.write(readCard, ora, minuti, secondi, giorno, mese, anno)????
se li dispone in automatico oppure devo dividerli io e specificare le celle in cui vanno inseriti?
se non chiedo troppo mi fareste vedere un esempio di codice?...
peppe91:
Grazie a tutti per le risposte....per la eeprom esterna dispongo di alcune 24c64 che sono i2c da 64Kb...
Attento che sono 64 kbit, non kbyte. Siccome di solito sono memorie da 64k X 8bit, hai un taglio di 8 kB (kbyte).
per quanto riguarda i byte sono riuscito a capire....quello che ancora non capisco è la tecnica di memorizzazione....mettiamo caso che il programma legga la carta RFID con il comando readCard, e per l'orario ho dichiarato ora, minuti, secondi, giorno, mese, anno, per scrivere i dati sulla eeprom cosa dovrei fare?
EEPROM.write(readCard, ora, minuti, secondi, giorno, mese, anno)????
se li dispone in automatico oppure devo dividerli io e specificare le celle in cui vanno inseriti?
se non chiedo troppo mi fareste vedere un esempio di codice?...
Devi usare un indice, vale a dire una variabile che contenga l'indirizzo al primo byte del BLOCCO di byte che contiene i valori.
Siccome abbiamo appurato che ti servono 12 byte, ammettendo che indice = n, il 1° byte del blocco puntato da indice è dato da:
EEPROM.write((indice*12+0), ora);
EEPROM.write((indice*12+1), minuti);
EEPROM.write(ecc.......
indice++;
emh... non ho capito la questione dell'indice..l'indice a che servirebbe?
Il "contatore" delle memorizzazioni fatte.
Arrivato a 100'000 butti il chip.
Ecco un esempio di codice
void scrive_eprom() {
trova_byte_libero_eprom(); // Cerca la prima posizione libera dove aggiungere i dati
DateTime now = RTC.now(); // Viene usata la libreria "RTClib.h" per il DS1307
i2c_eeprom_write_byte(0x50, address, now.day()); //viene richiamata la routine di scrittura, 0X50 e' l'indirizzo della EEprom esterna 24c64
delay(10);
i2c_eeprom_write_byte(0x50, address +1, now.month()); // scrive mese
delay(10);
i2c_eeprom_write_byte(0x50, address +2, now.year()); // scrive anno
delay(10);
i2c_eeprom_write_byte(0x50, address +3, now.hour());
delay(10);
i2c_eeprom_write_byte(0x50, address +4, now.minute());
delay(10);
i2c_eeprom_write_byte(0x50, address +5, now.second());
delay(10);
i2c_eeprom_write_byte(0x50, address +6, PRIMO BYTE RFID ); // va' inserito il valore del PRIMO BYTE RFID
delay(10);
i2c_eeprom_write_byte(0x50, address +7, SECONDO BYTE RFID );
delay(10);
i2c_eeprom_write_byte(0x50, address +8, TERZO BYTE RFID );
delay(10);
i2c_eeprom_write_byte(0x50, address +9, QUARTO BYTE RFID );
delay(10);
i2c_eeprom_write_byte(0x50, address +10, QUINTO BYTE RFID );
delay(10);
i2c_eeprom_write_byte(0x50, address +11, SESTO BYTE RFID );
delay(10);
i2c_eeprom_write_byte(0x50, address +12, 255 ); // mette a FF il Byte seguente. serve per trovare il primo byte libero con "trova_byte_libero_eprom()"
delay(10);
}
void trova_byte_libero_eprom()
{
//value = EEPROM.read(address);
value = i2c_eeprom_read_byte(0x50, address);
for (address = 0; address < 8172; address = address + 12 )
{
//value = EEPROM.read(address);
value = i2c_eeprom_read_byte(0x50, address);
if ( value == 255 ) { // quando ogni 12 Byte trova il valore 0xFF esce e
Serial.print(address);
Serial.print (F("\t"));
Serial.println ( value, DEC) ;
Serial.println();
break ;
}
delay(5);
}
}
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
Secondo me se trasformi tutto in UnixTime (Unix time - Wikipedia) con un singolo uint32 = 4 bytes hai la risoluzione di un secondo e vai avanti per 1600 anni prima di andare in overflow.
Nella libreria di Leo trovi le funzioni per trasformare da data e orario in secondi e viceversa.
Inoltre è facilissimo fare i conti per calcolare ad esempio differenze di orario senza ricorrere al calcolo sessagesimale e relativi controlli.
PaoloP:
Arrivato a 100'000 butti il chip.
E' da tenere in considerazione.
PaoloP:
Secondo me se trasformi tutto in UnixTime (Unix time - Wikipedia) con un singolo uint32 = 4 bytes hai la risoluzione di un secondo e vai avanti per 1600 anni prima di andare in overflow.
Nella libreria di Leo trovi le funzioni per trasformare da data e orario in secondi e viceversa.Inoltre è facilissimo fare i conti per calcolare ad esempio differenze di orario senza ricorrere al calcolo sessagesimale e relativi controlli.
OOOk....grazie a tutti per l'aiuto...ora mi è molto più chiaro e mi metto a lavoro per fare qualcosa...se ho qualche problema o dubbio posto qui... PaoloP...non complichiamoci la vita.....è da implementare nel sistema antifurto di una abitazione...quindi... va benissimo così...grazie ancora a tutti voi