Skip to content

Commit 65a2b0b

Browse files
jonathanhoggjimmo
authored andcommitted
docs/library/machine: Add docs for Counter and Encoder.
Add documentation for `machine.Counter` and `machine.Encoder` as currently implemented by the esp32 port, but intended to be implemented by other ports. Originally authored by: Ihor Nehrutsa <Ihor.Nehrutsa@gmail.com> and Jonathan Hogg <me@jonathanhogg.com>. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
1 parent 7c09952 commit 65a2b0b

File tree

6 files changed

+193
-0
lines changed

6 files changed

+193
-0
lines changed

docs/esp32/quickref.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,21 @@ Use the :ref:`esp32.PCNT <esp32.PCNT>` class::
448448
The PCNT hardware supports monitoring multiple pins in a single unit to
449449
implement quadrature decoding or up/down signal counters.
450450

451+
See the :ref:`machine.Counter <machine.Counter>` and
452+
:ref:`machine.Encoder <machine.Encoder>` classes for simpler abstractions of
453+
common pulse counting applications::
454+
455+
from machine import Pin, Counter
456+
457+
counter = Counter(0, Pin(2)) # create a counter as above and start it
458+
count = counter.value() # read the count as an arbitrary precision signed integer
459+
460+
encoder = Encoder(0, Pin(12), Pin(14)) # create an encoder and begin counting
461+
count = encoder.value() # read the count as an arbitrary precision signed integer
462+
463+
Note that the id passed to these ``Counter()`` and ``Encoder()`` objects must be
464+
a PCNT id.
465+
451466
Software SPI bus
452467
----------------
453468

docs/library/esp32.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,10 @@ implemented as thin Python shims around :class:`PCNT`.
305305
value. Thus the ``IRQ_ZERO`` event will also trigger when either of these
306306
events occurs.
307307

308+
See the :ref:`machine.Counter <machine.Counter>` and
309+
:ref:`machine.Encoder <machine.Encoder>` classes for simpler abstractions of
310+
common pulse counting applications.
311+
308312

309313
.. _esp32.RMT:
310314

docs/library/machine.Counter.rst

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
.. currentmodule:: machine
2+
.. _machine.Counter:
3+
4+
class Counter -- pulse counter
5+
==============================
6+
7+
Counter implements pulse counting by monitoring an input signal and counting
8+
rising or falling edges.
9+
10+
Minimal example usage::
11+
12+
from machine import Pin, Counter
13+
14+
counter = Counter(0, Pin(0, Pin.IN)) # create Counter for pin 0 and begin counting
15+
value = counter.value() # retrieve current pulse count
16+
17+
Availability: **ESP32**
18+
19+
Constructors
20+
------------
21+
22+
.. class:: Counter(id, ...)
23+
24+
Returns the singleton Counter object for the the given *id*. Values of *id*
25+
depend on a particular port and its hardware. Values 0, 1, etc. are commonly
26+
used to select hardware block #0, #1, etc.
27+
28+
Additional arguments are passed to the :meth:`init` method described below,
29+
and will cause the Counter instance to be re-initialised and reset.
30+
31+
On ESP32, the *id* corresponds to a :ref:`PCNT unit <esp32.PCNT>`.
32+
33+
Methods
34+
-------
35+
36+
.. method:: Counter.init(src, *, ...)
37+
38+
Initialise and reset the Counter with the given parameters:
39+
40+
- *src* specifies the input pin as a :ref:`machine.Pin <machine.Pin>` object.
41+
May be omitted on ports that have a predefined pin for a given hardware
42+
block.
43+
44+
Additional keyword-only parameters that may be supported by a port are:
45+
46+
- *edge* specifies the edge to count. Either ``Counter.RISING`` (the default)
47+
or ``Counter.FALLING``. *(Supported on ESP32)*
48+
49+
- *direction* specifies the direction to count. Either ``Counter.UP`` (the
50+
default) or ``Counter.DOWN``. *(Supported on ESP32)*
51+
52+
- *filter_ns* specifies a minimum period of time in nanoseconds that the
53+
source signal needs to be stable for a pulse to be counted. Implementations
54+
should use the longest filter supported by the hardware that is less than
55+
or equal to this value. The default is 0 (no filter). *(Supported on ESP32)*
56+
57+
.. method:: Counter.deinit()
58+
59+
Stops the Counter, disabling any interrupts and releasing hardware resources.
60+
A Soft Reset should deinitialize all Counter objects.
61+
62+
.. method:: Counter.value([value])
63+
64+
Get, and optionally set, the counter value as a signed integer.
65+
Implementations must aim to do the get and set atomically (i.e. without
66+
leading to skipped counts).
67+
68+
This counter value could exceed the range of a :term:`small integer`, which
69+
means that calling :meth:`Counter.value` could cause a heap allocation, but
70+
implementations should aim to ensure that internal state only uses small
71+
integers and therefore will not allocate until the user calls
72+
:meth:`Counter.value`.
73+
74+
For example, on ESP32, the internal state counts overflows of the hardware
75+
counter (every 32000 counts), which means that it will not exceed the small
76+
integer range until ``2**30 * 32000`` counts (slightly over 1 year at 1MHz).
77+
78+
In general, it is recommended that you should use ``Counter.value(0)`` to reset
79+
the counter (i.e. to measure the counts since the last call), and this will
80+
avoid this problem.
81+
82+
Constants
83+
---------
84+
85+
.. data:: Counter.RISING
86+
Counter.FALLING
87+
88+
Select the pulse edge.
89+
90+
.. data:: Counter.UP
91+
Counter.DOWN
92+
93+
Select the counting direction.

docs/library/machine.Encoder.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
.. currentmodule:: machine
2+
.. _machine.Encoder:
3+
4+
class Encoder -- quadrature decoding
5+
====================================
6+
7+
Encoder implements decoding of quadrature signals as commonly output from
8+
rotary encoders, by counting either up or down depending on the order of two
9+
input pulses.
10+
11+
Minimal example usage::
12+
13+
from machine import Pin, Encoder
14+
15+
counter = Counter(0, Pin(0, Pin.IN), Pin(1, Pin.IN)) # create Encoder for pins 0, 1 and begin counting
16+
value = counter.value() # retrieve current count
17+
18+
Availability: **ESP32**
19+
20+
Constructors
21+
------------
22+
23+
.. class:: Encoder(id, ...)
24+
25+
Returns the singleton Encoder object for the the given *id*. Values of *id*
26+
depend on a particular port and its hardware. Values 0, 1, etc. are commonly
27+
used to select hardware block #0, #1, etc.
28+
29+
Additional arguments are passed to the :meth:`init` method described below,
30+
and will cause the Encoder instance to be re-initialised and reset.
31+
32+
On ESP32, the *id* corresponds to a :ref:`PCNT unit <esp32.PCNT>`.
33+
34+
Methods
35+
-------
36+
37+
.. method:: Encoder.init(phase_a, phase_b, *, ...)
38+
39+
Initialise and reset the Encoder with the given parameters:
40+
41+
- *phase_a* specifies the first input pin as a
42+
:ref:`machine.Pin <machine.Pin>` object.
43+
44+
- *phase_b* specifies the second input pin as a
45+
:ref:`machine.Pin <machine.Pin>` object.
46+
47+
These pins may be omitted on ports that have predefined pins for a given
48+
hardware block.
49+
50+
Additional keyword-only parameters that may be supported by a port are:
51+
52+
- *filter_ns* specifies a minimum period of time in nanoseconds that the
53+
source signal needs to be stable for a pulse to be counted. Implementations
54+
should use the longest filter supported by the hardware that is less than
55+
or equal to this value. The default is 0 (no filter). *(Supported on ESP32)*
56+
57+
- *phases* specifies the number of signal edges to count and thus the
58+
granularity of the decoding. e.g. 4 phases corresponds to "4x quadrature
59+
decoding", and will result in four counts per pulse. Ports may support
60+
either 1, 2, or 4 phases and the default is 1 phase. *(Supported on ESP32)*
61+
62+
.. method:: Encoder.deinit()
63+
64+
Stops the Encoder, disabling any interrupts and releasing hardware resources.
65+
A Soft Reset should deinitialize all Encoder objects.
66+
67+
.. method:: Encoder.value([value])
68+
69+
Get, and optionally set, the encoder value as a signed integer.
70+
Implementations should aim to do the get and set atomically.
71+
72+
See :meth:`machine.Counter.value` for details about overflow of this value.

docs/library/machine.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ Classes
262262
machine.I2S.rst
263263
machine.RTC.rst
264264
machine.Timer.rst
265+
machine.Counter.rst
266+
machine.Encoder.rst
265267
machine.WDT.rst
266268
machine.SD.rst
267269
machine.SDCard.rst

docs/reference/glossary.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ Glossary
188188
Most MicroPython boards make a REPL available over a UART, and this is
189189
typically accessible on a host PC via USB.
190190

191+
small integer
192+
MicroPython optimises the internal representation of integers such that
193+
"small" values do not take up space on the heap, and calculations with
194+
them do not require heap allocation. On most 32-bit ports, this
195+
corresponds to values in the interval ``-2**30 <= x < 2**30``, but this
196+
should be considered an implementation detail and not relied upon.
197+
191198
stream
192199
Also known as a "file-like object". A Python object which provides
193200
sequential read-write access to the underlying data. A stream object

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy