problema con timer luci

Ciao ragazzi, come da titolo ho un problema con la temporizzazione di due luci, vi spiego, ho la necessità di fare accendere due luci ad un certo orario e dopo un tot di tempo si devono spegnere sole (la classica luce scala per intenderci in versione automatizzata) solo che non voglio bloccare il programma utilizzando la funzione delay, quindi leggendo anche gli articoli che ho visto postare diverse volte di Leo72, ho deciso di optare per la funzione millis.
E qui ho trovato un intoppo dal quale no riesco ad uscirne…ovvero il tempo che io imposto come ritardo non riesco a farlo partire solo dopo che le luci si sono effettivamente accese, ma inizia a contare da quando alimento la scheda, con il risultato che appena le luci si accendo all’orario impostato si spengono anche subito perché il tempo di ritardo impostato è già passato!
Vi posto lo sketck magari qualcuno mi riesce a dare una mano…

#include <Wire.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>

#define DS1307_I2C_ADDRESS 0x68

int luce1 = 6;
int luce2 = 7;

int statoLuce1 = 0;
int statoLuce2 = 0;

unsigned long previousMillis1 = 0;
unsigned long interval1 = 20000;
unsigned long previousMillis2 = 0;
unsigned long interval2 = 30000;

extern unsigned long timer0_millis;

void setup()
{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  Serial.begin(9600);
  pinMode(luce1, OUTPUT);
  pinMode(luce2, OUTPUT);
  
  
  setSyncProvider(RTC.get);
  if(timeStatus()!= timeSet)
     Serial.println("Impossibile sincronizzare con RTC");
  else
     Serial.println("Ora sincronizzata con RTC"); 
  
  //Impostare orari di accensioni
  Alarm.alarmRepeat(21, 55, 0, Prima); 
  Alarm.alarmRepeat(21, 55, 10, Seconda); 
  
  
}

void loop()
{
  accensioni();
  if(timeStatus() == timeSet){
     digitalClockDisplay();
     }
  Alarm.delay(1000);
}

void accensioni()
{
  unsigned long currentMillis = millis();
  if(statoLuce1 == 1){
    if(currentMillis - previousMillis1 > interval1) {
      previousMillis1 = currentMillis; 
      digitalWrite(luce1, LOW);
      statoLuce1 = 0;
      Serial.println("primo spegnimento");
      }
    }  

  currentMillis = millis();
  if(statoLuce2 == 1){
    if(currentMillis - previousMillis2 > interval2) {
      previousMillis2 = currentMillis; 
      digitalWrite(luce2, LOW);
      statoLuce2 = 0;
      Serial.println("secondo spegnimento");
      }
    }
  
}
    
void digitalClockDisplay(){
  
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}


// gestione luci 
void Prima(){
  Serial.println("Luce 1 accesa"); 
  digitalWrite(luce1, HIGH);
  statoLuce1 = 1;
  //timer0_millis = 0; //se includo l'azzeramento di millis mi crea un blocco di 20 secondi alla prima accensione
}

void Seconda(){
  Serial.println("Luce 2 accesa");
  digitalWrite(luce2, HIGH); 
  statoLuce2 = 1; 
}

come vedete ho anche provato ad azzerare il contatore alla prima accensione,//timer0_millis = 0; //se includo l'azzeramento di millis mi crea un blocco di 20 secondi alla prima accensione e in questo modo funziona, ma il programma va in blocco per 20 secondi e poi riprende…non so più che prove fare… :fearful: :astonished:

Grazie a tutti!! :slight_smile:

Due suggerimenti …

  1. DIMENTICA che esiste timer0_millis … e dimentica dove hai letto di azzerarlo … nel 99% dei casi è “ignoranza” nell’uso della funzione millis() dato che i casi, in cui occorre realmente forzarne l’azzeramento sono estremamente rari e specifici …

  2. All’accensione millis() ovviamente parte da 0, ma te la cosa non deve preoccupare …
    … la logica è : al tuo “… certo orario” MEMORIZZI in una variabile il valore di millis(), ad esempio la chiamiamo “partenza” dopo di che, con un IF fatto più o meno come segue, spegni le luci …

if ( millis() - partenza > tempoAttesa ) {
   << spegni le luci >>
}

… in pratica il trucco è salvare in una variabile il millis() del momento dell’inizio del conteggio e poi fare il confronto come ti ho indicato.

Vediamo se con queste indicazioni riesci a farlo … :slight_smile:

Guglielmo

Grazie mille per la dritta!!! Sono riuscito a farlo funzionare!!!

  1. DIMENTICA che esiste timer0_millis ... e dimentica dove hai letto di azzerarlo ... nel 99% dei casi è "ignoranza" nell'uso della funzione millis() dato che i casi, in cui occorre realmente forzarne l'azzeramento sono estremamente rari e specifici ...

sono d'accordo con te, la mia era stata solo una prova dettata dalla disperazione :fearful: ma che non mi piaceva molto specie per il "buio" di 20 secondi!! :~

Ancora Grazie per l'aiuto!! :)

Figurati, sono contento che ci sei riuscito ... .. e che quindi hai capito come usare la millis() per poter schedulare eventi senza bloccare il programma ;)

Guglielmo

Si finalmente ho capito…o almeno spero… :smiley: :smiley: :smiley: lo vedremo nelle seguenti applicazioni… :wink: