Fixed switch debouncing in the face of noise
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 17 Jul 2017 01:32:51 +0000 (18:32 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 17 Jul 2017 01:32:51 +0000 (18:32 -0700)
avr/src/config.h
avr/src/switch.c

index 3af328494840278a35f1bc27f21f7a03496ecde1..91fa97281586340e7e920d127f09ddd993d3935f 100644 (file)
@@ -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
index dbdacb048a6426188cc89b5ad0cd381a947cb7eb..3508cffc71980a27d7816e546ecdd34a5c35902e 100644 (file)
 
 \******************************************************************************/
 
-/* 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"
 
 #include <stdbool.h>
 
 
-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));
     }
   }