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

countio enhancements #5606

Closed
4 tasks done
dhalbert opened this issue Nov 21, 2021 · 8 comments
Closed
4 tasks done

countio enhancements #5606

dhalbert opened this issue Nov 21, 2021 · 8 comments

Comments

@dhalbert
Copy link
Collaborator

dhalbert commented Nov 21, 2021

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.
  • Add pullup/pulldown control.
@dhalbert dhalbert added this to the Long term milestone Nov 21, 2021
@mrdalgaard
Copy link

Great enhancements.
Also allowing to control pulls (pullup/pulldown), just like alarm and digitalio allows would be nice

@tonsofpcs
Copy link

@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
Copy link
Collaborator Author

dhalbert commented 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
Copy link
Collaborator Author

dhalbert commented Jan 4, 2022

Fixed by #5803.

@dhalbert dhalbert closed this as completed Jan 4, 2022
@felker
Copy link

felker commented 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
Copy link
Collaborator Author

@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.

@felker
Copy link

felker commented Mar 11, 2023

@dhalbert that is actually great to hear, since I switched to keypad after getting stuck with countio and it seems to be working quite well!

I observed debounce with countio and tried to fix it by changing await asyncio.sleep(0) to await asyncio.sleep(0.01), but clearly that did not help.

Is that how I would lengthen the polling interval in the keypad approach?

It would be great to add a paragraph or example to that interrupt guide encapsulating the info in your comment.

@dhalbert
Copy link
Collaborator Author

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.

Will do -- thanks for the suggestion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants