Hello !
I trying to dim a rgb light with a TIP120 and have no trouble dimming it.
But I want it do dim up to full light when a button have HIGH and when the button go low i want it to dim the light down to off..
Here is my code:
int ledPin = 3;
const int buttonPin = 2; // the number of the pushbutton pin
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// fade in from min to max in increments of 5 points:
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
// turn LED on:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(100);
}
}
if (buttonState == LOW) {
// turn LED on:
// fade out from max to min in increments of 5 points:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(100);
}
}
}
The problem is that the dimming always restart itself. When the button is LOW the light goes from 255 to 0 but after that i restart and do it again...
Please use code tags when posting code; so much easier to copy
type ** **[code]** **
paste your code after that
type ** **[code]** **
after that
It will look like below.
OK, the problem is that loop() is executed time after time after time. So every time you have done a dim cyle, loop is started again and the dim cycle starts again.
You need to keep track when the dimming is finished; the below uses a boolean variable that indicates the direction (up or down). The variable is static so its information is not lost between successive calls to loop. Once a down cycle is done, you can only do an up cycle and vice versa.
Be aware that you have to complete a dim cycle, else the direction will not change; this is just a quick and dirty solution (not tested).
int ledPin = 3;
const int buttonPin = 2; // the number of the pushbutton pin
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// remember the direction; false = dim down, true = dim up
static bool fDirection = false;
// fade in from min to max in increments of 5 points:
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH && fDirection == true) {
// turn LED on:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(100);
}
// done, change direction
fDirection = false;
}
if (buttonState == LOW && fDirection == false) {
// turn LED on:
// fade out from max to min in increments of 5 points:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(100);
}
// done, change direction
fDirection = true;
}
}
Note:
It's bad habit to use for loops with delays in your code. As an exercise, try to modify the code without using the for loop; instead use a static counter that you increment from 0 to 255 and decrement from 255 to 0 (in steps of 5).
If you get stuck, ask.
The one problem I have now is that the lights doesn't turn on the same time. First the green dim up, then the red and then the blue. Same when they dim down to just opposite...
Does it have anything to do with the delay ? I want them all to dim up at the same time.
int ledPinGreen = 3;
int ledPinRed = 5;
int ledPinBlue = 6;
const int sensorPin = 8; // the number of the pushbutton pin
int sensorState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the pushbutton pin as an input:
pinMode(sensorPin, INPUT);
Serial.begin(9600);
}
void loop() {
// remember the direction; false = dim down, true = dim up
static bool fDirectionRed = false;
static bool fDirectionBlue = false;
static bool fDirectionGreen = false;
{
int sensorState = digitalRead(sensorPin);
// print out the state of the button:
Serial.println(sensorState);
delay(10);
}
/////////
//GREEN
/////////
// fade in from min to max in increments of 5 points:
sensorState = digitalRead(sensorPin);
if (sensorState == HIGH && fDirectionGreen == true) {
// turn LED on:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPinGreen, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
// done, change direction
fDirectionGreen = false;
}
if (sensorState == LOW && fDirectionGreen == false) {
// turn LED on:
// fade out from max to min in increments of 5 points:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPinGreen, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
// done, change direction
fDirectionGreen = true;
}
///////////
// RED
//////////
if (sensorState == HIGH && fDirectionRed == true) {
// turn LED on:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPinRed, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
// done, change direction
fDirectionRed = false;
}
if (sensorState == LOW && fDirectionRed == false) {
// turn LED on:
// fade out from max to min in increments of 5 points:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPinRed, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
// done, change direction
fDirectionRed = true;
}
////////////
//BLUE
///////////
if (sensorState == HIGH && fDirectionBlue == true) {
// turn LED on:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPinBlue, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
// done, change direction
fDirectionBlue = false;
}
if (sensorState == LOW && fDirectionBlue == false) {
// turn LED on:
// fade out from max to min in increments of 5 points:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPinBlue, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(10);
}
// done, change direction
fDirectionBlue = true;
}
}
[code]
You must learn to think in the smallest possible steps and execute them (basically) in parallel. So do one step red, one step green and one step blue. Do a delay once you have done one step for each color and loop() will take care of the rest.
void loop() {
// remember the direction; false = dim down, true = dim up
static bool fDirection = false;
// femember the fade value
static int fadeValue = 0;
// fade in from min to max in increments of 5 points:
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH && fDirection == UP && fadeValue <= 250) {
fadeValue += 5;
analogWrite(ledPin, fadeValue);
}
if (fadeValue >= 255)
{
// done, change direction
fDirection = false;
}
// fade in from min to max in increments of 5 points:
if (buttonState == LOW && fDirection == DOWN && fadeValue >= 5) {
fadeValue -= 5;
analogWrite(ledPin, fadeValue);
}
if (fadeValue <= 0)
{
// done, change direction
fDirection = true;
}
// now we can do the short delay
delay(100);
}
The above code (not tested) should behave the same as the previous one I posted. You can modify to use the three different colors using three direction variables and three fade variables.
I've made one additional change; true and false don't mean much for a direction. Place the below at the tops of your code
I also want to have another button, if this button is presset I want for example the green light gradually go white, and when the button is released again I want it to go back to green again.
I have soldered so if OUTPUT 3 is active the RGB light is green and if OUTPUT 3 and 9 is activated the RGB lights white.
I know this is way over my head to make this, but maybe someone have some tips to make it easier ?
All right, now I have it like I want it, but i noticed a glitch.
If one of the ''buttons'' is released before the dimming is done the lights stop in the dimming position they are and wait a while before it start dimming up or down again.
Here is my code. (my longest code ever)
int ledPinGreen = 3;
int ledPinRed = 5;
int ledPinBlue = 6;
int ledPinWV = 9;
int ledPinWC = 10;
int ledPinWB = 11;
const int sensorPin = 8;
const int vPin = 2;
const int cPin = 4;
const int bPin = 7;
#define UP true
#define DOWN false
int sensorState = 0; // variable for reading the pushbutton status
int vState = 0;
int cState = 0;
int bState = 0;
void setup() {
// initialize the pushbutton pin as an input:
pinMode(sensorPin, INPUT);
pinMode(vPin, INPUT);
pinMode(cPin, INPUT);
pinMode(bPin, INPUT);
}
void loop() {
// remember the direction; false = dim down, true = dim up
static bool fDirectionGreen = false;
static bool fDirectionRed = false;
static bool fDirectionBlue = false;
static bool fDirectionWV = false;
static bool fDirectionWC = false;
static bool fDirectionWB = false;
// femember the fade value
static int fadeValueGreen = 0;
static int fadeValueRed = 0;
static int fadeValueBlue = 0;
static int fadeValueWV = 0;
static int fadeValueWC = 0;
static int fadeValueWB = 0;
sensorState = digitalRead(sensorPin);
vState = digitalRead(vPin);
cState = digitalRead(cPin);
bState = digitalRead(bPin);
///// GREEN /////
if (sensorState == HIGH && fDirectionGreen == UP && fadeValueGreen <= 250) {
fadeValueGreen += 5;
analogWrite(ledPinGreen, fadeValueGreen);
}
if (fadeValueGreen >= 255)
{
// done, change direction
fDirectionGreen = false;
}
// fade in from min to max in increments of 5 points:
if (sensorState == LOW && fDirectionGreen == DOWN && fadeValueGreen >= 5) {
fadeValueGreen -= 5;
analogWrite(ledPinGreen, fadeValueGreen);
}
if (fadeValueGreen <= 0)
{
// done, change direction
fDirectionGreen = true;
}
// now we can do the short delay
//// RED ////
if (sensorState == HIGH && fDirectionRed == UP && fadeValueRed <= 250) {
fadeValueRed += 5;
analogWrite(ledPinRed, fadeValueRed);
}
if (fadeValueRed >= 255)
{
// done, change direction
fDirectionRed = false;
}
// fade in from min to max in increments of 5 points:
if (sensorState == LOW && fDirectionRed == DOWN && fadeValueRed >= 5) {
fadeValueRed -= 5;
analogWrite(ledPinRed, fadeValueRed);
}
if (fadeValueRed <= 0)
{
// done, change direction
fDirectionRed = true;
}
// now we can do the short delay
////////// BLUE /////
if (sensorState == HIGH && fDirectionBlue == UP && fadeValueBlue <= 250) {
fadeValueBlue += 5;
analogWrite(ledPinBlue, fadeValueBlue);
}
if (fadeValueBlue >= 255)
{
// done, change direction
fDirectionBlue = false;
}
// fade in from min to max in increments of 5 points:
if (sensorState == LOW && fDirectionBlue == DOWN && fadeValueBlue >= 5) {
fadeValueBlue -= 5;
analogWrite(ledPinBlue, fadeValueBlue);
}
if (fadeValueBlue <= 0)
{
// done, change direction
fDirectionBlue = true;
}
/////// GREEN W ////////
if (vState == LOW && sensorState == HIGH && fDirectionWV == UP && fadeValueWV <= 250) {
fadeValueWV += 5;
analogWrite(ledPinWV, fadeValueWV);
}
if (fadeValueWV >= 255)
{
// done, change direction
fDirectionWV = false;
}
// fade in from min to max in increments of 5 points:
if (vState == HIGH && fDirectionWV == DOWN && fadeValueWV >= 5) {
fadeValueWV -= 5;
analogWrite(ledPinWV, fadeValueWV);
}
if (fadeValueWV <= 0)
{
// done, change direction
fDirectionWV = true;
}
/////////// RED W ///////////
if (cState == LOW && sensorState == HIGH && fDirectionWC == UP && fadeValueWC <= 250) {
fadeValueWC += 5;
analogWrite(ledPinWC, fadeValueWC);
}
if (fadeValueWC >= 255)
{
// done, change direction
fDirectionWC = false;
}
// fade in from min to max in increments of 5 points:
if (cState == HIGH && fDirectionWC == DOWN && fadeValueWC >= 5) {
fadeValueWC -= 5;
analogWrite(ledPinWC, fadeValueWC);
}
if (fadeValueWC <= 0)
{
// done, change direction
fDirectionWC = true;
}
//////////BLUE/////////
if (bState == LOW && sensorState == HIGH && fDirectionWB == UP && fadeValueWB <= 250) {
fadeValueWB += 5;
analogWrite(ledPinWB, fadeValueWB);
}
if (fadeValueWB >= 255)
{
// done, change direction
fDirectionWB = false;
}
// fade in from min to max in increments of 5 points:
if (bState == HIGH && fDirectionWB == DOWN && fadeValueWB >= 5) {
fadeValueWB -= 5;
analogWrite(ledPinWB, fadeValueWB);
}
if (fadeValueWB <= 0)
{
// done, change direction
fDirectionWB = true;
}
// now we can do the short delay
delay(100);
}
[code]
If I understand you correctly, you only want one presses to start the fading. In that case you need to remember the status of the button and check against the new status.
void loop()
{
// rememner last button state
static int vStatePrevious = LOW;
// remember if v is running
vool vRunning = false;
vState = digitalRead(vPin);
// there was a change
if (vState != vStatePrevious)
{
vStatePrevious = vState;
vRunning = true;
}
if(vRunning == true)
{
//fade the LED
...
...
// if the fadeValue reaches the limmit, set vRunning to false
}
}