Projektvorstellung UHR3.1 - Update der dritten Version meiner TEXTUHR auf Arduino-Basis
|
Die neue Elektronik:
Das neue Herz der Uhr ist ein ESP8266-12E, der über die Arduino-IDE programmiert wurde. Die Platine trägt ansonsten nur Spannungsregler und einen 74HCT541,
der als Levelshifter fungiert und Stripe und Display mit den nötigen 5V-Signalen versorgt. Ein 74HCT125 hätte es auch getan, aber beim 541er ist mir die
Pinbelegung sympathischer ;-)
Ansonsten die Pfostenstecker aus der Version 3, an die Stripe, Helligkeitssensor und Display angeschlossen sind. Auf eine RTC hab ich hier verzichtet, weil die Zeit alle
zwei Minuten geholt wird - das sollte reichen.
Die Adventskranz-Erweiterung ist ebenso nicht mehr an Bord - war mir nicht wichtig genug.
Der Sketch (das "Programm"):
#include <ESP8266WiFi.h> // Library fürs WLAN des ESP8266 #include <Adafruit_NeoPixel.h> // Library für Stripe-Ansteuerung #include <Time.h> // Library mit Zeit-Funktionen einbinden #include "UC121902-TNARX-A.h" // Library fürs Display einbinden UC121902_TNARX_A::Display display (12,13,5); // Display einstellen an Pins 12,13 und 15 #define PIXELPIN 4 // Datenpin für Stripe: 4 #define NUMPIXELS 37 // Stripe hat 36 LEDs/Pixels Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIXELPIN, NEO_GRB + NEO_KHZ800); //Stripe-Daten einstllen #define hsensor A0 // Helligkeitssensor hängt am analogen Eingang (Pin2 des ESP) int hell; // Helligkeitswert aus dem Sensor int ledhell=255; // Helligkeit der LEDs int mehrrot; // Variable für höheren Rot-Wert (abends) int mehrblau; // Variable für höheren Blau-Wert (morgens) const char* ssid = "MEINESSID"; // WLAN-SSID einstellen const char* password = "MEINPASSWORT" // WLAN-Key const char* host = "SERVERNAME"; // URL des Servers, von dem die Zeit geholt wird String url = "/zeit.php"; // Seite, die die Zeit anzeigt int stunde; // int minut; // int sekunde; // Variablen für die geholten Zeit-Daten int tag; int monat; int jahr; String disp; // Variable für den Display-Inhalt byte dispcount; // Hilfsvarialbe fürs Umschalten des Displays unsigned long lastholen; // Wann wurde zuletzt die Zeit geholt? unsigned long lastzeigen; // Wann wurde zuletzt die Zeit angezeigt? void setup() { //Serial.begin(115200); delay(10); pixels.begin(); // Initalisieren des Stripes delay(30); display.begin(); // Initalisieren des Displays /*Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); */ WiFi.begin(ssid, password); // WLAN-Verbindung herstellen while (WiFi.status() != WL_CONNECTED) { delay(500); //Serial.print("."); } /*Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println(); */ } void loop(){ if (millis()-lastholen > 120000 || (lastholen==0 && millis()>5000)){ // 120 Sekunden nach dem letzten Holen oder 5 Sek nach Start zeitholen(); // Funktion zum Holen der Zeitinfo lastholen=millis(); // Merken, wann die letzte Zeitinfo geholt wurde } if (millis()-lastzeigen > 1000){ // jede Sekunde: zeitdisplay(); // Zeit am Display anzeigen zeitzuled(hour(),minute()); // Zeit auf dem Stripe anzeigen lastzeigen=millis(); // Merken, wann zuletzt die Zeit angezeigt wurde helligkeit(); // Helligkeit neu prüfen } } void zeitzuled(int h, int m) // *** Funktion Stripeausgabe { /* LEDs und Anzeigen 35->fünf 33->zehn 31->viertel 29->vor 27->nach 25->halb 23->1 21->2 19->3 17->4 15->5 13->6 11->7 9->8 7->9 5->10 3->11 1->12 */ pxoff(); // Funktion aufrufen, das alle Pixel auf AUS setzt mehrblau=0; // Variable für mehr blau auf Null mehrrot=0; // Variable für mehr rot auf Null if (h<7) mehrblau=20; // Wenn Stunde kleiner als 7, Blauwert um 20 erhöhen if (h>18) mehrrot=20; // Wenn Stunde größer als 18, Rotwert um 20 erhöhen if (m>17) h+=1; // ab Minute 18 -> 1 Std größer anzeigen (13:20 -> zehn vor halb ZWEI) if (h>12) h-=12; // 12h-Format, also nach 12 Uhr 12 Std abziehen if (h==0) h=12; // 0 uhr = 12 pxon(25-h*2); // Stunde anzeigen (z.B. Std 6 -> Pixel 13) if (m>2 && m<8) { pxon(35); pxon(27); } // fünf nach if (m>7 && m<13) { pxon(33); pxon(27); } // zehn nach if (m>12 && m<18) { pxon(31); pxon(27); } // viertel nach if (m>17 && m<23) { pxon(33); pxon(29); pxon(25); } // zehn vor halb if (m>22 && m<28) { pxon(35); pxon(29); pxon(25); } // fünf vor halb if (m>27 && m<33) { pxon(25); } // halb if (m>32 && m<38) { pxon(35); pxon(27); pxon(25); } // fünf nach halb if (m>37 && m<43) { pxon(33); pxon(27); pxon(25); } // zehn nach halb if (m>42 && m<48) { pxon(31); pxon(29); } // viertel vor if (m>47 && m<53) { pxon(33); pxon(29); } // zehn vor if (m>52 && m<58) { pxon(35); pxon(29); } // fünf vor if (year()==1970) pxoff(); // nichts anzeigen, solange Uhr noch nicht gestellt pixels.show(); // alle Pixel gesetzt, Daten auf Stripe schreiben } void zeitholen() { display.prog.turnOn(); // Das Feld "PROG" auf dem Display einschalten display.print(" "); // Das Display leeren //Serial.print("connecting to "); //Serial.println(host); WiFiClient client; // Verbindung mit dem Server const int httpPort = 80; if (!client.connect(host, httpPort)) { // Wenn keine Verdindung zustande kommt... //Serial.println("connection failed"); display.chan.turnOn(); // Das Feld "CHAN" auf dem Display einschalten display.prog.turnOff(); // Das Feld "PROG" auf dem Display ausschalten return; // zum loop (CHAN bleibt an als Indikator, dass Update nicht erfolgt) } //Serial.print("Requesting URL: "); //Serial.println(url); client.print(String("GET ") + url + " HTTP/1.1\r\n" + // Request senden "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); // start waiting for the response unsigned long lasttime = millis(); // Zeit des letzten Updates speichern while (!client.available() && millis() - lasttime < 1000) {delay(1);} // max 1s warten while (client.available()) { String line = client.readStringUntil('\r'); // Antwort zeilenweise lesen if (line.indexOf("---DAT")>=0) { // Wenn die Zeile "---DAT" enthält... display.chan.turnOff(); // CHAN ausschalten (Indikator, dass Update erfolgt) //Serial.println(); //Serial.print("**Datum: "); //Serial.println(line.substring(8, 16)); tag=line.substring(8,10).toInt(); // Datumsangaben in Zahlen umwandeln monat=line.substring(11,13).toInt(); jahr=line.substring(14,16).toInt(); } if (line.indexOf("---UHR")>=0) { // Wenn die Zeile "---UHR" enthält... Serial.println(); //Serial.print("**Zeit: "); //Serial.println(line.substring(8, 16)); stunde=line.substring(8,10).toInt(); // Zeitangaben in Zahlen umwandeln minut=line.substring(11,13).toInt(); sekunde=line.substring(14,16).toInt(); } setTime(stunde,minut,sekunde,tag,monat,jahr); // Zeit und Datum einstellen //Serial.print(line); } // Serial.println("closing connection"); display.prog.turnOff(); // PROG am Display ausschalten } void zeitdisplay(){ // *** Funktion Displayausgabe disp=" "; // Stringvariable für Displayinhalt leeren if (dispcount<6){ // wenn wengier als 6 Sek vergangen... disp += " "; // Leerzeichen hinzufügen if (hour()<10) disp += "0"; // falls Stunde einstellig, Null einfügen disp += hour(); // Stunde einfügen disp += " "; // Leerzeichen einfügen if (minute()<10) disp += "0"; // falls Miunte einstellig, Null einfügen disp += minute(); // Minute einfügen disp += " "; // Leerzeichen einfügen if (second()<10) disp += "0"; // falls Sekunde einstellig, Null einfügen disp += second(); // Sekunde einfügen } else{ // ... sonst (6 oder mehr Sek vergangen) if (day()<10) disp += "0"; // falls Tag einstellig, Null einfügen disp += day(); // Tag einfügen disp += " "; // Leerzeichen einfügen if (month()<10) disp += "0"; // falls Monat einstellig, Null einfügen disp += month(); // Monat einfügen disp += " "; // Leerzeichen einfügen disp += year(); // Jahr einfügen (ist vierstellig) } if (year()==1970) disp=" - SEt - "; display.print(disp); // generierten String auf Display schreiben dispcount++; // Zähler um eins erhöhen if (dispcount==10) dispcount=0; // bei 10 auf Null setzen (nach 10 Sekunden) } void zeitseriell(){ // Kontoll-Funktion aus der Beta-Zeit /* Serial.println(); if(day()<10) Serial.print("0"); Serial.print(day()); Serial.print("."); if(month()<10) Serial.print("0"); Serial.print(month()); Serial.print("."); Serial.print(year()); Serial.print(" "); if(hour()<10) Serial.print("0"); Serial.print(hour()); Serial.print(":"); if(minute()<10) Serial.print("0"); Serial.print(minute()); Serial.print(":"); if(second()<10) Serial.print("0"); Serial.print(second()); */ } void pxon(int px){ // *** Funktion für Pixelansteuerung pixels.setPixelColor(px,pixels.Color(ledhell+mehrrot,ledhell,ledhell+mehrblau)); pixels.setPixelColor(px+1,pixels.Color(ledhell+mehrrot,ledhell,ledhell+mehrblau)); } void pxoff(){ // *** Funktion für alle Pixel aus for (int i=0;i<NUMPIXELS;i++){ // für jedes Pixel von 0 bis NUMPIXELS (Anzahl der Pixel)... pixels.setPixelColor(i,pixels.Color(0,0,0)); // ... setze alle 3 Farben (RGB) auf Null } } void helligkeit(){ hell=analogRead(hsensor); // Helligkeitswert einlesen ledhell =20+ hell/5; // ... und umrechnen } |
Ausblick / ToDo / Dankesworte:
Falls jemand Vorschläge hat oder
Fehler findet, darf er/sie sich gerne melden!
An dieser Stelle herzlichen Dank für die vielen Rückmeldungen auf die erste Version. Es war immer schön, mit anderen Uhrenbastlern aus ganz Europa zu fachsimpeln und Erfahrungen
auszutauschen!
Ein besonderer Gruß geht an phi, Frank und Matthias! ;)
Alle in erwähnten
Marken- und Warenzeichen oder Produktnamen sind Eigentum ihrer jeweiligen Inhaber.
Für die Inhalte externer Links sind die jeweiligen Seitenbetreiber verantwortlich.
Keine Haftung für eventuelle Schäden.