You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
countio.Counter was originally added to handle rotary encoders, but it can also be used as a general-purpose pin-interrupt detector. However, it could use some more functionality.
Right now Counter only counts falling edges. Generalize it to handle rising edges, and also transitions in either direction.
Provide an atomic fetch-and-clear operation, to avoid losing any counts. Some implementations use PWM instead of interrupts. It's not clear we can do this atomically cleanly.
Add an async method so you can await changes in the count. This is not really necessary: polling works, and maybe eventually we will add triggering an asyncio.Event.
@dhalbert Just read through your comments on #5803 there. It looks like it will be quite useful, thank you!
I'm curious, as I bounce between micropython and circuitpython for a project here due to differing demands, is there a way to tell how much time has elapsed in a pin state?
In the mentioned project I have a relatively slow speed serial protocol that depends on high pulse duration to determine 0/1 (0.8ms vs 1.2ms, with reset as high > 2ms OR low > 0.4ms). I've been able to decode it cleanly with 'flipping' interrupts in micropython, discerning values at > 2ms, > 1ms, and > .2 ms high and > 3ms low, through the use of utime.ticks_us() but I'd prefer to handle everything in circuitpython as the rest of my code is much cleaner and able to rely on existing libraries.
@tonsofpcs For that, you may want to try pulseio.PulseIn. We are also doing some pulse train work to read floppy discs right now, but I don't know if that will be generalized.
Is it possible to extend the functionality to read from the pin within the Counter context? I have a https://www.adafruit.com/product/3218 toggle switch connected to an M4, with the switch pins connecting a 3.3V and the input pin on the board. I want an interrupt to behave differently based on whether the switch transition to ON or OFF. But I don't seen an obvious way to read the state of the pin. I think the guide could really benefit from 1 more complicated example that uses countio.
@felker
I agree that there are use caes for reading the current state of the countio.Counter() pin, and that could be added to this API.
However, toggle switch (or any mechanical switch) is going to bounce. Instead of using countio for this, I suggest you use keypad to register switch transitions, as in https://learn.adafruit.com/cooperative-multitasking-in-circuitpython-with-asyncio/handling-interrupts#handling-interrupts-with-keypad-3106485. keypad has debouncing built in, and doesn't have to be used to pushbutton switches -- it could be used with toggle switches as well. Depending on the bounce characteristics of the switch you have, you may need to lengthen the polling interval. The keypad event (pressed or released) will implicitly give you the current state of the switch.
Is that how I would lengthen the polling interval in the keypad approach?
The interval argument in the keypad.Keys() constructor specifies the polling interval. A switch that bounces for longer might need a longer interval. If you see multiple events on a single switch throw, lengthen interval.
It would be great to add a paragraph or example to that interrupt guide encapsulating the info in your comment.
Activity
mrdalgaard commentedon Nov 22, 2021
Great enhancements.
Also allowing to control pulls (pullup/pulldown), just like alarm and digitalio allows would be nice
tonsofpcs commentedon Jan 4, 2022
@dhalbert Just read through your comments on #5803 there. It looks like it will be quite useful, thank you!
I'm curious, as I bounce between micropython and circuitpython for a project here due to differing demands, is there a way to tell how much time has elapsed in a pin state?
In the mentioned project I have a relatively slow speed serial protocol that depends on high pulse duration to determine 0/1 (0.8ms vs 1.2ms, with reset as high > 2ms OR low > 0.4ms). I've been able to decode it cleanly with 'flipping' interrupts in micropython, discerning values at > 2ms, > 1ms, and > .2 ms high and > 3ms low, through the use of utime.ticks_us() but I'd prefer to handle everything in circuitpython as the rest of my code is much cleaner and able to rely on existing libraries.
dhalbert commentedon Jan 4, 2022
@tonsofpcs For that, you may want to try
pulseio.PulseIn. We are also doing some pulse train work to read floppy discs right now, but I don't know if that will be generalized.dhalbert commentedon Jan 4, 2022
Fixed by #5803.
felker commentedon Mar 11, 2023
Really excited about this functionality--- I am working my way through https://learn.adafruit.com/cooperative-multitasking-in-circuitpython-with-asyncio/handling-interrupts right now.
Is it possible to extend the functionality to read from the pin within the Counter context? I have a https://www.adafruit.com/product/3218 toggle switch connected to an M4, with the switch pins connecting a 3.3V and the input pin on the board. I want an interrupt to behave differently based on whether the switch transition to ON or OFF. But I don't seen an obvious way to read the state of the pin. I think the guide could really benefit from 1 more complicated example that uses
countio.dhalbert commentedon Mar 11, 2023
@felker
I agree that there are use caes for reading the current state of the
countio.Counter()pin, and that could be added to this API.However, toggle switch (or any mechanical switch) is going to bounce. Instead of using
countiofor this, I suggest you usekeypadto register switch transitions, as in https://learn.adafruit.com/cooperative-multitasking-in-circuitpython-with-asyncio/handling-interrupts#handling-interrupts-with-keypad-3106485.keypadhas debouncing built in, and doesn't have to be used to pushbutton switches -- it could be used with toggle switches as well. Depending on the bounce characteristics of the switch you have, you may need to lengthen the polling interval. The keypad event (pressed or released) will implicitly give you the current state of the switch.felker commentedon Mar 11, 2023
@dhalbert that is actually great to hear, since I switched to
keypadafter getting stuck withcountioand it seems to be working quite well!I observed debounce with
countioand tried to fix it by changingawait asyncio.sleep(0)toawait asyncio.sleep(0.01), but clearly that did not help.Is that how I would lengthen the polling interval in the
keypadapproach?It would be great to add a paragraph or example to that interrupt guide encapsulating the info in your comment.
dhalbert commentedon Mar 11, 2023
The
intervalargument in thekeypad.Keys()constructor specifies the polling interval. A switch that bounces for longer might need a longerinterval. If you see multiple events on a single switch throw, lengtheninterval.Will do -- thanks for the suggestion!