Go Down

Topic: uso millis() (Read 6301 times) previous topic - next topic

Claudio_FF

#30
Jan 23, 2018, 07:34 pm Last Edit: Jan 23, 2018, 08:24 pm by Claudio_FF
Come spunto aggiungo anche il codice di esempio di miky_police in forma di macchine a stati, come suggerito qualche post precedente.

Oltre al fading lampeggia anche indisturbato il led on board, e allo stesso modo possono essere portati avanti altri N lavori indipendenti in contemporanea.

Curiosità: In questo codice le due funzioni gestFader e gestObdLed vengono eseguite circa 50mila volte al secondo ciascuna, quindi il ciclo programma è di circa 20 microsecondi.

Code: [Select]
//----------------------------------------------------------------------------
#define  EXT_LED_PIN  3
#define  OBD_LED_PIN  13
//----------------------------------------------------------------------------
void setup()
{
    pinMode(EXT_LED_PIN, OUTPUT);
    pinMode(OBD_LED_PIN, OUTPUT);
}
//----------------------------------------------------------------------------
void loop()
{
    gestFader();  // processo alba-tramonto su led esterno
    gestObdLed(); // processo lampeggio led on board 1Hz
}
//----------------------------------------------------------------------------
void gestObdLed()
{
    static unsigned long tempo = 0;

    if(millis() - tempo >= 500)
    {
        tempo += 500;
        digitalWrite(OBD_LED_PIN, !digitalRead(OBD_LED_PIN));
    }
}
//----------------------------------------------------------------------------
void gestFader()
{
    static byte          fase = 0;
    static unsigned long tempo = 0;
    static int           fadeValue = 0;

    switch (fase)
    {
        case 0: // IN ACCENSIONE (durata 1.53 sec)
            analogWrite(EXT_LED_PIN, fadeValue);
            if(millis() - tempo >= 30)
            {
                tempo += 30;
                fadeValue += 5;
                if(fadeValue > 255) { tempo = millis(); fase = 1; }
            }
            break;
        //------------------------------------------------------------
        case 1: // DURATA GIORNO 3 SECONDI
            if(millis() - tempo >= 3000)
            {
                fadeValue = 255;
                tempo = millis();
                fase = 2;
            }
            break;
        //------------------------------------------------------------
        case 2: // IN SPEGNIMENTO (durata 1.53 sec)
            analogWrite(EXT_LED_PIN, fadeValue);
            if(millis() - tempo >= 30)  
            {
                tempo += 30;
                fadeValue -= 5;
                if(fadeValue < 0) { tempo = millis(); fase = 3; }
            }
            break;
        //------------------------------------------------------------
        case 3: // DURATA NOTTE 5 SECONDI
            if(millis() - tempo >= 5000)
            {
                fadeValue = 0;
                tempo = millis();
                fase = 0;
            }
    }//end switch
}        
//----------------------------------------------------------------------------

La dimostrazione del fatto che il problema non è strettamente delay contro millis, ma la struttura logica con cui si imposta l'esecuzione, è il codice seguente, che fa la stessa cosa senza usare millis ma solo delay e non blocca nulla  ;)

Code: [Select]
//----------------------------------------------------------------------------
#define  EXT_LED_PIN  3
#define  OBD_LED_PIN  13
//----------------------------------------------------------------------------
void setup()
{
    pinMode(EXT_LED_PIN, OUTPUT);
    pinMode(OBD_LED_PIN, OUTPUT);
}
//----------------------------------------------------------------------------
void loop()
{
    gestFader();  // processo alba-tramonto su led esterno
    gestObdLed(); // processo lampeggio led on board 1Hz
    delay(10);    // temporizza il programma a passi di *circa* 10ms
}
//----------------------------------------------------------------------------
void gestObdLed()
{
    static unsigned long tempo = 0;
    static byte          counter = 0;

    if(++counter == 50)
    {
        counter = 0;
        digitalWrite(OBD_LED_PIN, !digitalRead(OBD_LED_PIN));
    }
}
//----------------------------------------------------------------------------
void gestFader()
{
    static byte          fase = 0;
    static unsigned long tempo = 0;
    static int           fadeValue = 0;
    static int           counter = 0;

    switch (fase)
    {
        case 0: // IN ACCENSIONE (durata 1.53 sec)
            analogWrite(EXT_LED_PIN, fadeValue);
            if(++counter == 3)
            {
                counter = 0;
                fadeValue += 5;
                if(fadeValue > 255) { counter = 0; fase = 1; }
            }
            break;
        //------------------------------------------------------------
        case 1: // DURATA GIORNO 3 SECONDI
            if(++counter == 300)
            {
                fadeValue = 255;
                counter = 0;
                fase = 2;
            }
            break;
        //------------------------------------------------------------
        case 2: // IN SPEGNIMENTO (durata 1.53 sec)
            analogWrite(EXT_LED_PIN, fadeValue);
            if(++counter == 3)
            {
                counter = 0;
                fadeValue -= 5;
                if(fadeValue < 0) { counter = 0; fase = 3; }
            }
            break;
        //------------------------------------------------------------
        case 3: // DURATA NOTTE 5 SECONDI
            if(++counter == 500)
            {
                fadeValue = 0;
                counter = 0;
                fase = 0;
            }
    }//end switch
}        
//----------------------------------------------------------------------------

Nota: naturalmente in questo caso il ciclo programma è di 10ms, le funzioni vengono cioè eseguite solo cento volte al secondo.

* * * * Una domanda ben posta è già mezza risposta * * * *

albepancio

ho copiato il tuo codice in un file di testo ( per leggerlo tutto)
il doppio loop non ho la piu pallida idea di come funzioni.
cmq
Code: [Select]
//variabili per loop RGB
const byte CR(3);// imposti i pin
const byte CB(5);// imposti i pin
const byte CV(6);// imposti i pin
const byte rgb[]={CR,CB,CV};// crei un array
byte puntaRGB=0;// crei una variabile e la poni a zero
byte Luminoso=0;// crei una variabile e la poni a zero
boolean pulsa=true;// crei una variabile boleana ( che non ho mai usato)
unsigned long tempoRGB=0;//qui crei la variabile di riferimento pe il millis()
byte velRGB=0;// altra variabile posta a zero

void setup()
{
 Serial.begin(9600);
 pinMode(ST,INPUT);// qui non ho capito il ST ????
   
 for(byte i=0;i<4;i++)//PER 4 volte (uno alla volta)
    {
     pinMode(bobMot[i],OUTPUT);  //bobMot ?????? questo non l ho capito                  //mette i pin del motorino PP in modalità USCITA
     pinMode(rgb[i],OUTPUT);// rgb e l array rgb[]= {CR,CB,CV} ????                           //mette i pin del led RGB in modalità USCITA
    } 

holetto la primaparte di codicenon ho capito un paio di cose e sulle altre ti ho scritto quello che ho capito
ho capito bene ? :)

Puso

#32
Jan 23, 2018, 08:26 pm Last Edit: Jan 23, 2018, 08:33 pm by Puso
ST e bobMot...servono a me per il mio di schetc li puoi cancellare.

 for(byte i=0;i<4;i++)//PER 4 volte (uno alla volta)
    {
   
     pinMode(rgb,OUTPUT);// rgb e l array rgb[]= {CR,CB,CV} ???? //mette i pin del led RGB in modalità USCITA
    }
Per N.volte metto i pin dell'Array in modalità uscita,come puntatore uso.

albepancio

ma nonli dovevi dichgiarae?
per il resto ho capito bene?

Puso

#34
Jan 23, 2018, 08:35 pm Last Edit: Jan 23, 2018, 08:37 pm by Puso
avevo dichiarato i pin(dandogli un nome)non avevo detto se erano Input oppure Output.
una cosa alla volta.

Puso

CR sta per colore rosso
CB sta per colore blu
CV sta per colore verde

albepancio

#36
Jan 23, 2018, 08:44 pm Last Edit: Jan 23, 2018, 09:01 pm by albepancio
Code: [Select]
const byte CR(3);// imposti i pin
const byte CB(5);// imposti i pin
const byte CV(6);// imposti i pin
const byte rgb[]={CR,CB,CV};// crei un array

se non sbaglio le uniche escludendo la boleanna e quella per il millis
sono queste
st e bobmot non sono state dichiarate o sbaglio?

Puso

#37
Jan 23, 2018, 08:50 pm Last Edit: Jan 23, 2018, 08:52 pm by Puso
non seguire i miei di consigli...segui quelli che ti sono già stati dati(quel poco che sò l' ho imparato da loro).

miky_police

se non sbaglio le uniche escludendo la boleanna e quella per il millis
sono queste
infatti... devi CONOSCERE/IMPARARE la sintassi... quella dichiarazione che ha fatto
Code: [Select]

const byte rgb[] = {CR,CB,CV}

come riportato nel codice è un array... sai cosa è un array? come si dichiara? come richiamare i valori dell'array?
come creare dei loop usando gli array (come ad esempio i for)? sai quanto codice ti fanno risparmiare?
Il mio code del post #24 è fatto su misura per il tuo quesito (posy #1)...
L'hai provato? Funziona? ::)
L'hai compreso?
Quote
Come spunto aggiungo anche il codice di esempio di miky_police in forma di macchine a stati
questo era l'obbiettivo al quale portarlo perché la reputo la tecnica di programmazione più pulita in assoluta e ritrovi in un attimo i pezzi di codice che ti servono per correzioni, implementazioni...
Il vero stupido è colui che fa e rifa la stessa cosa aspettandosi risultati diversi. A.E.

Puso

si ho dato un nome hai pin che utilizzo stando attento che siano in PWM.
poi dichiaro la prima volta se sono in uscita o in entrata.(ATTENZIONE)

miky_police

#40
Jan 23, 2018, 08:56 pm Last Edit: Jan 23, 2018, 08:59 pm by miky_police
Curiosità: In questo codice le due funzioni gestFader e gestObdLed vengono eseguite circa 50mila volte al secondo ciascuna, quindi il ciclo programma è di circa 20 microsecondi.
Domanda un po OT: come fai a calcolare il tempo per l'esecuzione dello sketch nonché quante volte lo esegue al secondo??? ::)
Il vero stupido è colui che fa e rifa la stessa cosa aspettandosi risultati diversi. A.E.

Puso

MATEMATICA...l'unico linguaggio.

albepancio

non riesco a vedere dichiarate la variabile ST e bobmot....

Puso

L'esempio che ti ho messo è una frazione di un mio schtec.....se fai solo copia incolla NON compila neppure.
Ragionaci sù.

miky_police

#44
Jan 23, 2018, 09:23 pm Last Edit: Jan 23, 2018, 09:28 pm by miky_police
Quote
non ho capito il doppio loop()
non c'è un doppio loop nel codice
Quote
non riesco a vedere dichiarate la variabile ST e bobmot....
ma se è solo un pezzo di sketch quello che ti ha postato....
questo proprio no?!...
Code: [Select]


/*Partendo dal fatto che tu devi avere un effetto alba tramonto e quindi
  i due valori di attesa sono decisamente diversi devi impostare due attese diverse
  e quindi il codice deve sapere se sei in un momento che deve accendere il led
  piuttosto che spegnerlo. Adesso il codice porta come 5 secondi di luce e quindi il led
  spento e 3 secondi di buio e quindi 3 secondi di led acceso.*/

boolean giorno;          //questo booleano ti serve per far capire se si deve accendere piuttosto che spegnere il led e viceversa
int ledPin = 3;          // LED
unsigned long tempo;     // tempo di riferimento


void setup() {
  pinMode(ledPin, OUTPUT);     // imposto il pin  ledPin come uscita
  tempo = millis();            // imposto il tempo di riferimento uguale a millis nel setup;
  digitalWrite(ledPin, LOW);   // spengo il led inizialmente come se ci fosse luce (condizione iniziale prima dell'esecuzione del programma)
  giorno = true;               // quindi indico, sempre come valore iniziale, che siamo in un momento in cui il led è spento
}


void loop() {

  if (giorno == true) { //------------------------------->se è giorno
    if (millis() - tempo >= 5000) { //------------------->se sono passati 5 secondi dall'ultimo aggiornamento
      accensioneLed(); //-------------------------------->eseguo l'accensione del led
      tempo = millis(); //------------------------------->aggiorno la variabile tempo
      giorno = false; //--------------------------------->gli dico che è notte
    }
  }
  else { //---------------------------------------------->se è notte
    if (millis() - tempo >= 3000) { //------------------->se sono passati 3 secondi dall'ultimo aggiornamento
      spegnimentoLed(); //------------------------------->eseguo lo spegnimento del led
      tempo = millis(); //------------------------------->aggiorno la variabile tempo
      giorno = true; //---------------------------------->gli dico che è giorno
    }
  }
}

void accensioneLed() {
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    analogWrite(ledPin, fadeValue);
    delay(30);
  }
}

void spegnimentoLed() {
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
    analogWrite(ledPin, fadeValue);
    delay(30);
  }
}


/*molto meccanicoso perchè non devi gestire nient'altro che un led. Io sarei andato di delay e Switch personalmente,
  molto meno ingarbugliato.*/

la prossima volta mi spreco meno... ::)
buona fortuna...
Poi io al posto tuo userei un RTC se proprio dovrei fare un alba tramonto, a meno che non vuoi mettere per 18 ore un attesa di 64800000 millisecondi....
Il vero stupido è colui che fa e rifa la stessa cosa aspettandosi risultati diversi. A.E.

Go Up