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.
... 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 :
... 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 ...
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 ...
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 ?
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?
Una cosa l’ho capita, sono ancora troppo scarso in materia Arduino
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();
}
}
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();
}
}
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) ... :
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