Encoder code added

pull/7/head
Peter Hinch 2016-09-05 09:14:38 +01:00
rodzic 13b3ab7076
commit a820755f5d
3 zmienionych plików z 87 dodań i 0 usunięć

Wyświetl plik

@ -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
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
Any code placed here is released under the MIT License (MIT).

Wyświetl plik

@ -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

Wyświetl plik

@ -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