Con Arduino il risparmio è senza dubbio assicurato dal suo costo contenuto. Quello che in alcuni progetti potrebbe tornarti utile sono i pin destinati alla gestione dei segnali PWM in numero inferiore rispetto ai pin di cui potresti aver bisogno.
In particolare se il tuo progetto è complesso come ad esempio un robot domestico, un braccio meccanico o un controllo per le luci della tua abitazione i 6 pin PWM dovrai utilizzarli per i servomotori o per il controllo dei motori in CC e se volessi anche aggiungervi qualche luce RGB sarebbero insufficienti.
Allo stesso modo se desideri utilizzare Arduino per un lampadario controllando la luminosità dei led RGB con il metodo visto fino ad oggi potresti controllare solo due led.
Ci sono delle librerie che ti permettono di utilizzare anche le altre uscite digitali con segnali simili al PWM, tuttavia il risultato è meno soddisfacente.
Ecco perchè trovandomi in questo problema ho escogitato questo metodo: utilizzando dei led RGB a catodo comune puoi collegare il terminale comune ( negativo o massa ) ad un pin di tipo PWM e i 3 cavi, uno per il rosso, uno per il verde e uno per il bleu puoi collegarli a 3 pin di tipo digitale ma non PWM, ad esempio i pin 2,4,7.
Il concetto su cui si basa questo sistema è quello di pilotare i led in modo che a definire se un colore sia acceso o spento sia il terminale positivo del led collegato al pin digitale non PWM e per definire l0intensità di quel colore potrai agire sul pin PWM in modo inverso a come faresti normalmente: ad esempio per avere la luminosità massima del rosso porterai ad HIGH il pin 2 ( a cui è collegato l’anodo del led rosso) e a 0 o LOW il catodo comune del led RGB, per diminuire l’intensità luminosa non dovrai dar altro che aumentare il valore sul pin PWM fino a 255 ( valore massimo PWM per Arduino ) in questa situazione Arduino provvederà a inviare i +5v al catodo che quindi non sarà in conduzione, lasciando il led spento.
Spero di essere stato chiaro sul ragionamento che mi ha portato a questa conclusione. Con questo metodo puoi pilotare fino a 6 led RGB in dissolvenza collegando ciascun catodo ad un pin di tipo PWM di Arduino (3,5,6,9,10,11) e gli anodi ai 3 pin visti su: 2 per il rosso, 4 per il verde e 7 per il bleu.
Ho introdotto in questo modo un’altro concetto, quello di matrice di accensione, in pratica ecco lo schema che intendo:
Come vedi puoi decidere quale led accendere e con quale intensità rispettando la seguente matrice:
pin NO PWM | valore | pin PWM | valore | esito | |
led 1 rosso | 2 | HIGH | 3 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 1 verde | 4 | HIGH | 3 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 1 bleu | 7 | HIGH | 3 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 2 rosso | 2 | HIGH | 5 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 2 verde | 4 | HIGH | 5 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 2 bleu | 7 | HIGH | 5 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 3 rosso | 2 | HIGH | 6 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 3 verde | 4 | HIGH | 6 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 3 bleu | 7 | HIGH | 6 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 4 rosso | 2 | HIGH | 9 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 4 verde | 4 | HIGH | 9 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 4 bleu | 7 | HIGH | 9 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 5 rosso | 2 | HIGH | 10 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 5 verde | 4 | HIGH | 10 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 5 bleu | 7 | HIGH | 10 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 6 rosso | 2 | HIGH | 11 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 6 verde | 4 | HIGH | 11 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% | |||
led 6 bleu | 7 | HIGH | 11 | 0 | acceso 100% |
HIGH | 125 | acceso 50% | |||
HIGH | 255 | spento 0% |
In pratica ciascun colore è pilotato dalla commutando tra il pin NO PWM ad HIGH ed il pin PWM ad un valore definito tra 0 e 255 dove 0 accende il led alla massima potenza e 255 lo spegne ( 0% ).
Se volessi accendere il led 5 verde a 1/4 di intensità dovresti commutare il pin 4 a HIGH e il pin 10 a 64 ( 256/4 ) lasciando a LOW i pin 2 e 7 ed a 255 i pin 3,5,6,9 e 11 otterrai che solo il led 5 verde è acceso ed alla luminosità desiderata.
Lo sketch che ti propongo è molto più semplice della matrice, controlla un solo led, il led 1 con i suoi 3 terminali, accendendo in sequenza i 3 colori rosso, verde e bleu fino alla loro intensità massima e poi spegnendoli nuovamente in dissolvenza.
int brightness = 255; // how bright the LED is int fadeAmount = 5; // how many points to fade the LED by int pinLed[]={2,4,7}; int pinLedPWM=5; int currLed=0; void setup() { for (int i = 0; i<=2; i++) { pinMode(pinLed[i], OUTPUT); } pinMode(pinLedPWM, OUTPUT); } void loop() { digitalWrite(pinLed[currLed],HIGH); analogWrite(pinLedPWM, brightness); brightness = brightness - fadeAmount; if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount; } if (brightness == 255) { currLed++; if ( currLed > 2 ) currLed = 0; for (int i = 0; i<=2; i++) { digitalWrite(pinLed[i],LOW); } } delay(30); }
Lo sketch è ripreso sull’esempio Fade presente nell’IDE Arduino ( File -> Examples -> Basics -> Fade ) e adattato per un led RGB.
linee 01 e 02: definisci due variabili di tipo integer in cui la prima memorizza il valore di luminosità iniziale, nel nostro caso spento (255) e la seconda il valore di step con cui far aumentare o calare la luminosità del led;
linea 04: definisci un array di tipo integer in cui memorizzi i pin relativi al colore rosso, verde e bleu; se volessi cambiare la sequenza di accensione non dovresti far altro che invertire i valori in questo array o collegare i led a pin differenti: esempio il bleu al pin 2, il rosso al pin 4 e il verde al pin 7;
linea 05: definisci a quale pin PWM colleghi il catodo comune dei led, non dimenticare la resistenza di limitazione per non bruciare il led, io ho utilizzato una 470Ω;
linea 07: imposta un contatore con l’indice rispetto all’array della linea 04 da cui partire, in questo sketch di esempio parti dal primo valore, posizione 0;
linea 10: definisci un ciclo da 0 a 2, valore massimo dell’array pinLed e per ciascun valore dell’array imposta la modalità di utilizzo del pin come OUTPUT, utilizza il comendo pinMode(pin, mode);
linea 11: fai la stessa cosa vista alla linea 10 per il pin PWM;
linea 15: porta ad HIGH il valore del pin non PWM corrente, alla prima esecuzione dello sketch il valore di currLed è 0, impostato alla linea 07, per cui il pin denominato pinLed[currLed] è il pin 2 a cui è collegato il terminale del led rosso;
linea 16: invia il segnale PWM al pin pinLedPWM mediante il comento analogWrite(pin,value), al primo ciclo del loop() il valore di brightness è 255 impostato alla linea 01;
linea 18: calcola il valore di brightness dopo averlo inviato, il valore viene ricavato da una semplice sottrazione: (valore iniziale – valore di step) -> (255 – 5) = 250 … domo n cicli il valore di brightness sarà 255 – (5 * n);
linee 20-22: con una condizione di tipo IF controlla che il valore di brightness non diventi inferiore a 0 o superiore a 255 in tal caso inverte il segno di fadeAmount in modo che l’operazione alla linea 18 dal ciclo successivo inverta il suo risultato, se ad esempio l’ultimo ciclo di loop() ha determinato (5 -5) = 0 invertendo fadeAmount al ciclo successivo avrai (0 – (-5)) = 5 allo stesso modo se brightness vale 255 l’operazione successiva sarebbe (255 – 5) = 250;
linee 24-26: un ulteriore controllo sul valore di brightness quando questo arriva a 255 ti consente di passare al led successivo, in pratica se brightness vale 255 vuol dire che hai raggiunto lo spegnimento del led corrente ( ad esempio il pinLed[0]) per cui incrementi il contatore currLed di 1 e verifichi al contempo che currLed non sia mai superiore a 2 essendo 3 i valori dell’array pinLed;
linea 28: sebbene all’interno della condizione presente alla linea 24 è una linea particolarmente importante, in quanto con un semplice ciclo da 0 a 2 spegne tutti i led collegati ai pin 2,4 e 7; questo passaggio è importante perché così facendo indipendentemente dal valore di brightness ottieni il reset di tutti i colori, è una frazione di secondo (vedi line 29) ed avviene solo quando la luminosità è già nulla per cui impercettibile, ma ti garantisce che solo il led corrente sarà riacceso e pilotato con il segnale PWM grazie alla linea 15;
linea 29: imposta un tempo di attesa tra un ciclo ed il successivo di 30 millisecondi, utili a dare un effetto alquanto realistico alla dissolvenza dei led.
Ed ecco un video dove puoi vedere lo sketch all’opera con uno e con due led contrapposti e sostenuti da un cilindro di carta:
Buon divertimento.
10 commenti
Vai al modulo dei commenti
Io ho usato un metodo un po più complicato:
ho usato 9 uscite arduino per pilotare 3 led x 3 colori ( avevo i led normali non gli RGB ma il risultato è uguale)
raccogliendo tutti i katodi x colore, facendoli passare attraverso 3 C-MOS di potenza ( uno x il rosso , uno x il giallo , e uno x il verde) nel mio caso ho usato gli IRF 640
e questi ( come avrai capito ) comandati dalle uscite PWN arduino
con questo metodo accendo i led con le uscite ( 2,3,4,5,6,7,8,12,13) ma li devo “accendere ” con un uscita PWN arduino ( io ho usato 9 rosso 10 giallo 11 verde)
quindi ho usato i MOS come un filtro per fare passare solo il segnale desiderato.
stesso metodo si potevano usare anche dei transistor collegando i katodi (- ) dei diodi con il connettore dei transistor e l’ emettitore a 0
Autore
Si, hai ragione un po’ complesso come metodo, ma se funziona è comunque una strada.
Certo non posso dire che la tua soluzione rispetti il titolo dell’articolo: “Arduino risparmiare pin PWM” 🙂 ma è interessante.
Mauro
Ciao Mauro,
e’ la prima volta che scrivo e innanzi tutto vorrei ringraziarti e farti i complimenti per la chiarezza e l’utilita’ dei tuoi articoli.
Relativamente a questo intelligente algoritmo per pilotare piu’ led RGB, mi sembra di capire che non sia possibile accendere ciascun led su un colore ottenuto dalla combinazione dei colori fondamentali che qui possono solo essere accesi o spenti. Io vorrei poter tenere accesi contemporaneamente 4 led RGB su 4 colori diversi che non siano solo rosso verde e blu ma anche giallo, celeste, viola etc., dando piu’ o meno potenza a ciascun colore di ciascun led indipendentemente. Credo che per ottenere questo, sarebbero necessari obbligatoriamente 12 pin pwm,
Ti ringrazio in anticipo se potrai darmi qualche dritta.
Saluti,
Aldo
Autore
Ciao Aldo,
si per fare quello che desideri hai bisogno di 12 pin PWM di base ( 3 colori X 4 Led ).
Tuttavia se tu volessi poi regolare l’intensità di ciascun led fissato il colore potresti usare un metodo simile a questo ma ti occorrerebbero altri 4 pin PWM da connettere al catodo di ciascun led.
Mauro
Ciao Mauro,
non ho la necessita’ di regolare l’intensita’ luminosa.
Il progettino che ho in mente e’ una pulsantiera per giochi a quiz con 4 pulsanti che mostri anche l’ordine di prenotazione dei giocatori. Volevo aggiungere la possibilita’ di far scegliere il colore del proprio led a ciascun giocatore tramite 3 potenziometri,
Ho ordinato dalla Texas Instruments, come free samples, 3 integrati tlc5940nt che dovrebbero permettere di moltiplicare il numero di pin pwm.
Spero di riuscire a farli funzionare.
Grazie, saluti,
Aldo
Autore
Ciao Aldo,
sono certo che c’è la farai con tanta buona volontà.
Mauro
Ciao Mauro, progetto molto interessante.
Maoltre ai tre colori in dissolvenza, si possono creare altri colori mantenendo fermo il layout??
Come fare ?
Autore
Ciao Maurizio,
non ho compreso cosa intendi.
Buongiorno, mi stavo chiedendo se questo esempio è possibile applicarlo a delle strisce led che illuminano i gradini di una scala.
Sono 9 strisce, fadein da 0 a 255 sul primo gradino, poi sul secondo e via di conseguenza.
Grazie mille
Autore
Ciao Gabriele,
sicuramente puoi adattarlo, certamente avrai bisogno di alcuni driver di controllo RGB per le strisce di led.