8000 docs/esp32: Add PCNT documentation. · fluispotter/micropython@53c1269 · GitHub
[go: up one dir, main page]

Skip to content

Commit 53c1269

Browse files
jonathanhoggkapetan
authored andcommitted
docs/esp32: Add PCNT documentation.
Document the new `esp32.PCNT` class for hardware pulse counting.
1 parent 4bc0485 commit 53c1269

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

docs/esp32/quickref.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,25 @@ supported ADC resolutions:
450450
- ``ADC.WIDTH_12BIT`` = 12
451451

452452

453+
Pulse Counter (pin pulse/edge counting)
454+
---------------------------------------
455+
456+
The ESP32 provides up to 8 pulse counter peripherals depending on the hardware,
457+
with id 0..7. These can be configured to count rising and/or falling edges on
458+
any input pin.
459+
460+
Use the :ref:`esp32.PCNT <esp32.PCNT>` class::
461+
462+
from machine import Pin
463+
from esp32 import PCNT
464+
465+
counter = PCNT(0, pin=Pin(2), rising=PCNT.INCREMENT) # create counter
466+
counter.start() # start counter
467+
count = counter.value() # read count, -32768..32767
468+
counter.value(0) # reset counter
469+
count = counter.value(0) # read and reset
470+
471+
453472
Software SPI bus
454473
----------------
455474

docs/library/esp32.rst

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,125 @@ Constants
164164

165165
Used in `idf_heap_info`.
166166

167+
168+
.. _esp32.PCNT:
169+
170+
PCNT
171+
----
172+
173+
This class provides access to the ESP32 hardware support for pulse counting.
174+
There are 8 pulse counter units, with id 0..7.
175+
176+
.. class:: PCNT([id], *, ...)
177+
178+
Create a new PCNT object with the given unit ``id`` or return the existing
179+
object if it has already been created. If the ``id`` positional argument is
180+
not supplied then a new object is created for the first unallocated PCNT
181+
unit. Keyword arguments are passed to the ``init()`` method as described
182+
below.
183+
184+
.. method:: PCNT.init(*, ...)
185+
186+
(Re-)initialise a pulse counter unit. Supported keyword arguments are:
187+
188+
- ``pin``: the input Pin to monitor for pulses
189+
- ``rising``: an action to take on a rising edge - one of
190+
``PCNT.INCREMENT``, ``PCNT.DECREMENT`` or ``PCNT.IGNORE`` (the default)
191+
- ``falling``: an action to take on a falling edge
192+
- ``mode_pin``: ESP32 pulse counters support monitoring a second pin and
193+
altering the behaviour of the counter based on its level - set this
194+
keyword to any input Pin
195+
- ``mode_low``: set to either ``PCNT.HOLD`` or ``PCNT.REVERSE`` to
196+
either suspend counting or reverse the direction of the counter (i.e.,
197+
``PCNT.INCREMENT`` behaves as ``PCNT.DECREMENT`` and vice versa)
198+
when ``mode_pin`` is low
199+
- ``mode_high``: as ``mode_low`` but for the behaviour when ``mode_pin``
200+
is high
201+
- ``filter``: set to a value 1..1023, in ticks of the 80MHz clock, to
202+
enable the pulse width filter
203+
- ``minimum``: set to the minimum level of the counter value when
204+
decrementing (-32768..-1) or 0 to disable
205+
- ``maximum``: set to the maximum level of the counter value when
206+
incrementing (1..32767) or 0 to disable
207+
- ``threshold0``: sets the counter value for the
208+
``PCNT.IRQ_THRESHOLD0`` event (see ``irq`` method)
209+
- ``threshold1``: sets the counter value for the
210+
``PCNT.IRQ_THRESHOLD1`` event (see ``irq`` method)
211+
- ``value``: reset the counter value (must be 0 if specified)
212+
- ``channel``: see description below
213+
214+
The hardware initialisation is done in stages and so some of the keyword
215+
arguments can be used in groups or in isolation to partially reconfigure a
216+
unit:
217+
218+
- the ``pin`` keyword (optionally combined with ``mode_pin``) can be used
219+
to change just the bound pin(s)
220+
- ``rising`, ``falling``, ``mode_low`` and ``mode_high`` can be used
221+
(singly or together) to change the counting logic - omitted keywords
222+
use their default (``PCNT.IGNORE`` or ``PCNT.NORMAL``)
223+
- ``filter`` can be used to change only the pulse width filter (with 0
224+
disabling it)
225+
- each of ``minimum``, ``maximum``, ``threshold0`` and ``threshold1`` can
226+
be used to change these limit/event values individually; however,
227+
setting any will reset the counter to zero (i.e., they imply
228+
``value=0``)
229+
230+
Each pulse counter unit supports two channels, 0 and 1, each able to
231+
monitor different pins with different counting logic but updating the same
232+
counter value. Use ``channel=1`` with the ``pin``, ``rising``, ``falling``,
233+
``mode_pin``, ``mode_low`` and ``mode_high`` keywords to configure the
234+
second channel.
235+
236+
The second channel can be used to configure 4X quadrature decoding with a
237+
single counter unit::
238+
239+
pin_a = Pin(2, Pin.INPUT, pull=Pin.PULL_UP)
240+
pin_b = Pin(3, Pin.INPUT, pull=Pin.PULL_UP)
241+
rotary = PCNT(0, pin=pin_a, falling=PCNT.INCREMENT, rising=PCNT.DECREMENT, mode_pin=pin_b, mode_low=PCNT.REVERSE)
242+
rotary.init(channel=1, pin=pin_b, falling=PCNT.DECREMENT, rising=PCNT.INCREMENT, mode_pin=pin_a, mode_low=PCNT.REVERSE)
243+
rotary.start()
244+
245+
.. method:: PCNT.value([value])
246+
247+
Call this method with no arguments to return the current counter value or
248+
pass the value 0 to reset the counter and return the value before reset.
249+
ESP32 pulse counters do not support being set to any value other than 0.
250+
Read and reset is not atomic and so it is possible for a pulse to be
251+
missed.
252+
253+
.. method:: PCNT.irq(handler=None, trigger=PCNT.IRQ_ZERO)
254+
255+
ESP32 pulse counters support interrupts on these counter events:
256+
257+
- ``PCNT.IRQ_ZERO``: the counter has reset to zero
258+
- ``PCNT.IRQ_MINIMUM``: the counter has hit the ``minimum`` value
259+
- ``PCNT.IRQ_MAXIMUM``: the counter has hit the ``maximum`` value
260+
- ``PCNT.IRQ_THRESHOLD0``: the counter has hit the ``threshold0`` value
261+
- ``PCNT.IRQ_THRESHOLD1``: the counter has hit the ``threshold1`` value
262+
263+
``trigger`` should be the desired events or'ed together. The ``handler``
264+
function should take a single argument which will be a bit mask indicating
265+
which counter event(s) occurred.
266+
267+
The handler is called with the MicroPython scheduler and so will run at a
268+
point after the interrupt. If another interrupt occurs before the handler
269+
has been called then the events will be coalesced together into a single
270+
call and the bit mask will indicate all events that have occurred.
271+
272+
To avoid race conditions between a handler being called and retrieving the
273+
current counter value, the ``value()`` method will force execution of any
274+
pending events before returning the current counter value (and potentially
275+
resetting the value).
276+
277+
Only one handler can be in place per-unit. Set ``handler`` to ``None`` to
278+
disable the event interrupt (or call ``irq()`` with no arguments).
279+
280+
.. Note::
281+
ESP32 pulse counters reset to *zero* when reaching the minimum or maximum
282+
value. Thus the ``IRQ_ZERO`` event will also trigger when either of these
283+
events occurs.
284+
285+
167286
.. _esp32.RMT:
168287

169288
RMT

0 commit comments

Comments
 (0)
0