Created
March 17, 2013 12:11
-
-
Save vshymanskyy/5181274 to your computer and use it in GitHub Desktop.
Arduino sketch for cycling through HSV space with an RGB diode.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
RGB | |
*/ | |
typedef class rgb | |
{ | |
public: | |
float r; // percent | |
float g; // percent | |
float b; // percent | |
public: | |
rgb(void): r(0), g(0), b(0) {} | |
rgb(float _r, float _g, float _b): r(_r), g(_g), b(_b) {} | |
} rgb; | |
typedef class hsv | |
{ | |
public: | |
float h; // angle in degrees | |
float s; // percent | |
float v; // percent | |
public: | |
hsv(void): h(0), s(0), v(0) {} | |
hsv(float _h, float _s, float _v): h(_h), s(_s), v(_v) {} | |
} hsv; | |
struct hsv rgb2hsv(struct rgb& in) | |
{ | |
hsv out; | |
float min, max, delta; | |
min = in.r < in.g ? in.r : in.g; | |
min = min < in.b ? min : in.b; | |
max = in.r > in.g ? in.r : in.g; | |
max = max > in.b ? max : in.b; | |
out.v = max; // v | |
delta = max - min; | |
if( max > 0.0 ) { | |
out.s = (delta / max); // s | |
} else { | |
// r = g = b = 0 // s = 0, v is undefined | |
out.s = 0.0; | |
out.h = NAN; // its now undefined | |
return out; | |
} | |
if( in.r >= max ) // > is bogus, just keeps compilor happy | |
out.h = ( in.g - in.b ) / delta; // between yellow & magenta | |
else | |
if( in.g >= max ) | |
out.h = 2.0 + ( in.b - in.r ) / delta; // between cyan & yellow | |
else | |
out.h = 4.0 + ( in.r - in.g ) / delta; // between magenta & cyan | |
out.h *= 60.0; // degrees | |
if( out.h < 0.0 ) | |
out.h += 360.0; | |
return out; | |
} | |
struct rgb hsv2rgb(struct hsv& in) | |
{ | |
float hh, p, q, t, ff; | |
long i; | |
rgb out; | |
if(in.s <= 0.0) { // < is bogus, just shuts up warnings | |
if(isnan(in.h)) { // in.h == NAN | |
out.r = in.v; | |
out.g = in.v; | |
out.b = in.v; | |
return out; | |
} | |
// error - should never happen | |
out.r = 0.0; | |
out.g = 0.0; | |
out.b = 0.0; | |
return out; | |
} | |
hh = in.h; | |
if(hh >= 360.0) hh = 0.0; | |
hh /= 60.0; | |
i = (long)hh; | |
ff = hh - i; | |
p = in.v * (1.0 - in.s); | |
q = in.v * (1.0 - (in.s * ff)); | |
t = in.v * (1.0 - (in.s * (1.0 - ff))); | |
switch(i) { | |
case 0: | |
out.r = in.v; | |
out.g = t; | |
out.b = p; | |
break; | |
case 1: | |
out.r = q; | |
out.g = in.v; | |
out.b = p; | |
break; | |
case 2: | |
out.r = p; | |
out.g = in.v; | |
out.b = t; | |
break; | |
case 3: | |
out.r = p; | |
out.g = q; | |
out.b = in.v; | |
break; | |
case 4: | |
out.r = t; | |
out.g = p; | |
out.b = in.v; | |
break; | |
case 5: | |
default: | |
out.r = in.v; | |
out.g = p; | |
out.b = q; | |
break; | |
} | |
return out; | |
} | |
int pinR = 9; | |
int pinG = 10; | |
int pinB = 11; | |
void show(struct rgb& color) | |
{ | |
analogWrite(pinR, 255 - (255.0 * color.r)); | |
analogWrite(pinG, 255 - (255.0 * color.g)); | |
analogWrite(pinB, 255 - (255.0 * color.b)); | |
} | |
void showCycle() | |
{ | |
for (int h = 0; h < 360; h++) | |
{ | |
hsv color(h, 1.0, 1.0); | |
rgb col_rgb = hsv2rgb(color); | |
show(col_rgb); | |
delay(50); | |
} | |
} | |
void showCycle(int n) | |
{ | |
for (int c = 0; c < n; c++) | |
{ | |
showCycle(); | |
} | |
} | |
#define BOUNCE_DURATION 20 // define an appropriate bounce time in ms for your switches | |
volatile unsigned long button1_timeout=0; // variable to hold ms count to debounce a pressed switch | |
volatile unsigned long button2_timeout=0; // variable to hold ms count to debounce a pressed switch | |
int button1_state = 0; | |
int button2_state = 0; | |
void button1_int() | |
{ | |
button1_state = !button1_state; | |
// this is the interrupt handler for button presses | |
// it ignores presses that occur in intervals less then the bounce time | |
if(millis() > button1_timeout) | |
{ | |
if (button1_state) { | |
rgb green(0, 1.0, 0); | |
show(green); | |
} | |
// Your code here to handle new button press | |
button1_timeout = millis() + BOUNCE_DURATION; // set whatever bounce time in ms is appropriate | |
} | |
} | |
void button2_int() | |
{ | |
button2_state = !button2_state; | |
// this is the interrupt handler for button presses | |
// it ignores presses that occur in intervals less then the bounce time | |
if(millis() > button2_timeout) | |
{ | |
if (button2_state) { | |
rgb red(1.0, 0, 0); | |
show(red); | |
} | |
// Your code here to handle new button press | |
button2_timeout = millis() + BOUNCE_DURATION; // set whatever bounce time in ms is appropriate | |
} | |
} | |
// the setup routine runs once when you press reset: | |
void setup() | |
{ | |
pinMode(pinR, OUTPUT); | |
pinMode(pinG, OUTPUT); | |
pinMode(pinB, OUTPUT); | |
attachInterrupt(0, button1_int, CHANGE); | |
attachInterrupt(1, button2_int, CHANGE); | |
} | |
int prev_h=0; | |
// the loop routine runs over and over again forever: | |
void loop() | |
{ | |
int h = map(analogRead(A1), 0, 1023, 0, 360); | |
if (h > prev_h+2 || h<prev_h-2) { | |
hsv color(h, 1.0, 1.0); | |
rgb col_rgb = hsv2rgb(color); | |
show(col_rgb); | |
prev_h = h; | |
} | |
delay(10); | |
//showCycle(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment