Pulse counter support

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: Pulse counter support

Post by OutoftheBOTS_ » Thu Aug 01, 2019 8:40 pm

pidou46 wrote:
Thu Aug 01, 2019 5:53 am
It seems able to handel encoders: https://docs.espressif.com/projects/esp ... /pcnt.html
- it count rising and/or falling edge
- a filter can be set to avoid glinches
- up to 8 counter are availables, not as much as STM32, but it enable quite sophisticated projects.

But now the hardest part is how to bring it to esp32 micropython port ?
My C skills dates from ages, and I have no idea where to start with ? I guess setting up a toolchain (GCC, ESP-IDF, ect...)
Is there somewhere a tutorial or even a sample of ported fonctionality ?
Thanks for the link to the info. The info isn't detailed but from what I read it won't read an quadrature encoder. It does have a 2 pin mode but from what I can gather it works by 1 pin is the counter pin and the other pin is a direction pin (something like a stepper motor driver). A quadrature encoder works differently were both pins are counter pins but depending on the order of the rising and falling of the 2 pins whether it is counting up or down.

The PCNT would be great to have added for reading single channel encoder but not sure if it will be capable of reading a quadrature encoder

see STM32F407 encoder mode that is capable of both single and quadrature encoders https://www.st.com/content/ccc/resource ... %2Cnull%5D

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: Pulse counter support

Post by OutoftheBOTS_ » Sat Aug 03, 2019 6:55 am

If you really want to use ESP and need to count a number of Quadrature encoders then you might be interested in this https://lsicsi.com/products/Development ... /LS7366RSh it has 6 32bit quadrature counters and is read by SPI. It is an ardunio shield made by the manufacturer of the LS7366R chip

User avatar
elliotwoods
Posts: 23
Joined: Wed Dec 04, 2019 8:11 am

Re: Pulse counter support

Post by elliotwoods » Wed Dec 04, 2019 8:14 am

Hah interesting
I was looking into this exact same thing today.
I implemented to C side of things:
https://github.com/elliotwoods/ESP32-Qu ... master/src

Now I'm looking into making it a MicroPython module for my own use

To note : you can use the ESP32's hardware counter.
It works perfectly.
If A rises high and B is low, count up
If A rises high and B is high, count down

Look at the states of A and B to get an 'addition factor' to multiply your resolution by 4 (check Encoder.cpp at link above)

pidou46
Posts: 101
Joined: Sat May 28, 2016 7:01 pm

Re: Pulse counter support

Post by pidou46 » Tue Dec 24, 2019 9:57 am

Hi elliotwoods,

Did you complete the python side ?

I think you are really close to bring this functionality to MP.
If you can post it here, maybe someone (maybe me) would be able to implement it in esp32 branch in time for 2.0 release ?

Anyhow, thanks to have shared.
nodemcu V2 (amica)
micropython firmware Daily build 05/31/2016

User avatar
mcauser
Posts: 507
Joined: Mon Jun 15, 2015 8:03 am

Re: Pulse counter support

Post by mcauser » Tue Dec 24, 2019 11:54 pm

Here's how I attempted to add the SigmaDelta peripheral:
https://github.com/micropython/micropyt ... 5452/files
It's a very simple peripheral, but shows you the pieces needed.

The Pulse Counter peripheral is much more complex.
https://docs.espressif.com/projects/esp ... /pcnt.html
It uses interrupts, so might be able to pinch some code from:
https://github.com/micropython/micropyt ... ne_timer.c

Something I'm going to look into further after the holidays.

sengp
Posts: 2
Joined: Mon Feb 03, 2020 11:16 am

Re: Pulse counter support

Post by sengp » Mon Feb 03, 2020 11:39 am

Hello,

micropython already supports interfacing to quadrature encoded signals, e.g. rotary encoders, based on the pulse counter unit available on ESP32.
See: https://forum.littlevgl.com/t/example-f ... er/1509/20

My software (polling) and pin interrupt based approaches to implement a rotary encoder interface on the ESP32, all failed. But this hardware based approach works very well when on rotary encoders like e.g. ALPS EC11 or BOURNS PEC11L.

Have fun :),

Peter

MasterOfGizmo
Posts: 50
Joined: Sun Nov 29, 2020 8:17 pm

Re: Pulse counter support

Post by MasterOfGizmo » Fri Jan 21, 2022 7:38 am

I have recently written a module to interface to the esp32 pulse counter. Find it at https://github.com/harbaum/micropython/ ... orts/esp32

This is able to run e.g. the rotary encoder demo (https://github.com/espressif/esp-idf/tr ... ry_encoder) in Python:

Code: Select all

# rotary.py - EC11
# Python version of 
# https://github.com/espressif/esp-idf/tree/master/examples/peripherals/pcnt/rotary_encoder
from machine import PCNT, Pin
from time import sleep

# reset counter to 0 once it reaches +/- 100
EC11_PCNT_DEFAULT_HIGH_LIMIT = 100
EC11_PCNT_DEFAULT_LOW_LIMIT = -100

pcnt = PCNT(0)  # setup PCNT unit 0

# accumulate every +/- 100 steps
accumu_count = 0

# react on pin 18 edges
pcnt.config(pin = Pin(18), ctrl = Pin(19), channel = 0, 
    pos_mode = PCNT.COUNT_DEC, neg_mode = PCNT.COUNT_INC, 
    lctrl_mode = PCNT.MODE_REVERSE, hctrl_mode = PCNT.MODE_KEEP,
    counter_h_lim = EC11_PCNT_DEFAULT_HIGH_LIMIT,
    counter_l_lim = EC11_PCNT_DEFAULT_LOW_LIMIT)

# react on pin 19 edges
pcnt.config(pin = Pin(19), ctrl = Pin(18), channel = 1, 
    pos_mode = PCNT.COUNT_INC, neg_mode = PCNT.COUNT_DEC, 
    lctrl_mode = PCNT.MODE_REVERSE, hctrl_mode = PCNT.MODE_KEEP,
    counter_h_lim = EC11_PCNT_DEFAULT_HIGH_LIMIT,
    counter_l_lim = EC11_PCNT_DEFAULT_LOW_LIMIT)

pcnt.filter_value(80)
pcnt.filter_enable()

def pcnt_handler(p):
    global accumu_count

    if p.event_status() & PCNT.EVT_H_LIM:
        accumu_count += EC11_PCNT_DEFAULT_HIGH_LIMIT;
    if p.event_status() & PCNT.EVT_L_LIM:
        accumu_count -= EC11_PCNT_DEFAULT_HIGH_LIMIT;

pcnt.event_enable(PCNT.EVT_H_LIM);
pcnt.event_enable(PCNT.EVT_L_LIM);
pcnt.irq(pcnt_handler)

pcnt.counter_clear()
pcnt.counter_resume()

# for i in range(50):
while True:
    print("counter:", accumu_count + pcnt.counter_value())
    sleep(.1)

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pulse counter support

Post by Roberthh » Fri Jan 21, 2022 12:25 pm

There is a PR open and ready to merge since a while at https://github.com/micropython/micropython/pull/6639. This PR shares the API with a counter/Encoder class for the MIMXRT port and the pure Python implementations for e.g. rp2.

KJM
Posts: 158
Joined: Sun Nov 18, 2018 10:53 pm
Location: Sydney AU

Re: Pulse counter support

Post by KJM » Fri Jan 21, 2022 9:27 pm

I've seen a few claims of using the low power microcontroller buried somewhere deep in the ESP32 to count meter pulses while the main micro is in deepsleep but never enough detail available for me to actually try it out. I currently use a 4000 series cmos chip to count & query it for totals after each deepsleep but would be nice to use the slow micro.

MasterOfGizmo
Posts: 50
Joined: Sun Nov 29, 2020 8:17 pm

Re: Pulse counter support

Post by MasterOfGizmo » Sun Jan 23, 2022 10:39 am

KJM wrote:
Fri Jan 21, 2022 9:27 pm
I've seen a few claims of using the low power microcontroller buried somewhere deep in the ESP32
That's the ULP. You can already access it from MP. The ULP is explained at https://docs.espressif.com/projects/esp ... s/ulp.html

Post Reply