I am using the following code as a starting point:
// Example 05: Turn on LED when the button is pressed
// and keep it on after it is released
// including simple de-bouncing.
// If the button is held, brightness changes.
//
// Copy and paste this example into an empty Arduino sketch
#define LED 9 // the pin for the LED
#define BUTTON 7 // input pin of the pushbutton
int val = 0; // stores the state of the input pin
int old_val = 0; // stores the previous value of "val"
int state = 0; // 0 = LED off while 1 = LED on
int brightness = 128; // Stores the brightness value
unsigned long startTime = 0; // when did we begin pressing?
void setup() {
pinMode(LED, OUTPUT); // tell Arduino LED is an output
pinMode(BUTTON, INPUT); // and BUTTON is an input
}
void loop() {
val = digitalRead(BUTTON); // read input value and store it
// yum, fresh
// check if there was a transition
if ((val == HIGH) && (old_val == LOW)) {
state = 1 - state; // change the state from off to on
// or vice-versa
startTime = millis(); // millis() is the Arduino clock
// it returns how many milliseconds
// have passed since the board has
// been reset.
// (this line remembers when the button
// was last pressed)
delay(10);
}
// check whether the button is being held down
if ((val == HIGH) && (old_val == HIGH)) {
// If the button is held for more than 500ms.
if (state == 1 && (millis() - startTime) > 500) {
brightness++; // increment brightness by 1
delay(10); // delay to avoid brightness going
// up too fast
if (brightness > 255) { // 255 is the max brightness
brightness = 0; // if we go over 255
// letâ??s go back to 0
}
}
}
old_val = val; // val is now old, letâ??s store it
if (state == 1) {
analogWrite(LED, brightness); // turn LED ON at the // current brightness level
} else {
analogWrite(LED, 0); // turn LED OFF
}
}
What I would like to do is make the LED fade IN and then once it has reached its maximum brightness (255) fade back out (0). The code I have written is not getting the job done and I am starting to get quite confused by what should be a pretty straight forward little project.
// Example 05: Turn on LED when the button is pressed
// and keep it on after it is released
// including simple de-bouncing.
// If the button is held, i changes.
//
// Copy and paste this example into an empty Arduino sketch
#define LED 9 // the pin for the LED
#define BUTTON 7 // input pin of the pushbutton
int val = 0; // stores the state of the input pin
int old_val = 0; // stores the previous value of "val"
int state = 0; // 0 = LED off while 1 = LED on
int i = 0; // Stores the i value
int brightness = 32;
unsigned long startTime = 0; // when did we begin pressing?
void setup() {
pinMode(LED, OUTPUT); // tell Arduino LED is an output
pinMode(BUTTON, INPUT); // and BUTTON is an input
}
void loop() {
val = digitalRead(BUTTON); // read input value and store it
// yum, fresh
// check if there was a transition
if ((val == HIGH) && (old_val == LOW)) {
state = 1 - state; // change the state from off to on
// or vice-versa
startTime = millis(); // millis() is the Arduino clock
// it returns how many milliseconds
// have passed since the board has
// been reset.
// (this line remembers when the button
// was last pressed)
delay(10);
}
// check whether the button is being held down
if ((val == HIGH) && (old_val == HIGH)) {
// If the button is held for more than 500ms.
if (state == 1 && (millis() - startTime) > 500) {
for (i = 0; i < 255; i++) { // loop from 0 to 254 (fade in)
brightness = i;
delay(10); // Wait 10ms because analogWrite
// is instantaneous and we would
// not see any change
}
for (i = 255; i > 0; i--) { // loop from 255 to 1 (fade out)
brightness = i;
delay(10); // Wait 10ms
}
}
}
old_val = val; // val is now old, let's store it
if (state == 1) {
analogWrite(LED, brightness); // turn LED ON at the current i level
} else {
analogWrite(LED, 0); // turn LED OFF
}
}
Any assistance to get me headed in the right direction would be greatly appreciated. Thank you.
for (i = 0; i < 255; i++) { // loop from 0 to 254 (fade in)
brightness = i;
delay(10); // Wait 10ms because analogWrite
// is instantaneous and we would
// not see any change
}
This will execute for about two and a half seconds before continuing with further execution. And in effect, your brightness will never be analogWrite()'d because analogWrite is actually not instantaneous, in a multithreaded mutex kind of way.
the counter variable is used to divide time into 256 time slots. In each time slot the LED can be on or off.
Example: brightness = 100
then the led is on for the first 100 time slots and off for the remaining 155 time slots.
By increasing brightness (outer loop) from 0 to 255 and then decreasing it, the LED is fading.
delay(1); makes sure that this fading isn't too fast. If you need a slower fading, simply change the delay value.
Forgive my ignorance but when I update the code as I think you suggest I get strange results. When I momentarily press the button, the light comes on as it should however, when I press and hold the button, the light goes up and then down and then shuts off and no longer actuates at all.
Here is the code as it now stands:
// Example 05: Turn on LED when the button is pressed
// and keep it on after it is released
// including simple de-bouncing.
// If the button is held, i changes.
//
// Copy and paste this example into an empty Arduino sketch
#define LED 9 // the pin for the LED
#define BUTTON 7 // input pin of the pushbutton
int val = 0; // stores the state of the input pin
int old_val = 0; // stores the previous value of "val"
int state = 0; // 0 = LED off while 1 = LED on
int i = 32; // Stores the i value
unsigned long startTime = 0; // when did we begin pressing?
void setup() {
pinMode(LED, OUTPUT); // tell Arduino LED is an output
pinMode(BUTTON, INPUT); // and BUTTON is an input
}
void loop() {
val = digitalRead(BUTTON); // read input value and store it
// yum, fresh
// check if there was a transition
if ((val == HIGH) && (old_val == LOW)) {
state = 1 - state; // change the state from off to on
// or vice-versa
startTime = millis(); // millis() is the Arduino clock
// it returns how many milliseconds
// have passed since the board has
// been reset.
// (this line remembers when the button
// was last pressed)
delay(10);
}
// check whether the button is being held down
if ((val == HIGH) && (old_val == HIGH)) {
// If the button is held for more than 500ms.
if (state == 1 && (millis() - startTime) > 500) {
for (i = 32; i < 255; i++) { // loop from 0 to 254 (fade in)
analogWrite(LED, i);
delay(10); // Wait 10ms because analogWrite
// is instantaneous and we would
// not see any change
}
for (i = 255; i > 0; i--) { // loop from 255 to 1 (fade out)
analogWrite(LED, i);
delay(10); // Wait 10ms
}
}
}
old_val = val; // val is now old, let's store it
if (state == 1) {
analogWrite(LED, i); // turn LED ON at the current brightness level
} else {
analogWrite(LED, 0); // turn LED OFF
}
}
// Example 05:
// Turn on LED when the button is pressed
// Keep LED on after button is released
// including simple de-bouncing.
// If the button is held, i changes.
//
// This uses a Finite State Machine.
// Finite-state machine - Wikipedia
//
// Copy and paste this example into an empty Arduino sketch
//pin declarations #define LED 9 // the pin for the LED #define BUTTON 7 // input pin of the pushbutton
//button config #define PULLUP_RESISTOR 1 //set to 0 if pulldown is used #define BUTTON_PRESSED (!PULLUP_RESISTOR)
//time variabels #define BUTTON_HOLD_LIMIT 500 //how long does the button need to be pressed #define LED_ON_AFTER_RELEASE 300 #define DEBOUNCE_DELAY 20 #define FADE_DELAY 5
//indicate program state
typedef enum State
{
BUTTON_PRESS,
BUTTON_HOLD,
BUTTON_RELEASED
} State;
State state=BUTTON_RELEASED;
//fade variables
boolean fadeIn = true; //keeps track of current fading when BUTTON_HOLD
boolean fadeOut = true; //fade out after BUTTON_PRESS
byte fadeState = 100;
unsigned long buttonPressTime = 0; // when did we begin pressing?
unsigned long buttonReleaseTime = 0; // when did we begin pressing?
//setup
void setup() {
pinMode(LED, OUTPUT); // tell Arduino LED is an output
pinMode(BUTTON, INPUT); // and BUTTON is an input
if (PULLUP_RESISTOR) digitalWrite(BUTTON,HIGH);
if (SERIAL_DEBUG) Serial.begin(BAUDRATE);
}
void loop() {
//read button && set state
if (digitalRead(BUTTON)==BUTTON_PRESSED && state == BUTTON_RELEASED){
state = BUTTON_PRESS;
buttonPressTime = millis();
delay(DEBOUNCE_DELAY);
} else if (digitalRead(BUTTON)==BUTTON_PRESSED && state == BUTTON_PRESS){
if (buttonPressTime + BUTTON_HOLD_LIMIT < millis()){
state = BUTTON_HOLD;
}
} else if (digitalRead(BUTTON)!=BUTTON_PRESSED && state != BUTTON_RELEASED){
if (state==BUTTON_PRESS) {
//only hold LED on if button was pressed and not held
buttonReleaseTime = millis();
}
state = BUTTON_RELEASED;
}
//execute program according to state
if (state == BUTTON_PRESS) {
analogWrite(LED, fadeState); // turn LED ON at the current brightness level
} else if (state == BUTTON_HOLD){
fadeState==0 ? fadeIn = true : (fadeState==255 ? fadeIn = false : fadeIn);//set fadeIn flag according to fadeState
fadeIn ? ++fadeState : --fadeState; //fade in or out
analogWrite(LED, fadeState); // set pwm at current fadeState
delay(FADE_DELAY);
} else if (state == BUTTON_RELEASED){
if ( buttonReleaseTime + LED_ON_AFTER_RELEASE > millis() ){
analogWrite(LED,fadeState);
delay(FADE_DELAY);
} else {
digitalWrite(LED, 0); // turn LED OFF
}
}
//trigger debug routine
debug();
}
//debug to serial
//TODO - debug all variables of interest
void debug(){
//debug
I'm not sure where all the complexity has come from. I modified the fading routine in examples. This fades in then out and pauses when the button is not pressed. Should do what you need.
// Fading LED
// by BARRAGAN <http://people.interaction-ivrea.it/h.barragan>
int value = 0; // variable to keep the actual value
int ledPin = 9; // light connected to digital pin 9
int buttonPin = 7;
int buttonVal;
int dir = 0;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop()
{
buttonVal = digitalRead(buttonPin);
while(buttonVal == HIGH)
{
if (dir == 0) // fade in (from min to max)
{
value += 5;
analogWrite(ledPin, value); // sets the value (range from 0 to 255)
delay(30); // waits for 30 milli seconds to see the dimming effect
if(value == 255)
dir = 1;
}
if (dir ==1) // fade out (from max to min)
{
value -= 5;
analogWrite(ledPin, value);
delay(30);
if(value == 0);
dir = 0;
}
buttonVal = digitalRead(buttonPin);
}
}
I just thought of something. Do you want to press the button, then have it fade in and out in one swoop? What is the sequence you're trying to achieve?
// Example 05: Turn on LED when the button is pressed
// and keep it on after it is released
// including simple de-bouncing.
// If the button is held, i changes.(after a set interval according to his code)
Although my code might seem overly complex (which is correct I suppose) it is useful being able to debug when needed, change between pullup and pulldown buttonlogic with the change of a 0 to a 1, it might be of interest to fade out after release. (This was not ment defensive, I just wanted to be a little pro complex ;))