From 4d98d7aecfe7ed10b9c584e50b06a284807911e3 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Sun, 17 Apr 2022 12:09:28 +0100 Subject: [PATCH] Improve encoder precision. --- gui/primitives/encoder.py | 26 +++++++++++++++----------- hardware_setup.py | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/gui/primitives/encoder.py b/gui/primitives/encoder.py index b83abf6..71005f9 100644 --- a/gui/primitives/encoder.py +++ b/gui/primitives/encoder.py @@ -1,12 +1,8 @@ # encoder.py Asynchronous driver for incremental quadrature encoder. -# Copyright (c) 2021 Peter Hinch +# Copyright (c) 2021-2022 Peter Hinch # Released under the MIT License (MIT) - see LICENSE file -# https://github.com/peterhinch/micropython-async/blob/master/v3/primitives/encoder.py -# This driver is intended for encoder-based control knobs. It is -# unsuitable for NC machine applications. Please see the docs. - import uasyncio as asyncio from machine import Pin @@ -17,9 +13,11 @@ class Encoder: callback=lambda a, b : None, args=()): self._pin_x = pin_x self._pin_y = pin_y + self._x = pin_x() + self._y = pin_y() self._v = 0 # Hardware value always starts at 0 self._cv = v # Current (divided) value - if ((vmin is not None) and v < min) or ((vmax is not None) and v > vmax): + if ((vmin is not None) and v < vmin) or ((vmax is not None) and v > vmax): raise ValueError('Incompatible args: must have vmin <= v <= vmax') self._tsf = asyncio.ThreadSafeFlag() trig = Pin.IRQ_RISING | Pin.IRQ_FALLING @@ -31,14 +29,20 @@ class Encoder: yirq = pin_y.irq(trigger=trig, handler=self._y_cb) asyncio.create_task(self._run(vmin, vmax, div, callback, args)) - # Hardware IRQ's - def _x_cb(self, pin): - fwd = pin() ^ self._pin_y() + # Hardware IRQ's. Duration 36μs on Pyboard 1. + def _x_cb(self, pin_x): + if (x := pin_x()) == self._x: # IRQ latency: if 2nd edge has + return # occurred there is no movement. + self._x = x + fwd = x ^ self._pin_y() self._v += 1 if fwd else -1 self._tsf.set() - def _y_cb(self, pin): - fwd = pin() ^ self._pin_x() ^ 1 + def _y_cb(self, pin_y): + if (y := pin_y()) == self._y: + return + self._y = y + fwd = y ^ self._pin_x() ^ 1 self._v += 1 if fwd else -1 self._tsf.set() diff --git a/hardware_setup.py b/hardware_setup.py index 4e7a964..02cf963 100644 --- a/hardware_setup.py +++ b/hardware_setup.py @@ -53,4 +53,4 @@ prev = Pin(18, Pin.IN, Pin.PULL_UP) # Move to previous control increase = Pin(20, Pin.IN, Pin.PULL_UP) # Increase control's value decrease = Pin(17, Pin.IN, Pin.PULL_UP) # Decrease control's value # display = Display(ssd, nxt, sel, prev) # 3-button mode -display = Display(ssd, nxt, sel, prev, increase, decrease, 5) # Encoder mode +display = Display(ssd, nxt, sel, prev, increase, decrease, 4) # Encoder mode