Here's an example of button debouncing you can try. My button is a jumper stuck in the button pin hole. When I ground it on the USB port housing (have to hold the board steady when I do it) that is a button press. You can use an actual button/switch, if you have the button wired to 5V and the pin side wired to ground through a pulldown resistor it will see button up as down and down as up but no damage.
All 3 of these files need to go in the sketch folder.
/* buttontimerclass example -- by GoForSmoke 2017 for public domain use
This uses a button or switch or jumper from pin 2 to GND.
Depending on your switch, the debounce value may need tuning.
Button output is a state value for use in the main sketch code.
-1, Undecided, pin state changed at least debounce-time ago.
0, button currently still not pressed.
1, button currently still pressed.
2, button released since last checked by sketch.
3, button pressed since last checked by sketch.
The main sketch may need to track previous output state for real dirty
switches. A clean switch can work with 3 ms debounce. I use 5 here.
*/
#include "Arduino.h"
#include "buttonlib.h"
// THIS IS WHERE YOU SET SWITCH PIN NUMBER AND DEBOUNCE MILLIS
buttonclass user( 2, 5 ); // pin # and debounce ms get compiled to flash
const byte ledpin = 13;
void setup()
{
Serial.begin( 115200 );
Serial.println( F( "\n Startup\n" ));
pinMode( ledpin, OUTPUT ); // default is INPUT LOW, now is OUTPUT LOW
}
void loop()
{
static byte buttonRead; // allocated once, used often
user.runButton(); // turns the crank once, make sure it runs often!
buttonRead = user.readOutput();
if ( buttonRead == 3 ) // 1st read since pressed
{
digitalWrite( ledpin, HIGH );
Serial.print( F( "button pressed millis() == " ));
Serial.println( millis());
}
else if ( buttonRead == 2 )
{
digitalWrite( ledpin, LOW );
Serial.print( F( "button released millis() == " ));
Serial.println( millis());
Serial.println( );
}
}
/*
button.h for public domain use by GoForSmoke May 29 2015
Revised Sept 2016
To use:
make a buttonclass object in your sketch
run that object every time through loop(), it is quickly done
when you want to know the status of the button, you read the object
it returns state; bit 0 = current, bit 1 = previous, bit 2 = bounce
*/
// button library, Sept 25th, 2016 by GoForSmoke
#ifndef button_h
#define button_h
#include "Arduino.h"
#define CURRENT_1 1
#define PREVIOUS_2 2
#define BOUNCE_4 4
typedef class button
{
private:
byte arduPin;
byte buttonState; // bit 0 = current, bit 1 = previous, bit 2 = bounce
byte startMs;
byte debounceMs;
public:
button(); // default constructor
void setButton( byte, byte ); // pin, debounce millis
button( byte, byte ); // pin, debounce millis
void setUpButton( void );
byte runButton( void ); // returns buttonState as below
// buttonState: bit 0 = current, bit 1 = previous, bit 2 = bounce
byte buttonRead(); // returns buttonState as above
};
#endif
// button library, Sept 25th, 2016 by GoForSmoke
#include "Arduino.h"
#include "button.h"
// button ================================================
button::button() // default constructor for arrays, needs the full setup
{
buttonState = CURRENT_1;
}
button::button( byte ap, byte dbm )
{
arduPin = ap;
debounceMs = dbm;
buttonState = CURRENT_1;
};
void button::setButton( byte ap, byte dbm ) // pin, debounce millis
{
arduPin = ap;
debounceMs = dbm;
pinMode( arduPin, INPUT_PULLUP );
};
void button::setUpButton( void )
{
pinMode( arduPin, INPUT_PULLUP );
};
byte button::buttonRead()
{
return buttonState;
};
byte button::runButton( void )
{
// static byte msNow;
buttonState &= BOUNCE_4 | CURRENT_1; // clears previous state bit
buttonState |= ( buttonState & CURRENT_1 ) << 1; // copy current state to previous
buttonState &= BOUNCE_4 | PREVIOUS_2; // clears current state bit
buttonState += digitalRead( arduPin ); // current state loaded into bit 0
// msNow = (byte) millis(); // gets the low byte of millis
if ( buttonState & 3 == CURRENT_1 || buttonState & 3 == PREVIOUS_2 ) // state change detected
{
buttonState ^= BOUNCE_4; // toggles debounce bit
// on 1st and odd # changes since last stable state, debounce is on
// on bounces back to original state, debounce is off
if ( buttonState & BOUNCE_4 )
{
// startMs = msNow; // starts/restarts the bounce clock on any change.
startMs = (byte) millis(); // starts/restarts the bounce clock on any change.
}
}
else if ( buttonState & BOUNCE_4 ) // then wait to clear debounce bit
{
// if ( msNow - startMs >= debounceMs ) // then stable button state achieved
if ( (byte)((byte)millis()) - startMs >= debounceMs ) // then stable button state achieved
{
// understand that stable state means no change for debounceMs. When time
// is over the state bits are manipulated to show a state change.
buttonState &= CURRENT_1; // clear all but the current state bit
if ( buttonState == 0 ) buttonState = PREVIOUS_2; // HIGH->LOW
else buttonState = CURRENT_1; // LOW->HIGH
// buttonState now appears as a debounced state change in bits 0 and 1
}
}
return buttonState;
};
// end button ============================================
I have another example (that uses the same library) showing how to make and use an array of buttons.