Go Down

Topic: strano problema con delay (Read 838 times) previous topic - next topic

tom95

ciao a tutti,

mi accade uno strano problema nel seguente codice.
Code: [Select]

void utilizzo()  //funzione richiamata dal loop
{
      contatore++;
      if( contatore == 1000)
          avviso();
}


nella funzione avviso viene effettuata una Serial.print.
Il problema è che questa viene sempre stampata, come se non esistesse l' IF.
Tuttavia, se inserisco un delay qualsiasi prima dell'IF (indifferentemente se prima o dopo l'incremento) il problema scompare....

Qualcuno ha qualce idea sul possibile motivo?
grazie in anticipo.

uwefed

Mi puzza si un array che viene usato oltre il suo indice o un puntatore che punta a caso nella memoria RAM.

Ci dai il sketch completo?

Ciao Uwe

PaoloP

#2
Sep 09, 2013, 09:44 am Last Edit: Sep 09, 2013, 09:46 am by PaoloP Reason: 1
Che tipo è contatore? Int, long, unsigned long?
Se fosse un int e lo richiami ad ogni loop fa in fretta a tornare a zero e quindi nuovamente a 1000. Potrebbe essere il motivo per cui stampa frequentemente.
Se invece inserisci un delay allora allunghi il tempo, ma prima o poi lo ristampa.

leo72

Con un pezzo di codice lungo 3 righe non si può capire cosa succede nel resto del programma che può magari influenzare questa funzione.
Se non è molto lungo, dovresti allegare tutto lo sketch.

tom95

per PaoloP è un int.

eccovi il codice, non è lungo e nemmeno difficile e comunque sia il problema è isolato, il resto non dovrebbe influenzare minimamente.
Code: [Select]

int  elettroDx = 9;
int  elettroSx = 10;
int  pompaDx = 11;
int  pompaSx = 12;
int  sensore = 13;
int  pulsante = 2;


volatile int contatore=0;
int x=0;

int nruote=0;
int Rsensore=0;

void setup ()
{
  Serial.begin(9600);
  pinMode(elettroDx, OUTPUT);
  pinMode(elettroSx, OUTPUT);
  pinMode(pompaDx, OUTPUT);
  pinMode(pompaSx, OUTPUT);
 
  pinMode(sensore, INPUT);   
 
}

void loop()
{
   
  if(true) //la condizione originale non era questa ma il problema sorge anche cosi
utilizzo();

}

void utilizzo()
{
      contatore++;
      delay(1);  //delay necessario altrimenti succede quanto spiegato prima
      if( contatore == 1000)
          avviso();
     
    lavaggio(); 
}


void lavaggio()
{
  //apertura pompe
  digitalWrite(pompaDx, HIGH);
  digitalWrite(pompaSx, HIGH);
  delay(1000); //indicativo per pressione
 
  //chiusura pompe
  digitalWrite(pompaDx, LOW);
  digitalWrite(pompaSx, LOW);
 
  //apertura valvole
  digitalWrite(elettroDx, HIGH);
  digitalWrite(elettroSx, HIGH);
 

  do
  {
      delay(1000);
      x++;
  }
  while((( x<=5 || input()==false)) && nruote<1);
 
  x=0;
  digitalWrite(elettroDx, LOW);
  digitalWrite(elettroSx, LOW);
     
}

boolean input()

  if( digitalRead(sensore)==HIGH && digitalRead(pulsante)==LOW && nruote==0  ) //attivato-->ruota && pulsante start premuto  0--> prima ruota
    {
        nruote++;  //possibile delay per utenti riconglioniti
        return true;
    }
    if( digitalRead(sensore)==HIGH && nruote==1  ) //attivato-->ruota && pulsante start premuto
    {
        nruote++;
        return true;
    }
          return false;
}
 

void avviso(){
   Serial.println("AIUTO");
}



grazie per l'aiuto

lucaleo

Code: [Select]

void utilizzo()  //funzione richiamata dal loop
{
      contatore++;
      if( contatore == 1000){
          avviso();}
}


io direi che mancano le graffe...

nid69ita

#6
Sep 10, 2013, 09:11 am Last Edit: Sep 10, 2013, 09:46 am by nid69ita Reason: 1
@lucaleo    non sono obbligatorie se c'e' solo una istruzione
ad esempio puoi anche scrivere un if così
Code: [Select]
if(x==0) print("x vale 0");
invece di
Code: [Select]
if(x==0)
{ print("x vale 0");
}


@tom95  la variabile è int (piccola) ma anche volatile.  Puoi togliere quell'attributo per verificare se è quello? Non credo, però nel codice non mi pare di vedere qualcosa che porti a quel problema.
my name is IGOR, not AIGOR

niki77


eccovi il codice, non è lungo e nemmeno difficile e comunque sia il problema è isolato, il resto non dovrebbe influenzare minimamente.


Ad occhio e croce dovrebbe eseguirti il blocco circa ogni 0,00025 secondi ,
Non penso che un essere umano riesca a seguirlo visivanente  .
Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

PaoloP

Come già detto, il problema è che con la variabile int che può contenere solo fino a 32767 valori (più i negativi che però non usa) il ciclo loop se lo mangia in un baleno quindi la condizione "contatore == 1000" si ripresenta dopo ogni overflow della variabile.

@Lucaleo, in questo caso le parentesi non influiscono.

@Tom95
Se vuoi aumentare il ciclo in modo che l'avviso si ripresenti meno spesso una una variabile unsigned long.
Dopo l'overflow la condizione verrà nuovamente verificata ma molto tempo dopo rispetto all'uso della variabile int.
Per eliminare il problema devi cambiare la logica del programma.

lucaleo

ah buono a sapersi!!
ma secondo voi conviene metterle lo stesso per una questione di ordine oppure si preferisce usare quella soluzione li quando è possibile??

leo72

Dipende dai "gusti". Io le metto anche per una sola istruzione, mi confondo meno a rileggere il codice.

nid69ita

Come detto da @leo dipende di gusti.
I manuali che ho letto suggeriscono di metterle comunque sempre, per confondersi meno e perchè se un giorno dei aggiungere una istruzione allora poi sei costretto ad inserire anche le graffe in quel momento. Tanto vale metterle sempre.  :D
my name is IGOR, not AIGOR

PaoloP

A volte servono per leggere meglio il codice

Esempio
Code: [Select]
if (condition)
 return true;
return false;


Illeggibile se non si ha dimestichezza col linguaggio.  :smiley-eek-blue:

leo72


lucaleo

se a è verificato b diventa
1 se c è verificato
0 se non lo è

giusto?? :D

Go Up