mirror of https://github.com/arendst/Tasmota.git
Enhanced counter debouncing
New commands CounterDebounceLow and CounterDebounceHigh to allow individual debounce times for low and high pulse widths to discard non valid falling edges. These are checked before legacy CounterDebounce checks distance between to valid falling edges. Useful to have robust counter results when using e.g. an TCRT5000 optical sensor to count electromechanical "Ferraris" electricity meters.
This commit is contained in:
parent
e5a44e6326
commit
4a2f3d87c5
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
\*********************************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue