I'm having an issue I can't figure out with debouncing a button. I'm a programming noob, this is my second project, first was making the flame effect you see in the first video below. I'm learning swiftly, but I'm stuck again. I'm aware of the various debounce hardware solutions, but I'm trying not to spend any more money on this project so I'm attempting to solve this issue with the software. I'm also just trying to learn the programming side of the arduino as much as possible.
I think the issue I'm having is the lastDebounceTime variable (taken from the debounce example) is being looped over and over again because instead of detecting a single button press, I'm trying to code a press and hold button.
The first code I have working is called TCK_grenade and is just for one button press&hold, and works fine.
The second one, TCK_Grenade_2b_deb1 is the code for one button but do two different things. The first button press&hold should spin the motor (1475 u-seconds, 1550 = still) and random the LEDs on and off. The second button press&hold should spin the motor the opposite direction (1600useconds, with 1550 being still/center) doing nothing with the LEDs.
What's happening with the debounce code, is it seems like the debounce timer is looping the debounce delay over and over. So I'll hold the button down, it will spin the servo in the correct direction for 400ms, then try to spin the motor the opposite direction for 400ms, and do that over and over all while still holding the button. What SHOULD happen is when the button is pressed and held the first time, flash the LEDS and spin the servo one way until the button is let go. When the button is pressed again, spin the servo the opposite direction so that the string can be un-wound from the spool without opening the enclosure. See the videos below for a visual.
EDIT: I Should note I'm using an SPST push button switch using the pullup resistor built into the arduino. I don't have a schmitt inverter or a resistor in the circuit other than the pullup on the button and the resistor for the LEDs.
Here's a video explaining what it should do (using TCK_grenade):
Here's a video of it's actually doing (using TCK_Grenade_2b_deb1):
I'm not going to post the TCK_grenade code, as it's just a missing all of the debounce and button press tracking code.
#include <Servo.h> // imported servo library
// Written by Will Dean, master electrician of the
// House Theatre of Chicago
// Show: The Crownless King.
// Grenade code for Davey Boone's bluff
// September, 2013
Servo myservo; // assign myservo variable from library Servo.h
// these don't change values, ever
const int buttonInput = 2;
const int lightOutput = 13; //short end gets resistor = - side
// changing variables
int buttonState; // current reading from the button input pin (pullup resisto
int ledState = -1; // I'm using the ledState to track button presses.
// Taken from a video tutorial here: http://www.youtube.com/watch?v=CnHKE_ls7F8
// 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.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 400; // the debounce time; increase if the output flickers
void setup() {
pinMode(lightOutput, OUTPUT); // setting LED pin to output the random values
pinMode(buttonInput, INPUT); // setting buttonInput pin to read Inputs
digitalWrite(buttonInput, HIGH); // Use the built in pullup resistor for button
myservo.attach(9); // setting myservo to read from pin 9
}
void loop()
{
buttonState = digitalRead(buttonInput); // read the state of the switch into a local variable
// check to see if you just pressed the button
// (ie the input when from HIGH to LOW), and you've waited
// long enough since the last press to ignore any noise:
if ((millis() - lastDebounceTime) > debounceDelay) { // millis = system time
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// BUTTON ON
if( (buttonState == LOW) && (ledState < 0) ) {
digitalWrite(lightOutput, HIGH); // Turn on LED
analogWrite(lightOutput, random(5,190)); //Make LED flash randomly
myservo.writeMicroseconds(14765); //spin servo slowly in the direction to wind the wire
ledState = -ledState; // inverse LED state
lastDebounceTime = millis(); // reset debounce timer
//BUTTON OFF
}
else { // otherwise, the button is on, IE in a LOW state
digitalWrite(lightOutput, LOW); //turn LED off
myservo.writeMicroseconds(1550); //Keep servo at 1550, which is the off position
//for this particular servo in microseconds
} // close else statement
} // close debounce if statment
// 2nd button press to unwind rope
if ((millis() - lastDebounceTime) > debounceDelay) {
//BUTTON ON
if( (buttonState == LOW) && (ledState > 0) ) {
digitalWrite(lightOutput, LOW); // Keep leds off
myservo.writeMicroseconds(1500); // Unwind servo
ledState = -ledState; // reverse ledState
lastDebounceTime = millis(); // reset debounce timer
} // close if statement
else {
//BUTTON OFF
myservo.writeMicroseconds(1550); // keep servo still
digitalWrite(lightOutput, LOW); // keep leds off
} // close last else statement
} // close debounce
} // close void loop
Thank you in advance for any help anyone can offer.
-Will