#define ENCODER_CLK 5 // 旋转编码器引脚 A
#define ENCODER_DT 6 // 旋转编码器引脚 B
#define ENCODER_SW 7 // 旋转编码器按钮引脚
#define LED 4 // LED 引脚
#define LED_DELAY 300 // LED 延时,单位为毫秒
#define SWITCH 19 // 拨码开关引脚
#define DEBOUNCE_TIME 50 // 消抖时间,单位为毫秒
#define LONG_PRESS_TIME 700 // 长按时间阈值,单位为毫秒
// 定义模式枚举
typedef enum {
SET_VOLUME,
SET_BACKLIGHT,
} Mode;
// 默认模式为调整音量
Mode mode = SET_VOLUME;
// 切换模式函数
void nextMode() {
switch (mode) {
case SET_VOLUME:
mode = SET_BACKLIGHT;
break;
case SET_BACKLIGHT:
mode = SET_VOLUME;
break;
}
}
bool encbtnState = HIGH; // 编码器按钮当前状态
bool lastEncbtnState; // 编码器按钮上一次的状态
bool isLongPress = false; // 用于记录是否已检测到长按
unsigned long lastDebounceTime = 0; // 上次消抖后的时间
unsigned long encbtnPressStartTime = 0; // 按钮按下时的时间
int clkLast;
// 编码器初始化
void encoder_init(){
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP); // 使用内部上拉
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), encoder_check, FALLING);
attachInterrupt(digitalPinToInterrupt(ENCODER_SW), encoder_check, FALLING);
lastEncbtnState = digitalRead(ENCODER_SW); // 初始化按钮状态
clkLast = digitalRead(ENCODER_CLK);
}
// 编码器检测
void encoder_check(){
int encoderMode = SET_BACKLIGHT;
int swValue = digitalRead(ENCODER_SW);
// 检测编码器按钮状态变化并进行消抖处理
if (swValue != lastEncbtnState) {
lastDebounceTime = millis(); // 记录消抖的时间
}
// 编码器按钮消抖
if ((millis() - lastDebounceTime) > DEBOUNCE_TIME) {
if(swValue != encbtnState){
encbtnState = swValue;
if (encbtnState == LOW) {
encbtnPressStartTime = millis(); // 记录按下时间
isLongPress = false; // 重置长按状态
} else {
// 按钮释放时,判断是长按还是短按
if (mode == SET_BACKLIGHT && !isLongPress && (millis() - encbtnPressStartTime < LONG_PRESS_TIME)) {
Serial.println("检测到短按,当前为:" + String(mode) + "模式,切换背光为:呼吸 / 流水");
}
if (mode == SET_VOLUME && !isLongPress && (millis() - encbtnPressStartTime < LONG_PRESS_TIME)) {
Serial.println("检测到短按,当前为:" + String(mode) + "模式");
}
}
}
}
// 按钮按住且超过长按时间
if (encbtnState == LOW && !isLongPress && (millis() - encbtnPressStartTime >= LONG_PRESS_TIME)) {
nextMode();
Serial.println("检测到长按,切换模式为"+ String(mode));
isLongPress = true; // 标记为已处理长按
}
lastEncbtnState = swValue; // 记录上次的按钮状态
int dtValue = digitalRead(ENCODER_DT);
int clkNew = digitalRead(ENCODER_CLK);
if(clkNew != clkLast && clkNew == LOW){
if(mode == SET_BACKLIGHT){
dtValue == HIGH ? Serial.println("亮度升高") : Serial.println("亮度降低");
}
if(mode == SET_VOLUME){
dtValue == HIGH ? Serial.println("音量升高") : Serial.println("音量降低");
}
}
clkLast = clkNew;
}
int swiLast; // 上一次的开关状态
int swiNew; // 开关当前状态
void switch_init(){
pinMode(SWITCH, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_SW), switch_check, FALLING);
swiLast = digitalRead(SWITCH); // 初始化开关状态
}
void switch_check(){
swiNew = digitalRead(SWITCH);
// 如果当前开关状态与上次状态不同,表示开关状态发生了变化
if (swiLast != swiNew) {
if (swiNew == LOW) {
Serial.println("开关切换到 蓝牙 状态");
} else {
Serial.println("开关切换到 WIFI 状态");
}
swiLast = swiNew; // 更新上次状态
}
}
void led_init(){
pinMode(LED, OUTPUT);
}
volatile bool ledState = HIGH;
unsigned long pastTime = 0;
void led_blink(){
digitalWrite(LED, ledState);
unsigned long curTime = millis();
if((curTime - pastTime) > LED_DELAY){
ledState = !ledState;
digitalWrite(LED, ledState);
pastTime = curTime;
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32-S3!");
encoder_init();
switch_init();
led_init();
}
void loop() {
// put your main code here, to run repeatedly:
encoder_check();
led_blink();
switch_check();
delay(10); // this speeds up the simulation
}