kopia lustrzana https://github.com/peterhinch/micropython-samples
Encoder code added
rodzic
13b3ab7076
commit
a820755f5d
12
README.md
12
README.md
|
@ -39,6 +39,18 @@ the same topic. Measures the round-trip delay. Adapt to suit your server address
|
||||||
QOS (quality of service, 0 and 1 are supported). After 100 messages reports maximum and
|
QOS (quality of service, 0 and 1 are supported). After 100 messages reports maximum and
|
||||||
minimum delays.
|
minimum delays.
|
||||||
|
|
||||||
|
## Rotary Incremental Encoder
|
||||||
|
|
||||||
|
Classes for handling incremental rotary position encoders. Note that the Pyboard timers can
|
||||||
|
do this in hardware. These samples cater for cases where that solution can't be used. The
|
||||||
|
encoder_timed.py sample provides rate information by timing successive edges. In practice this
|
||||||
|
is likely to need filtering to reduce jitter caused by imperfections in the encoder geometry.
|
||||||
|
|
||||||
|
There are other algorithms but this is the simplest and fastest I've encountered.
|
||||||
|
|
||||||
|
These were written for encoders producing TTL outputs. For switches, adapt the pull definition
|
||||||
|
to provide a pull up or pull down as required.
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
Any code placed here is released under the MIT License (MIT).
|
Any code placed here is released under the MIT License (MIT).
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import pyb
|
||||||
|
|
||||||
|
class Encoder(object):
|
||||||
|
def __init__(self, pin_x, pin_y, reverse, scale):
|
||||||
|
self.reverse = reverse
|
||||||
|
self.scale = scale
|
||||||
|
self.forward = True
|
||||||
|
self.pin_x = pin_x
|
||||||
|
self.pin_y = pin_y
|
||||||
|
self._pos = 0
|
||||||
|
self.x_interrupt = pyb.ExtInt(pin_x, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_NONE, self.x_callback)
|
||||||
|
self.y_interrupt = pyb.ExtInt(pin_y, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_NONE, self.y_callback)
|
||||||
|
|
||||||
|
def x_callback(self, line):
|
||||||
|
self.forward = self.pin_x.value() ^ self.pin_y.value() ^ self.reverse
|
||||||
|
self._pos += 1 if self.forward else -1
|
||||||
|
|
||||||
|
def y_callback(self, line):
|
||||||
|
self.forward = self.pin_x.value() ^ self.pin_y.value() ^ self.reverse ^ 1
|
||||||
|
self._pos += 1 if self.forward else -1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position(self):
|
||||||
|
return self._pos*self.scale
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self._pos = 0
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import pyb, utime
|
||||||
|
|
||||||
|
class EncoderTimed(object):
|
||||||
|
def __init__(self, pin_x, pin_y, reverse, scale):
|
||||||
|
self.reverse = reverse
|
||||||
|
self.scale = scale
|
||||||
|
self.tprev = 0
|
||||||
|
self.tlast = 0
|
||||||
|
self.forward = True
|
||||||
|
self.pin_x = pin_x
|
||||||
|
self.pin_y = pin_y
|
||||||
|
self._pos = 0
|
||||||
|
self.x_interrupt = pyb.ExtInt(pin_x, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_NONE, self.x_callback)
|
||||||
|
self.y_interrupt = pyb.ExtInt(pin_y, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_NONE, self.y_callback)
|
||||||
|
|
||||||
|
def x_callback(self, line):
|
||||||
|
self.forward = self.pin_x.value() ^ self.pin_y.value() ^ self.reverse
|
||||||
|
self._pos += 1 if self.forward else -1
|
||||||
|
self.tprev = self.tlast
|
||||||
|
self.tlast = utime.ticks_us()
|
||||||
|
|
||||||
|
def y_callback(self, line):
|
||||||
|
self.forward = self.pin_x.value() ^ self.pin_y.value() ^ self.reverse ^ 1
|
||||||
|
self._pos += 1 if self.forward else -1
|
||||||
|
self.tprev = self.tlast
|
||||||
|
self.tlast = utime.ticks_us()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rate(self): # Return rate in edges per second
|
||||||
|
self.x_interrupt.disable()
|
||||||
|
self.y_interrupt.disable()
|
||||||
|
if utime.ticks_diff(self.tlast, utime.ticks_us) > 2000000: # It's stopped
|
||||||
|
result = 0.0
|
||||||
|
else:
|
||||||
|
result = 1000000.0/(utime.ticks_diff(self.tprev, self.tlast))
|
||||||
|
self.x_interrupt.enable()
|
||||||
|
self.y_interrupt.enable()
|
||||||
|
result *= self.scale
|
||||||
|
return result if self.forward else -result
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position(self):
|
||||||
|
return self._pos*self.scale
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self._pos = 0
|
||||||
|
|
Ładowanie…
Reference in New Issue