[gelöst] Problem mit Deep Sleep bei ESP8266

Hallo zusammen,
ich habe meine Steuerung der Gartenhausbeleuchtung umgebaut und verwende nun per WLAN die Uhrzeit, um die LED-Kette abends einzuschalten und nachts wieder auszuschalten. Das funktioniert soweit ganz gut und den Zweig mit LDR zum Aktivieren bei Dunkelheit habe ich entfernt. Das Licht ging doch relativ früh an. Kernproblem ist der Stromverbrauch des ESP. Die letzten Tage gab es wenig Sonne und dafür tagelangen Regen. So ist der durch die Solarzelle gepufferte Akku doch leer geworden. Deshalb will ich tagsüber, wenn die LED-Kette ausgeschaltet ist, den ESP schlafen schicken. Trotz vieler Recherche bekomme ich diesen Teil nicht zum Laufen. Wenn die Funktion "sleep" aktiviert ist, gibt es einen kurzen Reset ohne die eingestellte Zeit zum Schlafen. Vielleicht kann jemand einen Blick darauf werfen und mir den entscheidenden Tipp geben.
Im Sketch ist die Funktion "sleep" auskommentiert. Zum Testen bitte wieder einkommentieren. Ein Bild zeigt noch die Gartenhütte bei Nacht.

// Gartenhaus Version ESP21
// 21.11.2023
// ESP8266 Com 5
// Test mit LED-Kette
// Test mit Sekunden OK
// Test mit Minuten OK
// Ansteuerung LED-Kette (D5, D6) OK
// Fehler: Deep Sleep geht noch nicht

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Pins definieren
int LED1 = 16;   // Assign LED1 to pin GPIO16 = D0
int LED2 = 2;    // Assign LED2 to pin GPIO2  = D4 WLAN OK
int PinD5 = 14;  // H-Bridge LEDs
int PinD6 = 12;  // H-Bridge LEDs
int PinD7 = 13;  // Define LED PinD7 Dunkelheit LEDs an
int PinD8 = 15;  // Define LED PinD8 LED-Kette an

// Initialstates definieren
int ledState1 = LOW;
int ledState2 = HIGH;

// Timer-Variablen für LED-Kette
long myTimer = 0;
long myTimeout = 1000;  // Verzögerungszeit 1 Sekunde

const char *ssid = "xxx";
const char *password = "xxx";

//Zeitverschiebung UTC <-> MEZ (Winterzeit) = 3600 Sekunden (1 Stunde)
//Zeitverschiebung UTC <-> MEZ (Sommerzeit) = 7200 Sekunden (2 Stunden)
const long utcOffsetInSeconds = 3600;
char daysOfTheWeek[7][12] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" };
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
///////////////////////////////////////////////////////////////////////////
void setup() {
    Serial.begin(115200);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Ich verbinde mich mit dem Internet...");
    }

    Serial.println("Ich bin mit dem Internet verbunden!");
    delay(2000);  ///////////////////
    timeClient.begin();

    // LEDs definieren
    pinMode(LED1, OUTPUT);     // LED-Kette an -> entfällt
    pinMode(LED2, OUTPUT);     // WLAN OK
    digitalWrite(LED1, HIGH);  // LED1 ausschalten
    digitalWrite(LED2, HIGH);  // LED2 ausschalten
    pinMode(PinD5, OUTPUT);    // H-Bridge LEDs
    pinMode(PinD6, OUTPUT);    // H-Bridge LEDs
    pinMode(PinD7, OUTPUT);    // Dunkelheit
    pinMode(PinD8, OUTPUT);    // Nachtruhe
}
///////////////////////////////////////////////////////////////////////////
void day_time() {
    timeClient.update();
    Serial.print(daysOfTheWeek[timeClient.getDay()]);
    Serial.print(", ");
    Serial.println(timeClient.getFormattedTime());
    Serial.println(timeClient.getHours());    // Aktuelle Stunde
    Serial.println(timeClient.getMinutes());  // Aktuelle Minute
    Serial.println(timeClient.getSeconds());  // Aktuelle Sekunde
    delay(1000);
}

void wifi_status() {
    // WiFi-Status: LED2 leuchtet, wenn WLAN OK
    if (WiFi.status() == WL_IDLE_STATUS) {
        digitalWrite(LED2, !digitalRead(LED1));
        Serial.println("WL_IDLE_STATUS");
    } else if (WiFi.status() == WL_CONNECTED) {
        digitalWrite(LED2, LOW);  // LED2 an
        Serial.print("WL_CONNECTED ");
        Serial.println(WiFi.localIP());
    } else if (WiFi.status() == WL_DISCONNECTED) {
        digitalWrite(LED2, HIGH);  // LED2 aus
        Serial.println("WL_DISCONNECTED");
    }
    //	delay(200);
}

void timer() {
    // LED-Kette an (Mit Minuten OK. Ändern in Stunden)
    if ((timeClient.getMinutes() >= 13)) {
        Serial.println("LED-Kette an");
        digitalWrite(PinD8, HIGH);  // LED Blau an
    }
    // Nachtruhe LED-Kette aus
    if ((timeClient.getMinutes() >= 33)) {
        Serial.println("LED-Kette aus");
        digitalWrite(PinD8, LOW);  // LED Blau aus
    }
}

void led_kette() {
    // Ansteuerung H-Bridge
    if (digitalRead(PinD8) == LOW) {  // Bei Dunkelheit
        digitalWrite(PinD5, LOW);
        digitalWrite(PinD6, LOW);
    } else {  // Bei Dunkelheit LED-Kette einschalten
        if (millis() > myTimeout + myTimer) {
            myTimer = millis();

            if (ledState1 == LOW) {
                ledState1 = HIGH;
            } else {
                ledState1 = LOW;
            }

            if (ledState2 == LOW) {
                ledState2 = HIGH;
            } else {
                ledState2 = LOW;
            }

            digitalWrite(PinD5, ledState1);
            digitalWrite(PinD6, ledState2);
        }
    }
}

void sleep() {
    if (digitalRead(PinD8) == LOW) {
        Serial.println("Ich gehe in 10 Sekunden schlafen");
        delay(10000);
        ESP.deepSleep(5e6); /* Sleep for 5 seconds */
    }
}

///////////////////////////////////////////////////////////////////////////
void loop() {
    day_time();
    wifi_status();
    timer();
    led_kette();
    //  sleep();
}

LG Hans

Hallo,
welchen ESP8266 verwendest du ? Es gibt mehrere.
Die meisten haben noch weitere Bauelemente drauf, die auch Strom brauchen und sich nicht in den Schlaf setzen lassen. Auch wenn der Controller schläft, wird noch viel Strom benötigt.

Ich verwende eine Version von AZDelivery (NodeMCU Amica). Nicht die Miniaturversion ohne Stromanschlüsse usw. Bei den Messungen verbleiben noch 5 mA im Sleep Mode, was für meinen Akku OK ist.
Mit diesem Beispielcode legt sich der ESP8266 schlafen:

#define ledPin 2 /**/

void setup()
{
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);

}

void loop()
{
  digitalWrite(ledPin, LOW);
  delay(5000);
  ESP.deepSleep(5e6); /* Sleep for 5 seconds */
}

Beim Hochladen muss man die Drahtbrücke von D0 zu RST entfernen und danach wieder einfügen. Das weißt du aber sicher. Bei meinen ersten Versuchen mit Deep Sleep bin ich promt darüber gestolpert.

Ok, wenn dir das reicht, ists gut.
Zum Deep Sleep kann ich nichts sagen, bei mir laufen alle am Netz.

Danke.
Vielleicht hat ein anderer User Erfahrungen mit Deep Sleep. Die Gartenhütte wird wie erwähnt mit einer kleinen Solarzelle und einem Akku versorgt.

Bitte warten:
Mit dem Code vom Sketch ist durch viele Kopieraktionen etwas schief gegangen. Ich melde mich später mit dem richtigen Programmcode. Sorry.

So, jetzt habe ich die Fehler in meinem Sketch gefunden und (hoffentlich) alle beseitigt. Das Muster funktioniert mit der Eingabe von Minuten in der Funktion "timer", also dem Zeitbereich, wann die LED-Kette leuchten soll. Mit den Stundenwerten (getHours), welche natürlich erforderlich sind, sollte es auch klappen. Kann ich erst nach dem Einbau testen. Bei dem Deep Sleep gibt es ein paar Stolperstellen, wo ich bei der ersten Nutzung prompt reingeraten bin:

  • Drahtbrücke von D0 zu RST im Betrieb erforderlich
  • Vor dem Hochladen in den ESP MUSS die Drahtbrücke entfernt werden!
  • Nach dem Hochladen die Drahtbrücke wieder anbringen
  • Die Stromversorgung kurz unterbrechen, damit der ESP neu startet (der Resetknopf versagt hier meistens). Am seriellen Monitor kann der Ablauf verfolgt werden.
    Der Deep Sleep ist wie erwähnt erforderlich, da bei schlechter Witterung und wenig Sonne die Solarzelle den Akku nicht genug auflädt. Die LED-Kette soll immer um 01 Uhr ausgeschaltet werden, um die Nachbarn nicht zu nerven (und Tiere in der Nachtruhe zu stören). Im nächsten Schritt wird die feste Startzeit durch eine Abfrage der Monate angepasst, so dass die LED-Kette im Sommerhalbjahr erst nach 22 Uhr eingeschaltet wird. Anbei der Sketch zum Ansehen. Nicht schön, aber er funktioniert :slight_smile:
// Gartenhaus Version ESP23
// 23.11.2023
// ESP8266 Com 5
// Ansteuerung LED-Kette (D5, D6) OK
// Test mit LED-Kette OK
// Test Deep Sleep mit Minuten OK (Ändern in Stunden unter void timer)

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Pins definieren
int LED2 = 2;    // LED2 to pin GPIO2 = D4 WLAN OK
int PinD5 = 14;  // H-Bridge LEDs
int PinD6 = 12;  // H-Bridge LEDs
int PinD8 = 15;  // LED-Kette an

// Initialstates definieren
int ledState1 = LOW;
int ledState2 = HIGH;

// Timer-Variablen
long myTimer = 0;
long myTimeout = 0;  // Verzögerungszeit Test: 1 Sekunde

const char *ssid = "xxx";
const char *password = "xxx";

//Zeitverschiebung UTC <-> MEZ (Winterzeit) = 3600 Sekunden (1 Stunde)
//Zeitverschiebung UTC <-> MEZ (Sommerzeit) = 7200 Sekunden (2 Stunden)
const long utcOffsetInSeconds = 3600;
char daysOfTheWeek[7][12] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" };
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
///////////////////////////////////////////////////////////////////////////
void setup() {
    Serial.begin(115200);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("");
        Serial.println("Ich verbinde mich mit dem Internet...");
    }

    Serial.println("Ich bin mit dem Internet verbunden!");

    timeClient.begin();

    // LEDs definieren
    pinMode(LED2, OUTPUT);     // LED als Output definieren
    digitalWrite(LED2, HIGH);  // LED" Ausschalten
    pinMode(PinD5, OUTPUT);    // H-Bridge LEDs
    pinMode(PinD6, OUTPUT);    // H-Bridge LEDs
    pinMode(PinD8, OUTPUT);    // LED-Kette an
}
///////////////////////////////////////////////////////////////////////////
void day_time() {
    timeClient.update();
    Serial.print(daysOfTheWeek[timeClient.getDay()]);
    Serial.print(", ");
    Serial.println(timeClient.getFormattedTime());
    Serial.println(timeClient.getHours());    // Aktuelle Stunde
    Serial.println(timeClient.getMinutes());  // Aktuelle Minute
    Serial.println(timeClient.getSeconds());  // Aktuelle Sekunde
}

void wifi_status() {
    // WiFi-Status: LED2 leuchtet, wenn WLAN OK
    if (WiFi.status() == WL_IDLE_STATUS) {  // when not connected to a network, but powered on
        digitalWrite(LED2, !digitalRead(LED2));
        Serial.println("WL_IDLE_STATUS");
    } else if (WiFi.status() == WL_CONNECTED) {
        digitalWrite(LED2, LOW);
        Serial.print("WL_CONNECTED ");
        Serial.println(WiFi.localIP());
    } else if (WiFi.status() == WL_DISCONNECTED) {
        digitalWrite(LED2, HIGH);
        Serial.println("WL_DISCONNECTED");
    }
}

void timer() {
    // LED-Kette an
    if ((timeClient.getMinutes() >= 24) && (timeClient.getMinutes() <= 25)) {
        Serial.println("LED-Kette an");
        digitalWrite(PinD8, HIGH);  // LED Blau an
        digitalWrite(LED2, LOW);    // LED2 an
    } else {
        // LED-Kette an
        Serial.println("LED-Kette aus");
        digitalWrite(PinD8, LOW);  // LED Blau aus
        digitalWrite(LED2, HIGH);  // LED2 aus
    }
}

void led_kette() {
    // Ansteuerung H-Bridge
    // LED-Kette aus
    if (digitalRead(PinD8) == LOW) {
        digitalWrite(PinD5, LOW);
        digitalWrite(PinD6, LOW);
    } else {  // Bei Dunkelheit LED-Kette nach Uhrzeit einschalten
        if (millis() > myTimeout + myTimer) {
            myTimer = millis();

            if (ledState1 == LOW) {
                ledState1 = HIGH;
            } else {
                ledState1 = LOW;
            }

            if (ledState2 == LOW) {
                ledState2 = HIGH;
            } else {
                ledState2 = LOW;
            }

            digitalWrite(PinD5, ledState1);
            digitalWrite(PinD6, ledState2);
        }
    }
}

void sleep() {
    if (digitalRead(PinD8) == LOW) {
        Serial.println("Ich gehe in 5 Sekunden für eine halbe Minute schlafen!");
        delay(5000);
        ESP.deepSleep(30e6); /* Sleep for 30 seconds. Anpassen nach Bedarf */
    }
}

///////////////////////////////////////////////////////////////////////////
void loop() {
    day_time();
    wifi_status();
    timer();
    led_kette();
    sleep();
}

Wird dir auf die Füße fallen.

Auch dies. millis() nutzt unsigned long.

Zum Thema Reset Beschaltung steht hier einiges. ESP8266 und ESP8285 WLAN Module Vielleicht hilft dir es beim Reset Problem.

Was verbraucht eigentlich deine Lichterkette an Strom?

Ich verwende für die LED-Kette einen Wechselblinker.
Quelle...
Der Reset durch Deep Sleep klappt jetzt. Hatte den Pin D0 von früheren Versuchen definiert, was die Ursache war. Die LEDs zucken nur fast unmerklich ab und zu, was ich für diesen Anwendungsfall tolerieren kann.

Danke für den Link. Ist interessant, auch wenn ich nicht alles verstehe. Mit dem Plotter habe ich aus Zeitgründen noch nicht gearbeitet.

Die Kette verbraucht etwa 10 mA bei 2,7 Volt. Genau kann ich das nicht sagen, da hier der Wechselblinker zum Einsatz kommt.

Verwendet habe ich ein fertiges Produkt von Amazon, was ich verbessern wollte. Die Mini-Solarzelle lädt einen kleinen Akku mit 1,2 Volt auf und enthält einen LDR, welcher bei Dunkelheit die LED-Kette einschaltet. Irgendwann in der Nacht geht die Kette mangels Strom einfach wieder aus. Mir hat die LED-Kette gefallen, obwohl es eine Spezial-Konstruktion ist: Die LEDs sind mittels Dioden gegeneinander geschaltet, so dass beim Anlegen der Spannung nur jede zweite LED leuchtet. Deshalb der Wechselblinker, welcher schnell die Polarität der Spannung umschaltet. Aufgrund der niedrigen Betriebsspannung der Kette habe ich zur Ansteuerung eine H-Bridge verwendet. Bei den trüben Tagen in letzter Zeit ist auch der Akku mit 10Ah leer geworden, weshalb ich den Deep Sleep nutzen will. Einen ordentlichen Schaltplan mit Fritzing gibt es (noch) nicht; nur eine Handskizze. Wenn das wirklich jemand sehen will, kann ich die Skizze scannen oder fotografieren. Meinen Prototyp mit der neuen Deep Sleep-Funktion baue ich in Kürze ein und hoffe, er läuft. Dann kommt alles ordentlich in ein kleines Gehäuse.

Ja, ich kenne die Stripes. Hatten wir erst in einem anderen Forum. Dort ging es dann auch darum die LEDs zu dimmen, jeden "Kanal" separat. Betraf dort aber ein Uno/Nano.
Aber dennoch ist der millis() Vergleich fehlerhaft. Auch die von dir verwendeten Variablen haben den falschen Wertebereich.

10mA bei dem auf dem Foto zu sehenden Licht? :astonished:
Kaum zu glauben.

Ich vermute, das deine Solarzelle es dennoch nicht schaffen wird, dein Akku ausreichend zu laden.

Ich hatte die LED-Kette früher auch mit einem Nano betrieben. Wegen der Möglichkeit mit der Uhrzeit durch WLAN dann auf den ESP8266 umgestellt.

Ich komme später nochmal darauf zurück, sonst habe ich zu viele Baustellen auf einmal.

So zeigt es zumindest mein Multimeter an. Es kann durch den Wechselblinker falsch sein. Müsste mal mein kleines digitales Oszi dranhängen.

In den Sommermonaten hat der Akku ausgereicht, obwohl das Licht schon früh anging (hatte einen LDR benutzt und vermutlich ungünstig platziert.

Wenn der anstehende Umbau fertig ist, komme ich ggf. auf die millis zurück. Durch den Sleep-Modus werde ich auf jeden Fall Strom sparen.

Ich habe jetzt nochmals Strom-Messungen durchgeführt.
Die LED-Kette habe ich mit 2,7 Volt in eine Richtung (jede zweite LED leuchtet) gemessen.
Ergebnis: 15 mA
Da durch den Wechselblinker die Richtung permanent getauscht wird, dürfte der Wert auch im Betrieb zutreffen.
Mein ESP8266 (AZDelivery) verbraucht ohne weitere Last 80 mA. Dazu kommt dann die LED-Kette. so dass ich auf rund 95 mA komme. Im Sleep Mode verbraucht der ESP8266 noch rund 10 mA. Das sind also nur noch etwa 10 % gegenüber dem Wach-Modus.
Die Sleep-Zeit stelle ich auf 10 Min. ein und warte vor dem Schlafengehen noch 1-2 Sekunden.
Aktuell sollen die LEDs von 19 - 01 Uhr leuchten. Dann greift der Sleep Mode bis zum nächsten Abend. Tagsüber wird der Akku von der Solarzelle geladen und m. E. sollte das auch bei schlechtem Wetter reichen. Ich baue nun meinen Prototyp in Kürze ein und werde nach einigen Tagen berichten, ob ich Erfolg habe.

In meiner Garage arbeitet ein Nano mit Akku, Solarzelle und Wechselrichter für den Torantrieb. Über den Sleep Mode für den Nano habe ich nichts genaues gefunden bzw. der Hinweis, man könnte nicht viel sparen. Habt ihr ggf. einen Link zu diesem Thema? Ansonsten würde ich den Nano durch ESP8266 bzw. ESP32 ersetzen.

Wenn Du Energie sparen willst, dann sind alle Platinen mit USB fehl am Platze. Dann musst Du Dir selbst was mit "nackten" MC basteln.

Gruß Tommy

Das ist mir bekannt, aber ich benutze lieber die Entwickler-Platinen mit einem Sheet zum Schrauben.
Der ESP8266 wird im Betrieb nicht per USB, sondern mit 5 Volt vom Solarregler über den Pin Vin versorgt und läuft damit einwandfrei. Die Spannung für die LED-Kette wird mittels 2,7 Volt-Regler erzeugt, wobei ich mit einem MOSFET diesen Zweig auch abschalten kann. Dann fließt hier nur Strom, wenn die LEDs leuchten sollen.
Wie gesagt teste ich das Projekt die nächsten Tage und melde mich wieder. Dann auch mit dem fertigen Sketch.

Somit hat der USB Chip weiter Spannung und Nuckelt am deinem Akku

Ist da nicht eine Diode von USB zu Vin, welche den Stromfluss verhindert? Habe irgendwo so was gelesen. Soll aber nicht bei allen Klonen drin sein. Kann man das messen? Mit der Diode soll verhindert werden, dass der ESP verdampft.

Nein, keine Diode. Und nein, darum geht es auch nicht.

Auf deinem ESP Board sind Bauteile, die Strom ziehen. Unabhängig vom Sleep des ESP.

Der Spannungsregler und der USB zu UART Wandler verbrauchen relativ viel.

In diesem Video wird gut erklärt, was Strom braucht. Und sogar Lösungswege dies zu minimieren. https://m.youtube.com/watch?v=ooQUDcfs1iM

Danke für den Link. Interessantes Video. Ich schaue mal, wie das mit meinem Prototyp läuft und ob der Akku reicht.
An meiner Garage gibt es eine 100 Ah-Batterie und eine 100 Watt Solarzelle. Ein Uno läuft ohne weitere Optimierung rund um die Uhr und der Fernsteuerempfänger hängt ebenfalls am Akku dran. Wenn das Tor betrieben wird, fließt schon ordentlich Strom (ca 7 A). Bisher hat der Akku immer gereicht, aber am Gartenhaus ist alles kleiner gebaut (Solarzelle 20 Watt, Akku 7,2 bzw. 10 Ah.

Grob gerechnet
7,2Ah sind nur zu erreichen, bei gewisser Belastung = in Datenblatt schauen,
das PV Modul gibt 1A raus (im Labor) jetzt im Herbst um die 0,2 wenn gut geht 0,5A, der PV Regler nimmt sich 5mA wen das Modul nix liefert, Schund PV Regler fängt an zu Laden wen das PV gibt Min. 3V mehr als der Akku gerade hat.
In der Woche kommen zusammen 0,84 Ah (Regler) + 1,68Ah für ESP ( gerechnet mit 10mA) = 2,5 Ah
Bei dem Wetter wird der Akku nie Voll, was dazu trägt das die Kapazität unter umständen nur für 3, 4 Tage reicht, nicht Vergessen das der Akku gibt die 7,2Ah ab, bis er vollendladen wird, auch bei Gellakku ist der nach kurzer zeit Tot, noch was, im niedriger die Temp desto geringer die Kapazität

Man überschätzt meistens was ein Kombi PV + Akku kann leisten

Ich habe eine neue Version mit dem ESP8266 in Betrieb genommen. Der notwendige Spannungswandler wird erst bei Bedarf über einen MOSFET eingeschaltet, was am Ruhestrom spart.
Aktuelle Messwerte:
Ruhestrom: 10 mA
Laststrom: 95 mA
Ohne Solarzelle hat der Akku an einem Tag 0,1 Volt Spannung verloren.
Den ESP32 Mini habe ich mir bestellt und baue die Schaltung damit um. Ebenso wird in Kürze die 20 Watt-Solarzelle gegen ein 50 Watt-Modul ersetzt.
Die Schaltung habe ich zur Verdeutlichung mit Fritzing gezeichnet. Mein Erstlingswerk; nicht schön, aber selten. Dann sind noch Bilder des Prototyps beigefügt. Demnächst gibt es ein Update und ich erhoffe mir vom ESP32 Mini noch weniger Ruhestrom.
Hier der Sketch:

// Gartenhaus Version ESP27
// 26.11.2023
// ESP8266 Com 5
// Ansteuerung LED-Kette (D5, D6) OK
/*
Programmier-Anleitung:
Drahtbrücke D0 zu RST unterbrechen
Stromversorgung unterbrechen
USB-Kabel zum PC einstecken
Sketch hochladen
Drahtbrücke wieder herstellen
Stromversorgung kurz unterbrechen
Nach 1 Minute sollte Uhrzeit per WLAN verfügbar sein
Messwerte:
Mit LED-Kette und MOSFET: 95 mA
Sleep-Mode:               10 mA
*/

// WLAN-Verbindung
#ifndef STASSID
#define STASSID "xxx"       // SSID
#define STAPSK "xxx"  // Passwort
#endif

// Configuration of NTP - Zeitzone
#define MY_NTP_SERVER "at.pool.ntp.org"
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"

// Globals for NTP
time_t now;  // this are the seconds since Epoch (1970) - UTC
tm tm;       // the structure tm holds time information in a more convenient way

// Bibliotheken einbinden
#include <ESP8266WiFi.h>
#include <time.h>

// Pins definieren
int start;       // Test
int end;         // Test
int LED2 = 2;    // LED2 to pin GPIO2 = D4 WLAN OK
int PinD5 = 14;  // H-Bridge LEDs
int PinD6 = 12;  // H-Bridge LEDs
int PinD7 = 13;  // MOSFET
int PinD8 = 15;  // LED-Kette an

// Initialstates definieren
int ledState1 = LOW;
int ledState2 = HIGH;

// Timer-Variablen für LED-Kette
int myTimer = 0;
int myTimeout = 0;  // Verzögerungszeit Test: 1 Sekunde

///////////////////////////////////////////////////////////////////////////
void setup() {
    Serial.begin(115200);
    Serial.println("\nNTP TZ DST - bare minimum");
    configTime(MY_TZ, MY_NTP_SERVER);  // --> Here is the IMPORTANT ONE LINER needed in your sketch!

    // start network
    WiFi.persistent(false);
    WiFi.mode(WIFI_STA);
    WiFi.begin(STASSID, STAPSK);
    while (WiFi.status() != WL_CONNECTED) {
        delay(200);
        Serial.print(".");
    }
    Serial.println("\nWiFi connected");
    // by default, the NTP will be started after 60 secs

    // LEDs definieren
    pinMode(LED2, OUTPUT);     // LED als Output definieren
    digitalWrite(LED2, HIGH);  // LED" Ausschalten
    pinMode(PinD5, OUTPUT);    // H-Bridge LEDs
    pinMode(PinD6, OUTPUT);    // H-Bridge LEDs
    pinMode(PinD7, OUTPUT);    // MOSFET
    pinMode(PinD8, OUTPUT);    // LED-Kette an
}
///////////////////////////////////////////////////////////////////////////

void current_time() {
    // Zeit einlesen und updaten
    time(&now);              // read the current time
    localtime_r(&now, &tm);  // update the structure tm with the current time
    Serial.print("Monat: ");
    Serial.print(tm.tm_mon + 1);
    Serial.println();
}

// Zum Testen - Im Betrieb in der loop unten auskommentieren
void showTime() {
    time(&now);              // read the current time
    localtime_r(&now, &tm);  // update the structure tm with the current time
    Serial.print("year:");
    Serial.print(tm.tm_year + 1900);  // years since 1900
    Serial.print("\tmonth:");
    Serial.print(tm.tm_mon + 1);  // January = 0 (!)
    Serial.print("\tday:");
    Serial.print(tm.tm_mday);  // day of month
    Serial.print("\thour:");
    Serial.print(tm.tm_hour);  // hours since midnight  0-23
    Serial.print("\tmin:");
    Serial.print(tm.tm_min);  // minutes after the hour  0-59
    Serial.print("\tsec:");
    Serial.print(tm.tm_sec);  // seconds after the minute  0-61*
    Serial.print("\twday");
    Serial.print(tm.tm_wday);  // days since Sunday 0-6
    if (tm.tm_isdst == 1)      // Daylight Saving Time flag
        Serial.print("\tDST");
    else
        Serial.print("\tstandard");
    Serial.println();
}

void calendar()
// Ein/Ausschaltzeit der LED-Kette, abhängig vom Monat
{
    switch (tm.tm_mon + 1) {  // Kalendermonate
        case 1: start = 19; break;
        case 2: start = 20; break;
        case 3: start = 21; break;
        case 4: start = 21; break;
        case 5: start = 22; break;
        case 6: start = 22; break;
        case 7: start = 22; break;
        case 8: start = 22; break;
        case 9: start = 22; break;
        case 10: start = 21; break;
        case 11: start = 19; break;
        case 12: start = 19; break;
    }
    Serial.print("Startzeit: ");
    Serial.println(start);
    end = 23;
    Serial.print("Endezeit: ");
    Serial.println(end);
}

void timer() {  // Stunden
    // LED-Kette an (Schaltzeiten)
    Serial.print("Stunde: ");
    Serial.println(tm.tm_hour);
    if ((tm.tm_hour >= start) && (tm.tm_hour <= end - 1)) {
        Serial.println("LED-Kette an");
        digitalWrite(PinD8, HIGH);  // LED Blau an
        digitalWrite(PinD7, HIGH);  // MOSFET an                             //    digitalWrite(LED2, LOW);    // LED2 an
    } else {
        // LED-Kette aus
        Serial.println("LED-Kette aus");
        digitalWrite(PinD8, LOW);  // LED Blau aus
        digitalWrite(PinD7, LOW);  // MOSFET aus

    }
}

void led_kette() {
    // Ansteuerung H-Bridge mit Pin5, 6
    // LED-Kette aus
    if (digitalRead(PinD8) == LOW) {
        digitalWrite(PinD5, LOW);
        digitalWrite(PinD6, LOW);
    } else {  // Bei Dunkelheit LED-Kette nach Uhrzeit einschalten
        if (millis() > myTimeout + myTimer) {
            myTimer = millis();
            if (ledState1 == LOW) {
                ledState1 = HIGH;
            } else {
                ledState1 = LOW;
            }
            if (ledState2 == LOW) {
                ledState2 = HIGH;
            } else {
                ledState2 = LOW;
            }
            digitalWrite(PinD5, ledState1);
            digitalWrite(PinD6, ledState2);
        }
    }
}

void sleep() {
    if (digitalRead(PinD8) == LOW) {
        Serial.println("Ich gehe in 2 Sekunden für 10 Sekunden schlafen!");
        Serial.println("Bis bald :-)");
        delay(2000);
        ESP.deepSleep(10 * 1e6); /* Sleep for 10 minuts. Anpassen nach Bedarf */
    }
}

///////////////////////////////////////////////////////////////////////////
void loop() {
    current_time();
    //  showTime(); // Zum Testen - Im Betrieb auskommentieren
    calendar();
    timer();
    led_kette();
    sleep();
    //  delay(2000);  // Zum Testen - Im Betrieb auskommentieren
}