ESP32-C3 — энергоэффективный микроконтроллер на новой архитектуре RISC-V с поддержкой Wi-Fi и BLE, хорошо подходящий для diy IoT-устройств. Чип обладает низким энергопотреблением в режиме глубокого сна до 44 мкА. В данной статье мы будем подключать не самый распространённый датчик HTU21D температуры и влажности. Рассмотрим реализацию проекта с использованием режима глубокого сна, измерение напряжения аккумулятора LIPO и отправкой данных с датчика на MQTT-сервер Home Assistan.

Подключение датчика
Схема подключения датчика и аккумулятора. Обратите внимание что I2C используется не аппаратный. Это связано с тем что пины GPIO8 и GPIO9 платы ESP32c3 super mini подтянуты к линии питания 3.3в из за этого на датчик в режиме глубокого сна поступает питание батареи это способствует дополнительной разрядки. Поэтому в коде используется переопределение пинов SDA и SCL на GPIO6, GPIO7. Библиотека Adafruit_HTU21DF
упрощает чтение данных:
Adafruit_HTU21DF HTU = Adafruit_HTU21DF(); // Определяем датчик HTU21D TwoWire I2CHTU = TwoWire(0); #define I2C_SDA 6 #define I2C_SCL 7 I2CHTU.begin(I2C_SDA, I2C_SCL, 100000);//Определяем новые пины шины I2C HTU.begin(&I2CHTU);
Делитель напряжения
ESP32-C3 имеет встроенный АЦП, но его входное напряжение не должно превышать 3.3 В. Для измерения напряжения батареи (например, Li-Ion 3.7 В) используется делитель напряжения. На схеме применяется мостовой делитель 1:1 (два резистора номиналом R1 = R2), подключенные к GPIO0(A0), что снижает напряжение в 2 раза. Формула расчета:
uint32_t Vb = 0; for (int i = 0; i < 16; i++){ Vb += analogReadMilliVolts(A0); // коррекция ADC } float Vbatt = 2 * Vb / 16 / 1000.0; // переводим в вольты uint8_t batt_percent = (uint8_t)mapPercent(Vbatt, minV, maxV);
Пояснение:
analogReadMilliVolts(A0)
возвращает значение в мВ на делителе используя коррекцию ADC.- Умножение на 2 компенсирует деление напряжения.
- Функция
mapPercent()
преобразует напряжение в проценты заряда.
Режим глубокого сна
Режим глубокого сна (Deep Sleep) ESP32-C3 отключает большинство компонентов, оставляя активным только RTC (Real-Time Clock), что снижает энергопотребление до 44 микроампер. В коде время сна задано как TIME_TO_SLEEP 300 * 1000000
мкс (5 минут). Для пробуждения используется аппаратный таймер. После отправки данных на сервер, микроконтроллер уходит в режим глубокого сна, экономя заряд батареи.
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP); esp_deep_sleep_start();
Отправляем и принимаем данные
Используем стандартные настройки подключения к WiFi сети любых модулей ESP32. Для передачи данных на MQTT сервер применяется библиотека <PubSubClient.h>. Для формирования JSON пакета библиотека <ArduinoJson.h>. После считывания данных с датчиков формируем правильный JSON и отправляем в топик MQTT сервера Home Assistan. Структура MQTT-сообщения выглядит следующим образом. ESP32-C3 отправляет JSON в топик ESP32_c3_mini/sensor
:
{ "temperature": 25.5, "humidity": 60, "battery": 75, "voltage": 3.6, "rssi": -65 }
На стороне Home Assistan происходит парсинг JSON. Каждый сенсор использует value_template
для извлечения данных:
value_template: "{{ value_json.temperature }}" # Доступ к полю "temperature"
Дополнительные параметры:
unique_id
: Уникальный идентификатор для интеграции.device_class
: Определяет тип данных для автоматической иконки и логики.unit_of_measurement
: Единица измерения.
Настройка файла configuration.yaml в Home Assistan для наших 5 датчиков: температура, влажность, заряд батареи, напряжение батареи, уровень сигнала WiFi выглядит следующим образом:
mqtt: sensor: # Температура - name: "ESP32-C3 Temperature" unique_id: "esp32c3_temperature" state_topic: "ESP32_c3_mini/sensor" unit_of_measurement: "°C" device_class: "temperature" value_template: "{{ value_json.temperature }}" # Влажность - name: "ESP32-C3 Humidity" unique_id: "esp32c3_humidity" state_topic: "ESP32_c3_mini/sensor" unit_of_measurement: "%" device_class: "humidity" value_template: "{{ value_json.humidity }}" # Заряд батареи - name: "ESP32-C3 Battery" unique_id: "esp32c3_battery" state_topic: "ESP32_c3_mini/sensor" unit_of_measurement: "%" device_class: "battery" value_template: "{{ value_json.battery }}" # Напряжение - name: "ESP32-C3 Voltage" unique_id: "esp32c3_voltage" state_topic: "ESP32_c3_mini/sensor" unit_of_measurement: "V" device_class: "voltage" value_template: "{{ value_json.voltage }}" # Уровень сигнала Wi-Fi - name: "ESP32-C3 RSSI" unique_id: "esp32c3_rssi" state_topic: "ESP32_c3_mini/sensor" unit_of_measurement: "dBm" device_class: "signal_strength" value_template: "{{ value_json.rssi }}"
Код программы для ESP32c3 super mini написан в Code Visual Studio доступен на github https://github.com/lvs-vladimir/esp32_c3_deep_sleep
#include <Arduino.h> #include <timer2Minim.h> #include <WiFi.h> #include <PubSubClient.h> #include <Adafruit_HTU21DF.h> #include <ArduinoJson.h> #include <Wire.h> WiFiClient espClient; PubSubClient client(espClient); timerMinim TimerToSleep(2000); Adafruit_HTU21DF HTU = Adafruit_HTU21DF(); // Определяем датчик HTU21D TwoWire I2CHTU = TwoWire(0); #define TIME_TO_SLEEP 310 * 1000000 // 5 минут Время в спящем режиме в микросекундах #define I2C_SDA 6 #define I2C_SCL 7 const char *ssid = ""; const char *password = ""; const char *mqtt_server = ""; const char *mqttUser = ""; const char *mqttPassword = ""; const float minV = 3.0;//Минимальное значение напряжение при котором будет работать esp32c3 const float maxV = 4.0;//Максимальное значение аккумулятора float mapPercent(float x, float min, float max){//Функция mapPercent выполняет линейное преобразование значения x return (x - min) * (100) / (max - min);//из исходного диапазона [min, max] в новый диапазон от 0 до 100. } void setup(){ pinMode(A0, INPUT); pinMode(10, OUTPUT); digitalWrite(10, HIGH);//включаем питание датчика I2CHTU.begin(I2C_SDA, I2C_SCL, 100000);//Инициализируем программные пины I2C HTU.begin(&I2CHTU); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED){ delay(500); } WiFi.macAddress(); uint32_t Vb = 0; for (int i = 0; i < 16; i++){ Vb += analogReadMilliVolts(A0); // коррекция ADC } float Vbatt = 2 * Vb / 16 / 1000.0; // переводим в вольты uint8_t batt_percent = (uint8_t)mapPercent(Vbatt, minV, maxV); client.setServer(mqtt_server, 1883); client.connect(WiFi.macAddress().c_str(), mqttUser, mqttPassword); JsonDocument doc; doc["temperature"] = HTU.readTemperature(); doc["humidity"] = HTU.readHumidity(); doc["battery"] = batt_percent; doc["voltage"] = Vbatt; doc["rssi"] = WiFi.RSSI(); char output[128]; serializeJson(doc, output); client.publish("ESP32_c3_mini/sensor", output); esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP); TimerToSleep.start(); } void loop(){ if (TimerToSleep.isReady()){ digitalWrite(10, LOW); client.disconnect(); WiFi.disconnect(); esp_deep_sleep_start(); } }
Потребления тока в режиме глубокого сна составляет примерно 50 мкА, что соответствует заявленным производителем характеристикам:

Во время загрузки и подключения к WiFi сети наблюдается кратковременный всплеск до 90мА потом потребление стабилизируется до 32 мА:

ESP32-C3 в связке с HTU21D позволяет создавать автономные IoT-устройства с минимальным энергопотреблением. Режим глубокого сна и MQTT-интеграция делают систему гибкой и масштабируемой.