power consumption much too high

Karl1964
Posts: 1
Joined: Wed Jul 23, 2025 9:16 am

power consumption much too high

Postby Karl1964 » Wed Jul 23, 2025 9:22 am

Dear community;
I'm at the end of my tether. I bought this https://www.diymore.cc/collections/esp8 ... ttery-base and wrote a sketch that sends the board into deep sleep and wakes it up 4 times a day to measure the humidity and report it to an MQTT server via WLAN...
So all in all, it's not a matter of high power consumption. What's more, the thing is powered by a powerful 82650 2000mAh battery.
Despite this, the battery died within 3 days. At the beginning I hadn't switched off BT and WLAN separately. I added this later. Nevertheless, extremely high consumption (0.2A)
I would really like to realize this project and hope for many useful tips.
Many thanks
Karl

Code: Select all

// === Bibliotheken ===
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <time.h>
#include <Preferences.h>
#include <esp_bt.h>  // Bluetooth off

// === PIN DEFINITIONEN ===
#define DHTPIN 22
#define SOIL_PIN 32
#define BATTERY_PIN 35

// === SENSOR ===
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// === MQTT ===
const char* ssid = "XXXXXX";
const char* password = "XXXXXX";
const char* mqtt_server = "192.168.0.XX";
const int mqtt_port = 1883;

String clientIdStr = "Balkon";
const char* clientId = clientIdStr.c_str();
String topicStr = String("sensor/") + clientIdStr;
const char* mqtt_topic = topicStr.c_str();

WiFiClient espClient;
PubSubClient client(espClient);

// === SYSTEM ===
bool debug = true;
Preferences preferences;
int measurementIntervalMin = 60; // Standard: 1 Messung pro Stunde

// === KALIBRIERUNG SOIL SENSOR ===
const int dryValue = 3167; // trocken
const int wetValue = 1215; // nass

// === GLOBALE VARIABLEN ===
int wifiQuality = 0;
float batteryVoltage = 0.0;

// === HILFSFUNKTIONEN ===
void debugLog(String msg) {
  if (debug) {
    Serial.println(msg);
    if (client.connected()) {
      String statusTopic = String(mqtt_topic) + "/Status";
      client.publish(statusTopic.c_str(), msg.c_str(), true);
    }
  }
}

void reconnectMQTT() {
  Serial.println("Starte MQTT-Verbindung...");
  Serial.println("Client ID: " + clientIdStr);
  Serial.printf("MQTT Server: %s:%d\n", mqtt_server, mqtt_port);
  Serial.println("MQTT Topic: " + String(mqtt_topic));

  while (!client.connected()) {
    Serial.print("Verbindung zu MQTT wird hergestellt...");
    if (client.connect(clientId)) {
      Serial.println("verbunden");
      debugLog("MQTT verbunden");
      String setTopic = String(mqtt_topic) + "/set/interval";
      Serial.println("Abonniere Topic: " + setTopic);
      client.subscribe(setTopic.c_str());

      // Retained Nachricht empfangen
      unsigned long start = millis();
      while (millis() - start < 2000) {
        client.loop();
        delay(10);
      }
    } else {
      Serial.print("Fehler, rc=");
      Serial.print(client.state());
      Serial.println(" versuche in 1s erneut");
      delay(1000);
    }
  }
}

void mqttCallback(char* topic, byte* payload, unsigned int length) {
  String messageTemp;
  for (int i = 0; i < length; i++) {
    messageTemp += (char)payload[i];
  }

  Serial.print("Nachricht empfangen auf Topic: ");
  Serial.print(topic);
  Serial.print(" | Payload: ");
  Serial.println(messageTemp);

  if (String(topic) == String(mqtt_topic) + "/set/interval") {
    int newInterval = messageTemp.toInt();
    if (newInterval >= 1 && newInterval <= 1440) {
      measurementIntervalMin = newInterval;
      preferences.putInt("interval", newInterval);
      debugLog("Neues Intervall gesetzt: " + String(newInterval) + " Minuten");
    } else {
      debugLog("Ungültiges Intervall erhalten: " + messageTemp);
    }
  }
}

void setupWifi() {
  delay(3000); // Vor WLAN-Start 3 Sekunden warten
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Verbinde mit WLAN");
  unsigned long start = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - start < 10000) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    long rssi = WiFi.RSSI();
    wifiQuality = map(rssi, -100, -30, 0, 100);
    wifiQuality = constrain(wifiQuality, 0, 100);
    Serial.print("WLAN verbunden! Signalstärke: ");
    Serial.print(wifiQuality);
    Serial.println("%");
  } else {
    Serial.println("WLAN Verbindung fehlgeschlagen");
    wifiQuality = 0;
  }
}

void syncTime() {
  configTime(3600, 3600, "pool.ntp.org", "time.nist.gov");
  Serial.print("Synchronisiere Uhrzeit...");
  struct tm timeinfo;
  int retries = 0;
  while (!getLocalTime(&timeinfo) && retries < 20) {
    delay(500);
    Serial.print(".");
    retries++;
  }
  Serial.println();
  if (retries < 20) {
    Serial.println("Uhrzeit erfolgreich synchronisiert:");
    Serial.println(getCurrentTimeString());
  } else {
    Serial.println("Uhrzeitsynchronisation fehlgeschlagen");
  }
}

String getCurrentTimeString() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    return "unknown";
  }
  char buffer[26];
  strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeinfo);
  return String(buffer);
}

void readBattery() {
  int raw = analogRead(BATTERY_PIN);  
  float voltage_adc = (float)raw / 4095.0 * 2.48;
  float teilerfaktor = 24.8;
  batteryVoltage = voltage_adc * teilerfaktor;
  batteryVoltage = round(batteryVoltage * 100) / 100.0;

  Serial.print("ADC raw: "); Serial.print(raw);
  Serial.print(" | ADC-Spannung: "); Serial.print(voltage_adc);
  Serial.print(" V | Batterie-Spannung: "); Serial.print(batteryVoltage);
  Serial.println(" V");
}

int readSoilPercent() {
  int raw = analogRead(SOIL_PIN);
  Serial.print("Boden Rohwert: ");
  Serial.println(raw);
  int percent = map(raw, dryValue, wetValue, 0, 100);
  return constrain(percent, 0, 100);
}

void publishData() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();

  if (isnan(temperature) || isnan(humidity)) {
    debugLog("Fehler beim Lesen des DHT-Sensors! Sende keine Daten in diesem Zyklus.");
    return;
  }

  int soil = readSoilPercent();
  readBattery();

  if (!client.connected()) {
    Serial.println("MQTT-Verbindung verloren, versuche Wiederverbindung vor dem Senden der Daten...");
    reconnectMQTT();
  }

  String now = getCurrentTimeString();
  char message[256];
  snprintf(message, sizeof(message),
           "{\"temperature\": %.1f, \"humidity\": %.1f, \"soil\": %d, \"wifi\": %d, \"battery\": %.2f, \"time\": \"%s\", \"interval_min\": %d}",
           temperature, humidity, soil, wifiQuality, batteryVoltage, now.c_str(), measurementIntervalMin);

  Serial.print("Sende MQTT-Nachricht: ");
  Serial.println(message);

  client.publish(mqtt_topic, message, true);
  debugLog("Payload gesendet.");
}

void goToSleep() {
  debugLog(String("Gehe in Tiefschlaf für ") + measurementIntervalMin + " Minuten...");
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  esp_bt_controller_disable();
  esp_sleep_enable_timer_wakeup((uint64_t)measurementIntervalMin * 60ULL * 1000000ULL);
  esp_deep_sleep_start();
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  btStop(); // Bluetooth deaktivieren
  dht.begin();

  preferences.begin("config", false);
  measurementIntervalMin = preferences.getInt("interval", 60);
  Serial.println("Intervall aus Preferences geladen: " + String(measurementIntervalMin));

  setupWifi();
  syncTime();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(mqttCallback);
  reconnectMQTT();

  publishData();
  goToSleep();
}

void loop() {
  // leer, alles im setup erledigt
}



username
Posts: 593
Joined: Thu May 03, 2018 1:18 pm

Re: power consumption much too high

Postby username » Fri Jul 25, 2025 5:27 am

You may put it to sleep. But if you cannot turn the power off to the sensors as well. there really is no point.

eriksl
Posts: 199
Joined: Thu Dec 14, 2023 3:23 pm
Location: Netherlands

Re: power consumption much too high

Postby eriksl » Thu Aug 14, 2025 4:15 pm

Actually, especially with WiFi on (and the transceiver not completely switched off ), I think three days on a lithium cell isn't even bad.

If you want to run microcontrollers from batteries, you really need to employ power management. Not the usual (automatic) "put the processor in sleep whenever it has nothing to do" (for nanoseconds...) but real power management. Where the processor and all of it's peripherals are completely switched off for extend periods of time. Something like wake up, take a measurement, done in half a second and then go to sleep again. Sleep as in: OFF and only wakeable from the RTC.

Who is online

Users browsing this forum: No registered users and 5 guests