From 9debd0b29d530303ef0e1d14014efe90efe64d0d Mon Sep 17 00:00:00 2001 From: Clough42 Date: Tue, 6 Oct 2020 15:10:38 -0700 Subject: [PATCH] Aggressively filter bad key input: require multiple consecutive reads, validate only one key is pressed, require all keys to be released beteween valid actions. --- els-f280049c/ControlPanel.cpp | 49 +++++++++++++++++++++++++++++++++-- els-f280049c/ControlPanel.h | 6 +++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/els-f280049c/ControlPanel.cpp b/els-f280049c/ControlPanel.cpp index 72ebc9b..5a6a5ba 100644 --- a/els-f280049c/ControlPanel.cpp +++ b/els-f280049c/ControlPanel.cpp @@ -32,6 +32,9 @@ // Time delay after sending read command, before clocking in data #define DELAY_BEFORE_READING_US 3 +// Number of times a key state must be read consecutively to be considered stable +#define MIN_CONSECUTIVE_READS 3 + // Lower the TM1638 CS (STB) line #define CS_ASSERT GpioDataRegs.GPBCLEAR.bit.GPIO33 = 1 @@ -47,6 +50,8 @@ ControlPanel :: ControlPanel(SPIBus *spiBus) this->value = NULL; this->leds.all = 0; this->keys.all = 0; + this->stableKeys.all = 0; + this->stableCount = 0; this->message = NULL; this->brightness = 3; } @@ -236,13 +241,53 @@ KEY_REG ControlPanel :: getKeys() configureSpiBus(); newKeys = readKeys(); - if( newKeys.all != this->keys.all ) { + if( isValidKeyState(newKeys) && isStable(newKeys) && newKeys.all != this->keys.all ) { + KEY_REG previousKeys = this->keys; // remember the previous stable value this->keys = newKeys; - return newKeys; + + if( previousKeys.all == 0 ) { // only act if the previous stable value was no keys pressed + return newKeys; + } } return noKeys; } +bool ControlPanel :: isValidKeyState(KEY_REG testKeys) { + // filter out any states with multiple keys pressed (bad communication filter) + switch(testKeys.all) { + case 0: + case 1 << 0: + case 1 << 2: + case 1 << 3: + case 1 << 4: + case 1 << 5: + case 1 << 6: + case 1 << 7: + return true; + } + + return false; +} + + +bool ControlPanel :: isStable(KEY_REG testKeys) { + // don't trust any read key state until we've seen it multiple times consecutively (noise filter) + if( testKeys.all != stableKeys.all ) + { + this->stableKeys = testKeys; + this->stableCount = 1; + } + else + { + if( this->stableCount < MIN_CONSECUTIVE_READS ) + { + this->stableCount++; + } + } + + return this->stableCount >= MIN_CONSECUTIVE_READS; +} + void ControlPanel :: setMessage( const Uint16 *message ) { this->message = message; diff --git a/els-f280049c/ControlPanel.h b/els-f280049c/ControlPanel.h index 2b8b92c..f118f1a 100644 --- a/els-f280049c/ControlPanel.h +++ b/els-f280049c/ControlPanel.h @@ -137,6 +137,10 @@ class ControlPanel // current key states KEY_REG keys; + // number of times current key state has been seen + KEY_REG stableKeys; + Uint16 stableCount; + // current override message, or NULL if none const Uint16 *message; @@ -159,6 +163,8 @@ class ControlPanel Uint16 reverse_byte(Uint16 x); void initSpi(); void configureSpiBus(void); + bool isValidKeyState(KEY_REG); + bool isStable(KEY_REG); public: ControlPanel(SPIBus *spiBus);