Stessa istruzione su 3 pin diversi in contemporanea

Buongiorno a tutti, dopo aver cercato ovunque chiedo a voi, sono un neofita e dovrei fare un albero di Natale con 3 Pin pwm che comandano un bc337. Il mio problema è che vorrei dimmerare i 3 pin in accensione e spegnimento contemporaneamente. Da quello che ho trovato lo posso fare con l’istruzione for, ma in questo caso lavoro su di un pin alla volta.
Come posso dimmerare assieme i 3 pin simultaneamente ?

Grazie in anticipo
Alex

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

... relativamnete alla tua domanda, semplicemente NON puoi.

Se fossero stati tre normali pin digitali da mandare assieme HIGH o LOW, la cosa era fattibile, ma qui ci sono di mezzo timers, interrupts, ecc. ed inoltre, pin a coppie, usano per il PWM timers diversi i quali richiedono, ovviamente, ciascuno la sua programmazione.

Guglielmo

Ma pensi davvero di accorgerti del ritardo tra eventi che avvengono a distanza di poche centinaia di nanosecondi?

Che cosa intendi per "contemporaneamente"? Se non ti riferisci alla fase, puoi farlo senza problemi.

Datman:
Che cosa intendi per "contemporaneamente"? Se non ti riferisci alla fase, puoi farlo senza problemi.

Lui vuole cambiare il valore del PWM sui tre pin simultaneamnete, come si fa per gli I/O digitali (... scrivendo direttamente sulla porta) e questo NON puoi farlo.

Guglielmo

Credo che voglia semplicemente fare uno sfumo progressivo da uno all'altro dei tre.
Basta fare un solo ciclo FOR e pilotare i 3 PWM sfasando i valori di 120°.

Mah, lui testualmente dice ...

ca666ro:
...Il mio problema è che vorrei dimmerare i 3 pin in accensione e spegnimento contemporaneamente. Da quello che ho trovato lo posso fare con l’istruzione for, ma in questo caso lavoro su di un pin alla volta.
Come posso dimmerare assieme i 3 pin simultaneamente ?

... quindi mi sembra di leggere che lui volesse proprio evitare la FOR ... cosa che NON è possibile con il PWM.

Guglielmo

Mah... Per sfumare gradualmente fra 3 LED, questo lo scrissi tempo fa e funziona:

int Z[69]={1,3,5,8,10,16,20,23,27,30,40,50,63,80,90,105,120,135,148,158,170,180,200,220,240,255,240,220,200,180,170,158,148,135,120,105,90,80,63,50,40,30,27,23,20,16,10,8,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte nR;
byte nG;
byte nB;

void setup(){}

void loop()
{
for(nR=0;nR<69;nR++)
  {
  analogWrite(9,Z[nR]);

  nG=nR+23; if(nG>68) nG-=69;
  analogWrite(10,Z[nG]);

  nB=nR+46; if(nB>68) nB-=69;
  analogWrite(11,Z[nB]);

  delay(10);
  }
}

Datman ... non ci capiamo, NON si sta discutendo di come sfumare, si sta discutendo sul fatto che NON esiste una possibilità di modifica del PWM simultanea su 3 pin (una unica istruzione) come invece esiste per un normale I/O su più pin.

Quello per cui aspettiamo invece una risposta è la giusta osservazione che gli ha fatto SukkoPera al post #3 ... perché questa necessità quando ad occhio nudo la cosa NON è apprezzabile ?

Guglielmo

Buongiorno a tutti, dopo aver cercato ovunque chiedo a voi, sono un neofita e dovrei fare un albero di Natale con 3 Pin pwm che comandano un bc337.

Quanto detto lascia intuire l'uso di librerie arduino che coinvolgono i timer hardware Timer1 e Timer2, in quanto Timer0 è impiegato dal core arduino per la gestione di millis().

Impiegando analogWrite() (o il metodo messo a disposizione di ogni libreria per la gestione dei sopra nominati timer) è proprio impossibile compiere contemporaneamente 3 di queste funzioni.

Anche svincolandosi dalle librerie standard, operando cioè sui tre registri di cui uno (Timer1) è ampio 16 bit saranno necessarie tre assegnazioni, restando ottimisti e dando per scontato che ogni operazione di assegnazione possa essere eseguita in un solo ciclo di clock (della durata di 1/16000000 secondi), 62,5ns moltiplicati per 3.

Si tratta di 187ns impiegati per modificare i tre PWM, ma bada che per semplificare non ho tenuto conto di possibili (e al momento non deducibili) cause che possono dilatare i tempi teorici. Ciò dimostra che è impossibile cambiare valore a 3 registri in un solo ciclo di clock.

Se invece diversamente hai approntato un algoritmo che genera il PWM via software, le prestazioni peggiorano enormemente, mettendo in evidenza un gioco di luci totalmente fuori sincronismo.

Per togliere di mezzo ogni dubbio sarebbe utile fornirci maggiore dettaglio esplicativo, oltre ad allegare anche il codice con cui stai sperimentando.

Ciao.

Eccomi qui, scusate il ritardo a rispondervi.
Innanzitutto chiedo scusa per la presentazione che ho appena provveduto a fare e ringrazio tutti per le vostre risposte.
Io sono nuovo del mondo di Arduino e programmazione percui, ho una mia idea di cosa sia una libreria, conosco qualche semplice istruzione, oppure spulcio in giro come per la realizzazione di questo progetto.
Faccio chiarezza al mio quesito:
Quello che voglio fare è un fade on e/o un fade off contemporaneamente su tre pin, per poter dare un gioco di luce di Led che aumentano e diminuiscono la loro luminosità contemporaneamente. Con l'istruzione for posso farlo un pin per voltare fin qua mi va bene, ma per farlo tutti e tre a assieme? Una soluzione che nella mia ignoranza mi è venuta in mente è quella di fare vari cicli for e aumentare per esempio da 0 a 50 led1, poi Led 2, poi Led 3. Successivamente da 50 a 100 Led 1poi Led 2 e poi Led 3 fino a portarli a 255 tutti e tre. Ovviamente è da provare, il codice lo scriverò in questi giorni.
Pensate che possa essere una soluzione?

P.S. X Guglielmo, grazie dei link, nel frattempo li studio.

Se avete altri link giratemeli pure, il tempo è poco in questo periodo ma pian piano li guardo.

Grazie a tutti

Secondo me non ti è ben chiara la velocità di esecuzione di Arduino. Prova come dici e vedrai :).

Guarda e prova quello che ho pubblicato. I tre LED vanno collegati, ciascuno tramite 330~470 ohm o più, ai pin 9, 10 e 11. Variando il delay(10) alla fine puoi modificare la velocità.

Ma, scusa, se quello che vuoi fare e' cambiare la luminosita' di tre led "contemporaneamente", per quale motivo vuoi usare tre pin ? ... non sarebbe piu semplice collegare i led (ovviamente ognuno con la propria resistenza) in parallelo, e poi usare un transistor pilotato da un'unico pin ?

Se invece intendi cambiare insieme ma con livelli diversi, allora nel tuo ciclo for dai ai pin i valori di tutte e tre le uscite per ogni ciclo ... il ritardo di commutazione sara' semplicemente quello del tempo di esecuzione di un'istruzione ...

Certo in quel modo non puoi usare l'indice del ciclo per dare il valore ... dovrai crearti un'array, magari a tre elementi, o piu semplicemente tre array distinti, che contengano tutti i valori che le uscite dovranno avere per ogni ciclo del for, ad esempio (semplificando al massimo),

arr1 -> 1 2 3 4 5 4 3 2
arr2 -> 3 4 5 4 3 2 1 2
arr3 -> 5 4 3 2 1 2 3 4

poi nel tuo for potrai scriverci 3 assegnazioni consecutive, una per ogni canale del PWM, a cui passerai il valore del rispettivo array con l'indice del for ... in questo modo, e' vero, le commutazioni non saranno istantaneamente identiche, ma saranno comunque in ritardo solo del tempo necessario ad eseguire l'operazione, poche decine di microsecondi fra una e l'altra, quindi assolutamente indistinguibili ad occhio ...

Basta un array solo e leggerlo con indici diversi. Per ottenere una variazione progressiva, però, non basta mettere valori che variano linearmente da 0 a 255! Comunque, poi, si noterà il salto fra spento e il primo valore (da spento ad acceso) e anche per un altro o due.

Si, non intendevo di usare quei valori, ma solo come esempio generico ... :wink:

Eccomi qua sempre in ritardo, grazie a tutti per le risposte. In effetti non conoscendo il mondo Arduino ho provato a sperimentare e con il ciclo for riesco a fare quello che volevo. Il problema è che se alla fine metto un ++ sembra infinito, quasi che si sia bloccato mettendo dei valori più alti si vede lo stacco della progressione che dura comunque circa 3 secondi ogni ripetizione del ciclo for.

Datman, dal tuoi post:
Credo che voglia semplicemente fare uno sfumo progressivo da uno all'altro dei tre.
Basta fare un solo ciclo FOR e pilotare i 3 PWM sfasando i valori di 120°.

Che significa? come si fa?

Il post successivo hai messo un codice, riusciresti a spiegarmelo per capire la logica?

Ora in pratica il mio problema è eliminare il salto del ciclo in maniera che la sfumatura in accensione e spegnimento sia più fluida e veloce.

Grazie a tutti come sempre.

Ps. Gli Array so che esistono ma non so bene cosa sono... devo ancora cimentarmi nell'argomento...

Ecco il codice commentato:

// Faccio un array contenente 69 valori da assegnare in successione alle uscite PWM per avere una variazione di luminosità gradevole (li ho aggiustati sperimentalmente):
int Z[69]={1,3,5,8,10,16,20,23,27,30,40,50,63,80,90,105,120,135,148,158,170,180,200,220,240,255,240,220,200,180,170,158,148,135,120,105,90,80,63,50,40,30,27,23,20,16,10,8,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte nR;
byte nG;
byte nB;

void setup(){} // Non c'è nulla

void loop()
{
for(nR=0;nR<69;nR++) // Per nR da 0 a 68:
  {
  analogWrite(9,Z[nR]); // Pilota il PWM dell'I/O 9 con i valori dell'array

  nG=nR+23; if(nG>68) nG-=69;
  analogWrite(10,Z[nG]); // Pilota il PWM dell'I/O 10 prendendo i valori dell'array sfasati di 23 elementi (arrivato all'ultimo elemento, ricomincia dal primo)

  nB=nR+46; if(nB>68) nB-=69;
  analogWrite(11,Z[nB]); // Pilota il PWM dell'I/O 11 prendendo i valori dell'array sfasati di 46 elementi (arrivato all'ultimo elemento, ricomincia dal primo)

  delay(10); // Attende 10mS prima di ricominciare con il valore successivo di nR.
  } // Finito il for(), ripete a partire da nR=0.
}

Grazie mille Datman, ora è più chiaro.
Grazie a tutti e buone feste.