Tiết kiệm pin

Deep sleep: cho ESP32 chạy pin nhiều tháng

Mã ví dụ dùng Arduino core cho ESP32

ESP32 đang kết nối WiFi tiêu thụ trung bình vài chục đến hơn 100mA, dòng đỉnh khi phát có thể vượt 300mA. Với pin thì không thể chạy liên tục. Giải pháp: ngủ sâu phần lớn thời gian, chỉ thức dậy đo, gửi, rồi ngủ lại.

Mã cơ bản

RTC_DATA_ATTR int bootCount = 0;   // giữ giá trị qua các lần ngủ

void setup() {
  Serial.begin(115200);
  bootCount++;
  Serial.printf("Lan thuc thu %d\n", bootCount);

  // ... đo cảm biến, gửi dữ liệu ...

  esp_sleep_enable_timer_wakeup(10ULL * 60 * 1000000ULL);   // 10 phút (µs)
  esp_deep_sleep_start();
}

void loop() {}

Sau deep sleep, chip khởi động lại từ setup(). Biến thường mất; chỉ biến RTC_DATA_ATTR được giữ.

Đánh thức bằng nút bấm (ext0/ext1)

// Thức khi GPIO33 xuống LOW (chỉ dùng chân RTC GPIO)
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0);

Chỉ các chân RTC mới đánh thức được (ví dụ GPIO 0, 2, 4, 12–15, 25–27, 32–39 trên ESP32 gốc). Có thể kết hợp timer và nút bấm.

Dòng tiêu thụ thực tế phụ thuộc vào board

Chip ESP32 ở deep sleep chỉ cần khoảng chục µA, nhưng trên board DevKit thì dòng thường là hàng mA vì:

Muốn thật sự tiết kiệm, hãy dùng board thiết kế cho pin (ví dụ có LDO dòng tĩnh thấp, không LED), hoặc tự làm mạch với module ESP32 trần và LDO dòng tĩnh thấp. Đo dòng bằng đồng hồ vạn năng hoặc thiết bị chuyên dụng trước khi tin vào ước tính.

Mẹo giảm thời gian thức

Tính nhanh tuổi thọ pin

Dòng trung bình = (dòng khi thức × thời gian thức + dòng khi ngủ × thời gian ngủ) / chu kỳ. Ví dụ thức 5 giây ở 120mA mỗi 10 phút, ngủ 20µA: khoảng 1mA trung bình. Pin 18650 dung lượng 2500mAh thực tế được khoảng 100 ngày, trước khi tính hao hụt do tự xả và nhiệt độ. Đây chỉ là ước tính, hãy đo thực tế.

Chú ý: đọc điện áp pin qua cầu chia điện trở sẽ rút dòng liên tục. Dùng điện trở lớn (ví dụ 1MΩ + 1MΩ) kèm tụ nhỏ 100nF cho ADC, hoặc dùng MOSFET để chỉ bật cầu chia khi đo.

Xem một ứng dụng thực tế: Trạm thời tiết ESP32 + BME280 gửi MQTT.