Go Down

Topic: Problema con contapezzi (Read 4 times) previous topic - next topic

leo72

Tempo fa avevo scritto qualcosa di simile.
In pratica facevo così.

Formattavo la EEPROM con una serie di byte standard (esempio $AA).
Ogni blocco di dati iniziava con un byte diverso da $AA, ovviamente. Siccome memorizzavo degli orari e delle letture, era facile avere un byte diverso da $FF dato che un'ora al max arriva a $17 (23d). Ogni volta che scrivevo un blocco di dati, incrementavo il puntatore all'indirizzo del blocco corrente.

In caso di riavvio, controllavo se la prima cella era diversa da $AA, segno che la EEPROM era già stata formattata e che quindi non era il primo avvio. A questo punto partiva un loop che mi "saltava" a blocchi attraverso la EEPROM finché non trovava una cella contenente appunto $AA e quello era l'indirizzo del 1° blocco libero disponibile.

E' ovvio che se io non svuotavo la EEPROM prima di averla riempita, il contatore ripartiva da 0, sovrascrivendomi i dati in fondo. Per ovviare a questo avevo messo un led di avviso per informarmi che i blocchi stavano per terminare.

rocco8383

Con lo sketch di PAOLOP(grazie) ho più cifrea  disposizione ma quando resetto azzera solo la prima cifra.Con lo sketch da te modificato quante volte potrò scrivere l'eeprom?

leo72


Con lo sketch di PAOLOP(grazie) ho più cifrea  disposizione ma quando resetto azzera solo la prima cifra.Con lo sketch da te modificato quante volte potrò scrivere l'eeprom?

Dipende da quante scritture fai e da quanto è grosso il tuo blocco di dati.
Ipotizziamo un blocco di 4 byte e 1 scrittura al secondo.
1K di EEPROM sono 1024 byte, quindi hai 1024/4=256 blocchi.
100.000 scritture per 256 blocchi, sono 256.000.000 blocchi. Scrivendone 1 al secondo bruci la EEPROM in 296 giorni.

PaoloP

#18
Mar 05, 2013, 11:47 am Last Edit: Mar 05, 2013, 11:54 am by PaoloP Reason: 1

Con lo sketch di PAOLOP(grazie) ho più cifre disposizione ma quando resetto azzera solo la prima cifra.


Code: [Select]
#include <LiquidCrystal.h>
#include <EEPROM.h>      

#define PINLED 13
#define INGRESSO1 8
#define INGRESSO2 7

int addr_a = 0; // 0,1,2,3                
int addr_b = 4; // 4,5,6,7              

unsigned long count_a = 0; // Valore massimo 4 miliardi 294...
unsigned long count_b = 0; // Valore massimo 4 miliardi 294...

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
 pinMode(INGRESSO1,INPUT);
 pinMode(INGRESSO2,INPUT);
 pinMode(PINLED,OUTPUT);
 digitalWrite(PINLED,HIGH);

 lcd.begin(16, 2);
 lcd.print(" xxxxxxxx");
 delay(3000);
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("Valori:");
 lcd.setCursor(0, 1);
 lcd.print("P1=");
 lcd.setCursor(10, 1);
 lcd.print("P2=");

 count_a = EEPROM_readlong(addr_a);          // leggo i valori a salvati nella precedente "sessione di lavoro"
 count_b = EEPROM_readlong(addr_b);          // leggo i valori b salvati nella precedente "sessione di lavoro"
}

void loop() {
 byte c = digitalRead(INGRESSO1);
 byte d = digitalRead(INGRESSO2);
 delay(10); // debounce

 if (c == HIGH){
   count_b++;
   EEPROM_writelong(addr_b, count_b);
   delay(500);
 }

 if (d == HIGH){
   count_a++;
   EEPROM_writelong(addr_a, count_a);
   delay(500);
 }

 if ((c == HIGH) && (d == HIGH)){
   count_a = 0;
   count_b = 0;
   delay(500);
   EEPROM_writelong(addr_b, count_b);
   EEPROM_writelong(addr_a, count_a);

   lcd.setCursor(4, 1);
   lcd.print("  ");
   lcd.setCursor(14, 1);
   lcd.print("  ");
 }

 lcd.setCursor(4, 1);
 lcd.print(count_a);
 lcd.setCursor(14, 1);
 lcd.print(count_b);
}

// read double word from EEPROM, give starting address
unsigned long EEPROM_readlong(int address) {
 //use word read function for reading upper part
 unsigned long dword = EEPROM_readint(address);
 //shift read word up
 dword = dword << 16;
 // read lower word from EEPROM and OR it into double word
 dword = dword | EEPROM_readint(address+2);
 return dword;
}

//write word to EEPROM
void EEPROM_writeint(int address, int value) {
 EEPROM.write(address,highByte(value));
 EEPROM.write(address+1 ,lowByte(value));
}

//write long integer into EEPROM
void EEPROM_writelong(int address, unsigned long value) {
 //truncate upper part and write lower part into EEPROM
 EEPROM_writeint(address+2, word(value));
 //shift upper part down
 value = value >> 16;
 //truncate and write
 EEPROM_writeint(address, word(value));
}

unsigned int EEPROM_readint(int address) {
 unsigned int word = word(EEPROM.read(address), EEPROM.read(address+1));
 return word;
}


Ho aggiunti la scrittura di 2 spazi bianchi quando si resetta.
Se prevedi cifre più lunghe aumenta il numero degli spazi ma attenzione a non andare oltre lo schermo altrimenti i numeri non si capiscono perche taglierebbe le cifre.

Per risolvere il problema protesti prendere una EEPROM i2c (http://www.robot-italy.com/it/24lc256i-i2c-eeprom.html) e quando si esaurisce la cambi.
Naturalmente bisognerebbe rivedere il codice.  :smiley-mr-green:
Però si trova molto materiale
--> http://playground.arduino.cc/Code/I2CEEPROM24LC512
--> http://www.hobbytronics.co.uk/arduino-external-eeprom
--> http://playground.arduino.cc/code/I2CEEPROM
--> https://github.com/mikeneiderhauser/I2C-EEPROM-Arduino
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

rocco8383

Ma quando la eeprom si esaurirà come si comporterà il contatore?Leggerà sempre l'ultimo valore che è riuscito a scrivere?

Go Up