I started with making it just show random colors, but then thought I could do better. The code below chooses a random Saturation and Hue, then turns the brightness all the way up, all the way down, and then starts over again.
//these have to be attached to PWM pins
int REDPin = 6;
int GREENPin = 5;
int BLUEPin = 3;
int vIncrement = 5;
unsigned int h = 0, s = 0, v = 0; //hsv
unsigned int r, g, b, hh, c, x, m;
void setup()
{
pinMode(REDPin, OUTPUT);
pinMode(GREENPin, OUTPUT);
pinMode(BLUEPin, OUTPUT);
randomSeed(analogRead(0));
Serial.begin(9600);
}
void loop()
{
v = v + vIncrement;
if (v <= 0){
h = random(0, 360);
hh = h / 60;
s = random(0, 255);
}
if (v <= 0 || v >= 255) // reverse the direction of the fading
{
if (v > 0x10000) //handle overflow - unsigned int
v = 0;
vIncrement = -vIncrement;
v = constrain(v, 0, 255);
}
c = (v * s) / 256;
x = (c * (60 - abs(h % 120 - 60))) / 60;
m = v - c; // 44
switch(hh){
case 0:
r = c + m;
g = x + m;
b = m;
break;
case 1:
r = x + m;
g = c + m;
b = m;
break;
case 2:
r = m;
g = c + m;
b = x + m;
break;
case 3:
r = m;
g = x + m;
b = c + m;
break;
case 4:
r = x + m;
g = m;
b = c + m;
break;
case 5:
r = c + m;
g = m;
b = x + m;
break;
default:
r=g=b=m;
}
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
analogWrite(REDPin, r);
analogWrite(GREENPin, g);
analogWrite(BLUEPin, b);
delay(20); // wait for 20 milliseconds to see the dimming effect
}
There are lots of algorithms out there for converting HSV to RGB, but I didn't like all the converting between float and int. This one does it only using unsigned ints (my Arduino uses 16-bit numbers, so I needed them unsigned to prevent overflow). It was based on the Wikipedia HSV page.
(For this algorithm, S, V, R, G, B are in [0, 255] and H is in [0, 360])
No comments:
Post a Comment