鼠標滾輪的機械式編碼器跟一般的增量編碼器還有點不一樣,這里是他的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);//延時增加程序穩定性 }
實驗現象:隨之鼠標滾輪正反轉,計數會增大或者減小,每過一秒輸出一次速度
