[RISOLTO] Azzeramento variabile su Arduino Uno e Mega in ciclo if else

Salve a tutti,
utilizzo un Arduino Mega, ma ho provato il codice anche sull’Uno e su un simulatore di Arduino.
Devo ricevere dei valori da un accelerometro e far si che in accelerazione in una determinata direzione sommi in una variabile “k” il numero di volte che viene ripetuta l’operazione e in un’altra variabile la somma di tutti i valori ricevuti dall’accelerometro.
Per semplificare un pò il problema ho scritto uno sketch di prova con un potenziometro al posto dell’accelerometro collegato al pin analogico 0.
Il mio problema è che sul simulatore va tutto bene, mentre quando testo il codice su Arduino(sia Mega che Uno) entrambe le variabili tornano a zero.
Non son riuscito a trovare alcun caso simile.

void setup() {
   Serial.begin(9600);
}
 
void loop() {

int k_new_prova_aggiornamento;
int accel_tmp_new_prova_aggiornamento;

 int potenzio = 0;
 float spostamento;
 float letturaAccel;
 float accel_tmp;
 int k;
 float tempo0;         // valore del tempo a inizio conteggio
 float tempoX = 0;            // valore del tempo a fine conteggio
 float spo;
   float tempo;
   float tempo2;


potenzio = analogRead(0);
  
  if (potenzio<80)
  {  
     tempoX=millis();  
       tempo =(tempoX-tempo0);
       tempo2= (tempo*tempo);
       spo= (spostamento*k_new_prova_aggiornamento*tempo2)/500000;
      
       Serial.print("\n     tempoX:    ");                          //
     Serial.print(tempoX);                                        //
       Serial.print("\n     tempo0:    ");                          //
     Serial.print(tempo0);                                        //
            
       Serial.print("\n     tempo:    ");                          //
     Serial.print(tempo);                                        //
      
     Serial.print("\nspostamento:    ");                         //
   Serial.print(spo);

     Serial.print("\nk :           ");                           // k prima di essere aggiornato a 0
 Serial.print(k);                                     //
                k=0;    
     Serial.print("\nk :           ");                           // k aggiornato a 0
 Serial.print(k);                                     //
     Serial.print('\n'); //
      
       
     accel_tmp=0;
       tempo2=0;       
       tempo=0;
       spostamento=0;
       k_new_prova_aggiornamento=0;
  

  }
  
  else if (k>=1){

      
       accel_tmp = accel_tmp + potenzio;
       accel_tmp_new_prova_aggiornamento=accel_tmp;
       k=k+1;
     k_new_prova_aggiornamento=k;
      
       letturaAccel = accel_tmp_new_prova_aggiornamento/k_new_prova_aggiornamento;
 spostamento=(letturaAccel);

 Serial.print("\npotenziozzozozo:    ");                     //
   Serial.print(potenzio); 
       
       Serial.print("\nletturaacc:    ");                          //
   Serial.print(letturaAccel);                                 //
      
   Serial.print("\nspostamento:    ");                         //
 Serial.print(spostamento);                                  //
      
       Serial.print("\ntmp:    ");                           //
   Serial.print(accel_tmp);                                    //

         Serial.print("\nk_tmp:    ");                           //
   Serial.print(k_new_prova_aggiornamento);                   //

     Serial.print("\nk :           ");                           //
 Serial.print(k);                                     //
                        
   Serial.print("\nTempoX:  ");                           //
   Serial.print(tempoX);                                     //
 
         Serial.print("\ntempo0:    ");                            //
   Serial.print(tempo0);                                       //
        
 Serial.print('\n');
     }
   else
     
    {
       tempo0=millis();
     accel_tmp = accel_tmp + potenzio;
       accel_tmp_new_prova_aggiornamento=accel_tmp;
       k=k+1;
     k_new_prova_aggiornamento=k;
      
       letturaAccel = accel_tmp_new_prova_aggiornamento/k_new_prova_aggiornamento;
 spostamento=(letturaAccel);

 Serial.print("\npotenzio:    ");                            //
   Serial.print(potenzio); 
       
       Serial.print("\nletturaacc:    ");                          //
   Serial.print(letturaAccel);                                 //
      
   Serial.print("\nspostamento:    ");                         //
 Serial.print(spostamento);                                  //
      
       Serial.print("\ntmp:    ");                           //
   Serial.print(accel_tmp);                                    //

         Serial.print("\nk_tmp:    ");                           //
   Serial.print(k_new_prova_aggiornamento);                    //

     Serial.print("\nk :           ");                           //
 Serial.print(k);                                     //
                        
   Serial.print("\nTempoX:  ");                           //
   Serial.print(tempoX);                                     //
 
         Serial.print("\ntempo0:    ");                            //
   Serial.print(tempo0);                                       //
        
 Serial.print('\n');
     }

}

le domande che ho da porre posso sintetizzarle così:
C’è qualche errore nel codice?
Perchè su un simulatore va e sull’arduino no?(potrebbe anche essere il simulatore non preciso, ma se il linguaggio è quello dovrebbe andare)

Ho provato a utilizzare sia while che for per provare a risolvere.
Il for non posso utilizzarlo in quanto non ho un valore fisso a cui fermarmi.
il while non riesce a fermarsi a meno che non dia in ingresso direttamente il pin, in pratica non aggiorna la variabile con il valore istantaneo. Se faccio finire il while con un break si ripresenta il problema delle variabili azzerate.
Ho provato anche a salvare nella EEPROM i valori e ricaricarli e funziona, però mi sembra oltre che troppo macchinoso, un inutile sfruttamento selvaggio di un componente soggetto a usura.

Grazie anticipatamente=)

ciao ElGiannone,

per risolvere il problema dell'azzeramento delle variabili, dato che le hai dichiarate tutte locali al loop(), anteponi ad ogni una di esse, o a quelle di cui t'interessa mantenere il valore, il qualificatore static...per capire cosa vuol dire guarda QUESTO link.

altra soluzione...dichiarale globali..cioè fuori dalle funzioni.

Grazie ORSO2001,
mi leggo bene il link e provo subito:)

In verità sbaglia il "simulatore" ...
... loop() è una funzione che, erroneamente tutti diciamo "gira in continuazione".

La realtà è un'altra, loop() è una funzione che viene "richiamata in continuazione", quindi inizia, finisce, si esce, si rientra, inizia, finisce, si esce, ecc. ecc.

In pratica, nel core, semplificando c'è:

for( ; ; ) {
   ...
   loop(); // ad ogni giro, il for chiama la funzione loop()
   ...
}

Per questo motivo, ogni volta che si entra le variabili vengono allocate nello stack, ed ogni volta che finsce e si esce, le varibili vengono buttate e lo stack liberato.

L'attributo "static" dice invece al compilatore di NON allocarle dinamicamente, ma staticamente, così che NON vengano buttate quando la funzione esce e che quando ricomincia le trovi ancora li.

Guglielmo

Era quello il problema:):):):):):):):slight_smile:
C'ero un paio di giorni sopra!!!!!

Grazie mille anche a gpb01 per l'ottima spiegazione del perchè.
Eviterò il simulatore allora, tanto ora ho un arduino per fare prove e posso usare quello reale:)

Sempre in tema su quello che ho chiesto come mai il while non usciva più dal suo loop??
Cioè perchè usciva solamente se in ingresso aveva il pin e non aggiornava la variabile?
perchè nel while si autorichiama la funzione senza uscire da essa?

Comunque ancora grazie:)

ElGiannone:
Era quello il problema:):):):):):):):slight_smile:
C'ero un paio di giorni sopra!!!!!

Grazie mille anche a gpb01 per l'ottima spiegazione del perchè.
Eviterò il simulatore allora, tanto ora ho un arduino per fare prove e posso usare quello reale:)

Sempre in tema su quello che ho chiesto come mai il while non usciva più dal suo loop??
Cioè perchè usciva solamente se in ingresso aveva il pin e non aggiornava la variabile?
perchè nel while si autorichiama la funzione senza uscire da essa?

Comunque ancora grazie:)

Nel codice da te postato non vedo while, ti riferisci al while usato per richiamare il loop?

... anche io NON vedo alcun while() e ... nel codice da me postato c'è una for() :smiley:

Guglielmo

gpb01:
... anche io NON vedo alcun while() e ... nel codice da me postato c'è una for() :smiley:

Guglielmo

Ecco, mi veniva il dubbio che fosse stato quello. Se così allora rispondo io

ElGiannone:
Era quello il problema:):):):):):):):slight_smile:
C'ero un paio di giorni sopra!!!!!

Grazie mille anche a gpb01 per l'ottima spiegazione del perchè.
Eviterò il simulatore allora, tanto ora ho un arduino per fare prove e posso usare quello reale:)

Sempre in tema su quello che ho chiesto come mai il while non usciva più dal suo loop??
Cioè perchè usciva solamente se in ingresso aveva il pin e non aggiornava la variabile?
perchè nel while si autorichiama la funzione senza uscire da essa?

Comunque ancora grazie:)

In pratica la funzione main non fa altro che chiamare le due funzioni setup e loop.

 setup();
for(;;) loop();

La funzione setup viene eseguita una sola volta mentre il loop viene eseguito di continuo da un while o da un for. Ogni volta che il loop (o qualsiasi altra funzione) viene chiamato, vengono rimesse in memoria le sue variabili e ogni volta che finisce vengono tolte dalla memoria. Perciò ogni volta che chiami il loop trovi tutti i valori delle sue variabili a 0 (o a qualche stato casuale). Non mi sono spiegato sicuramente bene, ma chiedi pure.

Esempio pratico:

 Chiamo il loop la prima volta -> (Sono il loop adesso) Dichiaro le mie variabili e faccio ciò che devo fare -> (Ancora da loop) Ora le mie variabili non servono più -> Chiamo il loop la seconda volta... stesse cose....

E così continua finché stacchi