Netherlands
Online
Tesla Member
Karma: 86
Posts: 9359
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #15 on: March 09, 2012, 03:55:08 pm » |
found this one in my experiments section. Code goes 360 degrees through hue space converting it to related RGB values. links to 2 website included // // FILE: RGB2HUE.pde // AUTHOR: Rob Tillaart // DATE: 2011-09-17 // // PUPROSE: color-rainbow // // http://www.dipzo.com/wordpress/?p=50 // http://www.easyrgb.com/index.php?X=MATH //
int Rpin=10; int Gpin=9; int Bpin=11;
float H,S,L, Rval,Gval,Bval;
void HSL(float H, float S, float L, float& Rval, float& Gval, float& Bval); float Hue_2_RGB( float v1, float v2, float vH );
void setup() { Serial.begin(9600);
pinMode(12, OUTPUT); }
void loop() { S=1; L=.5; Rval=0; Gval=0; Bval=0; for (int i = 0; i< 360; i++) { HSL(i/360.0,S,L,Rval,Gval,Bval);
//common anode configuration //analogWrite(Rpin, 255-Rval); //analogWrite(Gpin, 255-Gval); //analogWrite(Bpin, 255-Bval); //digitalWrite(12,HIGH);
//common cathode configuration analogWrite(Rpin, Rval); analogWrite(Gpin, Gval); analogWrite(Bpin, Bval); digitalWrite(12,LOW);
//print statements for debug Serial.print("position:"); Serial.print(H); Serial.print(" R:"); Serial.print(Rval); Serial.print(" G:"); Serial.print(Gval); Serial.print(" B:"); Serial.println(Bval); delay(100); } }
void HSL(float H, float S, float L, float& Rval, float& Gval, float& Bval) { float var_1; float var_2; float Hu=H+.33; float Hd=H-.33; if ( S == 0 ) //HSL from 0 to 1 { Rval = L * 255; //RGB results from 0 to 255 Gval = L * 255; Bval = L * 255; } else { if ( L < 0.5 ) var_2 = L * ( 1 + S ); else var_2 = ( L + S ) - ( S * L );
var_1 = 2 * L - var_2;
Rval = round(255 * Hue_2_RGB( var_1, var_2, Hu )); Serial.print("Rval:"); Serial.println(Hue_2_RGB( var_1, var_2, Hu )); Gval = round(255 * Hue_2_RGB( var_1, var_2, H )); Bval = round(255 * Hue_2_RGB( var_1, var_2, Hd )); }
} float Hue_2_RGB( float v1, float v2, float vH ) //Function Hue_2_RGB { if ( vH < 0 ) vH += 1; if ( vH > 1 ) vH -= 1; if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH ); if ( ( 2 * vH ) < 1 ) return ( v2 ); if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * (.66-vH) * 6 ); return ( v1 ); }
|
|
|
|
|
Logged
|
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #16 on: March 09, 2012, 05:16:58 pm » |
Interesting! I just tossed this version into my "play" directory: #define R #define G /* Define analog LED pins */ #define B
unsigned char r=~0,g=0,b=0;
void aw(unsigned char p,unsigned char v) { analogWrite(p,v); delay(50); } void setup(void) { analogWrite(R,r); analogWrite(G,g); analogWrite(B,b); } void loop(void) { do aw(G,++g); while (~g); do aw(R,--r); while ( r); do aw(B,++b); while (~b); do aw(G,--g); while ( g); do aw(R,++r); while (~r); do aw(B,--b); while ( b); }
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
Belgium
Offline
Full Member
Karma: 0
Posts: 211
I love Arduino!
|
 |
« Reply #17 on: March 10, 2012, 03:39:33 am » |
They all work fine, but how can I make a color display with the RGB value that I want, for example the color indigo : 111,0,255(red led is less bright, green led is off, blue led is at full brightness) ? So not automatic color change.
Should I make an array like this?: Red[] = {111,0,255} And how do I make the array display the color then?
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 86
Posts: 9359
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #18 on: March 10, 2012, 05:31:54 am » |
Should I make an array like this?: Red[] = {111,0,255} And how do I make the array display the color then? Yes, define colors as separate arrays 2) define a function something like this, (not tested) byte indigo[] = { 111,0, 255 }; byte red [] = {255, 0, 0 };
void displayColor(byte *color) { analogWrite(R, color[0]); analogWrite(G, color[1]); analogWrite(B, color[2]); }
then you can call - displayColor(red);
|
|
|
|
|
Logged
|
|
|
|
|
Belgium
Offline
Full Member
Karma: 0
Posts: 211
I love Arduino!
|
 |
« Reply #19 on: March 10, 2012, 06:54:21 am » |
That's what I wanted! With a little modification, it worked. Thank you! Now, how can I make a smooth transition between them? byte red [] = { 255, 0, 0 }; byte orange [] = { 255,127,0 }; byte yellow [] = { 255,255,0 }; byte green [] = { 0,255,0 }; byte blue [] = { 0,0,255 }; byte indigo[] = { 111,0,255 }; byte violet[] = { 127,0,255 };
int R = 11; int G = 10; int B = 9;
#define DELAY 3000
void setup(){ pinMode(R, OUTPUT); pinMode(G, OUTPUT); pinMode(B, OUTPUT); } void loop(){ displayColor(red); delay(DELAY); displayColor(orange); delay(DELAY); displayColor(yellow); delay(DELAY); displayColor(green); delay(DELAY); displayColor(blue); delay(DELAY); displayColor(indigo); delay(DELAY); displayColor(violet); delay(DELAY); }
void displayColor(byte *color) { analogWrite(R, color[0]); analogWrite(G, color[1]); analogWrite(B, color[2]); }
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Online
Tesla Member
Karma: 86
Posts: 9359
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #20 on: March 10, 2012, 07:28:47 am » |
Now, how can I make a smooth transition between them? You need an interpolation function, not trivial as it can have many parameters depending on the way you interpolate. linear interpolation is easiest (see code below, not tested might contain some bugs) void interpolate( byte *col1, byte *col2, byte *out, int stepnr, int maxsteps) { for (int i =0; i<3; i++) { out[i] = col1[i] + stepnr * (col2[i] - col1[i]) / maxsteps); } }
.... usage ...
for (int c=0; c<100; c++) { byte newColor[3]; interpolate(Red, Green, newColor, c, 100); displayColor(newColor); }
Give it a try
|
|
|
|
|
Logged
|
|
|
|
|
Belgium
Offline
Full Member
Karma: 0
Posts: 211
I love Arduino!
|
 |
« Reply #21 on: March 10, 2012, 08:48:42 am » |
Seems to be a bit to difficult for me, because I really don't know where I should place your code into my existing code  Should an easy fade out and fade in between each color be easier?
|
|
|
|
|
Logged
|
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #22 on: March 10, 2012, 10:01:18 am » |
Every RBG color consists of a red component, a green component, and a blue component. To output a single color, all that's needed is to output its components. If you want indigo with red = 111, green = 0, and blue = 255 then all that's needed is analogWrite(redPin,111); analogWrite(greenPin,0); analogWrite(bluePin,255); To produce the rainbow cycle you asked about, you'll find it helpful to take a look at a color wheel like the one I've attached below (click on the thumbnail to see full size). Notice that there are 6 (sixty degree) segments in each of which only one of the three components changes while the other two remain constant. What that means is than if you want to smoothly transition all the way around the wheel, you can do so by setting up a sequence of six loops, each of which changes only one of the three components - as I did in my previous post. 
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
Belgium
Offline
Full Member
Karma: 0
Posts: 211
I love Arduino!
|
 |
« Reply #23 on: March 10, 2012, 12:37:40 pm » |
Thanks for the tip!  Is it possible to fade out and fade back in to another color between the colors in my code, instead of a delay? So the colors does not just go out, but fade out, and then fade in to another color.
|
|
|
|
« Last Edit: March 10, 2012, 12:39:41 pm by TiboJ »
|
Logged
|
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #24 on: March 10, 2012, 12:43:19 pm » |
Certainly. All you need to do is choose that "another color" and choose which direction around the color wheel you want to go, then write the sequence(s) to show the intermediate values.
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #25 on: March 10, 2012, 01:24:35 pm » |
I might have misunderstood. If you were asking about fading the current color to dark, then gradually bringing up another color, then you might want to try something like this (untested): void write_rgb_components(unsigned char r,unsigned char g,unsigned char b) { static unsigned char old_r, old_g, old_b;
if (r != old_r) analogWrite(R,old_r = r); if (g != old_g) analogWrite(G,old_g = g); if (b != old_b) analogWrite(B,old_b = b); delay(50); }
void fade_from(unsigned char r,unsigned char g,unsigned char b) { unsigned i; for (i = 255; i != 0; i--) write_rgb_components((i * r) >> 8,(i * g) >> 8,(i * b) >> 8); write_rgb_components(0,0,0); }
void fade_to(unsigned char r,unsigned char g,unsigned char b) { unsigned i; for (i = 0; i < 256; i++) write_rgb_components((i * r) >> 8,(i * g) >> 8,(i * b) >> 8); write_rgb_components(r,g,b); }
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #26 on: March 10, 2012, 02:56:01 pm » |
Im not so good at this, but I find bitshift and other things like that hard to understand. I think that everybody is giving good advise, but its a bit over my head. Isn't it easier to make an array in the setup and then use it in the code without any calculations? arrayPos=0; stepSize=16
// red to magenta for (x=0; x<255; x+stepSize){ arrayRGB[arrayPos]=[255,0,x] arrayPos++; }
// magenta to blue for (x=255; x!=0; x-stepSize){ arrayRGB[arrayPos]=[x,0,255] arrayPos++; }
// blue to cyan for (x=0; x<255; x+stepSize){ arrayRGB[arrayPos]=[0,x,255] arrayPos++; }
// cyan to green for (x=255; x!=0; x--){ arrayRGB[arrayPos]=[0,255,x] arrayPos++; }
// green to yellow for (x=0; x<255; x+stepSize){ arrayRGB[arrayPos]=[x,255,0] arrayPos++; }
// yellow to red for (x=255; x!=0; x-stepSize){ arrayRGB[arrayPos]=[255,x,0] arrayPos++; }
|
|
|
|
|
Logged
|
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #27 on: March 10, 2012, 03:12:11 pm » |
@tiirak - we can't assign three values to a single (scalar) array element, but if calculating the values is sufficiently simple, then it may actually cost less to calculate values as needed than to calculate them and store/fetch them from an array.
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #28 on: March 10, 2012, 07:34:36 pm » |
Sorry, Im a newbee here. Just tied to write quick and easy to understand. What about this? // red to magenta for (x=0; x<255; x+stepSize){ arrayRGB[arrayPos][1]=255; arrayRGB[arrayPos][2]=0; arrayRGB[arrayPos][3]=x; arrayPos++; }
And isn't it better to take memory (if possible) and not cycles?
|
|
|
|
|
Logged
|
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #29 on: March 10, 2012, 08:27:23 pm » |
Hmm - you just used up all available RAM to store 3-byte red values, and then your program crashed. ]  It's up to you to decide if this is the best approach for your particular application. If the application were a simple learning exercise with a goal of transitioning smoothly from one displayed color to another, I would not be much inclined to worry about resources - but rather with my understanding of the interface between the standard hardware, my code, and techniques for producing color.
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
|