Aiuto o consigli per usare una eeprom esterna

Salve a tutti, prima cosa abbiate pietà di me, anche se sono iscritto dal 2010 il mio livello di programmazione è bassissimo.
Stavo giocando con un progettino trovato in rete ma mi sono arenato con le eeprom., volevo utilizzare una eeprom esterna (24c08) dove memorizzare un contatore(tramite 2 pulsanti) avanti/indietro e arrivato a zero attiva un led
Tutto quello che sono riuscito a fare è utilizzare la eeprom interna del mio arduino e senza attivazione del led
Qualche consiglio?

#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // connessione display (pin)

const int su = 10;
const int giu = 9;
const int led = 13;
byte datoeeprom;
int statosu = 0;
int statogiu = 0;


void setup() {
  pinMode(su, INPUT);
  pinMode(giu, INPUT);
  pinMode(led, OUTPUT);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  lcd.begin(16, 2);
  datoeeprom = EEPROM.read(1); //leggi il dato salvato nella eeprom nello slot 1

}
void loop() {
  lcd.print ("val");
  statosu = digitalRead (su);
  if( statosu == LOW)
  {
    datoeeprom++;//incrementa il valore alla pressione del pulsante "su"
  } 
  EEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
  statogiu = digitalRead (giu);
  if( statogiu == LOW)
  {
    datoeeprom--;//decrementa il valore alla pressione del pulsante "giu"
  } 
  EEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom

    lcd.setCursor(13, 0);
  lcd.print(datoeeprom);
  delay(200);
  lcd.clear();
}

Cortesemente, intanto, in conformità al regolamento, punto 7, edita (in basso a destra del post, bottone More → Modify) il tuo post e racchiudi il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra).

Poi, se magari usi la funzione del IDE Tools–>Auto Format, il codice ti viene formattato per bene, con le giuste indentature ed è più leggibile per tutti. :wink:

Guglielmo

Grazie Guglielmo, era il mio primo inserimento di un codice

Intanto nel tuo programma vedo un problema ...

... tu verifichi la pressione di un tasto e, se premuto, incrementi un contatore. Questo va bene con dei tasti "ideali", ma purtroppo, nella realtà, le cose non stanno così ed un tasto "reale" premuto provoca più o meno questo :

|500x273

... ed il tuo contatore si incrementerà di un numero casuale, dovuto ai rimbalzi.

Quindi, prima di pensare a salvare i valori in EEPROM, comincia a scrivere un programma che funzioni correttamente, e poi, piano piano, aggiungi anche le altre funzionalità.

Devi cercare "Arduino debouncing" ... che può essere fatto sia via software che via hardware ...

Guglielmo

per l' uso della eeprom esterna cerca "arduino 24c08". A me da 16.700 risultati. Ciao Uwe

Si Guglielmo, ho già inserito una resistenza da 10k collegata a + e input dei pulsanti (pull up) e non ci sono problemi di rimbalzi, poi se devo dirla tutta è solo per imparare la programmazione , essendo autodidatta l’unica è provare, sbagliare leggere,cercare, chiedere e riprovare. Non riesco proprio a capire come fare per attivare un led quando il contatore segnala zero

luca64: Si Guglielmo, ho già inserito una resistenza da 10k collegata a + e input dei pulsanti (pull up) e non ci sono problemi di rimbalzi

... permetti ? NON ci credo ... :grin:

Quella che descrivi è una semplice resistenza di pull-up il cui scopo è tenere HIGH il pin quando il pulsante è aperto, ma quando lo premi hai di sicuro quanto ti ho descritto.

Il minimo (... ma proprio il minimo) di debounce hardware prevede almeno una rete RC :)

luca64: Non riesco proprio a capire come fare per attivare un led quando il contatore segnala zero

In che senso ? Non basta una IF sul contatore che se == 0 accende il LED ?

Guglielmo

Essendo un EEprom esterna non devi usare la libreria EEPROM.h ma la libreria extEEPROM.h che trovi nel gestore delle librerie dell'IDE. Non sono sicuro che la libreria possa funzionare con quel modello ma prova ad inizializzarla con

extEEPROM EEPROM(kbits_8, 1, 16);

Naturalmente devi collegarla al bus I2C.

EDIT: Comunque se hai fatto girare per più di qualche secondo quel codice, la locazione 1 della EEPROM interna è andata... Non devi mai scrivere ripetutamente su una casella, il numero di scritture è limitato a 100'000. Me se scrivi ad ogni ciclo loop ogni pochi millesimi di secondo, 100'000 scritture le fai in poco meno di 2 minuti. Usa il comando update e non write.

Ma soprattutto, sei sicuro di dover memorizzare in EEPROM ogni singola variazione di questo contatore? Non potresti fare degli "snapshot" di tanto in tanto?

Siete troppo pessimisti. St da 4 millioni di cicli di scrttura e ATMEL 1 Millione.

Con una durata di un ciclo di scrittura di 5mS i 1 millioni di cicli li puoi realizzare non sotto i 14 ore.

Comunque avete ragione che i EEprom non sono fatti per essere scritti frequentemente.

Per ovviare questo problema si puó usare la RAM che alcuni RTC hanno (pe esempio il DS1307) oppure usare dei FRAM della RAMTEK http://it.rs-online.com/web/p/memorie-fram/7332269/

Ciao Uwe

Una cosa l’ho capita, sono ancora troppo scarso in materia Arduino :confused: Carissimo Guglielmo e Amici del forum, già che siete stati così gentili e disponibili, mi consigliate delle buone letture? Ho già “primi passi con Arduino” e “alla scoperta di Arduino Yun”

Per passare dalla eeprom interna a una esterna (24LC08) sto provando a utilizzare la libreria extEEPROM ma ottengo questi errori:

okdainviare.ino: In function 'void aumenta()':
okdainviare:66: error: 'myEEPROM' was not declared in this scope
okdainviare.ino: In function 'void diminuisci()':
okdainviare:83: error: 'myEEPROM' was not declared in this scope
'myEEPROM' was not declared in this scope
#include <LiquidCrystal.h>

#include <extEEPROM.h>
#include <Wire.h>
//#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // connessione display (pin)

int soglia = 0;
const int su = 10;
const int giu = 9;
const int led = 13;

byte datoeeprom;

int statosu = 0;
int statogiu = 0;




void setup()
{
  extEEPROM myEEPROM(kbits_2, 1, 8, 0x50);
  Serial.begin(9600);

  pinMode(su, INPUT);
  pinMode(giu, INPUT);
  pinMode(led, OUTPUT);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);

  lcd.begin(16, 2);
  datoeeprom = myEEPROM.read(1); //leggi il dato salvato nella eeprom nello slot 1

}

void loop()
{

  statogiu = digitalRead (giu);  // legge il valore dell'input

  if
  ( statogiu == LOW)
    pausagiu();  //se è premuto vai a


  statosu = digitalRead (su);  // legge il valore dell'input


  if
  ( statosu == LOW)
    pausasu();  //se è premuto vai a
  //}
}


void aumenta() {
  lcd.setCursor(4, 4);
  lcd.print ("Su");



  datoeeprom++;//incrementa il valore alla pressione del pulsante "su"

  myEEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
  delay(200);

  lcd.setCursor(13, 0);
  lcd.print(datoeeprom);
  delay(1000);
  lcd.clear();
}

void diminuisci() {
  lcd.setCursor(4, 4);
  lcd.print ("Giu");



  datoeeprom--;//decrementa il valore alla pressione del pulsante "giu"

  myEEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
  if (datoeeprom <= soglia) {
    disattiva();
  }

  delay(200);

  lcd.setCursor(13, 0);
  lcd.print(datoeeprom);
  delay(2000);
  lcd.clear();
}

void pausasu() {
  statosu = digitalRead (su);  // legge il valore dell'input

  if
  ( statosu == LOW)
    aumenta();  //se è premuto vai a
  //  delay(200);
}
void pausagiu() {
  statosu = digitalRead (su);  // legge il valore dell'input

  if
  ( statogiu == LOW)
    diminuisci();  //se è premuto vai a
  //  delay(200);
}
void disattiva() {
  lcd.setCursor(2, 1);
  lcd.print("Arrivato a zero");
  delay(3000);
  statosu = digitalRead (su);  // legge il valore dell'input


  if
  ( statosu == LOW)
    pausasu();  //se è premuto vai a
  if (datoeeprom <= soglia) {
    disattiva();
  }


}

dove sto sbagliando?

Stai sbagliando a dichiarare myEEPROM() all'interno del setup() rendendola "locale" invece che "globale".

Portala fuori, come già fai per lcd(), e vedrai che non ti darà più errore.

Guglielmo

P.S: Il codice è scritto in modo piuttosto disordinato ... dedica più tempo a scrivere il codice come si deve (...indentature, parentesi veramente necessarie, senza ritorno a capo inutili, ecc.), e vedrai che un domani lo rileggerai con più facilità.

Grazie Guglielmo,
errori spariti, ma il programma si blocca in setup quando trova
datoeeprom = myEEPROM.read(1);

#include <LiquidCrystal.h>

#include <extEEPROM.h>
#include <Wire.h>
//#include <EEPROM.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // connessione display (pin)
extEEPROM myEEPROM(kbits_8, 1, 8); //(kbits_8, 1, 1)
int soglia = 0;
const int su = 10;
const int giu = 9;
const int led = 13;

byte datoeeprom;

int statosu = 0;
int statogiu = 0;




void setup()
{

  // Serial.begin(9600);

  pinMode(su, INPUT);
  pinMode(giu, INPUT);
  pinMode(led, OUTPUT);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  lcd.begin(16, 2);

  lcd.setCursor(2, 6); //test per vedere dove si blocca
  lcd.print("111111");
  delay(2000);

  datoeeprom = myEEPROM.read(1); //

  lcd.setCursor(2, 6);  //test per vedere dove si blocca
  lcd.print("222222");
  delay(2000);
}

void loop()

{
  //  lcd.setCursor(2, 6);
  //  lcd.print("ok");
  // delay(2000);
  // if(datoeeprom <= soglia){
  //      disattiva();
  // }

  statogiu = digitalRead (giu);  // legge il valore dell'input

  if
  ( statogiu == LOW)
    pausagiu();  //se è premuto vai a


  statosu = digitalRead (su);  // legge il valore dell'input


  if
  ( statosu == LOW)
    pausasu();  //se è premuto vai a
  //}
}


void aumenta() {
  lcd.setCursor(4, 4);
  lcd.print ("Su");



  datoeeprom++;//incrementa il valore alla pressione del pulsante "su"

  myEEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
  delay(200);

  lcd.setCursor(13, 0);
  lcd.print(datoeeprom);
  delay(1000);
  lcd.clear();
}

void diminuisci() {
  lcd.setCursor(4, 4);
  lcd.print ("Giu");



  datoeeprom--;//decrementa il valore alla pressione del pulsante "giu"

  myEEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
  if (datoeeprom <= soglia) {
    disattiva();
  }

  delay(200);

  lcd.setCursor(13, 0);
  lcd.print(datoeeprom);
  delay(2000);
  lcd.clear();
}

void pausasu() {
  statosu = digitalRead (su);  // legge il valore dell'input

  if
  ( statosu == LOW)
    aumenta();  //se è premuto vai a
  //  delay(200);
}
void pausagiu() {
  statosu = digitalRead (su);  // legge il valore dell'input

  if
  ( statogiu == LOW)
    diminuisci();  //se è premuto vai a
  //  delay(200);
}
void disattiva() {
  lcd.setCursor(2, 1);
  lcd.print("Arrivato a zero");
  delay(3000);
  statosu = digitalRead (su);  // legge il valore dell'input


  if
  ( statosu == LOW)
    pausasu();  //se è premuto vai a
  if (datoeeprom <= soglia) {
    disattiva();
  }


}

Ho provato a seguire i vari comandi su https://github.com/JChristensen/extEEPROM
ma niente da fare

Come ti è già stato detto ... ... è tutto da verificare che quella libreria supporti la EEPROM da te scelta. Nella descrizione identifica chiaramente i modelli con cui è stata provata e quella che tu usi non mi sembra essere presente..

Se non è supportata, ti devi studiare il datasheet della EEPROM e scriverti tu le routines di R/W utilizzando le chiamate per il bus I2C (libreria Wire) ... ::)

Guglielmo

Io le EEprom 24LC516 le programmo con la libreria Wire.h senza nessun problema

http://www.logicaprogrammabile.it/utilizzare-una-memoria-seriale-24lc256/

Ma lui ha una 24C08.

Risolto, messo 2 resistenze di Pull da 4.7K sulla linea bus I2C e il comando Wire.begin(); per iniziallizare la libreria Wire mancante adesso gira che è una meraviglia. Grazie a tutti

luca64:
messo 2 resistenze di Pull da 4.7K sulla linea bus I2C

… emmm … quelle erano date per scontate visto che sono obbligatorie nel bus I2C :wink:

Guglielmo

PaoloP: Ma lui ha una 24C08.

Con il codice in esempio puoi scrivere e leggere tutte le eeprom della famiglia 24