用旋转编码器解决phyphox角度测量问题
一直要琢磨使用旋转编码器,这两天找资料看了看,发现也简单,也不简单。最便宜几元钱的、使用的最多的是增量式旋转编码器,就是顺时针、逆时针无限制,可以无休止转动下去,通过光电信号的检测来判断转动方向并返回码表,判断转动是否数据完整,从而可以计算角位移、角速度,转动的速度等等。另一种是绝对值编码器,比如细分360度圆周分成指定个数的区间,在每个区间里再划分一系列透光弧和挡光弧,透光为1、挡光为0,每区间比如有12个弧,也就是12bit,那么就可以把360度分成2的12次方即4096份,每分度就是0.087890625度,这就极度精确地测量角度了。绝对值编码器可以断电记忆,不同位置不同码值,显然比增量式编码器要狠的多,所以它就超级贵了,几百元一个。
我的是增量式,无牌子、无标签、无资料,所以只能自己试验炮制来的代码能不能直接用。能。
这是接线。接线其实也挺迷乱的。除VCC和GND之外,有一种引脚标为CLK、DT、SW,有一种引脚标为A、B、C,我这个三无,则标为S1、S2、KEY,事实上它们就是这么对应的。但在未知之前,好一通判断。
运行。现在,当我们每接收一次完成编码(10010011或00111001,没改小端),就把角度增或减指定的度数。因为这个东西是20,因此每次增减18度:
代码。我炮制来的,稍有改动,以后或有用。
intCLKbtn = 12;//S1
intDTbtn = 2;//S2
intSWbtn = 8;//KEY
intoldA = LOW;
intoldB = LOW;
longcount = 0L;
boollastButtonStatus = false;
unsignedchar check = 0x00;
voidsetup()
{
Serial.begin(9600);
pinMode(CLKbtn, INPUT);
pinMode(DTbtn, INPUT);
pinMode(SWbtn, INPUT);
digitalWrite(SWbtn, HIGH);//连接按钮的引脚设为上拉
}
voidloop()
{
int newA = digitalRead(CLKbtn);
int newB = digitalRead(DTbtn);
int SW = digitalRead(SWbtn);
//按键检测
bool buttonStatus = !digitalRead(SWbtn);//高电平时未按下,状态为false
if(buttonStatus != lastButtonStatus){
buttonStatus = !digitalRead(SWbtn);
delay(20);//去抖动
if (buttonStatus != lastButtonStatus)
{
Serial.println(buttonStatus ?"pressed" : "released");
lastButtonStatus = buttonStatus;//保存当前状态
}
}
//旋转检测
if (newA != oldA || newB != oldB)//变化时
{
Serial.print(" S1:");Serial.print(newA);
Serial.print(" S2:");Serial.println(newB);
check = (check << 2) + (newA <<1) + newB; //将变化的时序按位放入,用于对比。
if (newA == HIGH && newB == HIGH)//旋转结束
{
if (check == 0x87) //顺时针 10 00 01 11
{Serial.println("clockwise");
count --;
Serial.print(count*18);Serial.println("degree");}
else if (check == 0x4B) //逆时针 01 00 10 11
{Serial.println("anticlockwise");
count ++;
Serial.print(count*18);Serial.println("degree");}
else
{
Serial.println("waiting...");
}
}
oldA = newA;
oldB = newB;
}
}
------心存DREAM喜欢琢磨实验并自娱自乐的MIRACLE------
实验教学值得学习的去处:
2.学生自主创新实验