Skip to content

Commit 1341eac

Browse files
committed
DRIVERS.md Improve Encoder description.
1 parent c85001f commit 1341eac

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

v3/docs/DRIVERS.md

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -340,35 +340,37 @@ this for applications requiring rapid response.
340340

341341
# 6. Quadrature encoders
342342

343-
This is a work in progress. Changes may occur.
344-
345343
The `Encoder` class is an asynchronous driver for control knobs based on
346344
quadrature encoder switches such as
347345
[this Adafruit product](https://www.adafruit.com/product/377). The driver is
348346
not intended for applications such as CNC machines where
349347
[a solution such as this one](https://github.com/peterhinch/micropython-samples#47-rotary-incremental-encoder)
350348
is required. Drivers for NC machines must never miss an edge. Contact bounce or
351349
vibration induced jitter can cause transitions to occur at a high rate; these
352-
must be tracked.
350+
must be tracked. Consequently callbacks occur in an interrupt context with the
351+
associated concurrency issues.
353352

354-
This driver runs the user supplied callback in an `asyncio` context, so it runs
355-
only when other tasks have yielded to the scheduler. This ensures that the
356-
callback can run safely, even if it triggers complex application behaviour.
353+
This driver runs the user supplied callback in an `asyncio` context, so that
354+
the callback runs only when other tasks have yielded to the scheduler. This
355+
ensures that the callback runs with the same rules as apply to any `uasyncio`
356+
task. This offers safety, even if the task triggers complex application
357+
behaviour.
357358

358359
The `Encoder` can be instantiated in such a way that its effective resolution
359360
can be reduced. A virtual encoder with lower resolution can be useful in some
360361
applications.
361362

362363
The driver allows limits to be assigned to the virtual encoder's value so that
363364
a dial running from (say) 0 to 100 may be implemented. If limits are used,
364-
encoder values no longer represent absolute angles, as the user might continue
365-
to rotate the dial when it is "stuck" at an endstop.
365+
encoder values no longer approximate absolute angles: the user might continue
366+
to rotate the dial when its value is "stuck" at an endstop.
366367

367368
The callback only runs if a change in position of the virtual encoder has
368369
occurred. In consequence of the callback running in an `asyncio` context, by
369370
the time it is scheduled, the encoder's position may have changed by more than
370371
one increment. The callback receives two args, the absolute value of the
371-
virtual encoder and the signed change since the previous callback run.
372+
virtual encoder at the time it was triggered and the signed change in this
373+
value since the previous time the callback ran.
372374

373375
## 6.1 Encoder class
374376

@@ -385,34 +387,41 @@ Constructor arguments:
385387
down, to produce a virtual encoder with lower resolution. This was found usefl
386388
in some applications with the Adafruit encoder.
387389
7. `callback=lambda a, b : None` Optional callback function. The callback
388-
receives two args, `v` being the encoder's current value and `delta` being
389-
the signed difference between the current value and the previous one. Further
390-
args may be appended by the following.
390+
receives two integer args, `v` being the virtual encoder's current value and
391+
`delta` being the signed difference between the current value and the previous
392+
one. Further args may be appended by the following.
391393
8. `args=()` An optional tuple of positionl args for the callback.
392394

393395
Synchronous method:
394-
* `value` No args. Returns an integer being the `Encoder` current value.
396+
* `value` No args. Returns an integer being the virtual encoder's current
397+
value.
395398

396399
Class variable:
397400
* `delay=100` After motion is detected the driver waits for `delay` ms before
398401
reading the current position. This was found useful with the Adafruit encoder
399402
which has mechanical detents, which span multiple increments or decrements. A
400-
delay gives time for motion to stop enabling just one call to the callback.
403+
delay gives time for motion to stop in the event of a single click movement.
404+
If this occurs the delay ensures just one call to the callback. With no delay
405+
a single click typically gives rise to two callbacks, the second of which can
406+
come as a surprise in visual applications.
401407

402-
#### Note
408+
#### Note on accuracy
403409

404410
The driver works by maintaining an internal value `._v` which uses hardware
405411
interrupts to track the absolute position of the physical encoder. In theory
406-
this should be precise, but on ESP32 with the Adafruit encoder it is not:
407-
returning the dial to a given detent shows a small "drift" in position.
408-
409-
Currently under investigation: it may be a consequence of ESP32's use of soft
410-
IRQ's.
411-
412-
This is probably of little practical consequence as encoder knobs are usually
413-
used in systems where there is user feedback. In a practical application
414-
([micro-gui](https://github.com/peterhinch/micropython-micro-gui)) I can see no
415-
evidence of the missed pulses.
412+
this should be precise with jitter caused by contact bounce being tracked. With
413+
the Adafruit encoder it is imprecise: returning the dial to a given detent
414+
after repeated movements shows a gradual "drift" in position. This occurs on
415+
hosts with hard or soft IRQ's. I attempted to investigate this with various
416+
hardware and software techniques and suspect there may be mechanical issues in
417+
the device. Possibly pulses may occasionally missed with direction-dependent
418+
probability. Unlike optical encoders these low cost controls make no claim to
419+
absolute accuracy.
420+
421+
This is of little practical consequence as encoder knobs are usually used in
422+
systems where there is user feedback. In a practical application
423+
([micro-gui](https://github.com/peterhinch/micropython-micro-gui)) there is no
424+
obvious evidence of the missed pulses.
416425

417426
###### [Contents](./DRIVERS.md#1-contents)
418427

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