c - 如何读取旋转编码器输入
问题描述
我有一个关于如何读取旋转编码器输入的简单问题。如果我正确理解了这张图片,那么每转一圈都会触发引脚 A 的上升。然后,您必须检查引脚 B,如果编码器顺时针转动,则该引脚为高电平,如果编码器逆时针转动,则引脚 B 为低电平。
我尝试编写自己的代码而不使用任何库,因为我认为这会非常简单,但事实证明并非如此。
这是我写的代码:
#define rotary_A 2
#define rotary_B 3
void setup()
{
pinMode(rotary_A, INPUT);
pinMode(rotary_B, INPUT);
attachInterrupt(digitalPinToInterrupt(rotary_A), rotary_spin, RISING);
Serial.begin(9600);
}
void rotary_spin()
{
if (digitalRead(rotary_B) == HIGH)
Serial.println("+");
else
Serial.println("-");
}
+
当我顺时针转动它和逆时针转动它时,我期望得到-
。但是,我每回合都会得到几个输出,就像快速连续触发了几个中断一样。例如,当我顺时针转动编码器时:
-
-
+
+
和逆时针:
+
+
-
-
-
-
每次输出都不同,但最后一个字符总是正确的。
我怎么了?是不是很简单,还是有不同类型的编码器?
解决方案
这个问题意味着每转应该只有一个中断。但编码器通常每转产生一个以上的周期——有些是数千个。这可能就是中断似乎比预期发生得更快的原因。
在零延迟中断环境中,代码应该可以工作。但是如果在A相管脚变高后,B相管脚采样时间过长,就会失效。Serial.println
如果在前一个中断中仍在执行时出现下一个阶段 A 上升沿,则可能会发生这种情况。
一个简单的测试,看看是否是这种情况,就是非常非常缓慢地转动编码器。如果这导致正确的数据,则问题可能是中断延迟。Serial.println
然后可以用更快的东西代替,比如点亮 LED,看看这是否能解决延迟问题。
对于实际使用,您需要确保 A 相变高和 B 相被采样之间的最坏情况延迟足以满足编码器旋转的最大速率。
最后说明:代码应该能够充分检测方向,但不能用于增加/减少计数器以跟踪位置。这需要每个周期不止一个中断。
推荐阅读
- python-3.x - Prgm_MAWS:“IndexError:列表索引超出范围”
- django - 将用户名与模型一起保存在数据库中
- javascript - 参数在 AJAX 调用期间不包含 NULL 条目
- php - 在 Laravel 中以编程方式执行 Artisan CLI 命令失败
- arrays - 如何从字符串创建一个单独的字符串数组
- angular - 发送 forkjoin api,每个 api 之间有延迟
- python - Python继承:从子类创建父类对象
- javascript - 为 iframe 中的每个元素重放滚动事件
- java - 如果我暂停计时器,我会在计时器中遇到问题,它不会从停止的地方开始
- c++ - Visual Studio 2019 无法正确处理动态结构数组的聚合初始化