Alba, tramonto, acceso, spento .... e ancora alba

Che sarebbe la citazione di un certo film
una cosa del tipo “primavera estate autunno inverno e … ancora primavera”

Poi chi sa e cerca trova, chi non cerca ma aspetta la pappa pronta non trova nemmeno la “pappa fatta” quando gliela mostri…

tutto è nato da un certo numero di led che devono lampeggiare e poi anche alcuni fare fade in fade out
se cercate trovate qui vicino la discussione originale

come mio solito io parlo poco, nelle discussioni altrui
e nemmeno programmo molto, che’ non mi piace dare la pappa pronta ai pigri

però il lavoro lo ho svolto, e ne lascio qui il succo, che come ho detto, chi ha la voglia di cercare trova…

allora si comincia con un bel led lampeggiante su due tempi differenti

siccome i led saranno poi alla fine tanti parto da subito con un bell’array (di un solo elemento, per provare, poi si allunga)

// di Nelson-StandardOil
// IDE 1.8.10
// Progetto: albe tramonti e lampi
// Scopo:
// Data inizio lavori: 21/09/2020

// i pin dei led on off
byte pinonoff[] = {13};
// un solo pin per provare, poi ci si allarga
#define MAXONOFF sizeof pinonoff /sizeof pinonoff[0]
// i tempi dei led on off
unsigned long int ton[MAXONOFF] = {3000};
unsigned long int toff[MAXONOFF] = {500};
unsigned long int tstart[MAXONOFF];
bool statoonoff[MAXONOFF];
// solitamente uso strutture, ma qui ho volutamente lasciato semplice per i meno esperti


void setup(void)
{
   // abilito i pin in output
   for (byte i = 0; i < MAXONOFF; i++)
   {
      pinMode(pinonoff[i], OUTPUT);
   }
}

void loop(void)
{
   for (int i = 0; i < MAXONOFF; i++)
   {
      if (statoonoff[i])
      {
         if ((millis() - tstart[i]) > ton[i])
         {
            // spengo
            digitalWrite(pinonoff[i], 0);
            tstart[i] = millis();
            statoonoff[i] = 0;
         }
      }
      else
      {
         if ((millis() - tstart[i]) > toff[i])
         {
            // accendo
            digitalWrite(pinonoff[i], 1);
            tstart[i] = millis();
            statoonoff[i] = 1;
         }
      }
   }
}

come vedete faccio la prova col pin 13 (led on board)

ora si passa alla parte bella, si aggiunge un secondo led

// di Nelson-StandardOil
// IDE 1.8.10
// Progetto: albe tramonti e lampi
// Scopo:
// Data inizio lavori: 21/09/2020

// i pin dei led on off
byte pinonoff[] = {13, 11};
// due pin per continuare, ma basta aggiungere...
#define MAXONOFF sizeof pinonoff /sizeof pinonoff[0]
// i tempi dei led on off
unsigned long int ton[MAXONOFF] = {3000, 2500};
unsigned long int toff[MAXONOFF] = {500, 750};
unsigned long int tstart[MAXONOFF];
bool statoonoff[MAXONOFF];
// solitamente uso strutture, ma qui ho volutamente lasciato semplice per i meno esperti


void setup(void)
{
   // abilito i pin in output
   for (byte i = 0; i < MAXONOFF; i++)
   {
      pinMode(pinonoff[i], OUTPUT);
   }
}

void loop(void)
{
   for (int i = 0; i < MAXONOFF; i++)
   {
      if (statoonoff[i])
      {
         if ((millis() - tstart[i]) > ton[i])
         {
            // spengo
            digitalWrite(pinonoff[i], 0);
            tstart[i] = millis();
            statoonoff[i] = 0;
         }
      }
      else
      {
         if ((millis() - tstart[i]) > toff[i])
         {
            // accendo
            digitalWrite(pinonoff[i], 1);
            tstart[i] = millis();
            statoonoff[i] = 1;
         }
      }
   }
}

Ops, il programma è identico, salvo tre righe e un commento: ho aggiunto nella dichiarazione di array solo il nuovo piedino e i nuovi tempi
a dimostrazione che a pensare “prima” si fa meno fatica, dopo

e passiamo adesso alla fase con il fade
naturalmente uso la libreria fadeled.h, che si trova col gestore di librerie

anche qui dichiaro un array di fadeled, per la prima prova array di un solo elemento

// di Nelson-StandardOil
// IDE 1.8.10
// Progetto: albe tramonti e lampi
// Scopo:
// Data inizio lavori: 21/09/2020

// i pin dei led on off
byte pinonoff[] = {13};
// un solo pin per provare, poi ci si allarga
#define MAXONOFF sizeof pinonoff /sizeof pinonoff[0]
// i tempi dei led on off
unsigned long int ton[MAXONOFF] = {3000}; // tempo di ON per i led in ON/OFF
unsigned long int toff[MAXONOFF] = {500}; // tempo di OFF per i led in ON/OFF
unsigned long int tstart[MAXONOFF]; // ultimo istante di azionamento per i led ON/OFF
bool statoonoff[MAXONOFF]; // stato attuale dei led ON/OFF
// solitamente uso strutture, ma qui ho volutamente lasciato semplice per i meno esperti

// adesso il fade
#include <FadeLed.h>

FadeLed leds[] = {11};

#define FADENUM sizeof leds / sizeof leds[0]
unsigned long int fadeon[FADENUM] = {2000}; // tempo complessivo acceso per i led in fade-in (comprende il tempo di fadein)
unsigned long int fadeoff[FADENUM] = {1500}; // tempo complessivo spento per i led in fade-out (comprende il tempo di fadeout)
unsigned long int fadestart[FADENUM]; // ultimo istante di azionamento per il led in fade
bool statofade[FADENUM]; // stato attuale dei led in fade
unsigned long int fadetime[FADENUM] = {1000}; // tempo del fade (deve essere minore dei due tempi di acceso e spento)

void setup(void)
{
   // abilito i pin in output
   for (byte i = 0; i < MAXONOFF; i++)
   {
      pinMode(pinonoff[i], OUTPUT);
   }

   // definisco i tempi di fade

   for (byte i = 0; i < FADENUM; i++)
   {
      leds[i].setTime(fadetime[i]);
   }
}

void loop(void)
{
   // ad ogni ciclo devo richiamare la FadeLed::update();
   FadeLed::update();

   for (int i = 0; i < MAXONOFF; i++)
   {
      if (statoonoff[i])
      {
         if ((millis() - tstart[i]) > ton[i])
         {
            // spengo
            digitalWrite(pinonoff[i], 0);
            tstart[i] = millis();
            statoonoff[i] = 0;
         }
      }
      else
      {
         if ((millis() - tstart[i]) > toff[i])
         {
            // accendo
            digitalWrite(pinonoff[i], 1);
            tstart[i] = millis();
            statoonoff[i] = 1;
         }
      }
   }

   // adesso comando i fade
   for (int i = 0; i < FADENUM; i++)
   {
      if (statofade[i])
      {
         if ((millis() - fadestart[i]) > fadeon[i])
         {
            // spengo
            leds[i].set(0);
            fadestart[i] = millis();
            statofade[i] = 0;
         }
      }
      else
      {
         if ((millis() - fadestart[i]) > fadeoff[i])
         {
            // accendo
            leds[i].set(100);
            fadestart[i] = millis();
            statofade[i] = 1;
         }
      }
   }
}

la seconda parte, quella del fade, è chiaramente un copia-incolla della prima, dopo aver semplicemente cambiato i nomi delle variabili con quelle usate per i led di fade
e usando la leds.set() invece della digitalWrite()

insomma si tratta dello stesso programma ripetuto, con solo delle modifiche ovvie

e con questo ho finito

a dimostrare che facendo quello che dico si fa quello che si vuole, chi sa cercare ha capito
gli altri… non ho parole

Ah, che sia chiaro: mi sono fatto ridare una UNO dal pestifero nipote (che ha mollato solo UNO, una resistenza da 1 K e un led rosso, il tirchio)

quindi lo ho provato: non venitemi a dire che non va, che’ prima vi plonko e poi vi dimentico

... ma c'e' la funzione "plonka utente" nell'IDE ? ... :smiley:

Comunque, bei suggerimenti ... io tempo fa volevo fare dei fade indipendenti senza usare librerie, ma poi ho lasciato perdere per mancanza di tempo (ed abilita', soprattutto :P) ... mi sa che se trovo il tempo, ci riprovo (non per sminuire la fadeled, che neppure conosco, solo per curiosita' personale ... sono testardo :D)

Purtroppo non c'è

Ma io tengo nota...

Allora, ribadisco che non sono un programmatore, ma un "novello" di Arduino; ho letto e riletto documentazioni, ma cosa mi frega è LA SINTASSI... è un po' come se chiedessi a una persona come si dice "casa" in francese perchè è una lingua che non conosco e il tizio in questione mi dicesse di comprarmi un dizionario oppure un corso di lingue; adesso: io non devo diventare un programmatore, devo solamente fare qualche effetto di luce con Arduino, tramite esempi, suggerimenti e quant'altro trovo in rete; non devo iniziare da Adamo ed Eva per arrivare a capire perchè Noè ha costruito l'arca, raccontami la storia dell'arca e buonanotte, Noè l'ho capito lo stesso.
Non voglio la pappa pronta e neanche la cerco se no avrei chiesto a qualcuno di scrivermi il codice da zero, sto solo cercando di imparare, ma avolte quando non trovi un prodotto sullo scaffale al supermercato, hai bisogno di qualcuno che ti indichi col dito dov'è; ce l'hai davanti e NON LO VEDI.
Forse ho sbagliato forum, qui i neofiti non sono ben accetti, bisogna già essere esperti; beh, allora chiudete il forum e mettete tutta una serie di documenti e link così chi ha un problema se lo risolve.
Ho provato a scrivere e modificare del codice, ma non funziona, è l'uovo di Colombo, ma mi manca una virgola per arrivarci; sarò ottuso ma nonostante tutto non ci arrivo; ho postato il codice per vedere se qualcuno poteva individuare l'imprecisione o l'errore, ma niente, mi sento preso in giro da un moderatore che ha aperto un thread per scrivere del codice che io già scritto in maniera diversa, senza arrivare tra l'altro al punto che dico io, perchè neanche tu Standardoil hai diversificato i tempi di accensione fissa dei LED che si incrociano in dissolvenza.
Le cose si pensano prima, siamo d'accordo, ma durante o alla fine del lavoro, possono venire fuori idee e modifiche atte a migliorarlo e perfezionarlo.
Comunque al di la di tutto ringrazio chi mi ha spinto ad arrivare fino qui, ne avevo bisogno.

Miiii... che spatasciata

Complimenti, hai cercato e hai trovato

E adesso ?
E adesso hai avuto consigli, indicazioni, esempi e anche un programma funzionante

Che non hai capito, lo dimostra la tua considerazione sui tempi dei led in dissolvenza

A proposito, io non sono un moderatore, per fortuna mia sono un utente comune

Come avevo scritto (perché io vedo, prevedo e stravedo) non venitemi a dire che non va

Io lo ho provato, e quindi....

omega696:
... mi sento preso in giro da un moderatore che ha aperto un thread per scrivere del codice che io già scritto in maniera diversa, senza arrivare tra l'altro al punto che dico io, perchè neanche tu Standardoil ...

:o :o :o ... scusa, da quale moderatore ?

Gli unici moderatori della sezione Italiana del forum sono leo72 (Admin), UweFederer (che è anche Uwefed) ed io (gpb01) e ... non mi sembra che nessuno di noi ti abbia preso in giro, quindi ... occhio a ciò che si scrive ...

Per tutti il resto del tuo discorso ... beh, rileggi attentamente il punto 16.1 ed il punto 16.13 del REGOLAMENTO che spiegano la "filosofia" del forum ... si cerca di dare indicazioni, non soluzioni finite ed è compito dell'utente studiare i vari argomenti e capirli per poterli applicare ... ::slight_smile:

Guglielmo

Ho letto male, Standardoil non è un moderatore.

Avete ragione, allora ho sbagliato forum

Ho letto solo il primo pezzo di codice

...
byte pinonoff[] = {13, 11};
// due pin per continuare, ma basta aggiungere...
#define MAXONOFF sizeof pinonoff /sizeof pinonoff[0]
// i tempi dei led on off
unsigned long int ton[MAXONOFF] = {3000, 2500};
unsigned long int toff[MAXONOFF] = {500, 750};
unsigned long int tstart[MAXONOFF];
bool statoonoff[MAXONOFF];
...

Dimmi se ho capito bene;
pinonoff è l'array di pin dei tuoi led, è un array di byte ma pensi di aver bisogno di estenderlo in futuro?
MAXONOFF è la dimensione in byte dell'array diviso per la dimensione del tipo dato dell'array, quindi byte, quindi 1.
Da qui deduco ti sia predisposto ad un ampliamento...

ton sono i tempi di accensione dei 2 led previsti
toff quelli di spegnimento
tstart i millis di riferimento di ogni led.
statoonoff indica se stai accendendo o spegnendo per la direzione del fade.

Ci ho preso?
Poi vado a vedermi il resto.

Devo ammettere che sizeof mi ha fregato, perchè pensavo si dovesse scrivere sempre come sizeof(pinonoff) e non anche con sizeoff pinonoff :o

Maurizio

maubarzi:
… Devo ammettere che sizeof mi ha fregato, perchè pensavo si dovesse scrivere sempre come sizeof(pinonoff) e non anche con sizeoff pinonoff :o

… ha due significati diversi … QUI trovi una spiegazione, oppure … il solito “testo sacro” …

A.7.4.8 Sizeof Operator
The sizeof operator yields the number of bytes required to store an object of the type of its operand. The operand is either an expression, which is not evaluated, or a parenthesized type name. When sizeof is applied to a char, the result is 1; when applied to an array, the result is the total number of bytes in the array. When applied to a structure or union, the result is the number of bytes in the object, including any padding required to make the object tile an array: the size of an array of n elements is n times the size of one element. The operator may not be applied to an operand of function type, or of incomplete type, or to a bit-field. The result is an unsigned integral constant; the particular type is implementation-defined. The standard header <stddef.h> (See appendix B) defines this type as size_t.

Guglielmo

sì, socio, ci hai preso

ho fatto la apparentemente inutile cosa di usare un array di 1 elemento per fare prima (e poi perché un array è un array, si allarga quando si vuole, nel sorgente)

inoltre il pestifero mi ha sganciato UN solo diodo led, quindi fare array di 3 elementi era inutile
al 13 il led built in
al 11 il led aggiunto (perché 11? per il pwm senza spostarlo)

e via andare

poi ci hai azzeccato sui tempi e i modi

il trucco del sizeof array / sizeof array[0] che ti da la dimensione dello array lo ho imparato qui

anche se funziona solo se l'array è visibile ovvero grosso modo solo subito dopo averlo dichiarato, dato che se passi gli array alle funzioni arrivano tutti (s)puntat(or)i

e poi usare la dimensione così calcolata per dichiarare gli array "gemelli", credo si dica "array paralleli"

il tutto per non fare una struttura, che mi sarebbe venuto naturale, ma sarebbe stato difficile da capire

occhio però che sta(v)i ancora guardando la parte dei led ON-OFF

dopo trovi la versione con N (N intero positivo maggiore di 0) led

dopo trovi la parte PWM

ma tanto tutte la stessa minestra sono....

Occhio che per come ho scritto io i led, sia quelli onoff che quelli pwm partono tutti spenti

E poi si accendono coi loro tempi

E quindi fare quello che voleva quello che voleva fare sembra impossibile

Come tutte le espressioni in C si legge da destra

'Quello che voleva fare' identifica una persona

E diventa :

'Quello che voleva fare una persona bene identificata'

Ovvero, dopo aver risolto tutti i riferimenti nel testo, diventa:
Un led si spegne e uno si accende (con o senza pwm) sembra impossibile

Però gli array dei tempi sono tre, non due....
Con uno inizializzato a zero
E c'è anche l'array degli stati...

Necessita applicare la materia grigia

E intanto che aspetto la mia compagnia per la cena aggiungo

Sizeof non ha parentesi perché non è una funzione, ma un operatore, in C classico oltretutto risolto a compiletime

In C++ dato polimorfismo eredita tasse di successione e imposta di bollo diventa un operatore risolto a runtime

Ma sempre operatore è, sempre senza parentesi

Li vedi 'con' le parentesi perché si usa fare una cosa del tipo:

Sizeof (int)

Le parentesi sono quelle del casting , non dell'operatore

OT mode on

Ma questa mi manda in bianco?
Sono davanti al ristorante da mezz'ora
Se non arriva vi tiro un pistolotto sui led lampeggianti che non avete idea...

OT mode off

OT mode on II la vendetta
Ci si era sbagliati sul ristorante, ma se non vi ho fatto il pistolotto.....
OT mode off

Io sono abituato al Java che fino a poco tempo fa era purista sulla notazione ad oggetti, per cui operatori ridotti al minimo, poi si è evoluto per rendere meno prolisso il codice aggiungendo differenti notazioni...
Quindi mi aspettavo la funzione sizeof() e quindi mi ha tratto in inganno inizialmente.
Poi, ovviamente, se compila una ragione ci deve pur essere e quella più facile è che sia un operatore ecc. ecc. ecc.

Quindi con un po' di svitol sugli ingranaggi del cervello, alla fine tra cigolii e polvere rugginosa c'ero arrivato.

Per l'array mono elemento, era chiaro, l'estensione cui pensavo era sul tipo dato byte dell'array

byte pinonoff[] = {13, 11};

Visto che poi ti calcolavi la dimensione in modo dinamico in base al tipo ere già tutto pronto per un eventuale cambio in:

int pinonoff[] = {13, 11};

Qualora il numero di pin fosse aumentato tanto da non stare più dentro un byte.

Io, mi ero riferito al secondo codice postato, che aveva già un array di due elementi.

Comunque, l'esempio con un array monoelemento non mi aveva turbato minimamente, anzi, è un modo per far vedere come il caso monoelemento si possa gestire facilmente con la struttura multielemento, che poi era lo scopo del tuo codice ;D

L'unica cosa che non mi è piaciuta per una propensione intrinseca mia, è l'uso della libreria FadeLed.h
Ma solamente perchè non ritengo di dover scomodare una libreria per un compito come questo.
In genere, su compiti così semplici, ci metto meno a implementarmi la cosa da solo che a studiarmi e capire la libreria.

Per le struct, io purtroppo non le ho ancora imparate, ma appena ho un po' di tempo per darci un'occhiata seriamente mi ci tuffo perchè rendono più compatta e chiara la struttura dati invece di avere pezzi sparsi che poi ti devi ricordare che sono accoppiati.

Guglielmo: grazie per i rif. Io lavorando a tempo perso sul C sono facile all'arrugginimento e al dimenticamentare i dettagli del "sacro testo" che mi sono, si procurato tempo fa e parzialmente letto, ma anche parzialmente dimenticato :-[
Il forum, su questo, è un ottimo disossidante!

Maurizio

OK, socio, scusa se ho dubitato

adesso è chiaro

per le strutture: sono "magiche" per fare lavori come questo
comode, ben descrittive, passabili come argomento sia in forma di variabile che in forma di puntatore

se non fosse che ero deciso a scrivere una cosa leggibile avrei usato una struttura fin da subito

anzi, lo faccio adesso

eccolo, modificato al volo per usare un array di matrici invece che N array paralleli

// di Nelson-StandardOil
// IDE 1.8.10
// Progetto: albe tramonti e lampi
// Scopo:
// Data inizio lavori: 21/09/2020
// versione del 22-> solo on off, ma in una struttura

// la struttura completamente descrittiva dei led on off
typedef struct
{

   byte pin; // il piedino
   unsigned long int ton; // tempo di ON per i led in ON/OFF
   unsigned long int toff; // tempo di OFF per i led in ON/OFF
   unsigned long int tstart;// ultimo istante di azionamento per i led ON/OFF
   bool statoonoff;// stato attuale dei led ON/OFF

} onoff;

onoff matrice[] = {{13, 3000, 500}, {11, 500, 3000, 0, 1}};


#define MAXONOFF sizeof matrice / sizeof matrice[0]


void setup(void)
{
   // abilito i pin in output
   for (byte i = 0; i < MAXONOFF; i++)
   {
      pinMode(matrice[i].pin, OUTPUT);
   }
}

void loop(void)
{
   unsigned long int milia = millis();

   for (int i = 0; i < MAXONOFF; i++)
   {
      if (matrice[i].statoonoff)
      {
         if ((milia - matrice[i].tstart) > matrice[i].ton)
         {
            // accendo
            digitalWrite(matrice[i].pin, 0);
            matrice[i].tstart = milia;
            matrice[i].statoonoff = 0;
         }
      }
      else
      {
         if ((milia - matrice[i].tstart) > matrice[i].toff)
         {
            // spengo
            digitalWrite(matrice[i].pin, 1);
            matrice[i].tstart = milia;
            matrice[i].statoonoff = 1;
         }
      }
   }
}

come tutti i programmi modificati al volo ha qualche incertezza, tipicamente i nomi di variabile non sono granchè

chissa’ poi come mai l’inizializzazione del scondo led è “differente” da quella del primo…

ah, socio, va da se che se ti metti a usare la macro X poi queste inizializzazioni, invece che sembrare tediose cominciano ad essere una passeggiata…

mi sembra l’anno scorso ne avevo scritto, della macro X

ultima cosa, invece di richiamare la millis() tutte le volte che serve ho usato una variabile di appoggio, anche quì c’é la sua ragione, ma che non centra direttamente ne con le struct ne con i differenti lampeggi

ecco, magari un po’ con quello centra, specie in un ottica di PWM a manetta

Si, le struct non sono una cosa difficile, quello che mi manca è un approfondimento sulla sintassi, giusto per capire come referenziare gli elementi e se ci sono altre cose particolari da tenere in considerazione.
Per il resto non c'è nulla di complicato, o almeno non mi aspetto che ci sia.
In java si usano le classi bean per fare cose analoghe.

Riguardo la variabile di appoggio per millis, la uso anche io perchè mi piace gestire tutto il giro di loop in modo atomico, sotto questo punto di vista, con un unico riferimento temporale.
E anche quando aggiorno il ts di riferimento, non richiamo ulteriormente millis() ma tendenzialmente uso il valore dell'intervallo per avere un cadenzamento fisso anche se ci sono ritardi nell'esecuzione del codice.

Ok, sono cose che non cambiano nulla nella stragrande maggioranza dei casi, ma...

Maurizio

bravo centrato in pieno vinta bambolina

ma devo starci attento con te, sei troppo bravo, mi sbanchi

bando agli scherzi, che sei uno "forte" lo sapevo

se vai a cercare il mio "albe ed aurore" trovi forse un esempio interessante di come inizializzare