la settimana scorsa chiedevo come far eseguire uno sketch ed al reset eseguirne un altro, ho ripreso per mano il codice di prova ma come l'ho scritto sembra contorto pure a me che ne capisco poco, potete dagli un occhiata?
per funzionare funziona ma che altri modi ci sono per chiudere un ciclo su se' stesso, io li uso goto...
#include <EEPROM.h>
int val;
void setup(){
pinMode(13, OUTPUT);
val=EEPROM.read(0); //leggo la eeprom in posizione 0
}
void loop(){
if(val==1){
{EEPROM.write(0,0); //scrivo la eeprom in posizione 0 val=0
goto sketch1;} //salto a sketch1
}
if(val==0){
{EEPROM.write(0,1); //scrivo la eeprom in posizione 0 val=1
goto sketch2;} //salto a sketch2
}
sketch1:
{
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
goto sketch1; // richiudo il ciclo sketch1
}
sketch2:
{
digitalWrite(13, HIGH); // set the LED on
delay(100); // wait for a 1/10 second
digitalWrite(13, LOW); // set the LED off
delay(100); // wait for a 1/10 second
goto sketch2; // richiudo il ciclo sketch2
}
}
Ciao,
personalmente aborro i goto.... dovresti usare delle funzioni
void loop(){
if(val){
EEPROM.write(0,0); //scrivo la eeprom in posizione 0 val=0
sketch1();
}
else
EEPROM.write(0,1); //scrivo la eeprom in posizione 0 val=1
sketch2();
}
void sketch1(){
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
sketch2();
}
void sketch2(){
digitalWrite(13, HIGH); // set the LED on
delay(100); // wait for a 1/10 second
digitalWrite(13, LOW); // set the LED off
delay(100); // wait for a 1/10 second
sketch2();
}
il codice è comunque da ottimizzare ulteriormente...sketch1() e sketch2() fanno la stessa cosa a meno del tempo di delay. Puoi lavorarci ancora su.
N
void setup() {
sketch=leggiEEPROM(); //leggi
.... //qui farai quel che devi fare
}
void loop() {
..... //tuo programma
}
byte leggiEEPROM() {
byte tempByte=EEPROM.read(0);
if ((tempByte != 0) && (tempByte != 1)) { //valore non conforme
EEPROM.write(0, 0); //parto con "0"
tempByte = 0;
} else { //valore corretto (o 0 o 1)
EEPROM.write(0, tempByte^1); //inverto per la prox volta
}
return tempByte
}
L'approccio di Leo è il più sicuro. Leggere e scrivere dalla/sulla EEPROM nel loop non è mai consigliato (correggetemi se sbaglio). Una volta che ti tiri fuori il valore che hai memorizzato in EEPROM usalo per gestire il tempo di delay che vuoi implementare. del genere:
long time_delay;
void setup() {
sketch=leggiEEPROM(); //leggi
if (sketch){
time_delay = 1000;
}
else{
time delay = 100;
}
}
void loop(){
digitalWrite(13, HIGH); // set the LED on
delay(time_delay); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(time_delay); // wait for a second
time_delay = 100;
}
così dovrebbe fare quello che chiedi con poco codice.
N
grazie dei vostri esempi, e' quello che cercavo, io riesco a farlo ma avete visto come, tipo a martellate volevo qualche altro esempio piu' raffinato che ora mi studio
gli spazi son 512bytes ma come li indirizzo?
e' giusto scrivere cosi? EEPROM.write(150,12)?
indirizzo 150 dato 12 ?
(e l'ultimo indirizzo possibile e' 511?)
finora ho solo messo sull'indirizzo 0 zero o uno
e domanda tecnica, se io scrivo sull'indirizzo 0 fino a renderlo inutilizzabile, gli indirizzamenti successivi continuano a funzionare?
reizel:
scusate 2 domande OT sulla eeprom dell'atmeg328
gli spazi son 512bytes ma come li indirizzo?
Il 328 ha 1024 byte di memoria EEPROM. Se hai preso il dato dall'esempio allegato all'Arduino, è sbagliato ed è relativo all'168, che ha metà memoria.
e' giusto scrivere cosi? EEPROM.write(150,12)?
indirizzo 150 dato 12 ?
(e l'ultimo indirizzo possibile e' 511?)
Il modo è giusto, l'ultimo indirizzo è 1023.
finora ho solo messo sull'indirizzo 0 zero o uno
e domanda tecnica, se io scrivo sull'indirizzo 0 fino a renderlo inutilizzabile, gli indirizzamenti successivi continuano a funzionare?
In teoria sì, ma non so esattamente a livello elettrico cosa può succedere quando parte la circuiteria relativa ad una cella, se cioè poi si danneggiano anche i contatti adiacenti .
Ci vorrebbe astrobeed, ma è un po' latitante ultimamente. Mi pareva che se ne fosse già parlato in passato ma non mi ricordo cos'ho fatto stamattina, figurati se mi ricordo cose lette 6 mesi fa
io ricordo che avevo chiesto cosa succedeva quando superavi le massime scritture di codice sull'atmega, dissero che semplicemente non lasciava piu' scrivere nulla, per questo mi chiedevo se usando la eeprom ad indirizzi questa rimaneva utilizzabile nei bytes "ancora buoni"
Se scrivi troppe volte sulla stessa cella e quella si "rompe" le cose sono le seguenti.
Una cella eeprom é un MOSFET con un gate isolato nel silico. Programmandolo inietti per effetto tunnel delle cariche sul gate isolato. Cancellando li togli. A causa di materiali non perfetti restano nel tempo sempre cariche nel silicio (isolatore) che disturbano la programmazione e fanno che il gate non é piú isolato perfettamente. La cella si scarica e cambia dopo un po di tempo stato.
Tutti dei effetti poco da tenere sotto controllo.
superp:
Ciao,
personalmente aborro i goto.... dovresti usare delle funzioni
void loop(){
if(val){
EEPROM.write(0,0); //scrivo la eeprom in posizione 0 val=0
sketch1();
}
else
EEPROM.write(0,1); //scrivo la eeprom in posizione 0 val=1
sketch2();
}
void sketch1(){
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
sketch1();
}
void sketch2(){
digitalWrite(13, HIGH); // set the LED on
delay(100); // wait for a 1/10 second
digitalWrite(13, LOW); // set the LED off
delay(100); // wait for a 1/10 second
sketch2();
}
il codice è comunque da ottimizzare ulteriormente...sketch1() e sketch2() fanno la stessa cosa a meno del tempo di delay. Puoi lavorarci ancora su.
N
una ciamata recursiva della funzione nella stessa funzione riempe in pochissimo lo Stack e blocca o fa fare cose inaspettate al programma.
neanche l' uso del goto mi piace. io consiglio un loop con for o con while:
grazie uwe, anche per la spiegazione della eeprom, ora io e leo ce ne ricorderemo
superp: non ti ho risposto prima, il blink con 2 tempi diversi era solo per testare il codice senza rompimenti, lo sketch ovviamente e' tutt'altra cosa
Ora non voglio confondere le idee dicendo che il goto non deve essere odiato come la peste a prescindere.
Il problema del goto è legato alle etichette a cui si fa il salto, se per rapidità di esecuzione voglio usare un salto incondizionato dovrei farlo in codice non visibile al programmatore, tipo una funzione di libreria.
Devo anche fare attenzione alla leggibilità, il goto etichetta è un problema quando la fuzione contiene molto codice e l'eticchetta si trova distante dalla chiamata goto. La leggibilità peggiora quando nel codice ci sono più goto e più etichette, a questo punto è meglio passare ad asm inline.
if ((tempByte != 0) && (tempByte != 1)) { //valore non conforme
// così è più logico
byte n_max_sketch = 2;
if (tempByte > n_max_sketch - 1) { //valore non conforme