Controllo di led RGB in HSV
Come molti di voi, anche io in passato ho avuto la curiosità di “giocare” con i primi led RGB, e come credo tutti possiate aver constatato, il problema principale nell’utilizzo di questi led è la generazione di colori indipendentemente dalla luminosità che con l’assegnazione diretta dei valori RGB non è certo semplice ed intuitiva, cosa che invece risulta estremamente facile con il sistema di descrizione del colore HSV ovvero:
Hue (tonalità) Saturation (saturazione) Brightness (luminosità):

In pratica definendo il valore H (nel range da 0° a 360°) si definisce il colore; quindi con S la quantità in percentuale (valore da 0 a 1) di colore presente, e con B la percentuale (valore da 0 a 1) dell’intensità luminosa.
Ed agendo ad esempio sul solo valore B sarà possibile far accendere e spegnere gradualmente il led mantenendo ad ogni livello di luminosità il colore prescelto 🙂
Così, due anni or sono, scrissi questo semplice algoritmo per Xduino (vedi post originale):
//--- prototipo funzione
void HSVtoRGB( float h, float s, float v );
struct tipo_rgb{ //definisce la struttura dati RGB
unsigned char r; //red - rosso
unsigned char g; //green - verde
unsigned char b; //blue - blu
}
led[2], pin[2]; //definisce i due array utilizzati: i valori RGB e le relative uscite
//variabili di uso generale
byte x;
int h = 0;
float s, v;
void setup()
{
pin[0].r = 3; //assegna le uscite ai colori del primo led
pin[0].g = 6;
pin[0].b = 5;
pin[1].r = 9; //assegna le uscite ai colori del secondo led
pin[1].g = 11;
pin[1].b = 10;
for( x=0; x<2; x++){ //imposta i pin come uscite pinMode(pin[x].r, OUTPUT); pinMode(pin[x].g, OUTPUT); pinMode(pin[x].b, OUTPUT); } } void loop() { (h > 359) ? h = 0 : h++; //ciclo della tonalita
v = 0.5; //luminosita
s = 1; //saturazione
HSVtoRGB( 0, (float)(h), s, v );
HSVtoRGB( 1, (float)(360 - h), s, v );
for( x=0; x<2; x++){ //aggiorna le uscite
analogWrite(pin[x].r, 255 - led[x].r);
analogWrite(pin[x].g, 255 - led[x].g);
analogWrite(pin[x].b, 255 - led[x].b);
}
delay(10);
}
/* HSVtoRGB
(cc) 2008-2010 Kokiua (alias L.M.) from Sorbolo (Parma) - Italy
Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/
algoritmo rielaborato partendo da da http://www.cs.rit.edu/~ncs/color/t_convert.html
da RGB a HSB (Hue/Tonalita' - Saturation/Saturazione - Brightness/Luminosita')
HSB diventa HSV definendo Brightness = Value per distinguere la variabile B di RGB
i valori RGB che tornano sono nel range da 0-255
i valori in entrata sono:
h = [0.0-360.0] ( Tonalita' in gradi)
s = [0.0-1.0] (Saturazione in % dove 1 = 100%)
v = [0.0-1.0] (Luminosita' in % dove 1 = 100%)
*/
void HSVtoRGB( unsigned char x, float h, float s, float v )
{
int i;
float f, p, q, t, r, g, b;
if( s == 0 ) {
r = g = b = v; // achromatic (grey)
return;
} else {
h /= 60; // sector 0 to 5
i = floor( h );
f = h - i; // factorial part of h
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
switch( i ) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
default: r = v; g = p; b = q; break; // case 5:
}
}
led[x].r = 255 * r; //converto i valori RGB dal range 0.0-1.0 a 0-255
led[x].g = 255 * g;
led[x].b = 255 * b;
}
N.B. i led che ho utilizzato (2 ma possono essere chiaramente di più visto l’uso dell’array) sono a catodo comune e quindi la logica è invertita (per questo emetto il valore 255 – x).
Chiaramente sarà possibile “legare” uno o più parametri di controllo del colore ad ingressi analogici (al quale avremo collegato un sensore, un potenziometro, o altro) con grande semplicità, come in questo esempio:
//loop centrale modificato
void loop()
{
h = (float)((float)analogRead( 0 ) * (360.0L/1024.0L) ); //assegnazione del valore analogico letto nel pin 0 al parametro h (tonalità)
v = 0.5; //luminosita
s = 1; //saturazione
HSVtoRGB( 0, (float)(h), s, v );
HSVtoRGB( 1, (float)(360 - h), s, v );
for( x=0; x<2; x++){ //aggiorna le uscite
analogWrite(pin[x].r, 255 - led[x].r);
analogWrite(pin[x].g, 255 - led[x].g);
analogWrite(pin[x].b, 255 - led[x].b);
}
delay(10);
}
http://www.kokiua.com/2010/08/02/nuovo-tutorial-2/Tutorialcolore,hsv,Led,rgbCome molti di voi, anche io in passato ho avuto la curiosità di 'giocare' con i primi led RGB, e come credo tutti possiate aver constatato, il problema principale nell'utilizzo di questi led è la generazione di colori indipendentemente dalla luminosità che con l'assegnazione diretta dei valori RGB non è...kokiua
[email protected]Administratorkokiua
Lascia un commento
Devi essere connesso per inviare un commento.