掌控板旋转编码器驱动

MicroPython相关代码、库、工具
回复
头像
shaoziyang
帖子: 706
注册时间: 2019年 10月 21日 13:48

掌控板旋转编码器驱动

#1

帖子 shaoziyang » 2019年 11月 28日 12:30

原帖作者:chpczx 发表于 2019-8-7

这个是我在淘宝上买的便宜货,一个二元钱不到。这个编码器在生活中,常用来调节音量,苹果手表旁边也有一个。由于我贪小便宜,买到了垃圾货,一个是杂波多,再就是用手旋转时,稍稍松劲就会输出反向信号,最后松手也会输出反向信号,整整折磨了我一天多。尝试了物理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)

回复

  • 随机主题
    回复总数
    阅读次数
    最新文章