Arduino possiede una memoria di tipo EEPROM (Electrically Erasable Programmable Read-Only Memory), questa memoria è cancellabile elettricamente e quindi è possibile utilizzarla tramite lo stesso Arduino per salvare dei dati che ci interessano.
Il bello di questa memoria è che, anche togliendo tensione al circuito, il dato resta memorizzato.
Successivamente, dando nuovamente alimentazione, posso leggere i valori precedentemente salvati.
Grazie a questa memoria, ad esempio, è possibile memorizzare dati di temperatura catturati con un sensore in momenti differenti e poi rileggerli tutti insieme quando lo desidero.
In Arduino Uno la EEPROM è di 1KB, che sono 1024 Byte, possiamo quindi memorizzare 1024 numeri con valori compresi tra 0 e 255.
Ho realizzato un piccolo progetto per fare le prime prove sulla EEPROM, funziona così (scusate x la musica XD):
Entriamo più nel dettaglio della realizzazione:
Sul display viene letto il valore memorizzato nello spazio "1" della EEPROM.
Grazie a 2 pulsanti, incremento e decremento questo valore.
Raggiunto il valore desiderato premo il terzo pulsante, così facendo memorizzo il dato nella memoria e lo sostituisco al dato precedentemente memorizzato.
Per aiutarmi a capire l'avvenuta pressione del pulsante, comparirà un "S" sul display.
Ora, spegnendo e riaccendendo l'Arduino, verrà visualizzato l'ultimo dato salvato.
Questo è il circuito da realizzare:
Ecco lo sketch da caricare:
Ciao a tutti!
Seguimi sulle mie pagine per rimanere sempre aggiornato sui nuovi post!
Il bello di questa memoria è che, anche togliendo tensione al circuito, il dato resta memorizzato.
Successivamente, dando nuovamente alimentazione, posso leggere i valori precedentemente salvati.
Grazie a questa memoria, ad esempio, è possibile memorizzare dati di temperatura catturati con un sensore in momenti differenti e poi rileggerli tutti insieme quando lo desidero.
In Arduino Uno la EEPROM è di 1KB, che sono 1024 Byte, possiamo quindi memorizzare 1024 numeri con valori compresi tra 0 e 255.
Ho realizzato un piccolo progetto per fare le prime prove sulla EEPROM, funziona così (scusate x la musica XD):
Entriamo più nel dettaglio della realizzazione:
Sul display viene letto il valore memorizzato nello spazio "1" della EEPROM.
Grazie a 2 pulsanti, incremento e decremento questo valore.
Raggiunto il valore desiderato premo il terzo pulsante, così facendo memorizzo il dato nella memoria e lo sostituisco al dato precedentemente memorizzato.
Per aiutarmi a capire l'avvenuta pressione del pulsante, comparirà un "S" sul display.
Ora, spegnendo e riaccendendo l'Arduino, verrà visualizzato l'ultimo dato salvato.
Questo è il circuito da realizzare:
Ecco lo sketch da caricare:
- #include <LiquidCrystal.h>
- #include <EEPROM.h>
- LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // connessione display (pin)
- const int salva = 8;
- const int su = 10;
- const int giu = 9;
- byte datoeeprom;
- int statosu = 0;
- int statogiu = 0;
- int statosalva = 0;
- void setup() {
- pinMode(salva, INPUT);
- pinMode(su, INPUT);
- pinMode(giu, INPUT);
- digitalWrite(8, HIGH);
- 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"
- statogiu = digitalRead (giu);
- if( statogiu == LOW)
- {datoeeprom--;} //decrementa il valore alla pressione del pulsante "giu"
- statosalva = digitalRead (salva);
- if( statosalva == LOW)
- {EEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
- lcd.setCursor(0, 1);
- lcd.print("S");}
- lcd.setCursor(13, 0);
- lcd.print(datoeeprom);
- delay(200);
- lcd.clear();
- }
Seguimi sulle mie pagine per rimanere sempre aggiornato sui nuovi post!
Mi sto appassionando perchè comincio a capire qualche cosa, grazie a te Daniele!!!!!!!!!!
RispondiEliminaSalve Daniele ho un quesito da porti, ma se dovrei memorizzare valori superiori a 255?? Come potrei fare? GRAZIE in anticipo!!
RispondiEliminaCiao Samuele, se non ti serve particolare precisione puoi salvare tutti i valori che ti servono dividendoli prima per 10 (ad esempio per 1000 salvi 100).
EliminaIn alternativa puoi convertire il valore in binario e spezzarlo su 2 byte, poi puoi ricomporlo con il comando "shiftando" i bit. (La seconda opzione è leggermente più macchinosa).
Spero di essere stato utile, ciao!
Ciao Daniele,
RispondiEliminaIo dovrei aumentare/diminuire un setpoint di un PID tramite due pulsanti, e visualizzare il valore su LCD I2C.
Nel mio progtto mi sono avanzati solo due pin digitali, quindi vorrei fare in modo che la variabile sia scritta in eeprom, non so, dopo un dato tempo.
Mi potresti aiutare?
Grazie.
Filippo
Ciao Filippo,
Eliminapotresti usare la funzione Millis per capire che "un dato tempo" sia trascorso.
Trovi un esempio qui:
http://www.danielealberti.it/2013/06/blink-con-millis-anziche-delay.html
Grazie Daniele.
EliminaHo rifatto il circuito, e i 3 pulsanti ci stanno...
Ma ho una domanda:
Ho integrato (vedi sotto) al mio sketch il tuo. Ma ora come faccio a modificare la mia variabile (setpoint) entro i valori di temperatura 0-100?
/*
Il programma misura la temperatura tramite sensori DS18B20 per regolare la rotazione dei due ventole da PC a 12V 0,25A,
per controllare la temperatura della birra in fermentazione usando un terzo DS18B20 con funzione PID
L'uscita del PID pilota un circuito H-bridge per le celle di Peltier
*/
#include
#include // libreria di gestione del display lcd Grove I2C
#include // dichiarazione di utilizzo della libreria DallasTemperature
#include
#include
/* Definizioni globali */
// Il terminale data del sensore è connesso alla porta 4 di Arduino
#define ONE_WIRE_BUS 4
// Imposta la comunicazione oneWire per comunicare
// con un dispositivo compatibile
OneWire oneWire(ONE_WIRE_BUS);
// Passaggio oneWire reference alla Dallas Temperature.
DallasTemperature sensor(&oneWire);
double Setpoint, Input, Output;
int SNS_A = A0; // Legge corrente
int LPWM = 9; // H-bridge leg 1 ->LPWM
int enL = 8; // H-bridge enable pin 1 -> L_EN
int RPWM = 6; // H-bridge leg 2 ->RPWM
int enR = 7; // H-bridge enable pin 2 -> R_EN
//Inizializzazione del PID, impostazione a DIRECT (frigo), e dell'LCD
PID myPID(&Input, &Output, &Setpoint,2,5,1, REVERSE);
rgb_lcd lcd ;
// Pulsanti
const int salva = 2;
const int su = 12;
const int giu = 13;
byte datoeeprom;
int statosu = 0;
int statogiu = 0;
int statosalva = 0;
void setup()
{
Setpoint = 18; //definizione del set point
Serial.begin(9600);
Serial.println("Temperatura PIDout Corrente\n");
lcd.begin(16, 2);
digitalWrite(4, HIGH); // turn on pull-up resistor
// Pulsanti
pinMode(salva, INPUT);
pinMode(su, INPUT);
pinMode(giu, INPUT);
digitalWrite(2, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
datoeeprom = EEPROM.read(1); //leggi il dato salvato nella eeprom nello slot 1
//turn the PID on
myPID.SetMode(AUTOMATIC);
// Start up the OneWire library
sensor.begin();
// Configurazione PIN direzione e freno H-bridge
pinMode(LPWM, OUTPUT);
pinMode(RPWM, OUTPUT);
pinMode(enL, OUTPUT);
pinMode(enR, OUTPUT);
digitalWrite(enL, HIGH);
digitalWrite(enR, HIGH);
}
void loop() {
sensor.requestTemperatures();
// inizio loop PID
double temp = sensor.getTempCByIndex(0); // legge il valore della temperatura e la memorizza nella var. temp.
Input = temp; //temperatura passata in ingresso a PID
myPID.Compute();
digitalWrite(LPWM, LOW);
digitalWrite(RPWM,Output); //PWM con segnale in uscita pari a uscita PID
Serial.print( temp); // invia i valori al' LCD
Serial.print("\t");
Serial.print((Output/255*100));
Serial.print("\t");
Serial.print(digitalRead(SNS_A));
Serial.print("\n");
lcd.setCursor(3,0);
lcd.print("Temp:");
lcd.print(sensor.getTempCByIndex(0));
lcd.setCursor(3,1);
lcd.print("S.P.:");
lcd.print(Setpoint);
// fine loop PID
// Loop per pulsanti
statosu = digitalRead (su);
if( statosu == LOW)
{datoeeprom++;} //incrementa il valore alla pressione del pulsante "su"
statogiu = digitalRead (giu);
if( statogiu == LOW)
{datoeeprom--;} //decrementa il valore alla pressione del pulsante "giu"
statosalva = digitalRead (salva);
if( statosalva == LOW)
EEPROM.write(1, datoeeprom); //salva il dato nello slot 1 della eeprom
}
Salve a voi tutti! Premetto che, sono un novello apprendista per quanto concerne Arduino e non ho mai avuto a che fare con la programmazione nonostante la mia passione per l'elettronica ma sempre a livello hobbistico quindi da...praticone ovvero quelli che facciamo più danni...AHAHAH!!!!
RispondiEliminaAllora, la mia esigenza è questa. Devo fare girare due motori ovvero il primo motore controlla un oggetto e il secondo un'altro, nella fattispecie un roller e un condensatore, sono un radioamatore e la mia idea è quella di, una volta trovato l'accordo nelle varie bande, memorizzare la posizione dei due motorini e dopo tramite un commutatore rotativo selezionare la banda da leggere eventualmente su un display I2C e fare in modo così che si trovi l'accordo memorizzato. Questo è il mio problema...al momento...AHAHAH!!!
Che soluzione potrebbe esserci? Ribadisco....non conosco la programmazione e Arduino lo uso da qualche mese...."non parlate difficile che non vi capisco"...AHAHAH!!!
Ecco...dovreste accompagnarmi passo passo....a proposito, i motori non sono passo passo ma normalissimo motori a 12 V già ridotti.
Grazie anticipatemente
Mario