Skip to content

ESP32 Pulse Counter Driver #5216

Description

@nevercast

Add a driver for ESP32 Pulse Counter Hardware.

Related to: #5214

Activity

  1. tve commented on Jan 5, 2020

    @tve
    Contributor

    I want to implement this. Is there an API I should copy?

  2. nevercast commented on Jan 7, 2020

    @nevercast
    ContributorAuthor

    I don't know that any other devices have a "Pulse counter" in any sense, other than using just a hardware counter driven by a pin. I also have not seen a Python implementation for one.

    Other than a constructor that takes a Pin object, and a function that gets the counts, everything else might be device specific. Since this issue is ESP32 specific, perhaps go with something that is a close mapping to https://docs.espressif.com/projects/esp-idf/en/v3.3/api-reference/peripherals/pcnt.html in the same way that the RMT implementation closely matches the ESP IDF implementation.

    For now, I'd say, implement it under the esp32 namespace. from esp32 import PCNT, and we can discuss the API and make it more generic in the future.

    It's generally understood by the community that I've interfaced with that classes under the device specific namespaces are far more likely to change than something under machine for example. So start with the device specific implementation so that we have something to discuss and we can go from there.

    Thanks for offering your time to improve MicroPython ❤️ 🐍

  3. tve commented on Jan 7, 2020

    @tve
    Contributor

    Thanks for the comment. Please see #5496
    There is nothing esp32-specific in there and it is one abstraction on top of a generic timer that exposes one set of use-cases. There's also a link there to a thread on slack discussing it.

  4. sengpw commented on Jan 27, 2020

    @sengpw

    I want to implement this. Is there an API I should copy?

    Seems it is already implemented:
    from machine import DEC

    See:
    https://people.eecs.berkeley.edu/~boser/courses/49_sp_2019/N_gpio.html#_quadrature_decoder

    Sources seem to be here:
    https://github.com/bboser/MicroPython_ESP32_psRAM_LoBo/commit/15806f44ad565e77967da57d67ad068001f44e28

    But have no idea how to upstream this to micropython 1.12.

    Any ideas?

    Best regards,

    Peter

  5. tve commented on Jan 27, 2020

    @tve
    Contributor

    Use #5496?

  6. sengpw commented on Jan 28, 2020

    @sengpw

    Use #5496?

    I'm not shure about it, may be it's related to (see above):

    Add a driver for ESP32 Pulse Counter Hardware.

    Related to: #5214

    Already made some efforts, could integrate the code into lv-micropython V1.12. --> Test run OK. Must verify it on real hardware. But quadrature - decoder interface including counter based on ESP32 hardware seems to be already done. I'll notice when finished.

    best regards
    Peter

  7. mattytrentini commented on Jun 5, 2020

    @mattytrentini
    SponsorContributor

    The CircuitPython countio implementation is simple and neat; may be a good starting point for reference. (I see it's effectively a subset of yours, @tve).

  8. tve commented on Jun 5, 2020

    @tve
    Contributor

    I believe this is best implemented as dynamically loadable driver. This way it's easy to change things around. I did that: https://github.com/tve/mpy-lib/tree/master/esp32-counter. Of course that relies on #5711 but perhaps that gets reviewed someday and maybe even merged if the stars align...

  9. jonathanhogg commented on Jul 24, 2021

    @jonathanhogg
    Contributor

    I have need of the pulse counter in a current ESP32 project and, not seeing any maintained implementations, have gone ahead and rolled another. Sorry.

    Since there doesn't seem to be much movement on the idea of exposing the IDF functions through dynamic linking, I've just added it as a straight-C extension of the machine module in the ESP32 port. I started copying your API from #5496, @tve, but then took a slightly different tack when I realised that I couldn't figure out how to support all of the features of the ESP32 PCNT peripheral with it.

    So I have gone for this in the simple case:

    from machine import Counter, Pin
    
    counter = Counter(0, pin=Pin(12, Pin.IN), rising=Counter.INCREMENT)
    counter.start()
    count = counter.value()

    This looks like it ought to work OK as an API for other ports. However, using rising= and falling= instead of edge= allows for both to be specified, which means the extended functionality of the ESP32 PCNT peripheral can be used to do easy 1X decoding of a quadrature rotary encoder:

    from machine import Counter, Pin
    
    pin_a = Pin(12, Pin.IN, pull=Pin.PULL_UP)
    pin_b = Pin(14, Pin.IN, pull=Pin.PULL_UP)
    counter = Counter(0, pin=pin_a, rising=Counter.DECREMENT, falling=Counter.INCREMENT,
                         mode_pin=pin_b, mode_high=Counter.NORMAL, mode_low=Counter.HOLD)
    counter.start()
    count = counter.value()

    Or use mode_low=Counter.REVERSE to do 2X decoding. In fact, this implementation also supports calling the .init() method with an additional channel=1 keyword argument to configure the second channel of the PCNT, allowing for 4X decoding on a single PCNT unit.

    It also supports filter= to set the short pulse filter, minimum= and maximum= for setting counter limits, threshold0= and threshold1= for setting threshold event levels and all of the PCNT events (IRQ_ZERO, IRQ_MINIMUM, IRQ_MAXIMUM, IRQ_THRESHOLD0 and IRQ_THRESHOLD1) via the .irq(trigger=, handler=) method.

    I've not written any documentation for it yet I'm afraid. It's sitting in draft PR #7582 if anyone is interested in looking at it. Like I say, my primary reason for doing this is that I need it more than that I'm interested in seeing it through to mainline. I don't have any hardware for the other MicroPython architectures to work on an implementation of Counter for them.

  10. IhorNehrutsa commented on Dec 13, 2021

    @IhorNehrutsa
    Contributor

    docs\machine: Add Counter and Encoder classes. #8072
    ESP32: New hardware PCNT Counter() and Encoder(). #6639

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions