Heute ist ein Mikrocontroller hinter dem Türchen, mit dem ihr nicht nur verschiedene Sensoren auslesen und Aktoren steuern, sondern auch mit einem WLAN-Verbindung aufnehmen könnt. Es ist der ESP8266 und davon gleich drei Stück.
Das Breakout Board hat, neben dem Prozessor mit 4MByte Flash Speicher, einen CH340 USB zu seriell Converter, damit ihr das Modul einfach programmieren könnt. Die meisten der I/O-Pins sind herausgeführt. Ebenso ist ein Spannungsregler vorhanden, der aus der USB-Versorgungsspannung oder der Spannung am Vin Anschluss die 3.3 V Versorgungsspannung für den ESP8266 liefert. Hier gleich ein wichtiger Hinweis. Da der ESP8266 mit 3.3 V arbeitet, dürfen an seine Eingänge keine höheren Spannungen als 3.3 V angelegt werden!
Wie das Titelbild zeigt, wollen wir mit einem der Controller zusammen mit einem LCD-Display, wie es im Adventkalender am 4.12. vorgestellt wurde, eine Uhr mit Zeit- und Datumsanzeige bauen. Das Besondere dabei, die Zeit kommt von einem hochgenauen Zeitserver im Internet.
Zuerst ist ein wenig Lötarbeit erforderlich. An das Display sollte der I2C Adapter gelötet werden. Ich empfehle den I2C Adapter an der Unterseite anzubringen, da er bei einem geplanten Einbau in ein Gehäuse dann nicht im Weg ist.
Die Verdrahtung ist ganz einfach GND und Vcc des Displays verbinden wir mit G und VU des Controllers. Die Taktleitung SCL kommt an D1 und die Datenleitung SDA an D2.
Nun geht’s ans Programmieren mit der Arduino IDE. Wenn die Unterstützung der Boards mit ESP8266 MCU noch nicht installiert ist, müssen wir das jetzt nachholen. In der Arduino IDE gehen wir über das Menü Datei auf Voreinstellungen oder einfach mit „Strg+;“.
Im Formular klicken wir beim Punkt „Zusätzliche Boardverwalter-URLs“ auf das Symbol rechts neben dem Eingabefeld. Hier können wir nun die URL für den ESP8266 Boardverwalter eingeben:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Nachdem Voreinstellungen gespeichert wurden, rufen wir über das Menü Werkzeuge->Board:->Boardverwalter den Boardverwalter auf. Als Suchbegriff geben wir „esp8266“ ein. Wir erhalten folgenden Eintrag, den wir installieren.
Nun können wir im Menü Werkzeuge->Board:->ESP8266 Boards ein Board auswählen. Wir verwenden NodeMCU 1.0….
Jetzt ist alles bereit, um den Sketch für die Uhr zu installieren.
#include <ESP8266WiFi.h> //WLAN Unterstützung #include <TZ.h> //Zeitzonen Konstanten //Bibliothek für das LCD Display #include <LiquidCrystal_I2C.h> //SSID und PSK vom lokalen WLAN #define STASSID "****************" #define STAPSK "****************" //Zeitzone mit Sommer/Winterzeit Information #define MYTZ TZ_Europe_Berlin // LCD Adresse = 0x27, Anzahl Zeichen 16 Anzahl Zeilen 2 LiquidCrystal_I2C lcd(0x27,16,2); //Definition der deutschen Wochentags und Monatsnamen als Abkürzung char weekdays[7][4] = {"Son","Mon","Die","Mit","Don","Fre","Sam"}; //März wird wegen des Umlauts zuerst mit Marz initialisier //und im Setup auf März geändert char months[12][6] = {"Jan.","Feb.","Marz","Apr.","Mai","Juni","Juli","Aug.","Sep.", "Okt.","Nov.","Dez."}; //Anzeige der aktuellen Zeit am Display void showTime() { time_t now; //aktuelle Zeit struct tm * s_time; //Zeitstruktur aufgesplittet in Jahr, Monat, Tag, Stunden, Minuten und Sekunden char line_buffer[20]; //Buffer für Anzeigenzeile now = time(nullptr); //aktuelle Zeit lesen s_time = localtime(&now); //für die lokale Zeit in die Zeitstruktur umwandeln //Zeilenbuffer mit Datum füllen sprintf(line_buffer,"%s %i.%s %i ",weekdays[s_time->tm_wday],s_time->tm_mday,months[s_time->tm_mon],s_time->tm_year+1900); //Datum auf die serielle Schnittstelle ausgeben Serial.println(line_buffer); //Datum am Display in Zeile 1 anzeigen lcd.setCursor(0,0); lcd.print(line_buffer); //Zeilenbuffer mit Uhrzeit füllen strftime(line_buffer,16,"%H:%M:%S Uhr",s_time); //Uhrzeit auf die serielle Schnittstelle ausgeben Serial.println(line_buffer); //Uhrzeit am Display in Zeile 2 anzeigen lcd.setCursor(0,1); lcd.print(line_buffer); } //Setup Funktion void setup() { Serial.begin(115200); //Serielle Schnittstelle initialisieren months[2][1]=0xE1; //Monat März korrigieren //Display initialisieren und Beleuchtung ein lcd.init(); lcd.backlight(); //Interne Uhr konfigurieren configTime(MYTZ, "pool.ntp.org"); //WLAN initialisieren und mit dem WLAN verbinden WiFi.persistent(false); WiFi.mode(WIFI_STA); WiFi.begin(STASSID, STAPSK); } //Hauptschleife void loop() { //Zeit anzeigen showTime(); //1 Sekunde warten delay(1000); }
Hier der Download des Sketches.
Fast alles, was wir benötigen, ist im ESP8266-Paket enthalten. Nur die Bibliothek für das LCD-Display fehlt. Sie kann über die Bibliotheksverwaltung in der Arduino-IDE installiert werden.
Wir geben als Suchbegriff „I2C LCD“ ein und finden, etwas weiter unten in der Liste, die gewünschte Bibliothek.
Ehe wir den Sketch kompilieren, müssen wir die Zugangsdaten für das WLAN an Stelle der Sternchen eintragen.
Wundert euch nicht, wenn beim Kompilieren folgende Warnung angezeigt wird.
WARNUNG: Bibliothek LiquidCrystal_I2C behauptet auf avr Architektur(en) ausgeführt werden zu können und ist möglicherweise inkompatibel mit Ihrem derzeitigen Board, welches auf esp8266 Architektur(en) ausgeführt wird.
Diese Warnung kommt daher, dass in den Spezifikationen zur Bibliothek ein falscher Eintrag vorgenommen wurde. Die Bibliothek funktioniert einwandfrei mit ESP8266 MCSs.
Das Besondere an dieser Uhr, sie wird aus dem Internet regelmäßig synchronisiert. Außerdem wird automatisch zwischen Sommer- und Winterzeit umgeschaltet.
Viel Spaß beim Nachbau.
2 comments
Kurt Hennig
Hallo,
Ich habe den Code jetzt an drei verschiedenen ESP8266 (V3 von AZ, Wemos D1 und ESP-07 ausprobiert, funktioniert alles wunderbar. Beim Wemos und ESP-07 SDA Pin D2=GPIO4 und SCL Pin D1=GPIO5 benutzen. Das mit dem lcd.init stimmt bei der neueren libary, bei älteren oder bei parallel Anschluss muss es lcd.begin heißen.
Kurt
Andreas Dürmuth
Hallo,
leider hat sich ein Fehler bei der Initialisierung eingeschlichen. Bei mir funktionierte leider der originale Sketsch nicht. Es kam eine Fehlermeldung ‘class LiquidCrystal_I2C’ has no member named ‘init’. Der Fehler steckt bei mir in Zeile 53. Ich habe:
lcd.init(); abgeändert zu:
lcd.begin();
Nun läuft alles.
Viel Spaß allen anderen “Bastlern”
Gruß, Andreas