这个是我在淘宝上买的便宜货,一个二元钱不到。这个编码器在生活中,常用来调节音量,苹果手表旁边也有一个。由于我贪小便宜,买到了垃圾货,一个是杂波多,再就是用手旋转时,稍稍松劲就会输出反向信号,最后松手也会输出反向信号,整整折磨了我一天多。尝试了物理RC滤波,效果也不行,手上的东西总不能丢掉,只能用软件方法解决了,这个程序真正的解码部分很短,大家有质量好的,可以把消抖部分去掉。
对了,这个上面的sw是按钮输出。CLK,DT是两个信号线,SW在你按压时,输出低电平因此这个编码器要占用三个数字输入。编码解码原理是下面的时序图。
程序在mpythonx 0.33下调试通过。
Code: Select all
from machine import Pin
import time
ENC_STATES = [0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0]
class ENCODER_360:
def __init__(self, _clk, _dt, _sw):
self.clk =Pin(_clk, Pin.IN)
self.dt = Pin(_dt, Pin.IN)
self.sw = Pin(_sw, Pin.IN)
self.clk.irq(handler=self.check, trigger=(Pin.IRQ_RISING | Pin.IRQ_FALLING))
self.dt.irq(handler=self.check, trigger=(Pin.IRQ_RISING | Pin.IRQ_FALLING))
self.cmd = None
self.keyIsPressed = False
self.direction = 1
self._readings = 0
# 消抖所用变量
self.lastDV =0
self.lastCV=0
self.lastTicks=time.ticks_ms()
self.lastDirection = 0
def isPressed(self):
return not self.sw.value()
def check(self, pin):
# 消抖部分
dv = self.dt.value()
cv = self.clk.value()
if dv == self.lastDV and cv == self.lastCV:
return
else:
self.lastDV = dv
self.lastCV = cv
#核心解码部分
self._readings = (self._readings << 2 | cv << 1 | dv) & 0x0f
self.direction = ENC_STATES[self._readings]
# 再次消抖
if self.direction == 0:
self.direction = self.lastDirection
curTicks = time.ticks_ms()
x = curTicks- self.lastTicks
if x< 300 and self.direction !=self.lastDirection:
return
self.lastDirection = self.direction
self.lastTicks=curTicks
# 调用自定义处理函数
if self.cmd:
self.cmd(self.direction)
def callback(self, fn):
self.cmd = fn
if __name__ == "__main__":
from mpython import *
bm = ENCODER_360(Pin.P14, Pin.P15, Pin.P16)
volumn =127
def cmd(direction):
global volumn
volumn += direction*5
oled.fill(0)
oled.DispChar("volumn="+str(volumn), 0, 0)
oled.show()
bm.callback(cmd)
cmd(0)