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