Автономное IoT устройство на ESP32-C3-super mini

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-интеграция делают систему гибкой и масштабируемой.

 

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.