Accensione led dopo un tempo specifico.

Salve, sto programmando Arduino uno per il controllo del presepe alba-tramonto. Voglio subito precisare che non sono un programmatore, quindi nel caso dica o scriva baggianate chiedo scusa in anticipo. lo sketch che sto utilizzando l'ho preso su internet e adattato alle mie esigenze.

#define pin_down   10
#define pin_sun    11
#define pin_sunset 9
#define pin_moon   6
#define pin_starsA 5
#define pin_starsB 3
#define pin_luciint 2
#define pin_luciest 4
#define pin_lampi 12
 
long onemin1[4] = { 20972,114788,20976,143257 };
long onemin2[4] = { 12582,68874,12585,85953 };
long timeStepOld = 0;
long timeStep = 0;
 
long timeCurr = 0;
 
byte fade[]  = {255,250,245,240,235,230,225,220,215,210,205,200,195,190,185,180,175,170,165,160,155,150,145,140,135,130,125,120,115,110,105,100,95,90,85,80,75,70,65,60,55,50,45,40,35,30,25,20,15,10,5,0}; // 52 step
byte curr   = 0;
 
void setup() {
  Serial.begin( 9600 );
   
  pinMode( pin_down  ,OUTPUT );
  pinMode( pin_sun   ,OUTPUT );
  pinMode( pin_sunset,OUTPUT );
  pinMode( pin_moon  ,OUTPUT );
  pinMode( pin_starsA,OUTPUT );
  pinMode( pin_starsB,OUTPUT );
  pinMode( pin_luciint,OUTPUT );
  pinMode( pin_luciest,OUTPUT );
 
  analogWrite( pin_down  ,LOW );
  analogWrite( pin_sun   ,LOW );
  analogWrite( pin_sunset,LOW );
  analogWrite( pin_moon  ,LOW );
  analogWrite( pin_starsA,LOW );
  analogWrite( pin_starsB,LOW );
  digitalWrite( pin_luciint,LOW );
  digitalWrite( pin_luciest,LOW );
   
  Serial.println("-- START --");
}
 
void loop() {
  timeCurr = onemin2[curr];
  timeStep = (timeCurr/52);
 
  Serial.print("Current: "); Serial.println(curr);
  Serial.print("Time current: "); Serial.println(timeCurr);
  Serial.print("Time single step: "); Serial.println(timeStep);
 
  // down 
  if ( curr == 0 ) { 
     Serial.print("Fase: "); Serial.println("DOWN");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   fade[(51-i)]);
       if ( fade[i] < 25) digitalWrite(pin_luciest,    0 );
       analogWrite(pin_sun,    0 );
       analogWrite(pin_sunset, 0 );
       analogWrite(pin_moon,   fade[i] );
       analogWrite(pin_starsA, fade[i] );
       analogWrite(pin_starsB, fade[i] );
       digitalWrite(pin_luciint, 1 );
       delay( timeStep );
     }
     timeStepOld = timeStep;
  }
 
  // sun
  if ( curr == 1 ) {
     Serial.print("Fase: "); Serial.println("SUN");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   fade[i]);
       if ( fade[i] < 125) analogWrite(pin_sun,    fade[(51-i)]*2 );
       if ( fade[i] < 10) digitalWrite(pin_luciint,    0 );
       analogWrite(pin_sunset, 0 );
       analogWrite(pin_moon,   0 );
       analogWrite(pin_starsA, 0 );
       analogWrite(pin_starsB, 0 );
       digitalWrite(pin_luciest, 0 );
       delay( timeStepOld );
     }
     timeStepOld = (timeStepOld*52); // elapsed time
     timeCurr = (timeCurr - timeStepOld);
     delay( timeCurr );
  }
 
  // sunset
  if ( curr == 2 ) {
     Serial.print("Fase: "); Serial.println("SUNSET");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   0);
       analogWrite(pin_sun,    fade[i] );
       analogWrite(pin_sunset, fade[(51-i)] );
        if ( fade[i] < 150) digitalWrite(pin_luciint,    1 );
       analogWrite(pin_moon,   0 );
       analogWrite(pin_starsA, 0 );
       analogWrite(pin_starsB, 0 );
       digitalWrite(pin_luciest, 0 );
       delay( timeStep );
     }
     timeStepOld = timeStep;
  }
   
  // moon 
  if ( curr == 3 ) {
     Serial.print("Fase: "); Serial.println("MOON");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   0);
       analogWrite(pin_sun,    0 );
       analogWrite(pin_sunset, fade[i] );
       if ( fade[i] < 20) analogWrite(pin_moon,   fade[(51-i)]*2 );
       if ( fade[i] < 125) analogWrite(pin_starsA, fade[(51-i)]*2 );
       if ( fade[i] < 250) analogWrite(pin_starsB, fade[(51-i)]*2 );
       if ( fade[i] < 100) digitalWrite(pin_luciest,    1 );
       digitalWrite(pin_luciint, 1 );
       delay( timeStepOld );      
   }      
   timeStepOld = (timeStepOld*52); // elapsed time      
   timeCurr = (timeCurr - timeStepOld);      
   delay( timeCurr );
  }   
  curr++;
  if ( curr >= 4 ) { curr = 0; }
}

Questo codice funziona tutto alla perfezione come desidero, ora vorrei aggiungere una nuova animazione (che simulano i lampi nel cielo) dove il "pin_lampi 12" è la nuova luce da aggiungere.. Ho pensato di farlo facendo accende i spegnere i led dopo un certo periodo (es. 30000ms) e rispegnerli subito dopo (es. 30100ms) usando il comando millis da aggiungere nelle fasi che voglio, ma se metto due comandi millis di seguito entrambi non funzionano.
Come potrei fare?
Grazie mille.

Ciao, studiati il blink without delay. Alla fine un lampo è lo stesso principio del blink, cambiano solo le temporizzazioni :wink: vedo però dei delay nel tuo codice quindi penso che andrà rivisto anche quello, essendo delay una funzione bloccante. Per il momento ti consiglio di costruirti a parte il tuo effetto lampo e successivamente provare a integrarlo nello sketch che hai già

EDIT: mi correggo, non devi cambiare solo la temporizzazione altrimenti avresti solo un lampeggio più veloce, devi fare in modo che una volta fatto il lampo non si accenda più per un certo tempo. Tempo che può essere sempre quello oppure determinato in modo casuale con la funzione Random()

Durante il delay() non viene eseguito nessuna altra funzione. Se vuoi fare 2 cose (quasi) in contemporanea devi lavorare con millis() per gestire le tempistiche di tutte le cose come suggerisce doppiozero.

Ciao Uwe

davide12: ... per capire bene come usare la funzione millis(), che ti è stata da più persone suggerita, prova a leggere prima QUI, poi QUI ed infine leggi anche QUI e QUI ... doversi avere una visione migliore di come utilizzarla e quindi di come applicarla al tuo programma.

Guglielmo

Vi ringrazio delle vostre risposte, ho visto alcuni esempi con la funzione millis e ho provato ad applicarli al mio programma ma il problema rimane sempre lo stesso, se metto i funzione millis funziona, se ne metto 2 di seguito (per fermare il lampeggio oppure per accendere o spegnere) non funziona nessuna delle due ed in alcuni casi il programma si blocca.
Stavo pensando a questo punto che potrei riscrivere tutto il programma eliminando i delay e utilizzando solo millis che accende e spegne dopo un certo intervallo di tempo una o più luci. E' fattibile come cosa?

davide12:
... Stavo pensando a questo punto che potrei riscrivere tutto il programma eliminando i delay e utilizzando solo millis che accende e spegne dopo un certo intervallo di tempo una o più luci. E' fattibile come cosa?

... forse non siamo stati chiari noi, ma quella è l'unica soluzione praticabile :slight_smile:

Se usi la delay() finisci sempre in qualche cosa di bloccante, con la millis() invece puoi programmare vari eventi e nessuno blocca l'altro :wink:

Guglielmo

Voi siete stati chiarissimi, il problema sono io che non riesco a farmi capire. :slight_smile:
Ho scritto queste poche righe con il comando millis. Il mio obiettivo è quello di accendere un led in fade, spegnerlo in fade dopo un certo periodo e nel frattempo tenere a LOW le altre uscite e accendere un led passato un lasso di tempo e spegnerlo quando è passato un altro piccolo lasso di tempo.

#define lampi   12
#define luciint 2
#define luciest 4



#include <LEDFader.h>

LEDFader soleon = LEDFader(11);
LEDFader soleoff = LEDFader(11);

LEDFader albaon = LEDFader(10);
LEDFader albaoff = LEDFader(10);

LEDFader tramontoon = LEDFader(9);
LEDFader tramontooff = LEDFader(9);

LEDFader cometaon = LEDFader(6);
LEDFader cometaoff = LEDFader(6);

LEDFader stelleAon = LEDFader(5);
LEDFader stelleAoff = LEDFader(5);

LEDFader stelleBon = LEDFader(3);
LEDFader stelleBoff = LEDFader(3);

boolean state = true;
unsigned long int time;


void setup() {
  Serial.begin( 9600 );
   
  pinMode( lampi   ,OUTPUT );
  pinMode( luciint,OUTPUT );
  pinMode( luciest,OUTPUT );

 
  analogWrite( lampi   ,LOW );
  digitalWrite( luciint,LOW );
  digitalWrite( luciest,LOW );

soleon.fade(255, 10000);
soleoff.fade(0, 5000);

albaon.fade(255, 1000);
albaoff.fade(0, 5000);

cometaon.fade(255, 1000);
cometaoff.fade(0, 5000);

stelleAon.fade(255, 1000);
stelleAoff.fade(0, 5000);

stelleBon.fade(255, 1000);
stelleBoff.fade(0, 5000);

tramontoon.fade(255, 1000);
tramontooff.fade(0, 5000);









}

void loop()
{
    unsigned long currentMillis = millis();


//GIORNO
digitalWrite( lampi, 0);
digitalWrite( luciint, 0);
analogWrite( 3, 0);
digitalWrite( luciest, 0);
analogWrite( 5, 0);
analogWrite( 6, 0);
analogWrite( 9, 0);
analogWrite( 10, 0);
if((time+500)==millis()) {   soleon.update();   }
if((time+15000)==millis()) {   soleoff.update();    }
if((time+10000)==millis()) {   digitalWrite( lampi, 1); }
if((time+10100)==millis()) {   digitalWrite( lampi, 0);  }



}

Provandolo con arduino i led in fade partono ma una volta raggiunta la luminosità massima si bloccano, gli altri led non fanno nulla. Cosa ho sbagliato? Grazie di nuovo.

... beh ... direi che semplicemente NON hai studiato i link che ti ho messo, perché quello che hai scritto non ha nulla a che vedere con quello che è riportato in quei link.

Passare da delay() a millis() NON è operazione banale come credi ... richiede uno studio approfondito di quei link e la completa ristrutturazione del programma secondo una logica ad eventi temporali.

Quindi ...

  1. studia molto bene queli link ed assimilali, perché non basta una "letturina"
  2. fai un primo evento e verifica che funzioni
  3. solo dopo aver verificato che con un evento funzioni passa ad aggiungere altri eventi, sempre UNO alla volta e sempre verificando che il tutto continui a funzionare.

Vedrai che piano piano, con pazienza, arrivi alla soluzione.

Guglielmo

davide12:
Voi siete stati chiarissimi, il problema sono io che non riesco a farmi capire. :slight_smile:
Ho scritto queste poche righe con il comando millis. Il mio obiettivo è quello di accendere un led in fade, spegnerlo in fade dopo un certo periodo e nel frattempo tenere a LOW le altre uscite e accendere un led passato un lasso di tempo e spegnerlo quando è passato un altro piccolo lasso di tempo.

#define lampi   12

#define luciint 2
#define luciest 4

#include <LEDFader.h>

LEDFader soleon = LEDFader(11);
LEDFader soleoff = LEDFader(11);

LEDFader albaon = LEDFader(10);
LEDFader albaoff = LEDFader(10);

LEDFader tramontoon = LEDFader(9);
LEDFader tramontooff = LEDFader(9);

LEDFader cometaon = LEDFader(6);
LEDFader cometaoff = LEDFader(6);

LEDFader stelleAon = LEDFader(5);
LEDFader stelleAoff = LEDFader(5);

LEDFader stelleBon = LEDFader(3);
LEDFader stelleBoff = LEDFader(3);

boolean state = true;
unsigned long int time;

void setup() {
  Serial.begin( 9600 );
 
  pinMode( lampi  ,OUTPUT );
  pinMode( luciint,OUTPUT );
  pinMode( luciest,OUTPUT );

analogWrite( lampi  ,LOW );
  digitalWrite( luciint,LOW );
  digitalWrite( luciest,LOW );

soleon.fade(255, 10000);
soleoff.fade(0, 5000);

albaon.fade(255, 1000);
albaoff.fade(0, 5000);

cometaon.fade(255, 1000);
cometaoff.fade(0, 5000);

stelleAon.fade(255, 1000);
stelleAoff.fade(0, 5000);

stelleBon.fade(255, 1000);
stelleBoff.fade(0, 5000);

tramontoon.fade(255, 1000);
tramontooff.fade(0, 5000);

}

void loop()
{
    unsigned long currentMillis = millis();

//GIORNO
digitalWrite( lampi, 0);
digitalWrite( luciint, 0);
analogWrite( 3, 0);
digitalWrite( luciest, 0);
analogWrite( 5, 0);
analogWrite( 6, 0);
analogWrite( 9, 0);
analogWrite( 10, 0);
if((time+500)==millis()) {  soleon.update();  }
if((time+15000)==millis()) {  soleoff.update();    }
if((time+10000)==millis()) {  digitalWrite( lampi, 1); }
if((time+10100)==millis()) {  digitalWrite( lampi, 0);  }

}




Provandolo con arduino i led in fade partono ma una volta raggiunta la luminosità massima si bloccano, gli altri led non fanno nulla. Cosa ho sbagliato? Grazie di nuovo.

non vedo il motivo per cui devi usare un solo "millis"
puoi mettere anche 100 blink without delay. basta che usi 100 variabili con nome diverso

righe cosi
if((time+10000)==millis()) { digitalWrite( lampi, 1); }
if((time+10100)==millis()) { digitalWrite( lampi, 0); }
o piu precisamente ==millis si possono scrivere solo sotto l'effetto di stupefacenti :o
che stai cercando di fare di beccare millis al momento giusto :confused:

usare sempre <= oppure >= al posto di ==

elrospo:
usare sempre <= oppure => al posto di ==

L' uguale va per primo o dopo il segno < o >?

ExperimentUno:
L' uguale va per primo o dopo il segno < o >?

ExperimentUno:
L' uguale va per primo o dopo il segno < o >?

va dopo
ma devi comprendere il funzionamento
se metti == su millis che e qualcosa che va sempre avanti e non si ferma

non puoi mai trovarti == a millis
quindi o maggiore o minore
stessa cosa con analogread mettere sempre >= <=

oppure se serve trovarsi entro un range if k <=x && >=x

elrospo:
se metti == su millis che e qualcosa che va sempre avanti e non si ferma

Aspetti il turno successivo che passa per quel valore :smiley: :smiley: (1`193 ore dopo). Se sei fortunato e lasci acceso Arduino :smiley: :smiley:

Grazie dell'aiuto, alla fine sono riuscito a farlo funzionare!