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
}