ESP32-S3 控制 旋转编码器实验

ESP32-S3 旋转编码器模块实验 —— 脉冲计数与方向检测

本实验通过 ESP32-S3 旋转编码器模块 实现脉冲计数和旋转方向检测,同时支持按键按压检测。

通过串口监视器实时输出旋转方向和计数值,便于理解旋转编码器的工作原理。


一、实验名称

旋转编码器模块实验


二、接线说明

旋转编码器模块 ESP32-S3 引脚
VCC 3V3
GND GND
SW 15
DT (B) 16
CLK (A) 17

三、实验现象

  1. 程序下载成功后,旋转旋钮,串口监视器实时输出:

    • 旋转方向(CW 顺时针 / CCW 逆时针)
    • 当前计数脉冲值
  2. 按下旋转编码器按钮 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);
}

六、代码讲解

  1. 引脚初始化
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
  • CLK、DT 设置为输入用于读取脉冲信号。
  • SW 按键设置为内部上拉输入模式,避免浮空干扰。
  1. 脉冲计数与方向判断
if (currentStateCLK != lastStateCLK && currentStateCLK == 1) {
    if (digitalRead(DT) != currentStateCLK) { counter--; currentDir = "CCW"; }
    else { counter++; currentDir = "CW"; }
}
  • 当 CLK 信号发生上升沿时,读取 DT 判断旋转方向。
  • 顺时针(CW)计数加一,逆时针(CCW)计数减一。
  1. 按键检测与去抖
int btnState = digitalRead(SW);
if (btnState == LOW && millis() - lastButtonPress > 50) {
    Serial.println("Button pressed!");
    lastButtonPress = millis();
}
  • 检测按键按下状态,并通过时间间隔去抖。
  1. 延时控制
delay(1);
  • 防止 CPU 占用过高,同时提高稳定性。

七、实验效果

  1. 旋转编码器旋钮,串口显示:

    Direction: CW | Counter: 1
    Direction: CW | Counter: 2
    Direction: CCW | Counter: 1
    
  2. 按下旋钮按钮,串口显示:

    Button pressed!
    

八、总结

通过本实验,你可以掌握:

  • 旋转编码器脉冲读取方法
  • 顺时针 / 逆时针方向判断逻辑
  • 按键检测与去抖处理

这是学习 旋转控制、计数器设计用户交互接口 的基础。

posted @ 2025-08-16 16:02  jeikerxiao  阅读(100)  评论(0)    收藏  举报