《ESP32 控制 Arduino 的旋转编码器实现》
前言
编码器(encoder) 是将信号(如 比特流 )或 数据 进行编制、转换为可用以通讯、传输和存储的信号形式的设备。. 编码器把角位移或直线位移转换成电信号,前者称为码盘 ,后者称为码尺。.
按照读出方式编码器可以分为接触式和非接触式两种;按照工作原理编码器可分为增量式和绝对式两类。. 增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。绝对式编码器 的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。
本文主要介绍旋转编码器在Arduino开发中的应用。
Arduino ESP32
-
旋转编码器
旋转编码器
编码器接线图:
KY-040 模块包括两个内部上拉电阻,将引脚 CLK 和 DT 上拉到 VCC(+5V)。
引脚定义:
CLK |
Rotary encoder pin A |
DT |
Rotary encoder pin B |
SW |
Push button pin. Normally openundefined shorted to GND on press |
VCC |
Voltage supply |
GND |
Ground |
旋转编码器提供两种交互方式:
旋转– 您可以通过单击箭头来旋转旋钮。上箭头顺时针旋转一级,下箭头逆时针旋转一级。旋转旋钮将在 DT 和 CLK 引脚上产生数字信号,如下所述。
按钮– 单击旋钮以按下按钮。按下时,按钮将 SW 引脚与 GND 引脚连接起来。
每次用户旋转旋钮时,它都会在 DT 和 CLK 引脚上产生一个 LOW 信号:
顺时针旋转会导致 CLK 引脚首先变低,然后 DT 引脚也变低。
逆时针旋转会导致 DT 引脚先变低,然后 CLK 引脚变低。
两个引脚将在几毫秒内返回高电平。下图说明了这一点:
使用wokwi仿真:
#define ENCODER_CLK 4
#define ENCODER_DT 2
void setup() {
Serial.begin(115200);
pinMode(ENCODER_CLKundefined INPUT);
pinMode(ENCODER_DTundefined INPUT);
}
int lastClk = HIGH;
void loop() {
int newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
Serial.println("Rotated clockwise ⏩");
}
if (newClk == LOW && dtValue == LOW) {
Serial.println("Rotated counterclockwise ⏪");
}
}
}
但是在实际过程中,我们得到的效果并没有如仿真一样,编码器会发生抖动,读取时并不准确。
在使用Arduino 开发ESP32设计旋转编码器程序时。
使用到的库:BasicEncoder
跑一个测试程序试试:
#include <Arduino.h>
#include <BasicEncoder.h>
const int8_t pinA = 2;
const int8_t pinB = 5;
BasicEncoder encoder(pinAundefined pinB);
void setup() {
Serial.begin(115200);
Serial.println(F("Polling in loop()"));
}
void loop() {
encoder.service();
int encoder_change = encoder.get_change();
if (encoder_change) {
Serial.println(encoder.get_count());
}
// Even a short delay here will affect performance.
// Uncomment and change the delay to see what happens.
//delay(10);
}
如果在编译过程中遇到报错,有提到SREG,那就在库函数里帮它定义一下。
找到库所在的位置打开并进行修改,其他的坑我还没有碰到过。
至此,便可放心使用旋转编码器开发了。