Deep_Sleep ESP32

Hallo mein Name ist Thomas und ich bin neu hier im Forum.

Ich habe mir eine Wetterstation mit einem ESP32 DEVKIT V1 gebaut (BME280, BH1750, DS18B20, TSL2591, Anenometer, Windrichtung und Regenmenge) und die Werte werden per MQTT mosquitto an meine FHEM-Instanz übergeben. Das funktioniert auch tadellos aber da ich noch ziemlicher Anfänger in Sachen Arduino bin, verzweifle ich im Sketch mit Deep_Sleep zu erweitern und zu integrieren. Texte lesen, Videos schauen haben überhaupt nichts gebracht. Könnte mir jemand bitte dabei helfen?

VG Thomas

Dann lass das alles weg, und setze das was du gelesen und in deinen videos gesehen hast, in einem Test-Sketch um. Wenn du dann beschreiben kannst, woran genau du verzweifelst, kann eventuell jemand helfen.

Hallo Michael,

stimmt ein Forum lebt von Informationen, sorry.

Mit Hilfe diesen Link Deep-Sleep habe ich meinen Sketch erweitert und der ESP32 geht auch in Deep-Sleep, dass konnte ich im Seriellen-Monitor sehen aber es werden dann keine Werte übermittelt. Die Schwierigkeit ist das es eine Menge von Videos usw. gibt aber nichts dabei mit mehreren Sensoren oder es wird nicht verständlich erklärt. Da ich aber nicht nur copy & paste machen möchte sondern es gerne auch verstehen, ist es manchmal schwierig an Informatioen zu kommen.

VG Thomas

Was hast du erwartet, im Tiefschlaf?

Ok, nach dem Aufwachen werden keine Werte übermittelt. Ich bin davon ausgegangen das es für jeden selbstverständlich ist, dass während des Deep-Sleep keine Werte übermittelt werden können. Aber gut deshalb noch mal Es werden nach dem Aufwachen keine Werte übermittelt.

siehe #2
Ohne Sketch kann dir wohl keiner helfen.

Dieses Forum hat Regeln und dazu gehört, Programme in Code-Tags zu präsentieren. Diese Regel ist aus verschiedenen Gründen sinnvoll, daher solltest Du sie befolgen.

Sorry, falschen Button betätigt

#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "Adafruit_SI1145.h"
#include <BH1750.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <Wire.h>
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>

#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP 25

RTC_DATA_ATTR int bootCount = 0;

#define WIND_SPD_PIN 14
#define RAIN_PIN 25
#define WIND_DIR_PIN 35
#define VOLT_PIN 33
#define TEMP_PIN 4

#define WIFI_SSID ""
#define WIFI_PASSWORD ""

#define MQTT_HOST IPAddress(192, 168, ..., ...)
#define MQTT_PORT 1883

#define MQTT_PUB_TEMP "esp32/bme280/temperature"
#define MQTT_PUB_HUM "esp32/bme280/humidity"
#define MQTT_PUB_PRES "esp32/bme280/pressure"
#define MQTT_PUB_TEMP1WIRE "esp32/ds18b20/temperature"
#define MQTT_PUB_LUX "esp32/bh1750/lux"
#define MQTT_PUB_LIGHT "esp32/tsl2591/light"
#define MQTT_PUB_BATTERY "esp32/volt/battery"
#define MQTT_PUB_WINDSP "esp32/anenometer/windspeed"
#define MQTT_PUB_WINDDIR "esp32/windvane/windDir"
#define MQTT_PUB_RAIN "esp32/raincounter/rain"

Adafruit_BME280 bme;

float temp;
float hum;
float pres;

Adafruit_SI1145 uv = Adafruit_SI1145();

float UVindex;

BH1750 lightMeter(0x23);

float lux;

OneWire oneWire(TEMP_PIN);
DallasTemperature sensors(&oneWire);

float temp1wire;

volatile unsigned long timeSinceLastTick = 0;
volatile unsigned long lastTick = 0;
float windSpeed;

int vin;
String windDir = "";

#define S_IN_DAY 86400
#define S_IN_HR 3600
#define NO_RAIN_SAMPLES 2000
volatile long rainTickList[NO_RAIN_SAMPLES];
volatile int rainTickIndex = 0;
volatile int rainTicks = 0;
int rainLastDay = 0;
int rainLastHour = 0;
int rainLastHourStart = 0;
int rainLastDayStart = 0;
long secsClock = 0;

float batteryVolt;
float Vout = 0.00;
float Vin = 0.00;
float R1 = 27000.00;
float R2 = 100000.00;
int val = 0;

AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;

unsigned long previousMillis = 0;
const long interval = 10000;

void connectToWifi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void connectToMqtt() {
  mqttClient.connect();
}

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
    case SYSTEM_EVENT_STA_GOT_IP:
      connectToMqtt();
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      xTimerStop(mqttReconnectTimer, 0);
      xTimerStart(wifiReconnectTimer, 0);
      break;
  }
}

void onMqttConnect(bool sessionPresent) {
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  if (WiFi.isConnected()) {
    xTimerStart(mqttReconnectTimer, 0);
  }
}

void onMqttPublish(uint16_t packetId) {
}

void print_wakeup_reason() {
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch (wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
  }
}

void setup()
{
  Serial.begin(115200);
  delay(1000);
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  print_wakeup_reason();

  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

  bme.begin(0x76, &Wire);
  uv.begin(0x60);
  lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);
  sensors.begin();

  mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
  wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));

  WiFi.onEvent(WiFiEvent);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  mqttClient.onPublish(onMqttPublish);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);
  connectToWifi();

  Serial.println("Going to sleep now");
  delay(1000);
  Serial.flush();
  esp_deep_sleep_start();
  delay(5000);
  Serial.println("This will never be printed");

  pinMode(WIND_SPD_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(WIND_SPD_PIN), windTick, FALLING);

  pinMode(RAIN_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(RAIN_PIN), rainTick, FALLING);
  for (int i = 0; i < NO_RAIN_SAMPLES; i++) rainTickList[i] = 0;

  Read_Sensors_Data();
  Send_Data();

}

void loop()
{

}

void Read_Sensors_Data()
{

  temp = bme.readTemperature();
  hum = bme.readHumidity();
  pres = bme.readPressure() / 100.0F;
  sensors.requestTemperatures();
  temp1wire = sensors.getTempCByIndex(0);
  lux = lightMeter.readLightLevel();

  sensors.requestTemperatures();

  UVindex = uv.readUV();
  UVindex /= 100.0;

  lux = lightMeter.readLightLevel();

  val = analogRead(VOLT_PIN);
  Vout = (val * 3.3 ) / 4095.0;
  batteryVolt = Vout * ( R2 + R1) / R2 ;

  static unsigned long outLoopTimer = 0;
  static unsigned long wundergroundUpdateTimer = 0;
  static unsigned long clockTimer = 0;
  static unsigned long tempMSClock = 0;

  tempMSClock += millis() - clockTimer;
  clockTimer = millis();
  while (tempMSClock >= 1000)
  {
    secsClock++;
    tempMSClock -= 1000;
  }
  if (millis() - outLoopTimer >= 2000)
  {
    outLoopTimer = millis();
    if (timeSinceLastTick != 0) windSpeed = 1000.0 / timeSinceLastTick;

    windDirCalc();
    rainLastHour = 0;
    rainLastDay = 0;

    if (rainTicks > 0)
    {
      int i = rainTickIndex - 1;
      while ((rainTickList[i] >= secsClock - S_IN_HR) && rainTickList[i] != 0)
      {
        i--;
        if (i < 0) i = NO_RAIN_SAMPLES - 1;
        rainLastHour++;
      }
      i = rainTickIndex - 1;
      while ((rainTickList[i] >= secsClock - S_IN_DAY) && rainTickList[i] != 0)
      {
        i--;
        if (i < 0) i = NO_RAIN_SAMPLES - 1;
        rainLastDay++;
      }
      rainLastDayStart = i;
    }

  }
}

void windTick(void)
{
  timeSinceLastTick = millis() - lastTick;
  lastTick = millis();
}

void rainTick(void)
{
  rainTickList[rainTickIndex++] = secsClock;
  if (rainTickIndex == NO_RAIN_SAMPLES) rainTickIndex = 0;
  rainTicks++;
}

void windDirCalc()
{

  vin = analogRead(WIND_DIR_PIN);

  if (vin >= 212 && vin < 273) {
    windDir = "N";
  }
  else if (vin >= 577 && vin < 665) {
    windDir = "NNE";
  }
  else if (vin >= 483 && vin < 577) {
    windDir = "NE";
  }
  else if (vin >= 929 && vin < 943) {
    windDir = "ENE";
  }
  else if (vin >= 906 && vin < 929) {
    windDir = "E";
  }
  else if (vin >= 943 && vin < 1023) {
    windDir = "ESE";
  }
  else if (vin >= 795 && vin < 858) {
    windDir = "SE";
  }
  else if (vin >= 858 && vin < 906) {
    windDir = "SSE";
  }
  else if (vin >= 665 && vin < 748) {
    windDir = "S";
  }
  else if (vin >= 748 && vin < 795) {
    windDir = "SSW";
  }
  else if (vin >= 348 && vin < 399) {
    windDir = "SW";
  }
  else if (vin >= 399 && vin < 483) {
    windDir = "WSW";
  }
  else if (vin >= 0 && vin < 106) {
    windDir = "W";
  }
  else if (vin >= 163 && vin < 212) {
    windDir = "WNW";
  }
  else if (vin >= 106 && vin < 163) {
    windDir = "NW";
  }
  else if (vin >= 273 && vin < 348) {
    windDir = "NNW";
  }
}

void Send_Data() {

  unsigned long currentMillis = millis();
  // Every X number of seconds (interval = 10 seconds)
  // it publishes a new MQTT message
  if (currentMillis - previousMillis >= interval) {
    // Save the last time a new reading was published
    previousMillis = currentMillis;

    temp = bme.readTemperature();
    hum = bme.readHumidity();
    pres = bme.readPressure() / 100.0F;
    sensors.requestTemperatures();
    temp1wire = sensors.getTempCByIndex(0);
    lux = lightMeter.readLightLevel();

    uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());

    uint16_t packetIdPub2 = mqttClient.publish(MQTT_PUB_HUM, 1, true, String(hum).c_str());

    uint16_t packetIdPub3 = mqttClient.publish(MQTT_PUB_PRES, 1, true, String(pres).c_str());

    uint16_t packetIdPub4 = mqttClient.publish(MQTT_PUB_TEMP1WIRE, 1, true, String(temp1wire).c_str());

    uint16_t packetIdPub5 = mqttClient.publish(MQTT_PUB_LUX, 1, true, String(lux).c_str());

    uint16_t packetIdPub6 = mqttClient.publish(MQTT_PUB_LIGHT, 1, true, String(UVindex).c_str());

    uint16_t packetIdPub7 = mqttClient.publish(MQTT_PUB_BATTERY, 1, true, String(batteryVolt).c_str());

    uint16_t packetIdPub8 = mqttClient.publish(MQTT_PUB_WINDSP, 1, true, String(windSpeed).c_str());

    uint16_t packetIdPub9 = mqttClient.publish(MQTT_PUB_RAIN, 1, true, String(rainLastHour).c_str());

    uint16_t packetIdPub10 = mqttClient.publish(MQTT_PUB_WINDDIR, 1, true, String(windDir).c_str());

  }
}

Es wird :slightly_smiling_face:

Wenn Du nun noch in der Arduino-IDE Strg-t drückst, wird der Text lesbarer formatiert, nicht so links drangeklatscht. Du kannst dann Beitrag #9 verbessern.

Der Text "This will never be printed" brimgt mich zum Grübeln, ob danach jemals in setup etwas passiert. Bei Deiner Quelle endet dort setup :thinking:

Hallo,

bau doch erst mal alles ohne deep sleep auf, ganz normal , und lass alles zeitgetriggert im loop laufen. Wenn dann alles klappt rufst Du eine function auf ein die nur das deep sleep macht. agmue hat ja schon auf den Denkfehler in deinem Setup hingewiesen.
Heinz

Hallo,
der Code läuft ohne Deep-Sleep perfekt und mit MQTT-Explorer sehe ich das der eingestellte Intervall passt.
Mit dem Funktion Aufrufen die nur das Deep-Sleep macht verstehe ich nicht, kannst Du das genauer erklären bitte?

VG Thomas

Es wird besser :smiley:

... weil dieser Programmteil nie erreicht wird:

  delay(5000);
  Serial.println("This will never be printed");

  pinMode(WIND_SPD_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(WIND_SPD_PIN), windTick, FALLING);

  pinMode(RAIN_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(RAIN_PIN), rainTick, FALLING);
  for (int i = 0; i < NO_RAIN_SAMPLES; i++) rainTickList[i] = 0;

  Read_Sensors_Data();
  Send_Data();

Hallo
is doch eigentlich klar, erst alles manche und dann pennen gehen, wie im echten Leben.
Bau Dein setup mal so um . Ich würde alle anders aufbauen , ich denke abe es sollte gehen.
nicht getestet.

connectToWifi();

  pinMode(WIND_SPD_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(WIND_SPD_PIN), windTick, FALLING);

  pinMode(RAIN_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(RAIN_PIN), rainTick, FALLING);
  for (int i = 0; i < NO_RAIN_SAMPLES; i++) rainTickList[i] = 0;

  Read_Sensors_Data();
  Send_Data();

 Serial.println("Going to sleep now");
 delay(1000);
 Serial.flush();
  esp_deep_sleep_start();
  delay(5000);
  Serial.println("This will never be printed");

Moin, das hatte ich auch schon so ausprobiert aber funktioniert leider nicht.

Gruß Thomas

Funktioniert denn dieses verlinkte Beispiel bei Dir?

Sorry, hatte ich versäumt zu schreiben. Das Beispiel funktioniert

Das ist gut :slightly_smiling_face:

Da ich Deine komplexe Hardware nicht habe, kann ich Dir leider nicht konkreter helfen. Daher mußt Du nun das funktionierende Beispiel Schritt für Schritt um die Sensoren erweitern. Das ist mühselig, wird Dich aber an die Stelle führen, wo es zu Problemen kommt. Nach meiner Erfahrung kommst Du dann selbst auf die Lösung, wenn nicht, kannst Du dann hier noch mal fragen.

Eine Rückmeldung wäre auf jeden Fall eine willkommene Idee.

Ok das versuche ich am Wochenende mal und berichte oder frage hier nach. Danke für die Tipps und VG

Ich drücke die Daumen :crossed_fingers:

Was mir noch eingefallen ist: Wenn Du den ESP schlafen schickst, wissen die Sensoren nichts davon und produzieren weiter Daten. Das sollte eigentlich nichts ausmachen, aber möglicherweise mag ein Sensor das nicht. Dann müßtest Du den auch in einen Ruhemodus versetzen.