旋转编码器与电位器
旋转编码器是电位器的现代数字等效物,并且用途更广泛。
旋转编码器可以不停地旋转360°,而电位器只能旋转3/4圈。
电位器用于需要知道旋钮准确位置的情况。另一方面,旋转编码器用于需要知道位置变化而不是确切位置的情况。
旋转编码器如何工作?
编码器内部有一个开槽圆盘,连接到公共接地引脚 C。它还具有两个接触针 A 和 B,如下所示。
当转动旋钮时,A 和 B 按照特定顺序与公共接地引脚 C 接触,具体顺序取决于转动旋钮的方向。
当它们与公共地接触时,会产生两个信号。这些信号存在 90° 异相,因为一个引脚先于另一个引脚接触公共地。它被称为正交编码。
当顺时针旋转旋钮时,A 引脚先于 B 引脚接地。当逆时针旋转旋钮时,B 引脚先于 A 引脚接地。
通过监控每个引脚何时连接或断开接地,我们可以确定旋钮旋转的方向。这可以通过简单地观察 A 的状态改变时 B 的状态来完成。
当A改变状态时:
-
如果 B != A,则顺时针转动旋钮。
-
如果 B = A,则逆时针转动旋钮。
旋转编码器引脚
GND:接地。
VCC:通常在 3.3 至 5 伏之间。
SW:按钮开关的输出(低电平有效)。当按下旋钮时,电压变低。
DT(输出 B):与CLK输出类似,但滞后于CLK 90°相移。该输出用于确定旋转方向。
CLK(输出A):是用于确定旋转量的主要输出脉冲。每次仅通过一个制动装置(咔嗒声)向任一方向转动旋钮时,“CLK”输出就会经历一个先高后低的周期。
案例
Versatile_RotaryEncoder-1.3.1
项目地址:https://github.com/ruiseixasm/Versatile_RotaryEncoder
#include <Versatile_RotaryEncoder.h>#define clk 17
#define dt 16
#define sw 18// 每个编码器上要处理的函数原型设计
void handleRotate(int8_t rotation);
void handlePressRotate(int8_t rotation);
void handleHeldRotate(int8_t rotation);
void handlePress();
void handleDoublePress();
void handlePressRelease();
void handleLongPress();
void handleLongPressRelease();
void handlePressRotateRelease();
void handleHeldRotateRelease();//为编码器对象创建全局指针
Versatile_RotaryEncoder *versatile_encoder;// 用于记录旋转脉冲数
int rotationCount = 0;void setup() {Serial.begin(9600);versatile_encoder = new Versatile_RotaryEncoder(clk, dt, sw);//在此处向编码器加载所有neded句柄函数(最多9个函数)versatile_encoder->setHandleRotate(handleRotate);//旋转versatile_encoder->setHandlePressRotate(handlePressRotate);//按下时旋转versatile_encoder->setHandlePressRotateRelease(handlePressRotateRelease);//按下时旋转释放 versatile_encoder->setHandleHeldRotate(handleHeldRotate);//长按后旋转versatile_encoder->setHandleHeldRotateRelease(handleHeldRotateRelease);//长按后旋转释放 versatile_encoder->setHandlePress(handlePress);//短按versatile_encoder->setHandleDoublePress(handleDoublePress);//双击//versatile_encoder->setHandleDoublePress(nullptr); //禁用双击versatile_encoder->setHandlePressRelease(handlePressRelease);//短按释放versatile_encoder->setHandleLongPress(handleLongPress);//长按versatile_encoder->setHandleLongPressRelease(handleLongPressRelease);//长按释放Serial.println("Ready!");// 设置自己的defalt值(可选)// versatile_encoder->setInvertedSwitch(true); // 将开关行为从HIGH(高)转变为LOW(低)转变为LOW(低)// versatile_encoder->setReadIntervalDuration(2);// 将2ms设置为长按持续时间(默认为1ms)// versatile_encoder->setShortPressDuration(35); // 将35ms设置为短按持续时间(默认为50ms)// versatile_encoder->setLongPressDuration(550); // 设置550ms为长按持续时间(默认为1000ms)// versatile_encoder->setDoublePressDuration(350); // 设置350ms为双按持续时间(默认为250ms)}void loop() {//做编码器的读取和处理if (versatile_encoder->ReadEncoder()) {//每当读取编码器动作时,请在此处执行操作// 输出旋转脉冲数Serial.print("Rotation Count: ");Serial.println(rotationCount); }
}//根据您的需要在此处执行您的功能void handleRotate(int8_t rotation) {Serial.print("#1 Rotated: ");//旋转if (rotation > 0)Serial.println("Right");rotationCount++;elseSerial.println("Left");rotationCount--;
}void handlePressRotate(int8_t rotation) {Serial.print("#2 Pressed and rotated: ");//按下时旋转if (rotation > 0)Serial.println("Right");elseSerial.println("Left");
}void handleHeldRotate(int8_t rotation) {Serial.print("#3 Held and rotated: ");//长按后旋转if (rotation > 0)Serial.println("Right");elseSerial.println("Left");
}void handlePress() {Serial.println("#4.1 Pressed");//短按
}void handleDoublePress() {Serial.println("#4.2 Double Pressed");//双击
}void handlePressRelease() {Serial.println("#5 Press released");//短按释放
}void handleLongPress() {Serial.println("#6 Long pressed");//长按
}void handleLongPressRelease() {Serial.println("#7 Long press released");//长按释放
}void handlePressRotateRelease() {Serial.println("#8 Press rotate released");//按下旋转释放
}void handleHeldRotateRelease() {Serial.println("#9 Held rotate released");//保持旋转释放
}