From 2edd393e2ede176059d2f4c2a7d96e25aaedf1ff Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Sun, 16 Jul 2017 18:32:51 -0700 Subject: [PATCH] Fixed switch debouncing in the face of noise --- avr/src/config.h | 3 --- avr/src/switch.c | 70 +++++++++--------------------------------------- 2 files changed, 13 insertions(+), 60 deletions(-) diff --git a/avr/src/config.h b/avr/src/config.h index 3af3284..91fa972 100644 --- a/avr/src/config.h +++ b/avr/src/config.h @@ -103,8 +103,6 @@ enum { // Switch settings. See switch.c #define SWITCH_INTLVL PORT_INT0LVL_MED_gc -#define SW_LOCKOUT_TICKS 250 // ms -#define SW_DEGLITCH_TICKS 30 // ms // Motor ISRs @@ -242,7 +240,6 @@ enum { #define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arcs #define JUNCTION_DEVIATION 0.05 // default value, in mm #define JUNCTION_ACCELERATION 100000 // centripetal corner accel -#define JOG_JERK_MULT 1 // Jogging jerk multipler #define JOG_MIN_VELOCITY 10 // mm/min #define CAL_ACCELERATION 500000 // mm/min^2 #define CURRENT_SENSE_RESISTOR 0.05 // ohms diff --git a/avr/src/switch.c b/avr/src/switch.c index dbdacb0..3508cff 100644 --- a/avr/src/switch.c +++ b/avr/src/switch.c @@ -26,23 +26,6 @@ \******************************************************************************/ -/* Normally open switches (NO) trigger an interrupt on the - * falling edge and lockout subsequent interrupts for the defined - * lockout period. This approach beats doing debouncing as an - * integration as switches fire immediately. - * - * Normally closed switches (NC) trigger an interrupt on the - * rising edge and lockout subsequent interrupts for the defined - * lockout period. - * - * These functions interact with each other to process switch closures - * and firing. Each switch has a counter which is initially set to - * negative SW_DEGLITCH_TICKS. When a switch closure is DETECTED the - * count increments for each RTC tick. When the count reaches zero - * the switch is tripped and action occurs. The counter continues to - * increment positive until the lockout is exceeded. - */ - #include "switch.h" #include "config.h" @@ -51,21 +34,13 @@ #include -typedef enum { - SW_IDLE, - SW_DEGLITCHING, - SW_LOCKOUT -} switch_debounce_t; - - typedef struct { uint8_t pin; switch_type_t type; switch_callback_t cb; bool state; - switch_debounce_t debounce; - int16_t count; + bool triggered; } switch_t; @@ -84,22 +59,15 @@ static switch_t switches[SWITCHES] = { }; -static bool _read_state(const switch_t *s) { - return IN_PIN(s->pin); -} +static bool _read_state(const switch_t *s) {return IN_PIN(s->pin);} static void _switch_isr() { for (int i = 0; i < SWITCHES; i++) { switch_t *s = &switches[i]; - bool state = _read_state(s); - - if (state == s->state || s->type == SW_DISABLED) continue; - - s->debounce = SW_DEGLITCHING; - s->count = -SW_DEGLITCH_TICKS; // reset deglitch count - s->state = state; - PORT(s->pin)->INT0MASK &= ~BM(s->pin); // Disable INT0 + if (s->type == SW_DISABLED || s->triggered) continue; + s->triggered = _read_state(s) != s->state; + if (s->triggered) PORT(s->pin)->INT0MASK &= ~BM(s->pin); // Disable INT0 } } @@ -115,9 +83,9 @@ ISR(PORTF_INT0_vect) {_switch_isr();} void _switch_enable(switch_t *s, bool enable) { if (enable) { - PORT(s->pin)->INT0MASK |= BM(s->pin); // Enable INT0 + s->triggered = false; s->state = _read_state(s); // Initialize state - s->debounce = SW_IDLE; + PORT(s->pin)->INT0MASK |= BM(s->pin); // Enable INT0 } else PORT(s->pin)->INT0MASK &= ~BM(s->pin); // Disable INT0 } @@ -142,26 +110,14 @@ void switch_rtc_callback() { for (int i = 0; i < SWITCHES; i++) { switch_t *s = &switches[i]; - if (s->type == SW_DISABLED || s->debounce == SW_IDLE) continue; - - // state is either lockout or deglitching - if (++s->count == SW_LOCKOUT_TICKS) { - PORT(s->pin)->INT0MASK |= BM(s->pin); // Reenable INT0 - bool state = _read_state(s); - s->debounce = SW_IDLE; + if (s->type == SW_DISABLED || !s->triggered) continue; - // check if the state has changed while we were in lockout - if (s->state != state) { - s->state = state; - s->debounce = SW_DEGLITCHING; - s->count = -SW_DEGLITCH_TICKS; - } - - continue; - } + bool state = _read_state(s); + s->triggered = false; + PORT(s->pin)->INT0MASK |= BM(s->pin); // Reenable INT0 - if (!s->count) { // switch triggered - s->debounce = SW_LOCKOUT; + if (state != s->state) { + s->state = state; if (s->cb) s->cb(i, switch_is_active(i)); } } -- 2.27.0