I cannot seem to get a clean button press recognition using the examples for Debouncing on the forum. I have two momentary buttons tied to digital pins 14 and 15 and I have internal-pullups enabled (but I have also tried with external 10K resistors) and the other end of the buttons to GND. I also have the +5v side of each button tied to Interrupt 1 through N4148 diodes. I have the ISR triggering on the falling edge.
My code works fine but every 4th-5th button press, even with very slow purposeful button presses, the release triggers another interrupt. Looking at this with a scope the transients giving the false trigger seem to be occurring 200 microseconds BEFORE the definitive button press. It almost looks like I am hesitating on the press. Since it happens before not after, I dont think the debounce delay has any effect. I changed buttons and types a few times with no help. Should I reverse the polarity of the buttons and have them pulled down to ground and then put a capacitor across ?
/*
Button 1 connected to D14 (input with pull up but also tried external 10K resistor to +5V
Button 2 connected to D15 (input with pull up but also tried external 10K resistor to +5V
*/
#define SERIAL_BAUD 115200
const int PWM_button = 14; //for changing PWM pin action
const int DIR_button = 15; //for changing DIR pin direction
const int INT1_Pin = 3; //only interrupt available on Moteino
const int PWM_Out_Pin = 5;
const int DIR_Out_Pin = 7;
const int DutyCycle = 127;
int button1;
int button2;
int lastPWM_buttonState = LOW; // the previous button1 from the input pin
int lastDIR_buttonState = LOW; // the previous button1 from the input pin
unsigned long last_micros_INT1;
unsigned long debouncing_time = 250;
boolean INT1_flag = false;
boolean pwm_flag = false; //intial state is off
boolean dir_flag = false; // initial state is off
void setup() {
Serial.begin(SERIAL_BAUD);
pinMode(PWM_button,INPUT_PULLUP);
pinMode(DIR_button,INPUT_PULLUP);
pinMode(INT1_Pin,INPUT_PULLUP);
pinMode(PWM_Out_Pin, OUTPUT);
pinMode(DIR_Out_Pin, OUTPUT);
// set initial state
analogWrite(PWM_Out_Pin, LOW);
digitalWrite(DIR_Out_Pin, LOW);
attachInterrupt(1, debounce_INT1, FALLING);
}
void loop() {
if (INT1_flag){
button1 = !digitalRead(PWM_button);
button2 = !digitalRead(DIR_button);
ProcessButtons();
INT1_flag = false; //reset for next interrupt
last_micros_INT1 = 0; // reset for next interrupt
}
}
void ProcessButtons()
{
if (button1)
{
if (pwm_flag == false){ //if last PWM state was OFF --> set PWM_Out_Pin to ON
analogWrite(PWM_Out_Pin,DutyCycle);
pwm_flag = true; // set to new state
}
else {
analogWrite(PWM_Out_Pin, LOW);
pwm_flag = false; // set to new state
}
}
if (button2)
{
if (dir_flag == false){
digitalWrite(DIR_Out_Pin,HIGH);
dir_flag = true; // set to new state
}
else {
digitalWrite(DIR_Out_Pin, LOW);
dir_flag = false; // set to new state
}
}
}
void debounce_INT1(){
if(((unsigned long)(micros() - last_micros_INT1) >= debouncing_time * 1000)) {
last_micros_INT1 = micros();
INT1_flag = true; //set flag but make sure to reset it later
}
}