Go Down

Topic: memorizzazione eventi con data e ora (Read 1 time) previous topic - next topic

peppe91

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

Brunello

praticamente hai gia' fatto tutto...

come prevedi di leggere i dati sulla eeprom ?
Seriale.. ethernet

leo72


peppe91

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...

prepuzio

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.

vittorio68

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.

leo72


quanto spazio ho in ogni cella della eeprom?

1 byte, 8 bit.

Quote

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.

Quote

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.

Quote

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..

peppe91

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?...

leo72


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).

Quote

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:
Code: [Select]
EEPROM.write((indice*12+0), ora);
EEPROM.write((indice*12+1), minuti);
EEPROM.write(ecc.......
indice++;

peppe91

emh... :) non ho capito la questione dell'indice..l'indice a che servirebbe?

leo72

Il "contatore" delle memorizzazioni fatte.

PaoloP

Arrivato a 100'000 butti il chip.  :smiley-sad-blue:
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Brunello

Ecco un esempio di codice

Code: [Select]
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;
}

PaoloP

Secondo me se trasformi tutto in UnixTime (http://en.wikipedia.org/wiki/Unix_time) 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.
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

leo72


Arrivato a 100'000 butti il chip.  :smiley-sad-blue:

E' da tenere in considerazione.

Go Up