Che è una citazione da "la genesi" di Francesco Guccini
mi riallaccio così a quanti (e sono tanti) che vorrebbero fare dei generatori di alba e tramonto
sia per delle serre che per dei plastici che per dei presepi
io mi limito ad un generatore "universale" che permette la generazione in PWM di rosso verde e blu a dare tutte le possibili condizioni di luce
il tutto si basa sul lavoro "preparatorio" che avevo fatto per dare una mano a uno, qui
che poi se le è cavata egregiamente da solo, bene ne sono contento
però vi lascio qui il mio "distillato di sudore" che essendo ben commentato potrebbe essere una buona base di partenza per "allargarlo" per fare "di più" oppure anche per ridurlo
ad esempio si potrebbero gestire 2 o 3 "batterie" di led RGB per far "muovere" la luce durante il giorno, oltre che indebolire e cambiare colore
il trutto si basa su un tipo dati struct che deve contenere tutte le informazioni necessarie a rappresentare lo stato del sistema
ecco un esempio:
// la struttura che contiene le ore
typedef struct
{
byte ora;
byte minuto;
byte rosso;
byte verde;
byte blu;
char nome[15];
} orario;
naturalmente all'ora "giusta" serve di "eseguire" questa struttura, o meglio una variabile del tipo di questa struttura:
void accendi(orario appoggio)
{
// esegue l'accensione dei vari led come descritto in appoggio
analogWrite(LEDR, appoggio.rosso);
analogWrite(LEDG, appoggio.verde);
analogWrite(LEDB, appoggio.blu);
return;
}
come vedete gli faccio eseguire le accensioni in PWM, abbastanza banale ma sono le cose banali che vanno, l'idea, ripresa dalla programmazione in C++ sarebbe di "chiudere" tutte le operazioni dentro qui, senza andare in giro a sporcare il programma
non è programmazione ad oggetti, ma un'idea presa da li
ora si tratta di sapere se (e quando) agire sui led
a intervalli regolari (e qui si chiede aiuto alla millis e/o a un rtc
si chiama una funzione che data ora e minuto ci dice che "oggetto" dobbiamo eseguire
si puo' anche chiamarla di continuo, ad ogni giro di loop, tanto se la luminosità non cambia non ha effetto
ma servirà per dopo, vedrete
orario attuale(byte ora, byte minuto)
{
// restituisce la struttura orario che descrive lo stato attuale
// versione a scatti
for (byte i = 0; i < PASSI; i++)
{
int momento = ora * 60 + minuto;
if ((programma[i].ora * 60 + programma[i].minuto) > momento)
{
return programma[i - 1];
}
}
}
come vedete dandogli in pasto ora e minuto (anche simulati in un plastico) ci dice quale stato deve venire acceso
con una banale
accendi(attuale(ora, minuto));
la attuale() restituisce dritto tra le braccia della accendi() un oggetto adeguato
e in questa maniera evito di dover passare uno, due, o tre valori numerici, passo un oggetto struttura che per costruzione (lo abbiamo fatto così all'inizio) ha tutto quello che serve
se si dovesse aggiungere una seconda terna di led si allarga la struttura e si aggiungono tre righe alla esegui
ad esempio il membro char * nome è già li proprio per eventuali stampe
la vera menata sarebbe costruire l'array di struttura
per fortuna una vecchia caratteristica del preprocessore, poco documentata e credo risalente ancora al 'B' ci permette di farlo con facilità
#define STATI \
X( 0, 0, 0, 0, 0, mezzanotte) \
X( 2, 0, 5, 5, 10, stelle) \
X( 5, 35, 10, 12, 15, lucore) \
X( 6, 0, 100, 102, 55, alba) \
X( 8, 0, 255, 255, 255, giorno pieno)\
X(18, 0, 255, 255, 255, fine giorno)\
X(19, 0, 100, 102, 55, tramonto) \
X(19, 30, 50, 55, 2, notte) \
X(24, 00, 0, 0, 0, termine)
// ricordarsi che i nomi sono lunghi al massimo 15
// l'inizializzazione dell'array di struttura
#define X(ora, minuto, rosso, verde, blu, nome) {ora, minuto, rosso, verde, blu, #nome},
orario programma[] = { STATI
#undef X
};
//il numero di passi
#define PASSI sizeof (programma ) /sizeof (orario)
la prima define (STATI) non è terminata, notate la barra retroversa alla fine della riga
e notate pure la X(.....e qui si scrive ora minuto etc etc separati da virgola)
la barra retroversa NON termina la riga
mentre la X verrà usata in una successiva define a se stante
l'unica riga terminata è l'ultima
di maniera che il tutto appare coma un'unica lunghissima riga di define
la seconda define X(....
serve per espandere dentro una inizializzazione di array le varie X(...) che abbiamo scritto prima
difatti vedete che definosce la X( come quasi fosse una macro, ne espande anche gli argomenti
dopo la sua undef chiude la definizione dello array con };
la terza define è banale, per sapere il numero di elementi senza doverli contare
allego qui il file ino ma ci sono ancora due cose da dire
albatramonto.ino (4.4 KB)