@@ -340,35 +340,37 @@ this for applications requiring rapid response.
340
340
341
341
# 6. Quadrature encoders
342
342
343
- This is a work in progress. Changes may occur.
344
-
345
343
The ` Encoder ` class is an asynchronous driver for control knobs based on
346
344
quadrature encoder switches such as
347
345
[ this Adafruit product] ( https://www.adafruit.com/product/377 ) . The driver is
348
346
not intended for applications such as CNC machines where
349
347
[ a solution such as this one] ( https://github.com/peterhinch/micropython-samples#47-rotary-incremental-encoder )
350
348
is required. Drivers for NC machines must never miss an edge. Contact bounce or
351
349
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.
353
352
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.
357
358
358
359
The ` Encoder ` can be instantiated in such a way that its effective resolution
359
360
can be reduced. A virtual encoder with lower resolution can be useful in some
360
361
applications.
361
362
362
363
The driver allows limits to be assigned to the virtual encoder's value so that
363
364
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.
366
367
367
368
The callback only runs if a change in position of the virtual encoder has
368
369
occurred. In consequence of the callback running in an ` asyncio ` context, by
369
370
the time it is scheduled, the encoder's position may have changed by more than
370
371
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.
372
374
373
375
## 6.1 Encoder class
374
376
@@ -385,34 +387,41 @@ Constructor arguments:
385
387
down, to produce a virtual encoder with lower resolution. This was found usefl
386
388
in some applications with the Adafruit encoder.
387
389
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.
391
393
8 . ` args=() ` An optional tuple of positionl args for the callback.
392
394
393
395
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.
395
398
396
399
Class variable:
397
400
* ` delay=100 ` After motion is detected the driver waits for ` delay ` ms before
398
401
reading the current position. This was found useful with the Adafruit encoder
399
402
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.
401
407
402
- #### Note
408
+ #### Note on accuracy
403
409
404
410
The driver works by maintaining an internal value ` ._v ` which uses hardware
405
411
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.
416
425
417
426
###### [ Contents] ( ./DRIVERS.md#1-contents )
418
427
0 commit comments