#include <esp_sleep.h>
#include "driver/gpio.h" // 引入底层驱动库
const int ADC_PIN = 0;
const int LED_PINS[] = {4, 5, 6, 7};
const int WAKEUP_PIN = 3; // 建议使用 GPIO 3
const float DIVIDER_RATIO = 6.0;
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("\n--- [系统启动/唤醒] ---");
// 1. 初始化引脚
for (int i = 0; i < 4; i++) {
pinMode(LED_PINS[i], OUTPUT);
digitalWrite(LED_PINS[i], LOW);
}
// 2. 关键:确保唤醒引脚在睡眠期间也保持上拉
// 使用底层函数强制开启上拉,防止睡眠时引脚浮空触发假唤醒
gpio_set_direction((gpio_num_t)WAKEUP_PIN, GPIO_MODE_INPUT);
gpio_pullup_en((gpio_num_t)WAKEUP_PIN);
// 3. 配置 ADC
analogReadResolution(12);
analogSetAttenuation(ADC_11db);
// 4. 显示电量
displayBatteryLevel();
// 5. 重点:防抖并等待按键松开
Serial.println("检查按键状态...");
if (digitalRead(WAKEUP_PIN) == LOW) {
Serial.println("检测到按键按下,请松开按键以准备睡眠...");
while (digitalRead(WAKEUP_PIN) == LOW) {
delay(10); // 只要按着,就卡在这里不许睡眠
}
Serial.println("按键已松开!");
delay(200); // 松开后再等一下,消除物理抖动
}
// 6. 准备睡眠
Serial.println("正在关灯,准备睡眠...");
for (int i = 0; i < 4; i++) digitalWrite(LED_PINS[i], LOW);
// 启用 GPIO 唤醒模式
esp_deep_sleep_enable_gpio_wakeup(1ULL << WAKEUP_PIN, ESP_GPIO_WAKEUP_GPIO_LOW);
Serial.println(">>> 已经睡着了 (ZZZ...) <<<");
Serial.flush(); // 确保串口消息发完了再睡
esp_deep_sleep_start();
}
void loop() {}
void displayBatteryLevel() {
long rawSum = 0;
for(int i=0; i<20; i++) {
rawSum += analogRead(ADC_PIN);
delay(5);
}
float rawAvg = rawSum / 20.0;
float batteryVoltage = (rawAvg / 4095.0) * 3.3 * DIVIDER_RATIO;
Serial.print("电池总压: "); Serial.print(batteryVoltage); Serial.println(" V");
if (batteryVoltage > 14.2) digitalWrite(LED_PINS[0], HIGH);
if (batteryVoltage > 15.0) digitalWrite(LED_PINS[1], HIGH);
if (batteryVoltage > 15.8) digitalWrite(LED_PINS[2], HIGH);
if (batteryVoltage > 16.5) digitalWrite(LED_PINS[3], HIGH);
delay(5000); // 亮灯 5 秒
}