我有一个关于如何读取旋转编码器输入的简单问题。 如果我正确理解this图像,则每转都会触发引脚A的上升。然后,您必须检查引脚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("-");
}
我期望顺时针旋转+
,逆时针旋转-
。但是,我每转都会得到几个输出,就像快速连续触发了几个中断一样。例如,当我顺时针旋转编码器时:
-
-
+
+
和逆时针方向:
+
+
-
-
-
-
每次输出都不同,但是最后一个字符始终是正确的字符。
我怎么了?这不是那么简单,还是有不同类型的编码器?
答案 0 :(得分:1)
这个问题意味着每转只能有一个中断。但是编码器通常每转产生一个以上的周期-几千个。这可能就是为什么中断发生得比预期更快的原因。
在零延迟中断环境中,代码应该起作用。但是,如果在A相引脚变为高电平后对B相引脚进行采样的时间过长,它将失败。如果Serial.println
在上一个中断中仍在执行时,下一个A相上升沿就会发生。
一个简单的测试,看是否是这种情况,就是慢慢转动编码器非常,非常。如果这导致正确的数据,则问题可能出在中断延迟上。然后Serial.println
可以换成更快的东西,例如发光的LED,以查看是否可以解决延迟问题。
对于实际使用,您需要确保A相变高和B相采样之间的最坏情况延迟足以满足编码器最大旋转速率。
最后的提示:该代码应能够充分检测方向,但不能用于增加/减少计数器以跟踪位置。每个周期需要一个以上的中断。
答案 1 :(得分:0)
在Github上查看我的这个存储库。
https://github.com/KingZuluKing/Rotary-Encoder-Peripheral-System
必须是类似这样的东西,仓库中有更多细节。
void encode_Rotor_func()
{
lcd.clear();
Vol_Knob_stat=digitalRead(Vol_Knob);
if(Vol_Knob_stat==0)
{
Vol_Dir_stat=digitalRead(Vol_Dir);
if(Vol_Dir_stat==0 && deciBells<=9)
{
deciBells++;
lcd.setCursor(0, 0);
lcd.print("VOLUME= .");
lcd.setCursor(7, 0);
lcd.print(deciBells);
lcd.setCursor(10, 0);
lcd.print("dB's");
}
else if(Vol_Dir_stat==1 && deciBells >=-79)
{
deciBells--;
lcd.setCursor(0, 0);
lcd.print("VOLUME= .");
lcd.setCursor(7, 0);
lcd.print(deciBells);
lcd.setCursor(10, 0);
lcd.print("dB's");
}
else{
do something else etc.. etc....
}
}
}