essentially it is desired to dim down LEDs as they go through a spectrum of colors, using the arduino to accomplish it directly leads to an error as there are only 255 brightness levels, once dimmed to a certain level , the spectrum transitions get choppy, what I want to do is wire one potentiometer to dim the red blue and green inputs of the potentiometer but I can't think of a way that wouldn't cross the signals, I tried to find info on current sensitive resistors but I can't find a simple guide anywhere, ideas?
what I want to do is wire one potentiometer to dim the red blue and green inputs of the potentiometer
That doesn't make any sense to me - can you be clearer about
(1) your existing setup - post your code for instance.
(2) what you are trying to do to solve the PWM limitation (sounds like you
might be trying to do something in the analog domain to the LED outputs?
What LEDs are you using?
I tried to find info on current sensitive resistors but I can't find a simple guide anywhere, ideas?
Maybe because there is no such thing in nature? Where did you come across the name 'current sensitive resistor' ? I guess a fuse could be called a current sensitive resistor?
As far as your problem task, I think I have read around here people dealing with that using just software. What you need is unique mapping value of each color to use as the specific PWM value to be used for each color/desired brightness value, rather then assuming that there are 256 levels of brightness for each led. Led brightness Vs current is not a clean linear relationship to what the human eye can detect. This is often done with a array look-up table defined for each color. Therefore a single pot wired to a digital analog input pin could be used to access the three arrays for the proper pwm value to send to each of the color leds.
That make sense?
Lefty
guess a fuse could be called a current sensitive resistor?
- A very Boolean one, though
A LED could even be considered to be a current sensitive resistor.
But I think the OP may be going down the wrong track in trying to control the led brightness by varying the circuit resistance. The best way to control the apparent brightness of LED's at low levels is by varying the duty cycle using some kind of PWM.
allow me to post my code to clarify
//=============================================================================================
const int buttonLightPin = A3; //sets buttonLight to input 12
const int buttonShowPin = A5; //sets buttonShow to input 13
const int brightnessPotPin = A0; //sets the pot output to A0
const int colorPotPin = A1; // sets the color during solid light
int brightnessPotState; //variable for storing the value of the brightness pot
float brightnessSet =1; // variable for storing the brightness level
int buttonState = 2; // variable for storing the mode that the devvice is in
// 0 is for off, 1 is for light show and 2 is for solid color
int PIN_RED = 11; // input for red; red jumper, white cord
int PIN_GREEN = 10; // input for green; green jumper
int PIN_BLUE = 9; //input for blue; red jumper, yellow cord
int counter;
int numColors = 500;
int animationDelay = 0; //adjustable speed of animation
float brightness = 0; // default brightness level
int lag = 0;
int showCounter = 0;
int lightCounter = 0;
int offCounter = 0;
//============================================================================================
void setup()
{
Serial.begin(9600);
pinMode(buttonLightPin, INPUT_PULLUP);
pinMode(buttonShowPin, INPUT_PULLUP);
pinMode(brightnessPotPin, INPUT_PULLUP);
pinMode(colorPotPin, INPUT_PULLUP);
pinMode(PIN_RED, OUTPUT);
pinMode(PIN_BLUE, OUTPUT);
pinMode(PIN_GREEN, OUTPUT);
}
//=============================================================================================
void loop()
{
Serial.print("Begin");
float colorNumber = counter > numColors ? counter - numColors: counter;
float saturation = 1; // Between 0 and 1 (0 = gray, 1 = full color)
float hue = (colorNumber / float(numColors)) * 360;
float brightness = setBrightness();
long color = HSBtoRGB(hue, saturation, brightness);
float red = color >> 16 & 255;
float green = color >> 8 & 255;
float blue = color & 255;
buttonState = setButtonState(); //function below for determining button state
Serial.print(" MODE: ");
if(buttonState == 1) // if buttonstate is 1, light show will commence
{
Serial.print("SHOW");
setColor(red, green, blue); //writes the color chosen by HSBtoRGB
Serial.print(" Red: ");
Serial.print(red);
Serial.print("\t");
Serial.print(" Green: ");
Serial.print(green);
Serial.print("\t");
Serial.print(" Blue: ");
Serial.print(blue);
counter = (counter + 1) % (numColors * 2); // sets counter to increment the color changes
delay(animationDelay);
}
else if(buttonState == 2) // if buttonstate is 2, LEDs will emit solid colors determined by the colorPotPin
{
showCounter = 0;
offCounter = 0;
Serial.print("SOLID COLOR");
solidColor(brightness);
}
else if(buttonState == 0) // if buttonstate is 0, no light will emit
{
Serial.print("OFF");
off();
}
Serial.print("\t");
Serial.println("END");
}
//================================================================================================
float setBrightness() // finds brightness from pot
{
float brightnessPotState; //variable for storing the value of the brightness pot
brightnessPotState = analogRead(brightnessPotPin); //reads brightness
Serial.print(" Brightness Pot: ");
Serial.print(brightnessPotState);
if(brightnessPotState <= 1000) // converts pot input(0-1023) into a percentage
//i ignored the final 23 values and lumped it into a solid 100%
{
brightnessSet = brightnessPotState/1000;
}
else
{
brightnessSet = 1;
}
return brightnessSet; // returns the percentage brightness
}
//============================================================================================
int setButtonState() //toggles between Show, Light, and off
{
int buttonShow; // variable storing the value of the buttonShowPin
int buttonLight; //variable storing the value of the buttonLightPin
int x;
buttonShow = digitalRead(buttonShowPin);
buttonLight = digitalRead(buttonLightPin);
Serial.print("\t");
Serial.print (" Button Show: ");
Serial.print (buttonShow);
Serial.print ("\t");
Serial.print (" Button Light: ");
Serial.print (buttonLight);
Serial.print ("\t");
if (buttonShow == LOW)
{
return(1);
}
else if( buttonLight == LOW)
{
return(2);
}
else if(buttonLight == HIGH && buttonShow == HIGH)
{
return(0);
}
}
//============================================================================================
void off() // turns off all LEDs
{
analogWrite(PIN_RED, LOW);
analogWrite(PIN_GREEN, LOW);
analogWrite(PIN_BLUE, LOW);
}
//=============================================================================================
void solidColor(float brightness) //sets the color for light mode
{
int redSolid;
int blueSolid;
int greenSolid;
float colorPotState; //varible for storing the value of the color pot
colorPotState = analogRead(colorPotPin);
Serial.print("Color Pot State: ");
Serial.print(colorPotState);
if (colorPotState < 341) //first 1/3 of the pots potential value
{
colorPotState= (colorPotState * 3)/4; // converts pot value into a 0-255 range
redSolid = (256 - colorPotState) * brightness; //full to 0
greenSolid = colorPotState * brightness; // 0 to full
blueSolid = 1; //off
}
else if(colorPotState < 682) //second 1/3 of the pots potential value
{
colorPotState= ((colorPotState-341) * 3)/4; // converts pot value into a 0-255 range
redSolid = 1; //off
greenSolid = (256 - colorPotState) * brightness; //full to 0
blueSolid = colorPotState * brightness; // 0 to full
}
else // Remainder of the pots value
{
colorPotState= ((colorPotState-683) * 3)/4; // converts pot value into a 0-255 range
redSolid = colorPotState * brightness; // 0 to full
greenSolid = 1; //off
blueSolid = (256 - colorPotState) * brightness; //full to 0
}
Serial.print(" Red: ");
Serial.print(redSolid);
Serial.print("\t");
Serial.print(" Green: ");
Serial.print(greenSolid);
Serial.print("\t");
Serial.print(" Blue: ");
Serial.print("\t");
Serial.print(blueSolid);
analogWrite(PIN_RED, redSolid); //set red level based on pot value
analogWrite(PIN_GREEN, greenSolid); //set green level based on pot value
analogWrite(PIN_BLUE, blueSolid); //set blue level based on pot value
}
//================================================================================================
void setColor (unsigned char red, unsigned char green, unsigned char blue) //sets the color for each instance of the show
{
analogWrite(PIN_RED, red); // set red leve
analogWrite(PIN_GREEN, green); // set red leve
analogWrite(PIN_BLUE, blue); // set red leve
}
//=============================================================================================
long HSBtoRGB(float _hue, float _sat, float _brightness) //interprets and changes the color
{
float red = 0.0; // initialize local variables
float green = 0.0;
float blue = 0.0;
if (_sat == 0.0) // if there is no saturation, the color will turn off
{
red = _brightness;
green = _brightness;
blue = _brightness;
}
else
{
if (_hue == 360.0) // when hue reaches 360, it resets to 0
{
_hue = 0;
}
int slice = _hue / 60.0; // initializes varible to break the process into 6 "slices"
float hue_frac = (_hue / 60.0) - slice; // each slice is one 6th of the process
float aa = _brightness * (1.0 - _sat); // sets the 3 different functions for increasing and decreasing color based on saturation, brightness, and hue
float bb = _brightness * (1.0 - _sat * hue_frac);
float cc = _brightness * (1.0 - _sat * (1.0 - hue_frac));
switch(slice) //depending on which slice the program is in, it will pick one of these options to adjust the color
{
case 0:
red = _brightness;
green = cc;
blue = aa;
break;
case 1:
red = bb;
green = _brightness;
blue = aa;
break;
case 2:
red = aa;
green = _brightness;
blue = cc;
break;
case 3:
red = aa;
green = bb;
blue = _brightness;
break;
case 4:
red = cc;
green = aa;
blue = _brightness;
break;
case 5:
red = _brightness;
green = aa;
blue = bb;
break;
default:
red = 0.0;
green = 0.0;
blue = 0.0;
break;
}
}
long ired = red * 255.0; // set red
long igreen = green * 255.0; // set gren
long iblue = blue * 255.0; // set blue
return long((ired << 16) | (igreen << 8) | (iblue)); // return colors
}
//=============================================================================================
what essentially happens is that at a low level of brightness all colors only have values of 0 through 3, instead of 0 through 255
austinphilp:
what essentially happens is that at a low level of brightness all colors only have values of 0 through 3, instead of 0 through 255
Hi austinphilip, yes, of course, low levels of brightness correspond to low numbers. If the numbers were higher, the light would be brighter. Seems to me you need more than the standard 256 (8 bit) levels that analogWrite provides. Wiring up extra pots won't fix this.
I seem to remember reading that more levels are possible with, for example, Uno, but not sure if this would be possible on 3 outputs. Maybe on a Mega, I don't know.
Alternatively, use a TLC5940 to drive your leds. This would give 4096 (12 bit) levels.
Paul
HI, I see you have a pot to adjust brightness and a single pot to select color.
wiring a potentiometer to 3 different lines
Seems to indicate you want three controls one for each colour.
Do you really need:
A pot input for RED.
A pot input for GREEN
A pot input for BLUE
so that you can manually mix your RGB to get the colours you require.
What you also need to know is that the PWM setting and the LED output do not track, that is PWM 50% is not 50% LED light output.
It is also the same between the colours.
PWM 10% RED is not the same level of brightness as 10% of GREEN or BLUE. But having individual control should help overcome this.
Can you post a copy of your circuit at the moment, either CAD or picture of hand drawn circuit will do.
Hope to help..Tom...
The eye responds to light levels logarithmically, so if you want to dim an LED in what appears to be a smooth linear sequence, you need a log table for the PWM values. There will still be a little choppiness in the response, but it is not nearly so bad as with a simple linear sequence like 0,1,2,3, ..., 255
See this thread and links therein: Good look-up table for LED brightness - LEDs and Multiplexing - Arduino Forum
When this approach is applied to an RGB LED for color transitions, you probably won't even see the steps.