Spiegazioni per millis()

ok le graffe le ho messe solo per la spiegazione , mi hai capito lo stesso.

poi, voi mi dite che millis non interrompe il programma e per cui si possono impostare x istanze di millis che sono indipendenti.

#define led1 13
#define led2 12
#define led3 11

unsigned long tempoTrascorso;     // variabile usata per contare i millisecondi trascorsi dall'avvio di Arduino
unsigned long tempoled1 = 0;        // variabile usata per stabilire quando dovrà accendersi il primo led
unsigned long tempoled2 = 0;       // variabile usata per stabilire quando dovrà accendersi il secondo led
unsigned long tempoled3 = 0;      // variabile usata per stabilire quando dovrà accendersi il terzo led

void setup() {

pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(led3,OUTPUT);
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
}

void loop() {

tempoTrascorso = millis();                   // memorizzo millis() nella variabile tempoTrascorso

if(tempoTrascorso >= 10000)                 // Dopo 10 secondi la variabile tempoTrascorso viene azzerata
{
tempoTrascorso = 0;
tempoTrascorso = millis();
}

// Il primo led viene acceso dopo 1 secondo dall'avvio di arduino e spento dopo mezzo secondo

if(tempoTrascorso > tempoled1 + 1000)
{
digitalWrite(led1,HIGH);
tempoled1 = millis();
}

if(tempoTrascorso > tempoled1 + 500)
{
digitalWrite(led1,LOW);

}

// Il secondo led viene acceso dopo 2 secondi  dall'avvio di arduino e spento dopo 1 secondo

if(tempoTrascorso > tempoled2 + 2000)
{
digitalWrite(led2,HIGH);
tempoled2 = millis();
}

if(tempoTrascorso > tempoled2 + 1000)
{
digitalWrite(led2,LOW);

}

// Il terzo led viene acceso dopo mezzo secondo  dall'avvio di arduino spento dopo un quarto di secondo

if(tempoTrascorso > tempoled3 + 500)
{
digitalWrite(led3,HIGH);
tempoled3 = millis();

}
if(tempoTrascorso > tempoled3 + 250)
{
digitalWrite(led3,LOW);

}

}

ho trovato questo listato che è perfetto per quello che vi devo chiedere.

se uno lo prova vede che i tre led si accendono in modo autonomo secondo il tempo impostato.

Ma, se appena appena provi a cambiare un tempo e impostarlo su una temporizzazione piu lunga, nel termine di qualche secondo, sballa tutto, anche i tempi degli altri led......come mai?

grazie

Sarebbe interessante sapere da dove lo hai copiato
Contiene alcuni errori particolari
Non è che si tratta di un programma didattico fatto apposta per mostrare possibili errori?
Comunque, impara a cercare sul forum, che ti fa bene

kemosabesay:
voi mi dite che millis non interrompe il programma e per cui si possono impostare x istanze di millis che sono indipendenti.

'millis' legge il contatore e basta. Puoi usare tante variabili quante ne servono per memorizzare diversi tempi di partenza (anche) in momenti diversi, e poi usare quelle variabili per calcolare i diversi tempi trascorsi da quando sono state "caricate". Se il senso di "diverse istanze" è questo, allora si, è così.

kemosabesay:
Ma, se appena appena provi a cambiare un tempo e impostarlo su una temporizzazione piu lunga, nel termine di qualche secondo, sballa tutto, anche i tempi degli altri led......come mai?

La quantità di errori di logica in quel codice è talmente lunga che ora non ho proprio il tempo per descriverli tutti, perfino i nomi delle variabili non sono congruenti con quello che contengono, la comparazione con millis soffre dell'overflow, gli if non sono mutuamente esclusivi per cui interferiscono l'uno con l'altro, ci sono tre processi ma nessuna variabile di stato (la situazione) per controllarli ecc ecc...

Se vuoi scrivere programmi che fanno più cose indipendenti assieme, la strada è sempre quella della programmazione a stati (link). Ecco la versione corretta del programma con programmazione a stati, trova le mille piccole differenze :wink:

#define led1 13
#define led2 12
#define led3 11
//---------------------------------------------------------------------------------
unsigned long tempoAttuale;   // tempo attuale in millisecondi
unsigned long tempoled1 = 0;  // tempo inizio misura led1
unsigned long tempoled2 = 0;  // tempo inizio misura led2
unsigned long tempoled3 = 0;  // tempo inizio misura led3
byte          statLed1 = 0;   // stato processo led1
byte          statLed2 = 0;   // stato processo led2
byte          statLed3 = 0;   // stato processo led3
//---------------------------------------------------------------------------------
void setup() {
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(led3, OUTPUT);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
}
//---------------------------------------------------------------------------------
void loop() {
    tempoAttuale = millis();  // memorizzo il tempo attuale


    //////////////////////////////////////////////////////////////////////////////////////////
    //elaboro processo led1                                                                 //
    //due stati mutuamente esclusivi (notare else if) selezionati tramite variabile statLed1//
    //////////////////////////////////////////////////////////////////////////////////////////

    if(statLed1 == 0  &&  tempoAttuale - tempoled1 >= 1000) //accende led1 dopo 1 sec dall'avvio
    {
        digitalWrite(led1, HIGH); // accendo led
        tempoled1 = millis();     // da questo momento ricomincio misura tempo per led1
        statLed1 = 1;             // abilito prossimo stato
    }
    else if(statLed1 == 1  &&  tempoAttuale - tempoled1 >= 500) // spegne dopo mezzo sec.
    {
        digitalWrite(led1, LOW);
        statLed1 = 2;             // abilito prossimo stato, inesistente, processo fermo,
    }                             // il programma originale non fa altro con questo LED


    /////////////////////////
    //elaboro processo led2//
    /////////////////////////

    if(statLed2 == 0  &&  tempoAttuale - tempoled2 >= 2000) //accende led2 dopo 2 sec dall'avvio
    {
        digitalWrite(led2, HIGH);
        tempoled2 = millis();
        statLed2 = 1;
    }
    else if(statLed2 == 1  &&  tempoAttuale - tempoled2 >= 1000) // e spegne dopo 1 sec
    {
        digitalWrite(led2 ,LOW);
        statLed2 = 2;
    }


    /////////////////////////
    //elaboro processo led3//
    /////////////////////////

    if(statLed3 == 0  &&  tempoAttuale - tempoled3 >= 500) //accende led3 dopo mezzo sec dall'avvio
    {
        digitalWrite(led3, HIGH);
        tempoled3 = millis();
        statLed3 = 1;
    }
    else if(statLed3 == 1  &&  tempoAttuale - tempoled3 >= 250) // e spegne dopo 250ms
    {
        digitalWrite(led3, LOW);
        statLed3 = 2;
    }
}

Claudio_FF:
Se vuoi scrivere programmi che fanno più cose indipendenti assieme, la strada è sempre quella della programmazione a stati

Mah, non mi sembra sia l'unica, anche se certamente bella chiara lo è.
qui mi sembrava di aver fatto un timer multiplo, espandibile, senza usare macchine a stati e senza ricorrere alla programmazione ad oggetti (che non conosco):
https://forum.arduino.cc/index.php?topic=540296.msg3682514#msg3682514

Standardoil:
Sarebbe interessante sapere da dove lo hai copiato
Contiene alcuni errori particolari
Non è che si tratta di un programma didattico fatto apposta per mostrare possibili errori?
Comunque, impara a cercare sul forum, che ti fa bene

a parte che sto cercando un po dappertutto, e poi visto che se vengo qui è appunto per cercare risposte da chi si presume ne sappia di me.

Io non so se quel programma era a scopo didattico, io ve lo ho mostrato semplicemente per farvi delle domande come al solito, non capisco il sistema di rispondere cosi' secco e scocciato, scusa ma ti ho fatto qualcosa? ? ?

Non mi sembrava di essere "secco e scocciato", scusa se te ne ho dato impressione
Comunque non hai risposto...

chiedo scusa, ho male interpretato io...... :confused:

il sito da dove ho preso quell'esempio è questo:

Uno dei tuoi problemi è che pensi a scrivere codice (= copiare roba a caso) prima di capire il mirabolante principio matematico che c'è dietro, e così continui a pensare che millis() sia una roba mezza magica dall'utilizzo riservato ai guru di turno.

Rinnovo dunque l'invito a rispondere a queste domande:

SukkoPera:

  1. Supponiamo di avere acceso Arduino 5 secondi fa, che valore avrà millis() in questo momento?

  2. Supponiamo di accendere un led in questo momento e di volerlo spegnere dopo 2 secondi. Che valore avrà millis() al momento dello spegnimento?

  3. Quale sarà la differenza tra i due valori precedenti?

effettivamente si visto la fatica che sto facendo per capirlo, neanche fosse qualche trattato di astronomia.

  1. 5 secondi
  2. il valore di millis all'accensione
  3. millis accensione + 2 secondi

Come volevasi dimostrare, non ne hai azzeccata neanche una.

Rifletti e riprova.

PS: Tutte le risposte devono essere numeri "grezzi", tipo 1, 10, 100, 1000.

scusa ma tu hai parlato di Millis(), e mi dite che Millis() è la variabile che ritorna il tempo da quando è stato acceso il processore

Il fatto che sia un tempo lo sai tu, millis() di per sé ritorna un numero (unsigned long).

si ok ma è un numero che parte ed è indipendente o no!!!

Sì, per questo devi rispondere alle mie domande con 3 numeri.

ha ok

  1. 5
  2. 10+2
    3)10-7

Prima che te lo dica Sukko, te lo dico io ... NO, millis() NON avrà quei valori, pensaci e metti il NUMERO esatto che ti restituirà la funzione millis(), perché è quello che Sukko vuole vedere !!!

Guglielmo

Vedi? Non hai capito niente.

  1. millis() conta i millisecondi, quindi la risposta giusta è 5000. E pensare che il nome dovrebbe essere abbastanza autoesplicativo... :roll_eyes:

  2. Se lo accendo quando millis() segna 5000, 2 secondi saranno passati quando segnerà 7000.

  3. La risposta è 2000 (7000 - 5000), ovvero i 2 secondi che volevamo tenere acceso il led.

Ragiona su queste cose e falle tue, prima ancora di pensare a scrivere qualunque riga di codice, altrimenti non andrai da nessuna parte. Garantito.

già non avevo pensato ai Millis()secondi

ok quindi adesso come posso procedere?

Scrivimi un loop() che accende un led dopo che sono passati 4 secondi dall'accensione di Arduino.