I'm looking for some sample code.
I want to adjust from Red to Blue to Green with a single potentiometer, and can't quite picture the best way to do it.
I'm looking for some sample code.
I want to adjust from Red to Blue to Green with a single potentiometer, and can't quite picture the best way to do it.
Adjust what?
I think he wants to control an RGB LED with a single potentiometer, "scrolling" through the different hues.
That's really difficult. I've yet to find a solid program that does that, so for my project I'm using 3 separate pots with this code (common cathode LED):
const int redPin = 9;
const int greenPin = 10;
const int bluePin = 11;
const int redPot = 2;
const int bluePot = 1;
const int greenPot = 3;
int currentRed;
int currentGreen;
int currentBlue;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
void loop(){
currentRed = map(analogRead(redPot), 0, 1024, 0, 255);
currentGreen = map(analogRead(greenPot), 0, 1024, 0, 255);
currentBlue = map(analogRead(bluePot), 0, 1024, 0, 255);
analogWrite(redPin, 255 - currentRed);
analogWrite(greenPin, 255 - currentGreen);
analogWrite(bluePin, 255 - currentBlue);
}
However, this is the best code I've found for scrolling through hues (not mine):
// Potentiometer connected to analog pin 2 w/ pos 5v and grounded neg
// RGB LED connections are in this order when looking at LED: Red, Common Annode(Longest - also where 5v power is connected), Green, Blue
// RGB LED attached from digital pin 9(red), 10(green), 11(blue) w/ common annode to 5v power.
//Created 8 May 2010
//Commented by Dave a.k.a Ka0ticstyle
//*/
int potpin = 2; // POT connected to digital pin 2 - pos/neg are left and right connections on POT
int rpin = 9; // Red
int gpin = 10; // Green
int bpin = 11; // Blue
float h; // Hue range
int h_int; // Hue color
int r = 0, g = 0, b = 0; // Default RGB values
int val = 0; // Set POT value to default 0
void h2rgb(float h, int& R, int& G, int& B); // Instantiate h2rgb and it's variables a.k.a Hue to RGB
void setup() // Run once, when the sketch starts
{
Serial.begin(9600); // Begin the output of data to serial
}
void loop() // Run over and over again
{
val = analogRead(potpin); // Read the pin and display the value
h = ((float)val)/1024; // Get the range. pot value / 1024
h_int = (int) 360*h; // Get the color hue by multiplying by 360
h2rgb(h,r,g,b); // Call the h2rgb function passing it the hue value
Serial.print("POT value: ");
Serial.print(val); // Pot value
Serial.print(" = Hue of ");
Serial.print(h_int); // Color Hue value
Serial.print(" degrees. RGB values: ");
Serial.print(r); // Red value
Serial.print(" ");
Serial.print(g); // Green value
Serial.print(" ");
Serial.println(b); // Blue value
analogWrite(rpin, (255-r)); // Changes red led
analogWrite(gpin, (255-g)); // Changes green led
analogWrite(bpin, (255-b));
}
void h2rgb(float h, int& R, int& G, int& B) {
// Used HSV --> RGB function
// HSV - Hue, Saturation, Value
// RGB - Red, Green, Blue - example (255,255,255)
// Function below does a bunch of math to convert HSV values to RGB
int var_i;
float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;
if ( S == 0 ) //HSV values = 0 ÷ 1
{
R = V * 255;
G = V * 255;
B = V * 255;
}
else
{
var_h = h * 6;
if ( var_h == 6 ) var_h = 0; //H must be < 1
var_i = int( var_h ) ; //Or ... var_i = floor( var_h )
var_1 = V * ( 1 - S );
var_2 = V * ( 1 - S * ( var_h - var_i ) );
var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );
if ( var_i == 0 ) {
var_r = V ;
var_g = var_3 ;
var_b = var_1 ;
}
else if ( var_i == 1 ) {
var_r = var_2 ;
var_g = V ;
var_b = var_1 ;
}
else if ( var_i == 2 ) {
var_r = var_1 ;
var_g = V ;
var_b = var_3 ;
}
else if ( var_i == 3 ) {
var_r = var_1 ;
var_g = var_2 ;
var_b = V ;
}
else if ( var_i == 4 ) {
var_r = var_3 ;
var_g = var_1 ;
var_b = V ;
}
else {
var_r = V ;
var_g = var_1 ;
var_b = var_2 ;
}
R = (1-var_r) * 255; //RGB results = 0 ÷ 255
G = (1-var_g) * 255;
B = (1-var_b) * 255;
}
}
That's really difficult. I've yet to find a solid program that does that, so for my project I'm using 3 separate pots with this code (common cathode LED):
Really? have you tried to multiply the pots range (0 - 1023) by 64 to give you the max value of an unsigned int then convert the int back to RGB values?
void _565ToRGB( unsigned int color, byte * R, byte * G, byte * B)
{
*R = (color & 0xf800) >> 8;
*G = (color & 0x0FC0) >> 3;
*B = (color & 0x001f) << 3;
}
It will skip of course, but it is not very difficult to do. Perhaps you can use a DUE because I have heard they are capable of 12bit resolution instead of the 10bit that the analogRead() function uses now.
HazardsMind:
It will skip of course, but it is not very difficult to do. Perhaps you can use a DUE because I have heard they are capable of 12bit resolution instead of the 10bit that the analogRead() function uses now.
As it is human controlled, things can be slower than usual.
By oversampling you can achieve 11 up to 16 bits of resolution. Check out this article: http://www.atmel.com/images/doc8003.pdf
Aiming for 15 bits of resolution could allow around 7 samples per second. Or around 29hz for 14 bits. Just need to do lots of samples: 4n where n is the number of extra bits.
I did it with some RGB LED's on my truck a few years ago and it worked pretty good. Full post here but the relevant code is below.
The basic process it just cutting the 1023 steps 6 sections. Each of these 6 sections has a specific combination of 1 or more of the colors. For reference the abbreviations for the variable is fr, fg, fb for front red green and blue respectively. Then it's rr, rg, and rb for the rear colors.
I was using these calls:
intLights (0, 175, 0, rr, 0, fr); // takes a value from the pot (0-1023) and uses that value to change the colors on the led
intLights (165, 345, rr, rb, fr, fb);
intLights (335, 515, rb, rg, fb, fg);
intLights (505, 685, rg, rr, fg, fr);
intLights (675, 855, 0, rb, 0, fb);
intLights (845, 1015, 0, rg, 0, fg);
To feed this funtion:
void intLights (int low, int high, int LEDlower1, int LEDraise1, int LEDlower2, int LEDraise2){ //takes the value from the pot and turns it into led values
if(colorValue == 0) {
digitalWrite(rr, LOW);
digitalWrite(fr, LOW);
digitalWrite(rg, LOW);
digitalWrite(fg, LOW);
digitalWrite(rb, LOW);
digitalWrite(fb, LOW);
}
else if(colorValue >1000){
digitalWrite(rr, HIGH);
digitalWrite(fr, HIGH);
digitalWrite(rg, HIGH);
digitalWrite(fg, HIGH);
digitalWrite(rb, HIGH);
digitalWrite(fb, HIGH);
}
else if (colorValue > low && colorValue < high){
int LED1 = map (colorValue, low, high, 255, 10);
int LED2 = map (colorValue, low, high, 10, 255);
int LED3 = map (colorValue, low, high, 255, 10);
int LED4 = map (colorValue, low, high, 10, 255);
analogWrite (LEDlower1, LED1);
analogWrite (LEDraise1, LED2);
analogWrite (LEDlower2, LED3);
analogWrite (LEDraise2, LED4);
}
}
i believe this sketch takes one pot and an rgb LED
// INPUT: Potentiometer should be connected to 5V and GND
int potPin = 3; // Potentiometer output connected to analog pin 3
int potVal = 0; // Variable to store the input from the potentiometer
// OUTPUT: Use digital pins 9-11, the Pulse-width Modulation (PWM) pins
// LED's cathodes should be connected to digital GND
int redPin = 9; // Red LED, connected to digital pin 9
int grnPin = 10; // Green LED, connected to digital pin 10
int bluPin = 11; // Blue LED, connected to digital pin 11
// Program variables
int redVal = 0; // Variables to store the values to send to the pins
int grnVal = 0;
int bluVal = 0;
void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
}
// Main program
void loop()
{
potVal = analogRead(potPin); // read the potentiometer value at the input pin
if (potVal < 341) // Lowest third of the potentiometer's range (0-340)
{
potVal = (potVal * 3) / 4; // Normalize to 0-255
redVal = 256 - potVal; // Red from full to off
grnVal = potVal; // Green from off to full
bluVal = 1; // Blue off
}
else if (potVal < 682) // Middle third of potentiometer's range (341-681)
{
potVal = ( (potVal-341) * 3) / 4; // Normalize to 0-255
redVal = 1; // Red off
grnVal = 256 - potVal; // Green from full to off
bluVal = potVal; // Blue from off to full
}
else // Upper third of potentiometer"s range (682-1023)
{
potVal = ( (potVal-683) * 3) / 4; // Normalize to 0-255
redVal = potVal; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 - potVal; // Blue from full to off
}
analogWrite(redPin, redVal); // Write values to LED pins
analogWrite(grnPin, grnVal);
analogWrite(bluPin, bluVal);
}
This last one looks the most interesting.
It's really just dividing the pot into three regions that is a bit of a mental roadblock.
I think that red from full then fade in green, then fade green into blue with only blue at the top would be a good way.
Do share your results if you try it... Heck i might even give it a shot, Im curious to see how it performs.
Ok, I probably will.
the only thing i think that i was trying to do with my code that i don't think is captured in the one User0689 posted is the rest of the potential combinations. To catch "all" possible colors I think you have six distinct transitions.
The way i see it these are: