旋转编码器就是这个东西,正转和反转以及按下动作。英文叫Encoder
主要参考文章:https://www.cnblogs.com/watson8544/p/5454086.html,比论文有用多了。
旋转编码器的电路图如下,网上抄的,我也不懂。
大概A和B就是正反转,4和5就是按下动作。
用万能表测了LCD12864与mega2560的连接脚我数是 33 35 37 ,但实际上37好像是蜂鸣器,按 31、33、35定义则对应了,(1-31,3-33,5-35)
百度有好多旋转编码器的文章,有用一个中断,也有用二个中断,也有直接用D引脚作识别,但最有用的文章是上面这篇,其它的文章都没有深入认识到旋转编码器。仅凭万通用表对这旋转编码器的检测,导致认识不足,估计要示波器。
借用人家的描述,这段话是精髓,要好好理解:旋转编码器可以一直旋轉,旋轉一整周被分為20小格,正轉逆轉皆可,當轉動時,CLK腳位就會呈低電位,此時可讀取DT資料腳位,若為HIGH代表正轉,LOW代表逆轉;SW則是開關腳位,轉軸可被按下改變此腳位的狀態。另外+需接正電源,GND接地。
走了二天的弯路,过程不多说了。核心部分,需要使用一个中断,直接使用D引脚作编码识别,比较难识别准确。
引脚对应的中断如下:
板子型号 | int.0 | int.1 | int.2 | int.3 | int.4 | int.5 |
Uno, Ethernet | 2 | 3 | ||||
Mega2560 | 2 | 3 | 21 | 20 | 19 | 18 |
32u4 based (e.g Leonardo, Micro) | 3 | 2 | 0 | 1 | 7 |
Mega2560关于31 33 35引脚没有中断,可短接引脚,或者程序复制引脚状态,百度搜不出。
我自己试了开始是
#define interrupt 21 //可中断引脚,对应中断值为2
pinMode(interrupt,OUTPUT);
if(digitalRead(31)) {
digitalWrite(interrupt,HIGH);
}
else{
digitalWrite(interrupt,LOW);
}
在执行的时候,有点延时造成不准确。
想了想改成这样
pinMode(interrupt,OUTPUT);
digitalWrite(interrupt,digitalRead(CLK)); //直接赋值到可中断引脚
然后真的可以了。(DUE 全部引脚都可以中断,)
全部亲测程序如下(mega2560+Reprap LCD12864)
#define SERIAL_BAUDRATE 115200
#define CLK 31 // 定义连接脚位
#define DT 33
#define SW 35 //按下
#define interrupt 21 //可中断引脚,对应中断值为2
unsigned long previousMillis = 0;
int encoderPos =0;
void setup() {
// put your setup code here, to run once:
pinMode(CLK, INPUT_PULLUP); // 输入模式并启用内建上拉电阻
pinMode(DT, INPUT_PULLUP);
pinMode(SW, INPUT_PULLUP);
attachInterrupt(2, test1, FALLING); //中断,调用test1程序
Serial.begin(SERIAL_BAUDRATE);
}
void loop() {
// put your main code here, to run repeatedly:
pinMode(interrupt,OUTPUT);
digitalWrite(interrupt,digitalRead(CLK)); //直接赋值到可中断引脚
}
void test1(){
//unsigned long temp = millis();
if(millis() - previousMillis < 50) // 防动作过快
{
return;
}
previousMillis =millis();
//DT的状态代表正转和反转
encoderPos += digitalRead(DT) == HIGH ? 1 : -1;
Serial.println(encoderPos);
}
在这困了二天,有需要的朋友自己领悟了。