timer senza rtc e rampa tensione

buonasera, premetto che sono alle prime armi con il linguaggio arduino, e per i mostri che vedo in questo forumo questa cosa potrebbe esere una cosa banale da fare, ma che per me, non lo è :slight_smile:

Ho la necessità di controllare una lampada a led utilizzando 2 pin pwm (luce per un acquario, pilotata da un mosfet che lavora a livelli logici, collaudato il tutto con una semplice rampa pwm e funziona alla perfezione) un pin mi comanda un mosfet per il giorno (una ora di rampa da 0 a 5V ...poi tutto acceso 8 ore e poi rampa contrario di 1 ora da 5V a 0) ed il 2° pin pwm utilizzato per la luce notturna che va ad accendersi esattamente l'opposto della luce diurna.
leggendo in giro si utilizza un rtc, è proprio necessario? o rischio l'overflow come ho letto in giro? come dovrei buttare giù le righe di codice?

Grazie mille a tutti :slight_smile:

Se ti chiedi dell'overflow immagino che tu stia utilizzando la funzione millis per controllare il trascorrere del tempo.
Dipende da come la usi, ho scritto a proposito un piccolo articolo sul mio sito.

Ho anche scritto 2 librerie che forse potrebbero interessarti. La swRTC e la leOS (entrambe le trovi sul mio sito).
La prima crea un orologio software. Puoi così tenere il tempo senza componenti hardware aggiuntivi. La precisione della libreria è legata alla precisione del risonatore ceramico che viene utilizzato sull'Arduino, quindi c'è una certa differenza che si accumula giornalmente ma ho integrato una funzione per correggere questo scostamento.

La seconda "offerta" è il leOS (nella versione 2 uso il watchdog, evitando quindi di andare a toccare i timer del microcontrollore), che in pratica è un semplice schedulatore: imposti una funzione, imposti l'intervallo per la sua esecuzione e poi lasci fare tutto a lei. La libreria lancerà il task dopo il tempo prestabilito, senza interferire con il loop principale.

L' rtc servirebbe per fare un orologio, quindi confrontare ore-min-sec, poi si potrebbe fare anche senza dipende se il tuo arduino ha un risonatore o un quarzo e non hai detto che arduino hai.

Fallo col timer interno e non fargli mai mancare tensione, ogni tanto aggiorni l'orologio. Per l'overflow non è grave, non scoppia e non si inchioda, puoi resettarlo se ti fa piacere alle ore 00:00:00 così sei tranquillo (ogni 86400000 del millis)
Questo vale per programmazioni giornaliere da lunedì a domenica, se devi fare programmazioni differenziate durante la settimana la cosa si fa un po' più complicata.

EDIT: ho visto dopo la risposta di Leo, comunque dovresti utilizzare la sua swRTC, ti risparmi un sacco di calcoli

Lo svantaggio del swRTC é che si resetta quando va via le tensione. Un RTC ha una batteria che lo alimenta anche in mancanza di alimentazione.
Se vuoi aver sincronizzato laluce del aquario con la luce del giorno allora ti serve un RTC.
Ciao Uwe

uwefed:
Lo svantaggio del swRTC é che si resetta quando va via le tensione. Un RTC ha una batteria che lo alimenta anche in mancanza di alimentazione.

Ma lui chiedeva se era necessario usare un RTC, non è necessario. Ho solo presentato alcune soluzioni alternative all'RTC. :wink:

uwefed:
Lo svantaggio del swRTC é che si resetta quando va via le tensione. Un RTC ha una batteria che lo alimenta anche in mancanza di alimentazione.
Se vuoi aver sincronizzato laluce del aquario con la luce del giorno allora ti serve un RTC.
Ciao Uwe

infatti ho scritto

non fargli mai mancare tensione

Ma come sempre senti sempre l'esigienza di intervenire e ripetere quello che dicono gli altri

grazie mille, provo a studiarmi un po la libreria e vediamo cosa combino :slight_smile:

anche io sto programmando Arduino per pilotare la luce di un Acquario ho usato però un RTC e per fare l'incremento decremento come mi hanno consigliato qui ho usato la funzione millis() e tutto quello che ne segue
la cosa buona del RTC è che ha la batteria e il programma che lo controlla è semplice.

tu che circuteria hai messo sul pin PWM? cioè hai messo un mosfet e basta oppure altro?

ho utilizzato un mosfet che lavora e da il massimo passaggio di corente con 5V (irl530 oppure 540)

ho un dubbio, come faccio a "sincronizzare" le luci con il tempo? ...ammettiamo che a metà pomeriggio do tensione al crcuito, imposto l'ora, ma come faccio a dire che in quel momento esatto devo avere il 100% della luce oppure il 45% o meno o più a seconda?

Conviene ragionare col tempo in secondi. Conoscendo il tempo in secondi del momento in cui le luci devono essere allo 0% e quando al 100%, con una proporzione (o funzione matematica) ti calcoli la percentuale per l'ora corrente.
Naturalmente per avere un riferimento certo devi avere un RTC sincronizzato o quantomeno regolato sull'ora corrente, poi minuto più minuto meno non è che faccia differenze.
Il problema di un RTC software, come dicevano, è che spegnendo l'Arduino perde la sincronizzazione, quindi l'errore potrebbe essere molto maggiore di un minuto.

vanniboy:
ho un dubbio, come faccio a "sincronizzare" le luci con il tempo? ...ammettiamo che a metà pomeriggio do tensione al crcuito, imposto l'ora, ma come faccio a dire che in quel momento esatto devo avere il 100% della luce oppure il 45% o meno o più a seconda?

Qui devi intervenire tu nel senso che sarai tu a strutturare l'algoritmo in base alle tue esigenze. Se cioè vorrai un aumento/diminuzione a rampa dovrai stabilire delle percentuali e con una funzione, come ha detto Paolo, ti calcoli l'istante in cui sei a che valore di luminosità corrisponde.
Esempio.
Mettiamo che la tua rampa duri, per facilità di calcoli, 64 minuti.
Sapendo che su un pin PWM puoi "scrivere" un valore che va da 0 a 255, avrai 256 passi di illuminazione. Facendo 256/64 è facile trovare che la luminosità da scrivere sarà 4 volte il numero dei minuti dall'inizio della rampa.
Quindi se tu decidi alle 17:00 che debba iniziare il tramonto, esso finirà alle 17:00+0:64->18:04.
Se accendi la scheda alle 17:32, sarai a 32 minuti dall'inizio della rampa per cui la luminosità da "scrivere" sarà 32*4=128.

Ovviamente questo è un esempio, oltretutto stupido, ma ti spiega una possibile (delle molteplici) soluzioni.

vanniboy:
ho un dubbio, come faccio a "sincronizzare" le luci con il tempo? ...ammettiamo che a metà pomeriggio do tensione al crcuito, imposto l'ora, ma come faccio a dire che in quel momento esatto devo avere il 100% della luce oppure il 45% o meno o più a seconda?

Devi farti Tu una tabella con gli orari di accensione- spegnimento e durata del PWM.
Quella lo memorizzi nel Arduino e lo esegui.
Ciao Uwe

ciao, quindi con questa tabella che dovrei fare, come la dovrei impostare? scusa la domanda banale :slight_smile:
se voglio che l'alba duri 2 ore, ho quindi 256 "passi" da suddividere in 7200 secondi, e fanno 1 "passo" ogni 28 secondi (arrotondando il 28... vengono meno di 7200 secondi, per comodità).

ma io devo fare 256 linee ognuna con il valore da impostare in quel momento? o esiste un modo per fare la stessa cosa senza riscrivere 256 volte la stessa cosa?

o sbaglio il ragionamento in partenza?

Io continuo a suggerirti l'uso di un semplice algoritmo che ti calcoli la curva in base all'istante.

scusami, nelle risposte mi ero perso il tuo suggermiento! :slight_smile:
proverò a studiare un pò, anche se sono a digiuno da molto con arduino

La cosa più semplice senza impazzire di tabelle è usare la funzione map.

intensitàled = map(oraattuale, orainizio, orafine, 0, 255);

Come già detto è meglio se espimi oraattuale, orainizio e orafine in minuti o in secondi.

questo è una parte dello sketc :

int ore = rtc.getHours();
map(ore,8,10, 0,255);

così potrebbe funzionare anche nel calcolo nel momento in cui io imposto l'ora?

vanniboy:
questo è una parte dello sketc :

int ore = rtc.getHours();
map(ore,8,10, 0,255);

così potrebbe funzionare anche nel calcolo nel momento in cui io imposto l'ora?

No. Così hai solo 3 valori:
8->0
9->128
10->255
Devi usare i secondi come ti ha detto PaoloP, più che i secondi io userei il timestamp UNIX. Trasformi l'orario in timestamp (il numero di secondi dal 1970.0 ad oggi) e poi i conti li fai in secondi, in questo modo hai molti più valori. Con la map messa come hai fatto tu ottieni solo 2 valori perché map restituisce un intero.

scudsare ragazzi ma in incremeneto decremento tipo questo nooo?

int LED_White1=2;//pin 2 per il pwm
int valoreLed_W1=0;//variabile usata per l'incremento
int VLW1=255;//valore del pwm impostato
int delaytRAMPAW1=(minutiRampa1*60000)/VLW1;
//CONTROLLO INCREMENTO FADE LED BIANCHI 1
if(hour>=oreOnBianchi1 && minute>=minutiOnBianchi1 && hour<oreOffBianchi1 && valoreLed_W1<VLW1)
{
statoINC_W1 = 1;//fa parire l'incremento
}else
{
statoINC_W1 = 0;// stop al raggiungimento max luminositá LED
}
//ciclo di incremento del led bianchi 1
if (statoINC_W1 == 1)
{currentMillis_W1 = millis();
if(currentMillis_W1 - previousMillis_W1 > delaytRAMPAW1)
{
previousMillis_W1 = currentMillis_W1;
valoreLed_W1++;
analogWrite(LED_White1,valoreLed_W1);
Serial.print("valoreLed_W1: ");
Serial.println(valoreLed_W1);
}
}