|
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.