Problema in assenza di alimentazione plafoniera LED

Ciao a tutti!Sono Giuseppe e sono appena entrato in questo nuovo mondo anche se ho fatto qualcosa di c++ a scuola.
Ho costruito una plafoniera led per un acquario di barriera e ho utilizzato arduino per dimmerare con il fading i led in modo da ricreare alba/tramonto e regolare la potenza.
Per far questo ho utilizzato arduino uno e una display shield di rs robot.
Per creare alba(tramonto) ho utilizzato dei cicli for in cui ad ogni ripetizione,esattamente ogni 13 secondi con un delay, si incrementa(decrementa) di 1 il valore dell'uscita in pwm(da 0 a 255).
Il programma mi funziona bene e nel display mi compaiono le percentuali dei diversi led accesi e in che "fase" della giornata siamo.Per far partire il programma la prima volta ad orario premo il reset,ogni 24 ore il ciclo si ripete.
Questo è uno dei più grandi difetti del programma perchè,una volta mancata la corrente,il programma o ricomincia o impazzisce andando a sballare tutti gli orari biologici della vasca.Premetto che non ho utilizzato un rtc ma ho fatto il tutto con i delay,ovviamente la somma di tutti i delay deve dare 24h.
Il particolare se stacco la presa della plafoniera dopo un po' sul display mi compaiono simboli strani,come se il programma entra in errore.Se stacco l'alimentazione ad arduino e la riattacco ovviamente il programma ricomincia.
Riguardo il pilotaggio dei led ho collegato l'uscita di arduino all'ingresso dei driver led e la massa di arduino alla massa dei driver.
Come dovrei fare per migliorare il programma?Ho bisogno per forza di un rtc?

Il tuo problema è classico ed è sintomatico del fatto che l'Arduino non ha un orologio interno.
Devi usare o un RTC esterno oppure una batteria di backup che non ti faccia saltare l'alimentazione all'Arduino.

Ciao!Ho comprato l'rtc in modo da poter implementare nuove funzioni con arduino.
Non appena arriva vi ridisturberò :slight_smile: intanto grazie :slight_smile:

Ragazzi ho preso l'RTC.
Il programma che avevo scritto inizialmente solamente a furia di delay era molto semplice.
Adesso vorrei implementarlo con le funzioni dell'rtc in modo da far accendere le luci e farle spegnere ad un determinato orario.
Ho visto sul blog di mauro alfieri un bell'esempio per impostare data e ora con l'rtc direttamente dai tasti e visualizzarli sullo schermo.
Intanto vi posto i due codici.
Il primo è quello scritto da me attuale senza rtc
Il secondo è quello che pensavo di inserire per impostare data e ora
Chi mi sa aiutare?

// I pin digitali pwm sono 3,5,6,9,10,11.Il valore del duty cicle varia da 0 a 255

#include <LiquidCrystal.h>

#define BLUE 9
#define ROYAL 10
#define WHITE 11
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

int x=0,y=0,z=0;  //costanti per incremento royal,blu,bianchi


//la variabile x viene utilizzata per incrementare/decrementare il dutycicle dei royal e dei blu
//la variabile y viene utilizzata per incrementare/decrementare il dutycicle dei bianchi
//la variabile z viene utilizzata per incrementare/decrementare il dutycicle dei bianchi,royal e blu contemporaneamente


void setup()
{ 
  lcd.begin(16, 2);
  lcd.print("PlafoLED Reef");
  lcd.setCursor(0,1);
  lcd.print("peppuzzo#22");
  delay(5000);
  pinMode(BLUE,OUTPUT);
  pinMode(ROYAL,OUTPUT);
  pinMode(WHITE,OUTPUT);
}




void loop()
{
  
  //1 BLOCCO DI ISTRUZIONI ALBA:I ROYAL E I BLU SI ACCENDONO PER 20 MINUTI FINO AD ARRIVARE AL 35% DI INTENSITA' LUMINOSA,GLI ALTRI LED RESTANO SPENTI
  for(x=0;x<=90;x++)
  {
  analogWrite(ROYAL,x);
  analogWrite(BLUE,x);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ALBA");
  lcd.setCursor(0,1);
  lcd.print("R");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,1);
  lcd.print("B");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("W");
  lcd.print(y/1.8);
  lcd.print("%");
      delay(13000);
  }
  
  //2 BLOCCO DI ISTRUZIONI ALBA:I BIANCHI SI ACCENDONO PER 20 MINUTI FINO AD ARRIVARE AL 35%,I ROYAL E I BLU RESTANO FISSI AL 35%
  for(y=0;y<=90;y++)
  {
  analogWrite(WHITE,y);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ALBA");
  lcd.setCursor(0,1);
  lcd.print("R");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,1);
  lcd.print("B");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("W");
  lcd.print(y/1.8);
  lcd.print("%");
      delay(13000);
  }
  
 
  
  //3 BLOCCO DI ISTRUZIONI ALBA:BIANCHI,BLU E ROYAL SI ACCENDONO PER ALTRI 20 MINUTI FINO AD ARRIVARE AL 70%
  for(z=90;z<=180;z++)
  {
  analogWrite(ROYAL,z);
  analogWrite(WHITE,z);
  analogWrite(BLUE,z);
 lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ALBA");
  lcd.setCursor(0,1);
  lcd.print("R");
  lcd.print(z/1.8);
  lcd.print("%");
  lcd.setCursor(9,1);
  lcd.print("B");
  lcd.print(z/1.8);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("W");
  lcd.print(z/1.8);
  lcd.print("%");
  
   delay(13000);
  }
  
  
 
 
 
 
 
 
  //BLOCCO DI ISTRUZIONI A REGIME 
  lcd.setCursor(0,0);
  lcd.print("GIORNO");
  delay(25200000); //aspetto 25200s = 7h di luce
  
  
  
  
  //1 BLOCCO DI ISTRUZIONI TRAMONTO:BIANCHI,BLU E ROYAL DIMINUISCONO LA LUMINOSITA'  DAL 70% AL 35%  
  for(z=180;z>=90;z--)
  {
  analogWrite(ROYAL,z);
  analogWrite(WHITE,z);
  analogWrite(BLUE,z);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("TRAMONTO");
  lcd.setCursor(0,1);
  lcd.print("R");
  lcd.print(z/1.8);
  lcd.print("%");
  lcd.setCursor(9,1);
  lcd.print("B");
  lcd.print(z/1.8);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("W");
  lcd.print(z/1.8);
  lcd.print("%");
  
  delay(13000);
  }
  
  
  
  
 //2 BLOCCO DI ISTRUZIONI TRAMONTO:I BIANCHI DIMINUISCONO LA LUMINOSITA' DAL 35% A 0
  for(y=90;y>=0;y--)
  {
  analogWrite(WHITE,y);
 lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("TRAMONTO");
  lcd.setCursor(0,1);
  lcd.print("R");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,1);
  lcd.print("B");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("W");
  lcd.print(y/1.8);
  lcd.print("%");
 
  delay(13000);
  }
  
 
 
 
  //3 BLOCCO DI ISTRUZIONI TRAMONTO: BLU E ROYAL DIMINUISCONO LA LUMINOSITA' DAL 35% A 0
  for(x=90;x>=0;x--)
  {
  analogWrite(ROYAL,x);
  analogWrite(BLUE,x);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("TRAMONTO");
  lcd.setCursor(0,1);
  lcd.print("R");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,1);
  lcd.print("B");
  lcd.print(x/1.8);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("W");
  lcd.print(y/1.8);
  lcd.print("%");
  delay(13000);
  }
  
  //BLOCCO DI ISTRUZIONI NOTTURNO
  lcd.noDisplay();
  delay(54180000);  //aspetto 54180s = 15,05h di buio contro le 8,95h di luce
  lcd.display();
}
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
 
#define BACKLIGHT 2
#define CONTRAST  3
 
#define SET       A0
#define PIU       A1
#define MENO      A2
 
char buffer[10];
unsigned long time=0;
unsigned long timeSet=0;
int  setModeTime=2000;
 
RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
 
void setup () {
    pinMode( BACKLIGHT, OUTPUT );
    pinMode( CONTRAST, OUTPUT );
    digitalWrite( BACKLIGHT, HIGH );
    analogWrite( CONTRAST, 40 );
 
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2);
 
    if (! RTC.isrunning()) {
      Serial.println("RTC is NOT running!");
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
 
    pinMode( SET, INPUT );
    pinMode( PIU, INPUT );
    pinMode( MENO, INPUT );
}
 
void loop () {
 
    if ( analogRead( SET ) < 1000) { time = millis(); }
 
    DateTime now = RTC.now();
    lcd.clear();
 
    sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
    lcd.setCursor(0,0);
    lcd.print( buffer );
 
    char buffer[10] = "";
 
    sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.setCursor(0,1);
    lcd.print( buffer );
 
    if (time > 0 && setModeTime < (millis() - time) ) { setMode( now ); }
 
    delay(1000);
}
 
void setMode( DateTime now ) {
    boolean setMode = true;
    int setModeLevel = 0;
 
    int _day = now.day();
    int _month = now.month();
    int _year = now.year();
    int _hour = now.hour();
    int _min = now.minute();
    int _sec = now.second();
 
    lcd.clear();
    lcd.setCursor(0,0);
    sprintf(buffer,  "%s: %02d", "Giorno", _day);
    delay( 1000 );
    timeSet = millis();
 
    while ( setMode ) {
      if ( analogRead(SET) > 1000 || analogRead(PIU) > 1000 || analogRead(MENO) > 1000 ) { timeSet = millis(); }
 
      lcd.setCursor(0,0);
 
      // Set Day
      if ( setModeLevel == 0 ) {
        if ( analogRead(PIU) > 1000 && _day < 31) { _day++; }
        if ( analogRead(MENO) > 1000 && _day > 1) { _day--; }
 
        sprintf(buffer,  "%s: %02d", "Giorno", _day);
      }
      // Set Month
      if ( setModeLevel == 1 ) {
        if ( analogRead(PIU) > 1000 && _month < 12) { _month++; }
        if ( analogRead(MENO) > 1000 && _month > 1) { _month--; }
 
        sprintf(buffer,  "%s: %02d", "Mese", _month);
      }
      // Set Year
      if ( setModeLevel == 2 ) {
        if ( analogRead(PIU) > 1000 && _year < 9999) { _year++; }
        if ( analogRead(MENO) > 1000 && _year > 1900) { _year--; }
 
        sprintf(buffer,  "%s: %02d", "Anno", _year);
      }
      // Set Hour
      if ( setModeLevel == 3 ) {
        if ( analogRead(PIU) > 1000 && _hour < 24) { _hour++; }
        if ( analogRead(MENO) > 1000 && _hour > 1) { _hour--; }
 
        sprintf(buffer,  "%s: %02d", "Ora", _hour);
      }
      // Set Minute
      if ( setModeLevel == 4 ) {
        if ( analogRead(PIU) > 1000 && _min < 60) { _min++; }
        if ( analogRead(MENO) > 1000 && _min > 1) { _min--; }
 
        sprintf(buffer,  "%s: %02d", "Minuti", _min);
      }
      // Set Second
      if ( setModeLevel == 5 ) {
        if ( analogRead(PIU) > 1000 && _sec < 60) { _sec++; }
        if ( analogRead(MENO) > 1000 && _sec > 0) { _sec--; }
 
        sprintf(buffer,  "%s: %02d", "Secondi", _sec);
      }
 
      lcd.print( buffer );
      if ( analogRead(SET) > 1000 ) { lcd.clear(); setModeLevel++;  }
      if ( setModeLevel > 5 ) { setModeLevel=0; }
 
      if (timeSet > 0 && (setModeTime*2) < (millis() - timeSet) ) {
         RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec));
         setMode = false;
      }
      delay(200);
    }
}

programmaplafoniera.ino (4.05 KB)