ESP32-S3 控制 旋转编码器实验
ESP32-S3 旋转编码器模块实验 —— 脉冲计数与方向检测
本实验通过 ESP32-S3 旋转编码器模块 实现脉冲计数和旋转方向检测,同时支持按键按压检测。
通过串口监视器实时输出旋转方向和计数值,便于理解旋转编码器的工作原理。
一、实验名称
旋转编码器模块实验
二、接线说明
| 旋转编码器模块 | ESP32-S3 引脚 |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SW | 15 |
| DT (B) | 16 |
| CLK (A) | 17 |
三、实验现象
-
程序下载成功后,旋转旋钮,串口监视器实时输出:
- 旋转方向(CW 顺时针 / CCW 逆时针)
- 当前计数脉冲值
-
按下旋转编码器按钮 SW 时,串口显示 “Button pressed!”。
四、注意事项
- 确认 CLK、DT、SW 接线与 ESP32-S3 IO 对应正确。
- 按键 SW 接入内部上拉电阻模式,避免悬空抖动。
- 串口波特率设置为 115200,以便实时显示数据。
五、完整代码示例
// Rotary Encoder Inputs
#define CLK 17
#define DT 16
#define SW 15
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
unsigned long lastButtonPress = 0;
void setup() {
// Set encoder pins as inputs
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
// Setup Serial Monitor
Serial.begin(115200);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
}
void loop() {
// Read the current state of CLK
currentStateCLK = digitalRead(CLK);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1) {
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter--;
currentDir = "CCW";
} else {
// Encoder is rotating CW so increment
counter++;
currentDir = "CW";
}
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
}
// Remember last CLK state
lastStateCLK = currentStateCLK;
// Read the button state
int btnState = digitalRead(SW);
// If we detect LOW signal, button is pressed
if (btnState == LOW) {
// if 50ms have passed since last LOW pulse, it means that the
// button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
}
// Remember last button press event
lastButtonPress = millis();
}
// Put in a slight delay to help debounce the reading
delay(1);
}
六、代码讲解
- 引脚初始化
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
- CLK、DT 设置为输入用于读取脉冲信号。
- SW 按键设置为内部上拉输入模式,避免浮空干扰。
- 脉冲计数与方向判断
if (currentStateCLK != lastStateCLK && currentStateCLK == 1) {
if (digitalRead(DT) != currentStateCLK) { counter--; currentDir = "CCW"; }
else { counter++; currentDir = "CW"; }
}
- 当 CLK 信号发生上升沿时,读取 DT 判断旋转方向。
- 顺时针(CW)计数加一,逆时针(CCW)计数减一。
- 按键检测与去抖
int btnState = digitalRead(SW);
if (btnState == LOW && millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
lastButtonPress = millis();
}
- 检测按键按下状态,并通过时间间隔去抖。
- 延时控制
delay(1);
- 防止 CPU 占用过高,同时提高稳定性。
七、实验效果
-
旋转编码器旋钮,串口显示:
Direction: CW | Counter: 1 Direction: CW | Counter: 2 Direction: CCW | Counter: 1 -
按下旋钮按钮,串口显示:
Button pressed!
八、总结
通过本实验,你可以掌握:
- 旋转编码器脉冲读取方法
- 顺时针 / 逆时针方向判断逻辑
- 按键检测与去抖处理
这是学习 旋转控制、计数器设计 和 用户交互接口 的基础。

浙公网安备 33010602011771号