Options for using peripherals (PCNT?) for switch debouncing

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Options for using peripherals (PCNT?) for switch debouncing

Postby meowsqueak » Wed Jan 10, 2018 1:11 am

The two "classical" ways to debounce a switch in software involve either regular polling followed by a counter, delay or shift register, or use of an interrupt with a timestamp comparison to disregard spurious transitions.

I had an idea to use the counter peripheral (PCNT) to debounce a switch - the idea being that the switch could be used as the control input to a counter such that it would count up when it's asserted, and count down when it isn't. The idea is that the counter might start at, say, 0, and if it counts up to 10 then the switch is considered "pressed", and if it counts down to -10 then it's considered "released". Anywhere in-between is "undecided". Once one of these threshold values is reached, the counter is limited to that value and can only keep the same value, or move back towards the other threshold.

The counter needs a regular and persistent clock to count from. Perhaps a GPIO could be shared with, say, an PWM output channel that is generating the clock pulses at a known rate (say, 1 kHz). Then if the switch is asserted, so is the control signal and the counter will count up. I think the PCNT can be configured to count down when the control signal is de-asserted. If a threshold is reached, a watchpoint interrupt can be used to signal to a task that the switch state has changed.

The main problem seems to be that the maximum/minimum threshold "watchpoints" reset the counter to zero when reached, so I can't see a way for the threshold value to be "held" while the switch state is maintained. However even if the counter is being reset every, say, 10ms, then it acts as an interrupt filter, only generating one switch state interrupt for every 10 or so GPIO transitions. So maybe this is a viable option.

I've noticed that the counter also has a filter, so I wondered if it can be used to debounce the switch signal directly. However the filter length seems to be tied directly to the APB clock, so with a maximum value of 1023 cycles (12.79 us) it isn't long enough for many switches that have bounces in the order of a few milliseconds.

I'm left considering what other ideas are viable on this platform. Although I could just have a dedicated task that sleeps for 1/100th of a second and regularly samples the GPIO to debounce "in software", it would be interesting to see if there's a way to offload this to the hardware.

Any ideas?

ESP_Sprite
Posts: 9761
Joined: Thu Nov 26, 2015 4:08 am

Re: Options for using peripherals (PCNT?) for switch debouncing

Postby ESP_Sprite » Wed Jan 10, 2018 8:02 am

I doubt the pulse counter is viable... it counts pulses on its input, not time, so when you press the button, you may get a pulse count anywhere from 1 to lots. When you release the key again, 0 to a lot of counts is added to the counter again. You have no way to deduce the key state from that.

For what you can use: the MCPWM module has got a lot of options, and I'd suspect you could configure that to do what you want, but I don't immediately see how. You may also be able to use the RMT: as far as I can see, it can start measuring after a level change and only cause an interrupt when it hasn't seen a change for a while. But to be fair, in general I'd implement debouncing in software nowadays.

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Options for using peripherals (PCNT?) for switch debouncing

Postby meowsqueak » Thu Jan 11, 2018 6:55 am

Ok, fair enough - probably too much effort for too little gain.

So, "debouncing in software" in this context might be a simple FreeRTOS task with a (say) 10-tick delay that simply samples the GPIO regularly and debounces that (e.g. history comparison)? That's what I have been using with success, although I've seen interrupt-based mechanisms with FreeRTOS too.

ESP_Sprite
Posts: 9761
Joined: Thu Nov 26, 2015 4:08 am

Re: Options for using peripherals (PCNT?) for switch debouncing

Postby ESP_Sprite » Thu Jan 11, 2018 1:54 pm

Yes, you can either use a task, or e.g. an esp_timer callback to read out the buttons and debounce them like that.

Who is online

Users browsing this forum: Bing [Bot] and 90 guests