Pages: [1]   Go Down
Author Topic: Debounce Problem, please help  (Read 946 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

HI,
I am a novice when i comes to arduino and programming, I just picked up mine about two weeks ago and am having some trouble wrapping my head around software debouncing. I've been trying to figure out what I'm doing wrong, it doesn't seem to make any difference no matter what i do with the code.
I have one button attached to pin 2 and an rgb led attached to pin 9 for red, 10 for green, and 11 for blue
the way my program is supposed to work goes like this:
I press the button and it should light up white (all three led's at once) and then fade out.
then if i press it a second time it should light up red then fade out, and the third press goes to green, and the fourth to blue, then back to white.
what happens is most of the times it skips 1 or more of the other colors, sometimes it skips all the way back to the one that just lit.
I'm sure I'm missing something simple here,
my code looks like this:
Quote
int trigger = 2;
int rled = 9;
int gled = 10;
int bled = 11;
int dimmingTimer = 2;
boolean lastButton = LOW;
boolean currentButton = LOW;

void setup ()
{
  pinMode (trigger, INPUT);
  pinMode (rled, OUTPUT);
  pinMode (gled, OUTPUT);
  pinMode (bled, OUTPUT);
}
//Debouce function
boolean debounce(boolean last)
{
  boolean current = digitalRead(trigger);
  if (last != current)
  {
    delay(5);
    current = digitalRead(trigger);
  }
  return current;
}

void loop()
{
  currentButton = debounce(lastButton);
  if (lastButton == LOW && currentButton == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(rled, fadeValue);  
    analogWrite(gled, fadeValue);
    analogWrite(bled, fadeValue);    
    // wait time between dimming steps    
    delay (dimmingTimer);
  }
    lastButton = currentButton;
    currentButton = debounce(lastButton);
    if (lastButton == LOW && currentButton == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(rled, fadeValue);      
    // wait time between dimming steps    
    delay (dimmingTimer);
  }
  lastButton = currentButton;
    currentButton = debounce(lastButton);
    if (lastButton == LOW && currentButton == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(gled, fadeValue);      
    // wait time between dimming steps    
    delay (dimmingTimer);
  }
  lastButton = currentButton;
      currentButton = debounce(lastButton);
    if (lastButton == LOW && currentButton == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(bled, fadeValue);      
    // wait time between dimming steps    
    delay (dimmingTimer);
  }
  lastButton = currentButton;
}

my button is pulled down to ground wit a 10k resisterand pulls high to 5v when pressed, and I am lighting up a a 12v led strip by controlling 3 mosfetts with pwm signal.

Any help would be much appreciated. Thank you in advance
« Last Edit: October 11, 2012, 05:43:11 pm by littlefoot » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 630
Posts: 49998
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All the time that you are diddling around fading LEDs has taken care of any bouncing of the switch, unless you have the worlds crappiest switch.

You don't need that convoluted debounce function.

You should have some Serial.print() statements to see what is going on. And, of course, a Serial.begin() statement to set up serial communications.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for your quick reply.
I'm sure monitoring the serial data could help, but i'm not sure where i should put the serial.print() in the code, or what i'm looking for when reading the serial data. I have never done that before.
if you could point me to a specific thing i should be doing i would appreciate that a lot.
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1283
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You use serial.prin() to tell you what is going on in the program. In othefr words you write messages to yourself so that you can follow what is going on and if things go wrong you have somewhere to look.

You can look at the serial data being sent (text) in the serial monitor that is part of the Arduino IDE.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

0
Offline Offline
Newbie
*
Karma: 1
Posts: 33
Yes.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm supposing that since there is no wait between debouncing the button and looping through the code, you just keep looping and WHEN the button is pressed a pseudoRANDOM part of your code activates, "hey I got a button press after the red but before the green section so I'll light up green'.


doesn't do exactly as you say, because it doesn't wait for the old animation before mixing colours...
Includes debounce code from http://www.arduino.cc/en/Tutorial/Debounce

I don't have my duino plugged in, or any buttons/leds handy, so I can't actually test it but I'm fairly confident this will work.

 
Code:
const int triggerPin = 2;
const int rledPin = 9;
const int gledPin = 10;
const int bledPin = 11;

byte rValue = 255; //global values for the leds
byte gValue = 255;
byte bValue = 255;

int animStep = 0; //value from 0-3, referring to white, red, green, blue
int dimmingTimer = 2;   //number of mS between updates (ish).  higher = slower
boolean lastButtonState = LOW; //used for debounce, previous reading of button state
boolean buttonState = LOW;     //current reading of button state

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup ()
{
  pinMode (triggerPin, INPUT);
  pinMode (rledPin, OUTPUT);
  pinMode (gledPin, OUTPUT);
  pinMode (bledPin, OUTPUT);
}

void loop()
{
//update leds
displayColour();

//dim led values
dimLedValues();

//check for a button press, assigns values to buttonState (global)
checkButton();

//act on button if pressed, setting appropriate led value high
if (buttonState) {
updateLedValues();
buttonState = LOW;
} //end if

//animation delay
delay(dimmingTimer);

}//end loop

void updateLedValues() //button detected, update led values
{
switch (animStep) { //do cool stuff in here.
  case 0:   //first step, white
  rValue = 255;
  gValue = 255;
  bValue = 255;
    break;
  case 1: //add red
  rValue = 255;
    break;
  case 2: //add green
  gValue = 255;
    break;
  case 3: //add blue
  bValue = 255;
    break;


  default:
  break;
    // statements
}//end switch animStep
animStep++;

if (animStep > 3) animStep = 0;//loop animation


}//end updateLedValues

void checkButton() //includes debounce code from http://www.arduino.cc/en/Tutorial/Debounce
{ //saves a debounced button state to global buttonState
  // read the state of the switch into a local variable:
  int reading = digitalRead(triggerPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise: 

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
 
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
    buttonState = reading;
  }
 
  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;

}

void dimLedValues()//move r g b values down one notch if above zero
{
if (rValue>0) rValue--;
if (gValue>0) rValue--;
if (bValue>0) rValue--;
}

void displayColour() //set the analog outputs to the values set elsewhere
{
analogWrite(rledPin,rValue);
analogWrite(gledPin,gValue);
analogWrite(bledPin,gValue);
}//end displayColour
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, it doesn't quite work, the leds flicker all kinds of crazy. But i think i see where your going, I'll play around with this code and see what i can accomplish.

Thank you very much for your hard work.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, figured it all out. I think it could be more simple though.
heres what i came up with
Quote
const int trigger = 2;
const int modeButton = 4;
const int rled = 9;
const int gled = 10;
const int bled = 11;

boolean lastButton = LOW;
boolean currentButton = LOW;

int colorStep = 0;//Color identifier
int modeStep = 0;//Mode identifier
int dimmingTimer = 2; //Timer for dimming, higher = longer

//Debouce function
boolean debounce(boolean last)
{
 boolean current = digitalRead(modeButton);
  if (last != current)
  {
    delay(5);
    current = digitalRead(modeButton);
  }
  return current;
}

void setup ()
{
  pinMode (trigger, INPUT);
  pinMode (modeButton, INPUT);
  pinMode (rled, OUTPUT);
  pinMode (gled, OUTPUT);
  pinMode (bled, OUTPUT);
}

void loop()
{
  if (colorStep > 3) colorStep = 0;
  if (colorStep == 0) //White
  if (digitalRead (trigger) == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(rled, fadeValue);   
    analogWrite(gled, fadeValue);
    analogWrite(bled, fadeValue);   
    // wait time between dimming steps   
    delay (dimmingTimer);
    if (fadeValue == 0) colorStep ++;
  } 
  if (colorStep == 1) //Red
  if (digitalRead (trigger) == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(rled, fadeValue);     
    // wait time between dimming steps   
    delay (dimmingTimer);
    if (fadeValue == 0) colorStep ++;
  }
  if (colorStep == 2) //Green
  if (digitalRead (trigger) == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(gled, fadeValue);     
    // wait time between dimming steps   
    delay (dimmingTimer);
    if (fadeValue == 0) colorStep ++;
  }
  if (colorStep == 3) //Blue
  if (digitalRead (trigger) == HIGH)
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1)
  {
    // sets the value (range from 0 to 255):
    analogWrite(bled, fadeValue);     
    // wait time between dimming steps   
    delay (dimmingTimer);
    if (fadeValue == 0) colorStep = 0;
  }
}
Logged

California
Offline Offline
Faraday Member
**
Karma: 89
Posts: 3410
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Use Code tags, not Quote tags when posting code.
Logged

Pages: [1]   Go Up
Jump to: