旋转编码器从外观上来看很接近旋转电位器,但是旋转编码器没有终点,随便转多少圈。
我是淘宝上随便买了一个,一共5个端子,其中2个是电源,1个是按压开关,按下的状态为LOW,剩余两个端子是比较时序使用的。
网上找来的例程是给arduino uno使用的,移植到nodeMCU上需要略做改动。
一、重新定义接入针脚,两个测时序的端子分别接D1和D2,按钮端子接D0
二、重新绑定中断attachInterrupt(4, updateEncoder, CHANGE),当电平改变时触发中断
三、ICACHE_RAM_ATTR void updateEncoder(),定义中断后所执行的函数时,要加上ICACHE_RAM_ATTR
int encoderPinA = 5;
int encoderPinB = 4;
int buttonPin = 16;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
long readEncoderValue(void) {
return encoderValue / 4;
}
boolean isButtonPushDown(void) {
if (!digitalRead(buttonPin)) {
delay(5);
if (!digitalRead(buttonPin))
return true;
}
return false;
}
void setup() {
Serial.begin (9600);
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(buttonPin, INPUT);
digitalWrite(encoderPinA, HIGH); //turn pullup resistor on
digitalWrite(encoderPinB, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(5, updateEncoder, CHANGE);
attachInterrupt(4, updateEncoder, CHANGE);
}
void loop() {
//Do stuff here
if (isButtonPushDown()) {
Serial.println("you push button down!!!");
}
Serial.println(readEncoderValue());
delay(50); //just here to slow down the output, and show it will work even during a delay
}
ICACHE_RAM_ATTR void updateEncoder() {
int MSB = digitalRead(encoderPinA); //MSB = most significant bit
int LSB = digitalRead(encoderPinB); //LSB = least significant bit
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}