Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced counter debouncing #8021

Merged
merged 1 commit into from
Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion tasmota/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,10 @@ struct SYSCFG {
uint8_t bri_preset_high; // F07
int8_t hum_comp; // F08

uint8_t free_f09[179]; // F09
uint8_t free_f09[175]; // F09

uint16_t pulse_counter_debounce_low; // FB8
uint16_t pulse_counter_debounce_high; // FBA
uint32_t keeloq_master_msb; // FBC
uint32_t keeloq_master_lsb; // FC0
uint32_t keeloq_serial; // FC4
Expand Down
59 changes: 55 additions & 4 deletions tasmota/xsns_01_counter.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,20 @@
#define D_PRFX_COUNTER "Counter"
#define D_CMND_COUNTERTYPE "Type"
#define D_CMND_COUNTERDEBOUNCE "Debounce"
#define D_CMND_COUNTERDEBOUNCELOW "DebounceLow"
#define D_CMND_COUNTERDEBOUNCEHIGH "DebounceHigh"

const char kCounterCommands[] PROGMEM = D_PRFX_COUNTER "|" // Prefix
"|" D_CMND_COUNTERTYPE "|" D_CMND_COUNTERDEBOUNCE ;
"|" D_CMND_COUNTERTYPE "|" D_CMND_COUNTERDEBOUNCE "|" D_CMND_COUNTERDEBOUNCELOW "|" D_CMND_COUNTERDEBOUNCEHIGH ;

void (* const CounterCommand[])(void) PROGMEM = {
&CmndCounter, &CmndCounterType, &CmndCounterDebounce };
&CmndCounter, &CmndCounterType, &CmndCounterDebounce, &CmndCounterDebounceLow, &CmndCounterDebounceHigh };

struct COUNTER {
uint32_t timer[MAX_COUNTERS]; // Last counter time in micro seconds
uint32_t timer_low_high[MAX_COUNTERS]; // Last low/high counter time in micro seconds
uint8_t no_pullup = 0; // Counter input pullup flag (1 = No pullup)
uint8_t pin_state = 0; // LSB0..3 Last state of counter pin; LSB7==0 IRQ is FALLING, LSB7==1 IRQ is CHANGE
bool any_counter = false;
} Counter;

Expand All @@ -51,7 +55,30 @@ void CounterUpdate4(void) ICACHE_RAM_ATTR;
void CounterUpdate(uint8_t index)
{
uint32_t time = micros();
uint32_t debounce_time = time - Counter.timer[index];
uint32_t debounce_time;

if (Counter.pin_state) {
// handle low and high debounce times when configured
if (digitalRead(pin[GPIO_CNTR1 +index]) == bitRead(Counter.pin_state, index)) {
// new pin state to be ignored because debounce time was not met during last IRQ
return;
}
debounce_time = time - Counter.timer_low_high[index];
if bitRead(Counter.pin_state, index) {
// last valid pin state was high, current pin state is low
if (debounce_time <= Settings.pulse_counter_debounce_high * 1000) return;
} else {
// last valid pin state was low, current pin state is high
if (debounce_time <= Settings.pulse_counter_debounce_low * 1000) return;
}
// passed debounce check, save pin state and timing
Counter.timer_low_high[index] = time;
Counter.pin_state ^= (1<<index);
// do not count on rising edge
if bitRead(Counter.pin_state, index) return;
}

debounce_time = time - Counter.timer[index];
if (debounce_time > Settings.pulse_counter_debounce * 1000) {
Counter.timer[index] = time;
if (bitRead(Settings.pulse_counter_type, index)) {
Expand Down Expand Up @@ -103,7 +130,13 @@ void CounterInit(void)
if (pin[GPIO_CNTR1 +i] < 99) {
Counter.any_counter = true;
pinMode(pin[GPIO_CNTR1 +i], bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP);
attachInterrupt(pin[GPIO_CNTR1 +i], counter_callbacks[i], FALLING);
if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high)) {
Counter.pin_state = 0;
attachInterrupt(pin[GPIO_CNTR1 +i], counter_callbacks[i], FALLING);
} else {
Counter.pin_state = 0x8f;
attachInterrupt(pin[GPIO_CNTR1 +i], counter_callbacks[i], CHANGE);
}
}
}
}
Expand Down Expand Up @@ -213,6 +246,24 @@ void CmndCounterDebounce(void)
ResponseCmndNumber(Settings.pulse_counter_debounce);
}

void CmndCounterDebounceLow(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32001)) {
Settings.pulse_counter_debounce_low = XdrvMailbox.payload;
CounterInit();
}
ResponseCmndNumber(Settings.pulse_counter_debounce_low);
}

void CmndCounterDebounceHigh(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32001)) {
Settings.pulse_counter_debounce_high = XdrvMailbox.payload;
CounterInit();
}
ResponseCmndNumber(Settings.pulse_counter_debounce_high);
}

/*********************************************************************************************\
* Interface
\*********************************************************************************************/
Expand Down