鼠标滚轮的机械式编码器跟一般的增量编码器还有点不一样,这里是他的AB相时序解释:https://blog.csdn.net/u011798737/article/details/70990823
视频解释:https://v.douyin.com/eyH7jxT/,滚轮每走一格灯会变一次状态,灯闪的有先后,这样就可以判断出是正转还是反转。
实验电路,非常简单,GND接编码器的地,编码器其他两个线接数字输入2.3(注意数字输入01脚跟串口是复用的,如果用了串口功能就没法用GPIO了,我一开始没留意这问题搞得没法烧程序了)。为了信号稳定,设置23脚接内部上拉电阻。
程序原理,脚2每次变状态时给计数加1或者减1,用脚2变状态时脚3的状态来确定是加1还是减1.
代码
#include <MsTimer2.h>//加入计时器用来测量速度 #define DEBOUNCE_TIME 8 //延时用来过滤不正常的信号,此数字太大的话会对快速的旋转不起反应 // 定义引脚2.3 int APhase = 2; int BPhase = 3; long count = 0;//计数 long preverCount = 0;//上一次的计数 long cerrentCount = 0;//当前计数 void getSpeed(){ preverCount = cerrentCount; cerrentCount = count; Serial.println( "speed is " + String (cerrentCount - preverCount) ) ; } void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(APhase, INPUT_PULLUP);//上拉电阻 pinMode(BPhase, INPUT_PULLUP); pinMode(LED_BUILTIN,OUTPUT); MsTimer2::set(1000, getSpeed);//改变计时时间可以调整速度的刷新率 //开始计时 MsTimer2::start(); } void loop() { //put your main code here, to run repeatedly: int firstAPhaseState= digitalRead(APhase); digitalWrite(LED_BUILTIN,firstAPhaseState);//用板上自带的灯显示A相的状态 if (firstAPhaseState == 1 ) { delay(DEBOUNCE_TIME); int secendAPhaseState = digitalRead(APhase); //从1变成0 开始判断是正转还是反转 if (secendAPhaseState == 0) { //用B相信号判断正反转 if (digitalRead(BPhase) == 0) { count++; Serial.println(count); } if (digitalRead(BPhase) == 1) { count--; Serial.println(count); } } } //初始状态是0的判断,想改进的话可以用外部中断的上升沿事件 if (firstAPhaseState == 0) { delay(DEBOUNCE_TIME); int secendAPhaseState = digitalRead(APhase); if (secendAPhaseState == 1) { if (digitalRead(BPhase) == 1) { count++; Serial.println(count); } if (digitalRead(BPhase) == 0) { count--; Serial.println(count); } } } delay(1);//延时增加程序稳定性 }
实验现象:随之鼠标滚轮正反转,计数会增大或者减小,每过一秒输出一次速度