Grazie, nel frattempo ho fatto una ricerca su Youtube e ho visto là. Però in un video viene detto che la EEprom ha un limite di scrittura di 100.000 scritture per cella, per cui non bisogna abusare, è vero?
Ogni cella è un Byte, quindi in una cella posso scrivere un numero fino a 255, giusto? Se devo scrivere il numero1000, scriverò EEPROM.update(0,1000); e per leggere EEPROM.read(0); giusto?
update scrive il nuovo valore solo se diverso dal precedente, giusto? Serve a risparmiare scritture sulla EEprom, allora è vero il limite di 100.000 scritture a cella?
Il limite delle 100k scritture c'è.
Per salvare un valore più grande di un byte non puoi usare write o update. O scomponi il valore in diversi byte oppure più semplicemente usi put(). E per leggere usi get().
Nel link postato da @Datman c'è scritto tutto.
Di inglese conosco solo yes e no, per cui quando devo leggere qualche testo in inglese devo far uso di Google. A prorposito, esco un attimo fuori tema, quando usavo Chrome, una pagina in inglese veniva riconosciuta automaticamente e mi chiedeva se fare la traduzione della pagina. Con il browser Microsoft ciò non accade, c'è un sistema per arrivare allo stesso risultato?
Mi direte: installa Chrome. Mi scoccia avere due browser se si può fare tutto con uno, in più ho visto che a volte mi capitano siti in cui crome non funzionano bene e lo stesso sito col browser Microsoft funziona bene.
Ritornando alla EEPROM, se scrivo un numero più grande di un byte con put(0,1234567) e poi devo scrivere un altro numero, come faccio a sapere da quale cella iniziare a scrivere se non so quanti byte ha occupato il vecchio numero?
Nel mio caso non mi pongo il problema perché devo memorizzare una variabile per il mio progetto, ma pongo la domanda giusto per capire meglio.
Non mi ero mai posto la domanda perché appunto di solito si scrive un singolo byte, o una variabile il cui tipo (e quindi occupazione) è conosciuto a priori.
Nel caso di una costante numerica basta un cast per forzare il tipo desiderato:
EEPROM.put(0, (uint32_t)1234567);
...e così ho scoperto che Serial.print non funziona con valori o variabili a 64 bit ("error: call of overloaded 'print(long long int&)' is ambiguous")
Ho fatto una ricerca su internet sulle variabili e ho stilato questo resoconto, va bene oppure ho sbagliato ad interpretare qualcosa?
--------- Variabili --------------------
Le variabili dichiarate prima di setup e void, possono essere usate da entrambi.
Le variabili dichiarate in setup o void, possono essere usate solo nel relativo ciclo.
float x = 1,2; -> Contenitore per numeri con la virgola nel range numerico da 3.4028235E+38 a -3.4028235E+38. Occupa 4 byte. E' a 32 bit
double x = 1,2; -> Contenitore per numeri con la virgola nel range numerico da 1.7E308 a -1.7E308. Occupa 8 byte. E' a 64 bit
long x = 0; -> Contenitore per numeri interi nel range numerico, da -2147483648 a 2147483647. Occupa 4 byte
unsigned long x = 0; -> Contenitore per numeri interi nel range numerico, da 0 to 4,294,967,295 (2^32 – 1) Occupa 4 byte
int x = 0; -> Contenitore per numeri interi nel range numerico da -32768 a 32767. Occupa 2 byte
unsigned int x = 0; -> Contenitore per numeri interi senza segno nel range numerico, da 0 a 65535. Occupa 2 byte
char car = 'c'; --> Assegna alla variabile car il carattere presente tra gli apici. Occupa 1 byte
int intero = car; --> assegna alla variabile intero il valore ascii del carattere contenuto nella variabile car
String stringa = "parola o frase"; --> assegna alla variabile stringa ciò che è contenuto nelle virgolette #define x 10 --> Nello sketch la x viene sostituita dal 10, non è una variabile che può variare
bool x = FALSE; -> Contenitore per valori booleani (TRUE, FALSE). Occupa 1 byte
Setup e void?... Void è solo l'assenza di un parametro. Le variabili dichiarate fuori da tutto sono comuni a tutte le funzioni, tra cui setup() e loop().
float x=1,2; Attento a usare sempre il punto come separatore decimale nel codice!
Double su Arduino Uno e molti altri microcontrollori AVR è a 32 bit come float.
Char e byte sono variabili a 8 bit, con e senza segno.
String è un oggetto; le stringhe del C sono array di caratteri.
#define effettua la sostituzione di ciò che sta prima dello spazio con ciò che sta dopo prima della compilazione.
true e false (in minuscolo!) sono costanti definite come 1 e 0, così come HIGH e LOW.
Occhio che le dimensioni variano in base all'architettura. Finché rimani su uno, nano, mega ok, se passi su esp o altre schede potrebbero cambiare.
Per il double (e anche per le altre) guarda qui.
Ni, assegna alla variabile car il codice ASCII del carattere.
Dire che una variabile tipo char contiene un carattere è un'astrazione. A livello astratto può anche andare bene immaginare che in memoria siano memorizzati i caratteri , ma fisicamente i caratteri non esistono, ci sono solo codici che li identificano secondo una convenzione comune chiamata codifica o encoding (in questo caso la codifica ASCII).
int intero = car; --> assegna alla variabile intero il valore ascii del carattere contenuto nella variabile car
Per quanto detto prima, nella variabile intero viene semplicemente ricopiato il codice già presente nella variabile car. Siccome il tipo int su ArduinoUno/Nano ecc occupa due byte, il codice ASCII viene copiato nel byte basso (gli 8 bit meno significativi), mentre il byte alto viene impostato a zero.
Per quanto riguarda i tipi, c'è una denominazione comune valida per tutte le architetture, e una "descrittiva", che su architetture diverse può indicare variabili di grandezza diversa.
Nello shetch precedente, all'inizio del loop, ho aggiunto le righe per variare il tempo con due pulsanti e relativa visualizzazione a schermo, ho anche aggiunto la scrittura e lettura su EEPROM. Per ora ho messo lettura e scrittura come commento, lo toglierò quando ho finito.
Una perplessità, la scrittura su EEProm, da come ho fatto il codice, viene fatta ad ogni pressione dei tasti, c'è un modo per scriverlo una sola volta?
void setup() {
DimmableLight::setSyncPin(2); // Imposta il pin 2 per la sincronizzazione dello zero
DimmableLight::begin(); //Inizializza la libreria
l1.setBrightness(0); // Imposta alba a zero
Serial.begin(9600); // Inizializza la seriale alla velocità di 9600
lcd.init(); // Inizializza LCD
lcd.backlight(); // Attiva retroilluminazione
lcd.clear(); // Cancella lo schermo
// tempo = EEPROM.read(0);
// if (tempo=0) tempo=300; // Imposta il tempo a 5 minuti qualora nella posizione zero non ci fosse nulla
} // Fine setup
void loop() {
tasto = analogRead(A0);
if ( tasto<900 && tasto>690 ) { // Se è stato premuto un tasto varia il tempo
lcd.clear(); // Cancella lo schermo
lcd.setCursor(0, 0); // Imposta il cursore alla colonna 0 e riga 0
lcd.print("Tempo Giorno = ");
lcd.setCursor(16, 0);
lcd.print(tempo);
if (tasto<892 && tasto >888) { // Tasto decrementa
tempo--;
if (tempo<120) tempo=120; // Il tempo minimo è di 2 minuti
}
if (tasto <696 && tasto >692) { // Tasto incrementa
tempo++;
if (tempo>600) tempo=600; // Il tempo max è di 10 minuti
}
// EEPROM.update(0,tempo); // Scrive il valore di tempo nella posizione zero solo se il valore da scrivere è diverso dal precedente
}
Poi il codice continua con le variazioni di luminosità per le varie fasi del giorno.
Mi pare che la variabile tempo sia più grande di un byte. Se è così non puoi usare update() che accetta solo un parametro byte.
Devi usare put() per salvare e get() per leggere.
EEPROM.update (1, tempo >> 8); // Prende solo gli 8 bit più significativi e li sposta a destra di 8, che equivale a dividere per 8: High byte.
EEPROM.update (0, tempo & 0b11111111); // Oppure & 255: prende solo gli 8 bit meno significativi, che sono il resto della divisione: Low byte.
// È solo aritmetica in base 2... :)
e poi rimetterli insieme.
Ooops... Avevo scritto &&, che è l'AND logico tra due condizioni, mentre qui bisogna usare &, che è l'operazione binaria AND tra bit.