but it doesn’t like my chopping. And i think the code is probably a bit over complex for my simple purpose.
What approach would the panel suggest for this simple task?
P.S. for my project, i would also like to be able to serial print a linerar representation of the colour value. I guess the easiest way to do this would be to assign the planned colour range an arbitrary value: red is 0, green is 128, blue is 256..
this may over complicate matters, it may make it simpler.
Attached is code I did for a similar project using an ATtiny85 but it will easily adapt to normal Arduino by just altering the relevant LED pin numbers to Arduino PWM pins (the ones with a ~ mark by them). This code is designed to work with the equivalent of common cathode LED's but should still work with common anode. Don't forget your resistors.
/* ATtiny85
--U--
Reset |1 8| VCC
(A3) D3 |2 7| D2 (A1)
PWM (A2) D4 |3 6| D1 PWM
GND |4 5| D0 PWM
-----
*/
// HLSMAX BEST IF DIVISIBLE BY 6. RGBMAX, HLSMAX must each fit in a byte.
#define HLSMAX 240 // H,L, and S vary over 0-HLSMAX
#define RGBMAX 255 // R,G, and B vary over 0-RGBMAX
#define RedPin 0
#define GreenPin 1
#define BluePin 4
const long mainDelay = 10; // Delay between each colour change
byte R,G,B; // Target RGB colour
byte Ro,Go,Bo; // Current RGB colour
void setup() {
pinMode(RedPin,OUTPUT);
pinMode(GreenPin,OUTPUT);
pinMode(BluePin,OUTPUT);
}
void loop() {
for (word Hue=0; Hue <= HLSMAX; Hue++){ // Once around the circle
HLS2RGB(Hue,HLSMAX,HLSMAX/2); // Get target R,G,B colour
boolean OK = false; //Flag colours don't match
while (OK == false){
long loopTime = millis(); //Read timer
while ((millis() - loopTime) < mainDelay) {
} // Delay
OK = true; // Flag colours match
if (R > Ro){ // Target R greater than current Ro
Ro++; // Increment current
OK = false; // Flag colours will change
}
if (R < Ro){ // Target R less than current Ro
Ro--; // Decrement current
OK = false; // Flag colours will change
}
if (G > Go){
Go++;
OK = false;
}
if (G < Go){
Go--;
OK = false;
}
if (B > Bo){
Bo++;
OK = false;
}
if (B < Bo){
Bo--;
OK = false;
}
analogWrite(RedPin,Ro);
analogWrite(GreenPin,Go);
analogWrite(BluePin,Bo);
}
}
}
void HLS2RGB(word hue, word sat, word lum) {
word M1,M2; // calculated numbers
sat = constrain(sat, 1, HLSMAX); // Don't allow sat<=0 or sat>HLSMAX
lum = constrain(lum, 0, HLSMAX/2); // Don't allow lum<0 or lum>(HLSMAX/2)
if (lum <= (HLSMAX/2))
M2 = (lum*(HLSMAX + sat) + (HLSMAX/2))/HLSMAX;
else
M2 = lum + sat - ((lum*sat) + (HLSMAX/2))/HLSMAX;
M1 = 2*lum-M2;
// get RGB, change units from HLSMAX to RGBMAX
R = (Hue2RGB(M1,M2,hue+(HLSMAX/3))*RGBMAX +(HLSMAX/2))/HLSMAX;
G = (Hue2RGB(M1,M2,hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;
B = (Hue2RGB(M1,M2,hue-(HLSMAX/3))*RGBMAX +(HLSMAX/2))/HLSMAX;
}
// Utility routine for HLS2RGB
byte Hue2RGB(word m1, word m2, word hue) {
// range check: note values passed add/subtract thirds of range
if (hue < 0)
hue += HLSMAX;
if (hue > HLSMAX)
hue -= HLSMAX;
// return r,g, or b value from this tridrant
if (hue < (HLSMAX/6))
return ( m1 + (((m2-m1)*hue+(HLSMAX/12))/(HLSMAX/6)));
if (hue < (HLSMAX/2))
return ( m2 );
if (hue < ((HLSMAX*2)/3))
return ( m1 + (((m2-m1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6)));
else
return ( m1 );
}