dubbio su while

Buonasera a tutti,
se ho un ciclo while che deve essere eseguito solo se millis è inferiore a N millesimi di secondo ed al suo interno non ho alcun comando è come se dicessi al microcontrollore di attendere senza far nulla?

Sì, ma allora tanto vale usare delay().

ciao…se intendi una cosa del genere:

while(millis()<=10000){
}

è come un delay eseguito una sola volta che all’avvio arresta il programma, in questo caso, per 10 secondi.

@SukkoPera: però il delay() viene eseguito sempre (se non metti altre condizioni)…in questo modo solo una volta (con il mio esempio)

Ah sì, certo, davo per scontato che fosse una cosa tipo:

unsigned long x = millis ();
while (millis () - x < 5000)
  ;

ORSO2001:
ciao…se intendi una cosa del genere:

while(millis()<=10000){

}



è come un delay eseguito una sola volta che all'avvio arresta il programma, in questo caso, per 10 secondi.

@SukkoPera: però il delay() viene eseguito sempre (se non metti altre condizioni)...in questo modo solo una volta (con il mio esempio)

… ecco, messo così è uno dei pochissimi casi in cui all’ovewrflow del contatore di millis() avrai la ripetizione di quel ritardo .

Guglielmo

Code: [Select]

while(millis()<=10000){
}

è come un delay eseguito una sola volta che all’avvio arresta il programma, in questo caso, per 10 secondi.

@SukkoPera: però il delay() viene eseguito sempre (se non metti altre condizioni)…in questo modo solo una volta (con il mio esempio)

… ecco, messo così è uno dei pochissimi casi in cui all’ovewrflow del contatore di millis() avrai la ripetizione di quel ritardo .

Guglielmo

si…esatto…quindi, più esatto dire, che questo “delay” si verificherà ogni volta che millis() parte da 0 :smiley:

Vi ringrazio per le risposte, sto facendo il debug di uno sketch e devo capire quali affittano le cause degli strani sintomi manifestati :slight_smile:

Proseguendo nel debug debbo porvi un altro interrogativo, è possibile che creare due variabili, con nomi diversi, una su loop ed una su setup determini l'insorgenza di errori?
Nel gestire una temporizzazione ho notato che se richiamo la variabile che ho precedentemente dichiarato =millis() ho dei risultati non attesi mentre se chiamo solo millis() tutto funziona perfettamente.

Ciao...sinceramente non ho capito cos'intendi...due variabili globali? locali?...puoi postare il codice!?

Stai attento ci sono variabili globali, esistenti dapertutto e variabili locali definiti in una funzione che esiste solo in quella funzione.

Ciao Uwe

#include <LiquidCrystal.h>
LiquidCrystal lcd (6, 7, 9, 10, 11, 12);

unsigned long tempoAttuale = 0;
unsigned long tempoRegistrato = 0;
int minuti = 0;
int ore = 0;
unsigned long secondi = 0;

const int pulsanteMinuti = 5;
const int pulsanteOre = 4;
byte statoPulsanteMinuti;
byte statoPulsanteOre;

int valSensore;
float temperatura;

void setup() {
  lcd.begin (16, 2);
  lcd.print ("Buongiorno mondo");
  digitalWrite (pulsanteMinuti, HIGH);
  digitalWrite (pulsanteOre, HIGH);
  delay (2000);

  lcd.clear ();
  lcd.setCursor (0, 0);
  lcd.print ("Imposta orario");
  delay (2000);

  lcd.clear ();
  lcd.setCursor (0, 0);
  lcd.print ("UTC: ");
  lcd.print (ore);
  lcd.print (":");
  lcd.print (minuti);
  lcd.print (":");
  lcd.print (secondi);
  
  pinMode (LED_BUILTIN, OUTPUT);

  //unsigned long x = millis();             questo provoca errore
  //unsigned long y = 0;

  lcd.clear ();
  lcd.setCursor (0, 0);
  lcd.print ("UTC: 00:00:00");

  while (millis() < 29999) {
    statoPulsanteMinuti=digitalRead (pulsanteMinuti);
    statoPulsanteOre=digitalRead (pulsanteOre);
    if (statoPulsanteMinuti == LOW) {
      minuti++;
      digitalWrite (LED_BUILTIN, HIGH);
      delay (333);
      digitalWrite (LED_BUILTIN, LOW);
    }
    if (statoPulsanteOre == LOW) {
      ore++;
      digitalWrite (LED_BUILTIN, HIGH);
      delay (333);
      digitalWrite (LED_BUILTIN, LOW);
    }
    if (minuti<10){
      lcd.setCursor (9, 0);
      lcd.print (minuti);
      lcd.setCursor (8, 0);
      lcd.print ("0");
    }
    if (minuti>9){
      lcd.setCursor (8, 0);
      lcd.print (minuti);
    }
    if (minuti>59){
      minuti=0;
    }
    if (ore<10){
      lcd.setCursor (6, 0);
      lcd.print (ore);
      lcd.setCursor (5, 0);
      lcd.print ("0");
    }
    if (ore>9){
      lcd.setCursor (5, 0);
      lcd.print (ore);
    }
    if (ore > 23) {
      ore = 0;
    }  
  }
}

void loop() {
  tempoAttuale = millis() / 1000;
  secondi = tempoAttuale - tempoRegistrato;

  if (secondi<10){
    lcd.setCursor (12, 0);
    lcd.print (secondi);
    lcd.setCursor (11, 0);
    lcd.print ("0");    
  }
  if (secondi>9){
    lcd.setCursor (11, 0);
    lcd.print (secondi);
  }
  if (tempoAttuale - tempoRegistrato > 59) {
    tempoRegistrato = tempoAttuale;
    minuti++;
  }
  if (minuti<10){
    lcd.setCursor (9, 0);
    lcd.print (minuti);
    lcd.setCursor (8, 0);
    lcd.print ("0");
  }
  if (minuti>9){
    lcd.setCursor (8, 0);
    lcd.print (minuti);
  }
  if (minuti > 59) {
    minuti = 0;
    ore++;
  }  
  if (ore<10){
    lcd.setCursor (6, 0);
    lcd.print (ore);
    lcd.setCursor (5, 0);
    lcd.print ("0");
  }
  if (ore>9){
    lcd.setCursor (5, 0);
    lcd.print (ore);
  }
  if (ore > 23) {
    ore = 0;
  }

  valSensore = analogRead (3);
  temperatura = (valSensore/1023+50)/10;

  lcd.setCursor (0, 1);
  lcd.print (temperatura);
  lcd.print (" gradi C");
}

ecco il codice, scorrete pure tutto finchè non trvate “questo provoca errore” tra i commenti sulla destra

la riga a cui mi riferivo è quella subito seguente nel ciclo while, x e y mi servirebbero perché vorrei eseguire un ritardo ogni volta che il ciclo viene eseguito ma che in questo caso ho omesso per focalizzare l'attenzione sul problema descritto

ciao...non so se sia perchè non dichiari come INPUT i due pin pulsanteMinuti e pulsanteOre ma li metti solo HIGH.

ORSO ti ringrazio per la risposta ma non l ho dichiarati perché Arduino imposta di default tutti i pin come input e li ho messi in HIGH per attivare la resistenza interna di pull-up

E cosa vuol dire “provoca errore” ?
E’ chiaro che se tu crei una variabile all’interno del setup(), questa vale solo nel setup()

Brunello, significa che se non uso le variabili dichiarate in quelle due righe tutto lo sketch funziona a meraviglia.
Comunque ieri ho fatto un’ulteriore test isolando una parte delle istruzioni, il risultato è stato il seguente:

in questo codice la variabile “a” è dichiarata all’inizio e ne consegue che il ciclo if viene effettivamente eseguito quando “tempoAttuale-a>1”

#include <LiquidCrystal.h>
LiquidCrystal lcd (6, 7, 9, 10, 11, 12);

unsigned long tempoAttuale;
int a = 0;

int valSensore;
int temperatura;

void setup() {
  lcd.begin (16, 2);
  lcd.print ("Buongiorno mondo");
  delay (2000);
}

void loop() {
  tempoAttuale = millis() / 1000;
  
  if ((tempoAttuale-a)>1){
    valSensore = analogRead (A0);
    temperatura = map (valSensore, 0, 1023, -50, 450);
    lcd.setCursor (0, 1);
    lcd.print (temperatura);
    lcd.print (" gradi C");
    a=tempoAttuale;
  }
}

ho provato invece a dichiarare la variabile “a” subito dopo la riga “void loop (){” ma in questo caso la temporizzazione era compromessa ed il ciclo veniva eseguito in continuazione senza alcuna attesa.

Qualcuno saprebbe dirmi perché? Credo io stia tralasciando qualcosa di importante…

mentorade:
Qualcuno saprebbe dirmi perché? Credo io stia tralasciando qualcosa di importante..

SI, devi studiarti la differenza che c'è in 'C' tra variabili locali e variabili globali ...
... a seconda di dove metti la variabile, la visibilità cambia.

Se fai una ricerca con Google per "c local and global variables" e troverai molte spiegazioni dettagliata.

Guglielmo

... c'è anche un'altro errore ... " a = tempoAttuale;" ... tutto ciò che ha a che fare con millis() (e tempoAttuale contiene il valore di millis()) deve essere unsigned long e NON int, NON puoi memorizzare un valore di millis(), che è a 32 bit non segnato, in una variabile di 16 bit e segnata !!!

Quindi ... anche 'a' deve essere unsigned long (e questo indipendentemente dal fatto che tempoAttuale contenga il valore in 'secondi', dato che, teoricamente ... può arrivare a 4294967 secondi) !!!

Guglielmo

Grazie Guglielmo, il secondo è stato un errore di disattenzione dato che avevamo già parlato della questione millis.
Per quanto riguarda le variabili, sto leggendo su Arduino progetti e soluzioni ma distingue solo globali da volatili e statiche, temo mi abbia messo solo altra confusione in testa. Sul web ho trovato una definizione ma non molto più esauriente di quella proposta dal libro del kit per principianti.
Forse mi volevi dire che, la ragione per cui dichiarando "a" come locale non ottenevo il risultato sperato è che al termine del loop il micro perde il valore contenuto nella stessa? E quindi è come se a quel confronto (tempoAttuale-a>1) lei fosse sempre 0 (dato che la dichiaravo con valore iniziale 0)?

Scusa la confusione con cui cerco di spiegarmi ma riflette la confusione che ho in testa :wink:

mentorade:
Forse mi volevi dire che, la ragione per cui dichiarando “a” come locale non ottenevo il risultato sperato è che al termine del loop il micro perde il valore contenuto nella stessa? E quindi è come se a quel confronto (tempoAttuale-a>1) lei fosse sempre 0 (dato che la dichiaravo con valore iniziale 0)?

Precisamente. Una variabile locale viene creata (ed eventualmente inizializzata) quando si entra nello scope (in questo caso nella funzione) in cui è definita e cessa di esistere quando si esce da lì.

Una variabile globale “esiste sempre”.