Go Down

Topic: Mini esempio all'uso di Millis() (Read 136 times) previous topic - next topic

-zef-

Salve a tutti,
visto che millis() sembra un tantino ostico da utilizzare ho pensato di fare qualche piccolo esempio sperando sia di aiuto a qualcuno. Ogni listato è l'evoluzione del precedente così da avere tre step su come aggiungere cose nuove senza modificare quelle già fatte

Nel primo esempio si farà lampeggiare un led con tempi diversi ad ogni lampeggio.

Nel secondo insieme al lampeggio del primo led ci sarà un secondo che lampeggia con tempi invertiti rispetto al primo, l'effetto visivo è un tantino caotico, ma da l'idea della flessibilità di millis() nel gestire cose diverse con tempi diversi in modo parrallelo, senza che un lampeggio interferisca con l'altro

Con il terzo esempio ho aggiunto un terzo led che però lampeggia con un tempo fisso, così da far vedere ancora meglio come i primi due led sembra vivano di vita propria.

Non sono certo una cima nel scrivere programmi, ho cercato di rendere tutto il più semplice e comprensibile possibile, i tre listati sembrano funzionare avendoli testati con arduino, non so se il lampeggio è come dovrebbe ma rende l'idea di come usare millis.

Ogni commento/critica è sempre ben accetta  ;D


PRIMO ESEMPIO

Code: [Select]
#define pin_led1 2          //piedino su cui collegare il nostro led, (inserire in serie una resistenza da almeno 330Ohm)

int intervallo_led1 = 1000;   //l'intervallo di tempo tra un azione e la successiva, tempo che può essere fisso o cambiare dopo ogni azione come in questo esempio (si vedrà più avanti)
unsigned long tempo_led1;     //variabile che memorizza il valore attuale di millis() sarebbe il punto in cui decidiamo di far partire il cronometro per conteggiare il tempo
byte ciclo_led1 = 0;          //serie di cose che si devono fare dopo ogni tempo trascorso con millis

void setup() {
  pinMode(pin_led1, OUTPUT);

  tempo_led1 = millis();      //facciamo partire il nostro cronometro salvando il valore attuale di millis nella variabile
}

void loop() {
  if  (millis() - tempo_led1 >= intervallo_led1)    //millis() esegue il suo conteggio, quando la differenza tra millis e il tempo che avevamo salvato prima è maggiore dell'intervallo
                                                    //esegue quanto riportato in seguito
  {
    play_led1();                                    //la funzione da richiamare ogni volta che passa il tempo indicato in intervallo_led1

    //dopo aver eseguito la funzione precedente l'esecuzione del programma riprende da qui
    if (ciclo_led1 < 7) ++ciclo_led1; else ciclo_led1 = 0;  //visto che le cose da fare sono 8 (da 0 a 7) incrementa il ciclo di 1 o lo azzera se è arrivato a 7
    tempo_led1 = millis();
  }


}

void play_led1() {
  //Con valore contenuto in ciclo_led1 esegue le istruzioni corrette ogni volta che viene chiamata la funzione play_led1
  switch (ciclo_led1) {
    case 0:                   // visto che si parte da zero questa è la prima cosa che deve fare la nostra funzione play_led1, e quindi accende il led1
      digitalWrite(pin_led1, HIGH);
      break;
    case 1:                   //il programma inizia con una pausa di 1000mS, poi accende il led per altri 1000mS e adesso lo spegne ma....
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 700;  //...per la prossima pausa invece di 1000mS impostiamo un intervallo di 700mS, così da avere un lampeggio un po' più veloce. Quindi nel nostro ciclo_led
                              //di cose da fare non siamo bloccati ad avere un intervallo di tempo sempre uguale, ma possiamo per ogni step decidere un tempo diverso
      break;
    case 2:                   //dopo che il led è stato spento per 700mS lo riaccende
      digitalWrite(pin_led1, HIGH);
      break;
    case 3:                   //anche qua, sempre dopo 700mS esegue quanto segue, spegne il led e...
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 350;  //...cambiamo di nuovo la durata dell'intervallo, da 700mS a 350mS, il led lampeggia più veloce
      break;
    case 4:                   //accende per 350mS
      digitalWrite(pin_led1, HIGH);
      break;
    case 5:                   //spegne per 350mS
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 100;  //sempre più veloce
      break;
    case 6:                   //accende per 100mS
      digitalWrite(pin_led1, HIGH);
      break;
    case 7:                   //spegne per 100mS
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 1000;   //arrivati alla fine del ciclo si ricomincia daccapo, essendo partiti con un tempo di 1000mS riassegnamo ad intervallo_led1 un secondo di tempo
      break;
  }
}

 

-zef-

SECONDO ESEMPIO
Code: [Select]
#define pin_led1 2          //piedino su cui collegare il nostro led, (inserire in serie una resistenza da almeno 330Ohm)
#define pin_led2 3          //altro led

int intervallo_led1 = 1000;   //l'intervallo di tempo tra un azione e la successiva, tempo che può essere fisso o cambiare dopo ogni azione come in questo esempio (si vedrà più avanti)
int intervallo_led2 = 100;    //il secondo intervallo per gestire un altro ciclo in parallelo al precedente con tempi diversi
unsigned long tempo_led1;     //variabile che memorizza il valore attuale di millis() sarebbe il punto in cui decidiamo di far partire il cronometro per conteggiare il tempo
unsigned long tempo_led2;     //ogni ciclo deve avere la sua variabile per memorizzare il tempo trascorso con millis
byte ciclo_led1 = 0;          //serie di cose che si devono fare dopo ogni tempo trascorso con millis
byte ciclo_led2 = 0;


void setup() {
  pinMode(pin_led1, OUTPUT);
  pinMode(pin_led2, OUTPUT);

  tempo_led1 = millis();      //facciamo partire il nostro cronometro salvando il valore attuale di millis nella variabile
  tempo_led2 = millis();
}

void loop() {
  //------------------------------------------------PRIMO CICLO INDIPENDENTE
  if  (millis() - tempo_led1 >= intervallo_led1)    //millis() esegue il suo conteggio, quando la differenza tra millis e il tempo che avevamo salvato prima è maggiore dell'intervallo
                                                    //esegue quanto riportato in seguito
  {
    play_led1();                                    //la funzione da richiamare ogni volta che passa il tempo indicato in intervallo_led1

    //dopo aver eseguito la funzione precedente l'esecuzione del programma riprende da qui
    if (ciclo_led1 < 7) ++ciclo_led1; else ciclo_led1 = 0;  //visto che le cose da fare sono 8 (da 0 a 7) incrementa il ciclo di 1 o lo azzera se è arrivato a 7
    tempo_led1 = millis();
  }
  //------------------------------------------------SECONDO CICLO INDIPENDENTE
  if  (millis() - tempo_led2 >= intervallo_led2)    //millis() esegue il suo conteggio, quando la differenza tra millis e il tempo che avevamo salvato prima è maggiore dell'intervallo
                                                    //esegue quanto riportato in seguito
  {
    play_led2();                                    //la funzione da richiamare ogni volta che passa il tempo indicato in intervallo_led1

    //dopo aver eseguito la funzione precedente l'esecuzione del programma riprende da qui
    if (ciclo_led2 < 7) ++ciclo_led2; else ciclo_led2 = 0;  //visto che le cose da fare sono 8 (da 0 a 7) incrementa il ciclo di 1 o lo azzera se è arrivato a 7
    tempo_led2 = millis();
  }
  
}

void play_led1() {
  //Con valore contenuto in ciclo_led1 esegue le istruzioni corrette ogni volta che viene chiamata la funzione play_led1
  switch (ciclo_led1) {
    case 0:                   // visto che si parte da zero questa è la prima cosa che deve fare la nostra funzione play_led1, e quindi accende il led1
      digitalWrite(pin_led1, HIGH);
      break;
    case 1:                   //il programma inizia con una pausa di 1000mS, poi accende il led per altri 1000mS e adesso lo spegne ma....
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 700;  //...per la prossima pausa invece di 1000mS impostiamo un intervallo di 700mS, così da avere un lampeggio un po' più veloce. Quindi nel nostro ciclo_led
      //di cose da fare non siamo bloccati ad avere un intervallo di tempo sempre uguale, ma possiamo per ogni step decidere un tempo diverso
      break;
    case 2:                   //dopo che il led è stato spento per 700mS lo riaccende
      digitalWrite(pin_led1, HIGH);
      break;
    case 3:                   //anche qua, sempre dopo 700mS esegue quanto segue, spegne il led e...
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 350;  //...cambiamo di nuovo la durata dell'intervallo, da 700mS a 350mS, il led lampeggia più veloce
      break;
    case 4:                   //accende per 350mS
      digitalWrite(pin_led1, HIGH);
      break;
    case 5:                   //spegne per 350mS
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 100;  //sempre più veloce
      break;
    case 6:                   //accende per 100mS
      digitalWrite(pin_led1, HIGH);
      break;
    case 7:                   //spegne per 100mS
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 1000;   //arrivati alla fine del ciclo si ricomincia daccapo, essendo partiti con un tempo di 1000mS riassegnamo ad intervallo_led1 un secondo di tempo
      break;
  }
}

void play_led2() {
  //Con valore contenuto in ciclo_led2 esegue le istruzioni corrette ogni volta che viene chiamata la funzione play_led2
  switch (ciclo_led2) {
    case 0:                   // visto che si parte da zero questa è la prima cosa che deve fare la nostra funzione play_led2, e quindi accende il led1
      digitalWrite(pin_led2, HIGH);
      break;
    case 1:                   //il programma inizia con una pausa di 100mS, poi accende il led per altri 100mS e adesso lo spegne ma....
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 350;  //...per la prossima pausa invece di 100mS impostiamo un intervallo di 350mS, così da avere un lampeggio un po' più lento.
      break;
    case 2:                   //dopo che il led è stato spento per 350mS lo riaccende
      digitalWrite(pin_led2, HIGH);
      break;
    case 3:                   //anche qua, sempre dopo 350mS esegue quanto segue, spegne il led e...
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 700;  //...cambiamo di nuovo la durata dell'intervallo, da 350mS a 700mS, il led lampeggia più lentamente
      break;
    case 4:                   //accende per 700mS
      digitalWrite(pin_led2, HIGH);
      break;
    case 5:                   //spegne per 700mS
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 1000; //sempre più lentamente
      break;
    case 6:                   //accende per 1000mS
      digitalWrite(pin_led2, HIGH);
      break;
    case 7:                   //spegne per 1000mS
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 100;  //arrivati alla fine del ciclo si ricomincia daccapo, essendo partiti con un tempo di 100mS riassegnamo ad intervallo_led2 un tempo di 100mS
      break;
  }
}

-zef-

TERZO ESEMPIO
Code: [Select]
#define pin_led1 2          //piedino su cui collegare il nostro led, (inserire in serie una resistenza da almeno 330Ohm)
#define pin_led2 3          //altro led
#define pin_led3 4          //non c'è due senza tre

int intervallo_led1 = 1000;   //l'intervallo di tempo tra un azione e la successiva, tempo che può essere fisso o cambiare dopo ogni azione come in questo esempio (si vedrà più avanti)
int intervallo_led2 = 100;    //il secondo intervallo per gestire un altro ciclo in parallelo al precedente con tempi diversi
const int intervallo_led3 = 200;  //per il terzo lampeggio impostiamo un valore fisso tra accensione e spegnimento del led, quindi non serve una variabile ma una costante non dovendo essere più cambiato il valore
unsigned long tempo_led1;     //variabile che memorizza il valore attuale di millis() sarebbe il punto in cui decidiamo di far partire il cronometro per conteggiare il tempo
unsigned long tempo_led2;     //ogni ciclo deve avere la sua variabile per memorizzare il tempo trascorso con millis
unsigned long tempo_led3;
byte ciclo_led1 = 0;          //serie di cose che si devono fare dopo ogni tempo trascorso con millis
byte ciclo_led2 = 0;
// e il ciclo_led3? Dovendo solo fare un lampeggio quindi la stessa cosa ripetuta all'infinito non serve più un ciclo

void setup() {
  pinMode(pin_led1, OUTPUT);
  pinMode(pin_led2, OUTPUT);
  pinMode(pin_led3, OUTPUT);

  tempo_led1 = millis();      //facciamo partire il nostro cronometro salvando il valore attuale di millis nella variabile
  tempo_led2 = millis();
  tempo_led3 = millis();
}

void loop() {
  //------------------------------------------------PRIMO CICLO INDIPENDENTE
  if  (millis() - tempo_led1 >= intervallo_led1)    //millis() esegue il suo conteggio, quando la differenza tra millis e il tempo che avevamo salvato prima è maggiore dell'intervallo
                                                    //esegue quanto riportato in seguito
  {
    play_led1();                                    //la funzione da richiamare ogni volta che passa il tempo indicato in intervallo_led1

    //dopo aver eseguito la funzione precedente l'esecuzione del programma riprende da qui
    if (ciclo_led1 < 7) ++ciclo_led1; else ciclo_led1 = 0;  //visto che le cose da fare sono 8 (da 0 a 7) incrementa il ciclo di 1 o lo azzera se è arrivato a 7
    tempo_led1 = millis();
  }
  //------------------------------------------------SECONDO CICLO INDIPENDENTE
  if  (millis() - tempo_led2 >= intervallo_led2)    //millis() esegue il suo conteggio, quando la differenza tra millis e il tempo che avevamo salvato prima è maggiore dell'intervallo
                                                    //esegue quanto riportato in seguito
  {
    play_led2();                                    //la funzione da richiamare ogni volta che passa il tempo indicato in intervallo_led1

    //dopo aver eseguito la funzione precedente l'esecuzione del programma riprende da qui
    if (ciclo_led2 < 7) ++ciclo_led2; else ciclo_led2 = 0;  //visto che le cose da fare sono 8 (da 0 a 7) incrementa il ciclo di 1 o lo azzera se è arrivato a 7
    tempo_led2 = millis();
  }

  //------------------------------------------------TERZO CICLO INDIPENDENTE
  if  (millis() - tempo_led3 >= intervallo_led3)
  {
    digitalWrite(pin_led3, !digitalRead(pin_led3)); //questa istruzione imposta l'uscita del pin_led3 al contrario di come la legge, se è HIGH la rende LOW e viceversa
    tempo_led3 = millis();
  }
  
}

void play_led1() {
  //Con valore contenuto in ciclo_led1 esegue le istruzioni corrette ogni volta che viene chiamata la funzione play_led1
  switch (ciclo_led1) {
    case 0:                   // visto che si parte da zero questa è la prima cosa che deve fare la nostra funzione play_led1, e quindi accende il led1
      digitalWrite(pin_led1, HIGH);
      break;
    case 1:                   //il programma inizia con una pausa di 1000mS, poi accende il led per altri 1000mS e adesso lo spegne ma....
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 700;  //...per la prossima pausa invece di 1000mS impostiamo un intervallo di 700mS, così da avere un lampeggio un po' più veloce. Quindi nel nostro ciclo_led
      //di cose da fare non siamo bloccati ad avere un intervallo di tempo sempre uguale, ma possiamo per ogni step decidere un tempo diverso
      break;
    case 2:                   //dopo che il led è stato spento per 700mS lo riaccende
      digitalWrite(pin_led1, HIGH);
      break;
    case 3:                   //anche qua, sempre dopo 700mS esegue quanto segue, spegne il led e...
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 350;  //...cambiamo di nuovo la durata dell'intervallo, da 700mS a 350mS, il led lampeggia più veloce
      break;
    case 4:                   //accende per 350mS
      digitalWrite(pin_led1, HIGH);
      break;
    case 5:                   //spegne per 350mS
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 100;  //sempre più veloce
      break;
    case 6:                   //accende per 100mS
      digitalWrite(pin_led1, HIGH);
      break;
    case 7:                   //spegne per 100mS
      digitalWrite(pin_led1, LOW);
      intervallo_led1 = 1000;   //arrivati alla fine del ciclo si ricomincia daccapo, essendo partiti con un tempo di 1000mS riassegnamo ad intervallo_led1 un secondo di tempo
      break;
  }
}

void play_led2() {
  //Con valore contenuto in ciclo_led2 esegue le istruzioni corrette ogni volta che viene chiamata la funzione play_led2
  switch (ciclo_led2) {
    case 0:                   // visto che si parte da zero questa è la prima cosa che deve fare la nostra funzione play_led2, e quindi accende il led1
      digitalWrite(pin_led2, HIGH);
      break;
    case 1:                   //il programma inizia con una pausa di 100mS, poi accende il led per altri 100mS e adesso lo spegne ma....
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 350;  //...per la prossima pausa invece di 100mS impostiamo un intervallo di 350mS, così da avere un lampeggio un po' più lento.
      break;
    case 2:                   //dopo che il led è stato spento per 350mS lo riaccende
      digitalWrite(pin_led2, HIGH);
      break;
    case 3:                   //anche qua, sempre dopo 350mS esegue quanto segue, spegne il led e...
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 700;  //...cambiamo di nuovo la durata dell'intervallo, da 350mS a 700mS, il led lampeggia più lentamente
      break;
    case 4:                   //accende per 700mS
      digitalWrite(pin_led2, HIGH);
      break;
    case 5:                   //spegne per 700mS
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 1000; //sempre più lentamente
      break;
    case 6:                   //accende per 1000mS
      digitalWrite(pin_led2, HIGH);
      break;
    case 7:                   //spegne per 1000mS
      digitalWrite(pin_led2, LOW);
      intervallo_led2 = 100;  //arrivati alla fine del ciclo si ricomincia daccapo, essendo partiti con un tempo di 100mS riassegnamo ad intervallo_led2 un tempo di 100mS
      break;
  }
}

elrospo

#3
Jan 13, 2018, 10:54 pm Last Edit: Jan 13, 2018, 10:55 pm by elrospo
Code: [Select]
[quote author=-zef- link=msg=3562447 date=1515865856]
Salve a tutti,


Ogni commento/critica è sempre ben accetta  ;D



su millis() non c 'è molto da capire una volta che lo si è capito  :smiley-confuse:

se ci mettiamo a fare un tutorial ogni volta che riusciamo a far lampeggiare un led
forse non abbiamo ancora compreso del tutto qualcosa

-zef-

sul forum sembra che parecchi hanno difficoltà nel padroneggiare millis() far lampeggiare qualche led penso sia il modo più semplice per avere un riscontro visivo di quanto viene eseguito nel programma  ;)


nid69ita

#5
Jan 14, 2018, 11:37 am Last Edit: Jan 14, 2018, 11:38 am by nid69ita
Secondo me alcuni esempio possono essere utili. Ma il vero problema di millis() è quando la si vuole usare per fare qualcosa di multitasking arrivando molte volte a dover scrivere anche codice per una macchina a stati finiti. Non semplice fare esempi "semplici"
my name is IGOR, not AIGOR

Go Up