【问题标题】:Rotary Encoder State Machine - Can only read ONE of two pin states per interrupt旋转编码器状态机 - 每个中断只能读取两个引脚状态之一
【发布时间】:2018-01-10 18:49:18
【问题描述】:

背景:

在阅读this arduino example 后,我正在使用状态机为格雷码旋转编码器编写驱动程序。我的设备是使用 .net 微框架用 c# 编码的。由于它不是一个实时嵌入式操作系统,因此我只能在中断期间捕获编码器两个引脚之一的状态。中断时,事件排队等待在高优先级线程中运行。产生中断的引脚状态作为参数传递给“ISR”,也就是NativeEventHandler 委托。在处理程序运行时读取第二个引脚的状态是不准确的,因为它是在实际事件排队之后的几毫秒。(我已经尝试过了)

在我的例子中,基本状态是引脚 A 和 B 都拉高(值 = 1)

所以,我只有 4 个可测量的状态,但实际状态是基于之前的状态。

  1. 引脚 A 高 1
  2. 引脚 B 高 1
  3. 引脚 A 低 0
  4. B 脚低 0

我在制作不会混淆的状态转换表时遇到问题。我正在尝试提出一些快速的逻辑或一些按位运算来完成此操作。

这是我想出的状态表(不是转换表):

Pin State   Assigned Value  State Name
PinB-High   4               CW Rot
PinA-High   3               CW3
PinB-Low    2               CW2
PinA-Low    1               CW1
Start       0               Start
PinB-Low    5               CCW1
PinA-Low    6               CCW2
PinB-High   7               CCW3
PinA-High   8               CCW Rot

如何仅在 4 个状态下获得正确的转换?

【问题讨论】:

    标签: c# events bit-manipulation state-machine .net-micro-framework


    【解决方案1】:

    在格雷码中,一次只有一位变化,我建议不要将其视为 4 个状态,而是尝试以位表示来考虑它。假设 PinA 是位 0,PinB 是位 1。

    既然你说两个引脚在基本状态下都是高电平,那么转换可能是:

    CW: b11 -> b01 -> b00 -> b10

    CCW: b11 -> b10 -> b00 -> b01

    根据您的编码器的工作方式,逻辑可能会颠倒。

    然后您应该能够使用开关盒轻松处理它。

    【讨论】:

      【解决方案2】:

      即使您考虑每个编码器状态的位对,接触弹跳的噪声也很大,以至于使用状态机对这些激励进行解码,结果也可能不准确。混合状态加上某种电容器去抖动和与中断函数中引入的接触反弹时间规范相匹配的一些延迟,可以提供帮助。从一种编码器品牌和型号到另一种编码器品牌和型号,弹跳会发生很大变化。操作系统中的软件延迟会使事情变得更糟。这需要时间和一些测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-14
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-25
        相关资源
        最近更新 更多