Projekt:SpaceUhr

Crystal Clear action run.png
SpaceUhr

Status: stable

BCD-Uhr Space open.jpg
Beschreibung Zeit zum Verein zu düsen
Ansprechpartner Hendi


Übersicht

Info: Das gute Stück ist derzeit zur Überarbeitung auf meinem Schreibtisch! Kommt bald wieder mit mehr Features!

Ansprechpartner

  • Hendrik  

Kurze Beschreibung

Diese Uhr zeigt mithilfe von 16 BCD (binary coded digit)-codierten LEDs eine per NTP (Network time protocol) empfangene Uhrzeit sowie einen aus der Statusseite erhaltenen Spacestatus an. Hierbei werden gesetzte Bits der Uhrzeitanzeige durch weiße LEDs angezeigt. Bei geöffnetem Space sind die ungesetzten Bits "im Hintergrund" grün, bei Störungen oder geschlossenem Space rot. Da die beiden ersten Bit bei der 1. Stelle der Stunde nie benutzt werden wird das höchste Bit bei Ausstellungen im Space als Erinnerung für eine Betätigung der Türklingel verwendet. Unmittelbar beim Drücken der Türklingel blitzt und dröhnt das gute Stück.

. Die BCD-Uhr ist ein Klassiker unter den Digital- und Mikrocontrollerschaltungen und wurde sicher schon in 1000 Variationen als Beispiel genutzt.

Soft- und Hardware

Das Gehirn der Schaltung ist ein Expressif ESP8266 Microcontroller mit WLAN, der mit einer BASIC-Firmware (ESP8266BASIC V3) und der unten unter Referenzen angehängten Anwendung "SpaceUhr" programmiert ist, weiterhin muss man noch die Zugangsdaten des lokalen WLAN angeben, um einen Abruf der Daten zu ermöglichen. Zur Darstellung dient ein Strip mit RGB-LEDs, die durch einen jeweils eingebauten WS2812-Controller über eigene Intelligenz verfügen und vom ESP mit einem seriellen Bus programmiert werden können. Wichtig: Die serielle Datenleitung gleich am ESP8266-Modul mit einem Widerstand von 1k abschließen, das verringert EMV-Probleme!

Beteiligte Personen

  • Hendrik

Benötigte Teile

  • +5.104V Spannungsquelle, ca. 100 mA, USB-Netzteil verwendbar
  • ESP8266 Modul
  • 16 WS2812-LEDs, möglichst auf Strip montiert
  • Verbindungsleitung
  • WLAN-Zugang zum abrufen der Daten
  • 1 k Widerstand

Lesehilfe

Die Anzeige ist in 4 Nibble aufgeteilt, mit dem höchsten Wert jeweils rechts. Die Lesefolge ist also HH:MM. Pro Ziffer sind bei den weißen LEDs die im Feld "Wert" stehenden Zahlen zu addieren um den Wert der Ziffer zu erhalten.

Die folgende Tabelle hilft die LED-Zeile zu lesen:

LED Nr. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Wert 8 4 2 1 8 4 2 1 8 4 2 1 8 4 2 1
Element 1. Stelle Stunde 2. Stelle Stunde 1. Stelle Minute 2. Stelle Minute


Beispielbild

Nach der obigen Tabelle zeigt die Uhr 19:41 an. Die grünen LEDs die ungesetzte Bits repräsentieren signalisieren das der Space geöffnet ist.

Projekttagebuch

Date Name Was
01.04.2017 Hendi Das meiste erledigt =)
02.04.2017 Hendi Dokumentation in Wiki
05.10.2017 Fabian/Robert Störung im 2m band entdeckt, Aktualisierungsrate der LEDs spiegelt sich im Wasserfall wieder
26.10.2017 Hendi Temperaturübertragung an Telegram Bot verbessert
26.10.2017 Hendi Akustische Warnung bei fehlendem Klingelsensor, längere Klingel-Anzeigedauer, Anzeige bei geschlossenem Space aus
02.02.2018 Hendi Schäden von Umzug saniert
2024-10-24 Hendi Uhr war beschädigt, neu geklebt

Verbesserungsvorschläge Allgemein

Verbesserungsvorschläge Hardware

Hardware für Deep sleep vorbereiten (Verbindung WAKE-Pin mit Reset-Pin)

Verbesserungen Software

  • Abruf der Daten wenige Sekunden vor Minutenwechsel, Update der Anzeige möglichst genau zum Minutenwechsel
  • Sleep-Mode zwischen Update der Anzeige und Beginn der Startsequenz so daß rechtzeitig zum Abruf alles wach
  • Morsetiming nicht exakt

Referenzen

Code

guioff
msgbranch [message]
neo.stripcolor(0,13,0,0,5)
delay 7000
neo.stripcolor(0,13,0,0,0)
time.setup(2,1,"pool.ntp.org")
mytime=""
timercb 3000, [drawClock]
door=0
offenzu=""
drawcount=59
wait

[message]
timercb 0, [drawClock]
pwmfreq 800
RetMsg = "0"
msgcmd=msgget("cmd")
if msgcmd="secret" then
   for n=1 to 10
   neo.stripcolor(0,15,64,64,64)  
   gosub [morsed]
   neo.stripcolor(0,15,0,0,0)
   zeit=millis()
   do
   loop until millis()>(zeit+250)
   next
   door=30
   RetMsg="1"
   endif
timercb 3000, [drawClock]
MsgReturn RetMsg
wait

[drawClock]
timercb 0, [drawClock]
drawcount=drawcount+1
gosub [aquireandpost]
gosub [dotime]
if left(offenzu,1)=="o" then
gosub [drawm2]
gosub [drawm1]
gosub [drawh2]
gosub [drawh1]
gosub [drawflags]
end if
if drawcount > 20 then 
drawcount=0
gosub [minuteservice]
end if
timercb 1000, [drawClock]
wait

[drawh1]
my=myh1
if my="0" then
neo(12,0,5,0)
neo(13,0,5,0)
endif
if my="1" then
neo(12,20,20,20)
neo(13,0,5,0)
endif
if my="2" then
neo(12,0,5,0)
neo(13,20,20,20)
endif
return

[drawh2]
my=myh2
if my="0" then
neo(8,0,5,0)
neo(9,0,5,0)
neo(10,0,5,0)
neo(11,0,5,0)
endif
if my="1" then
neo(8,20,20,20)
neo(9,0,5,0)
neo(10,0,5,0)
neo(11,0,5,0)
endif
if my="2" then
neo(8,0,5,0)
neo(9,20,20,20)
neo(10,0,5,0)
neo(11,0,5,0)
endif
if my="3" then
neo(8,20,20,20)
neo(9,20,20,20)
neo(10,0,5,0)
neo(11,0,5,0)
endif
if my="4" then
neo(8,0,5,0)
neo(9,0,5,0)
neo(10,20,20,20)
neo(11,0,5,0)
endif
if my="5" then
neo(8,20,20,20)
neo(9,0,5,0)
neo(10,20,20,20)
neo(11,0,5,0)
endif
if my="6" then
neo(8,0,5,0)
neo(9,20,20,20)
neo(10,20,20,20)
neo(11,0,5,0)
endif
if my="7" then
neo(8,20,20,20)
neo(9,20,20,20)
neo(10,20,20,20)
neo(11,0,5,0)
endif
if my="8" then
neo(8,0,5,0)
neo(9,0,5,0)
neo(10,0,5,0)
neo(11,20,20,20)
endif
if my="9" then
neo(8,20,20,20)
neo(9,0,5,0)
neo(10,0,5,0)
neo(11,20,20,20)
endif
return



[drawm1]
my=mym1
if my="0" then
neo(4,0,5,0)
neo(5,0,5,0)
neo(6,0,5,0)
neo(7,0,5,0)
endif
if my="1" then
neo(4,20,20,20)
neo(5,0,5,0)
neo(6,0,5,0)
neo(7,0,5,0)
endif
if my="2" then
neo(4,0,5,0)
neo(5,20,20,20)
neo(6,0,5,0)
neo(7,0,5,0)
endif
if my="3" then
neo(4,20,20,20)
neo(5,20,20,20)
neo(6,0,5,0)
neo(7,0,5,0)
endif
if my="4" then
neo(4,0,5,0)
neo(5,0,5,0)
neo(6,20,20,20)
neo(7,0,5,0)
endif
if my="5" then
neo(4,20,20,20)
neo(5,0,5,0)
neo(6,20,20,20)
neo(7,0,5,0)
endif
if my="6" then
neo(4,0,5,0)
neo(5,20,20,20)
neo(6,20,20,20)
neo(7,0,5,0)
endif
if my="7" then
neo(4,20,20,20)
neo(5,20,20,20)
neo(6,20,20,20)
neo(7,0,5,0)
endif
if my="8" then
neo(4,0,5,0)
neo(5,0,5,0)
neo(6,0,5,0)
neo(7,20,20,20)
endif
if my="9" then
neo(4,20,20,20)
neo(5,0,5,0)
neo(6,0,5,0)
neo(7,20,20,20)
endif
return


[drawm2]
my=mym2
if my="0" then
neo(0,0,5,0)
neo(1,0,5,0)
neo(2,0,5,0)
neo(3,0,5,0)
endif
if my="1" then
neo(0,20,20,20)
neo(1,0,5,0)
neo(2,0,5,0)
neo(3,0,5,0)
endif
if my="2" then
neo(0,0,5,0)
neo(1,20,20,20)
neo(2,0,5,0)
neo(3,0,5,0)
endif
if my="3" then
neo(0,20,20,20)
neo(1,20,20,20)
neo(2,0,5,0)
neo(3,0,5,0)
endif
if my="4" then
neo(0,0,5,0)
neo(1,0,5,0)
neo(2,20,20,20)
neo(3,0,5,0)
endif
if my="5" then
neo(0,20,20,20)
neo(1,0,5,0)
neo(2,20,20,20)
neo(3,0,5,0)
endif
if my="6" then
neo(0,0,5,0)
neo(1,20,20,20)
neo(2,20,20,20)
neo(3,0,5,0)
endif
if my="7" then
neo(0,20,20,20)
neo(1,20,20,20)
neo(2,20,20,20)
neo(3,0,5,0)
endif
if my="8" then
neo(0,0,5,0)
neo(1,0,5,0)
neo(2,20,20,20)
neo(3,0,5,0)
endif
if my="9" then
neo(0,20,20,20)
neo(1,0,5,0)
neo(2,20,20,20)
neo(3,0,5,0)
endif
return

[dotime]
io(pwo,4,0)
mytime = time()
myh1 = mid(mytime,12,1)
myh2 = mid(mytime,13,1)
mym1 = mid(mytime,15,1)
mym2 = mid(mytime,16,1)
return

[drawflags]
end if 
if alive<>"secret" then
  neo(15,5,0,0)
else  
  neo(15,0,door,0)
endif
return

[morsed]
   io(pwo,4,256)
   zeit=millis()
   do
   loop until millis()>(zeit+300)
   io(pwo,4,0)
   zeit=millis()
   do
   loop until millis()>(zeit+100)
   io(pwo,4,256)
   zeit=millis()
   do
   loop until millis()>(zeit+100)
   io(pwo,4,0)
   zeit=millis()
   do
   loop until millis()>(zeit+100)
   io(pwo,4,256)
   zeit=millis()
   do
   loop until millis()>(zeit+100)
   io(pwo,4,0)
   zeit=millis()
   do
   loop until millis()>(zeit+300)
   return

[aquireandpost]
tempcount=tempcount+1
vt=io(ai)  
tempsum=tempsum+vt
if tempcount=60 then
tscount=tscount+1
tempsum=  -47/5120*tempsum + 1230537/5120
tempsum=tempsum-2
if tscount=1 then 
io(po,16,0)
sendts("thingspeaktoken","2",str(tempsum))
nyutemp=str(tempsum)
nyumessage = "codeblatz.ddns.net/soap.php?token=secret&tag=spacetemperature&value=" & nyutemp
nubsi=wget(nyumessage,80)
io(po,16,1)
tscount=0
end if
tempcount=0
tempsum=0
end if
return

[minuteservice]
alive=wget("esp-doorbell/msg")
if alive=="secret" then
else
io(pwo,4,256)
zeit=millis()
do
loop until millis()>(zeit+1)
io(pwo,4,0)
end if 
offenzu=wget("status.schaffenburg.org/")
return