Go Down

Topic: codice, eeprom e 2 sketch distinti al reset, vs consigli (Read 694 times) previous topic - next topic

reizel

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...

Code: [Select]
#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
  }
}


superp

Ciao,
personalmente aborro i goto.... dovresti usare delle funzioni

Code: [Select]

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
"The question is not whether intelligent machines can have emotions, but whether machines can be intelligent without any emotions"

leo72

Ecco come la vedo io:

Code: [Select]
byte sketch;

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
}

superp


Ecco come la vedo io:

Code: [Select]
byte sketch;

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:

Code: [Select]

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
"The question is not whether intelligent machines can have emotions, but whether machines can be intelligent without any emotions"

reizel

grazie dei vostri esempi, e' quello che cercavo, io riesco a farlo ma avete visto come, tipo a martellate :smiley-yell: volevo qualche altro esempio piu' raffinato che ora mi studio ;)


reizel

scusate 2 domande OT sulla eeprom dell'atmeg328

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?

leo72


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.

Quote

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.

Quote

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 .

reizel

grazie leo, e si' i 512 li avevo letti dall'esempio di arduino.cc :*

per la domanda tecnica credo che solo utenti uwe compatibili potrebbero darci una risposta certa ]:D

altrimenti per noi mortali non resta che scriverci uno sketch che faccia piantare la eeprom e contare le scritture :smiley-roll-blue:

leo72

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  :smiley-eek:

reizel

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"

leo72


uwefed

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.

Ciao Uwe

uwefed


Ciao,
personalmente aborro i goto.... dovresti usare delle funzioni

Code: [Select]

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:
Quote
void sketch1(){
for( ;; )
{
codice del sketch 1
}}

oppure
Quote
void sketch1(){
while(1)
{
codice del sketch 1
}}

Ciao Uwe

reizel

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

MauroTec

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.

Code: [Select]

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


Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Go Up