Problema con contapezzi

Allora con questo sketch penso di essere vicino alla soluzione.Non riesco però ad azzerare tutto il contatore ma solo la cifra di partenza.

 #include <LiquidCrystal.h>
    #include <EEPROM.h>       
    int addr_a = 0;                 
    int addr_b = 1;                


    int in=8;
    int in2=7;


    int a = 0;
    int b = 0;
    int c= 0;
    int d = 0;

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

    void setup() {
      pinMode(in,INPUT);
      pinMode(13,OUTPUT);
      digitalWrite(13,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=");
      a = EEPROM.read(addr_a);          // leggo i valori a salvati nella precedente "sessione di lavoro"
      b=  EEPROM.read(addr_b);          // leggo i valori b salvati nella precedente "sessione di lavoro"
    }

    void loop() {

      c=digitalRead(in);
      if ( c== 1){b=b+1; EEPROM.write(addr_b, b); delay(500); }
      d=digitalRead(in2);
      if ( d== 1){a=a+1; EEPROM.write(addr_a, a);delay(500);}
      if (( c ==1) & ( d==1)){a=0; b=0; delay(500);EEPROM.write(addr_b, b);EEPROM.write(addr_a, a);}

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

Prova così.
Avevi dimenticato di mettere l'ingresso 2 in INPUT col pinmode.

......

Non puoi registrare un contatore maggiore di 255 (un byte) [Thanks Leo]
Devi aggiungere del codice se vuoi registrare un dato su più celle nella eeprom.

EDIT: Ho trovato questo topic interessante con un bel codice pronto per scrivere unsigned long (http://arduino.cc/forum/index.php/topic,45220.0.html)
integrandolo col tuo programma diventa:

#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(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;
}

PaoloP:
Non puoi registrare un contatore maggiore di 256 (un byte)

Ad esser precisi, 255.
256 è il numero di valori diversi che un byte può tenere, valori che vanno da 0 a 255.

Adesso manca solo l'algoritmo di wear leveling e potresti andare avanti per 6'400'000 scritture.
Con una scrittura al secondo la EEPROM durerebbe poco più di 2 anni.

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.

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?

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?

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.

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

#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. :grin:
Però si trova molto materiale
--> Arduino Playground - I2CEEPROM24LC512
--> http://www.hobbytronics.co.uk/arduino-external-eeprom
--> Arduino Playground - HomePage
--> GitHub - mikeneiderhauser/I2C-EEPROM-Arduino: Interface Library from Arduino V1.X to Microchip 24LC256 or 24LC512 EEPROM

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

Anzi se qualcuno è interessato ne ho 3 stecche di queste eeprom, se si paga la spedizione le spedisco

Una domanda.... siete tutti a pensare come ottimizzare le scritture sulla EEPROM... ma.. rocco: ha pensato anche che questa EEPROM va svuotata perché con 1024 byte e basta non ci scrivi nulla, se la frequenza è di qualche sscrittura al secondo?

Effettivamente leo72 ha ragione.Dovrei montarlo su una pressa che a seconda del lavoro effettuato conterà o meno...ma non con la fequenza da voi immaginata perchè è azionata da due pulsanti, da una persona fisica che dovra caricare e scaricare il pezzo dallo stampo....

Riesci a quantificare l'utilizzo di questa pressa, nell'arco di una giornata lavorativa?
Salverai poi solo la data e l'ora dell'azionamento, giusto? Oppure anche il codice dell'operatore?

Può esere che lavori per 5 giorni di fila e che poi rimanga ferma per altrettati.Producendo in 8 ore da 500 a 2500Pz

leo72:
Una domanda.... siete tutti a pensare come ottimizzare le scritture sulla EEPROM... ma.. rocco: ha pensato anche che questa EEPROM va svuotata perché con 1024 byte e basta non ci scrivi nulla, se la frequenza è di qualche scrittura al secondo?

In che senso svuotata?
Trascriverla su un'altra eeprom per continuare a contare?

Non ho capito perché non dovrebbe scrivere?? :roll_eyes:
La scrittura impiega 3,3 ms a byte e ne deve scrivere 4 per un contatore a 32bit. Ne ha dei tempo tra una scrittura e l'altra.

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

esatto

Ma scrivere su una semplice SD o microSD ?

nid69ita:
Ma scrivere su una semplice SD o microSD ?

E poi il divertimento dov'è? :grin:

rocco8383:
Anzi se qualcuno è interessato ne ho 3 stecche di queste eeprom, se si paga la spedizione le spedisco

Quali eeprom? Le 24LC256?

Se le hai già allora butto giù il codice per usarle. 8)

azz, ma se deve usare Arduino per lavoro, forse è meglio un modulino x scrivere su SD, non vi pare? $)

Dipende.
Metti che lui abbia questa pressa con cui si voglia contare i il numero dei pezzi prodotti.
Una volta finita la serie il contatore viene azzerato.

Se come ha detto lui

rocco8383:
Può esere che lavori per 5 giorni di fila e che poi rimanga ferma per altrettati.Producendo in 8 ore da 500 a 2500Pz

possiamo stimare che in un mese produca fino anche 7500 pezzi avremo su una cella la durata di 100'000/7500 = 13.3 mesi, poco più di un anno.
Se cicliamo la scrittura sulla roma interna di Arduino esso durerà (con 2 contatori a 32 bit) 1024/8*1.11 = 142 anni.
Se poi mettiamo la eeprom i2c da 256Kb credo che finisca prima il mondo del contatore.
Quindi ritengo inutile la SD a meno che non voglia creare delle statistiche più complete includendo anche data e ora dei pezzi fabbricati (ma questa potrebbe essere vista come violazione alla legge 300 del '70 riguardo il controllo sulle attività lavorative - anche la pressa ha i suoi diritti). :grin: