Auswahl
Projekte
Impressum
lang:en   lang:de

 
 
 
time... Eine DCF77 basierte Uhr, die die Zeit mittels 39 LEDs anzeigt. Zum Ablesen muss man sein Hirn etwas anstrengen, da man nicht einfach die Ziffern sieht oder gar imaginäre Zeiger.
Nein, man muss zählen können. also genau das richtige für schlaflose Nächste.
Damit sie auch Nachts nicht blendet, werden die LEDs in der Helligkeit an die Umgebungshelligkeit angepasst.

Vor langer Zeit...

Es sollte mal ein Geschenk werden. Versprochen vor rund 15 Jahren. Damals hätte ich es mit einem 8051 Prozessor in Assembler realisieren müssen und einem Haufen weiterer DIL-Bausteine.
Ein Gehäuse hatte ich damals schon (darin ist inzwischen ein Blei-Akku-Ladegerät untergebracht). Ein riesiges Plastik-Ding, damit die ganze Steinzeit-Elektronik darin Platz gehabt hätte. Und selber ätzen hätte ich die Leiterkarte auch noch müssen.
Nun hat sich die Sache dann doch etwas hingezogen, die Entwicklung und Miniaturisierung aber ging weiter und ich habe es jetzt mit einem AVR Microcontroller und einer Hand voll SMD-Bausteinen realisiert. Also einem 32-poligen QFP Käferchen, etwas Hühnerfutter und eine Leiterkarte über PCB-Pool.
Dank dem GNU-Projekt gibt es auch perfekte Toolchains und man muss sich nicht mehr hochverschulden, um gnädigerweise bei einem kommerziellen Anbieter eine erstehen zu dürfen.

Funktion

 
Eingespeist wird ein rohes DCF77 Signal von irgendeinem Empfänger. Vorgesehen ist ein Optokoppler, somit kann man das DCF77-Signal als Strom-Schnittstelle mit 1mA..10mA liefern.
Dank der vielen Hardware auf dem Atmega8-Micocontroller kann man das DCF77-Signal in Hardware vermessen lassen und braucht danach in Software nur noch "die Bits sortieren". Kniffelig ist aber, wie man die Uhrzeit noch einigermaßen hinbekommt, wenn das DCF77-Signal mal gestört ist oder komplett ausfällt. Dafür hat die Karte einen 32768Hz Uhrenquarz. Der hat sich aber als so schlecht herausgestellt, daß ich in Software kompensieren musste, damit die Uhr nicht pro Minute 3 Sekunden nachgeht.
Den internen ADC verwende ich, um den externen LDR abzufragen. Damit regele ich die Helligkeit der LEDs.
Die Uhrzeit wird in 6 LED-Reihen angezeigt. Lesen muss man die Uhr wie eine normale digitale Uhr auch. Nur sieht man keine Zahlen, sondern die Uhrzeit ergibt sich aus der Anzahl der leuchtenden LEDs. Die 6 Reihen sind organisiert in drei Gruppen: Stunden, Minuten, Sekunden. Und pro Gruppe gibt es eine Reihe mit bis zu 5 LEDs für die Zehner-Stelle und 9 LEDs für die Einer-Stelle.
Die LEDs selber werden im Zeitmultiplex-Betrieb betrieben. Jede Gruppe wird für 5ms eingeschaltet und dabei über 14 GPIO des Prozessors entschieden, welche LED von dieser Gruppe aktiv sein soll und welche nicht. Dann erfolgt der Wechsel zu nächsten Gruppe und so weiter.
Innerhalb der 5ms wird die Helligkeit der LEDs noch mittels Pulsweiten-Modulation gesteuert. Und das noch zusätzlich in zwei Stufen. In der hellen Stufe treiben die GPIOs des Prozessors die LEDs aktiv mit 5V-Pegeln (über 360 Ohm in Serie), in der dunklen Stufe passiv über die im Prozessor eingebauten Pull-Up-Widerstände und die 360 Ohm. Die dunkle Stufe läßt die LEDs nur noch leicht glimmen und sind so Nachts blendfrei abzulesen.

Gehäuse

Wie immer fange ich meine Projekte mit der Auswahl eines Gehäuses an. Das Gerät sollte nicht langweilig aussehen (wie selber gebaut sehen die Sachen immer schon von alleine aus), also auch optisch was her machen.
Hier bot sich ein Gehäuse des nordamerikanischen Herstellers Hammond an. Den Typen 1553 gibt es im transparenten, blauen Kunsstoff. Darin kann man auch noch die Leiterkarte erkennen und wenn man auf der mit dem Lötkolben keine Verbrechen begangen hat, braucht man sich nicht einmal dafür schämen.
Hier das Produktfoto vom Hersteller. Zum Zeitpunkt der Erstellung dieser Webseite, konnte man diese Info abrufen unter: zur Produktseite
Schraubt man es auseinander, hat man zwei unterschiedliche Halbschalen. Und die Halbschale mit den Schrauben"bolzen" für die Leiterkarte und der Beschriftung ist die Rückwand. Nur so als Hinweis, bevor man sich beim Bohren vertut.
Das Datenblatt des Gehäuses habe ich hier. Falls jemand mal ein eigenes Projekt mit diesem Gehäuse starten möchte, habe ich hier noch eine Leiterkartendefinition, die genau in dieses Gehäuse passt (EAGLE-Format). Die Lage "Reference" markiert den Bereich, der im Gehäuse die etwas abgesenkte Anzeigenfläche darstellt.

Schmankerl

Nunja, die Uhr passt sich in der LED-Helligkeit an die Umgebungshelligkeit an. Somit ist sie prima als "Nachttisch-Uhr" geeignet. Mir hat aber nie gefallen, daß diese Uhren immer irgendwie so stehen, daß man sie nicht ablesen kann, ohne sich Nachts müde im Bett verrenken zu müssen. Die Lösung: Ein Schwanenhals. Eigentlich für Mikrofone gedacht, die man ja auch beliebig ausrichten können möchte, kann man dies nun auch mit dieser Uhr tun.
 
Der Schwanenhals und seine mechanische Befestigung im Gehäuse ist auch der Grund für die etwas merkwürdige Leiterkartenform. Normalerweise geht die Leiterkarte bis zum "Panel", da hier aber eine Schraube sitzt, musste sie etwas kürzer sein.
Übrigens war es zum Zeitpunkt der Aufnahme 15:45 Uhr und 38 Sekunden.

Schaltplan

Die Schaltpläne liegen im PostScript-Format vor:

Leiterkarte

Die Ähnlichkeiten zwischen CAD-System und realer Karte sind wie immer verblüffend...
 
Oberseite, CAD Oberseite, Leiterkarte
CAD Bild
Leiterkarte
Unterseite, CAD Unterseite, Leiterkarte
CAD Bild
Leiterkarte
Hier die zugehörige EAGLE-Layout-Datei

Stückliste

Diese Bauteile gilt es zu besorgen
Typ Wert Bauform Menge Name(n)
CPU Atmega8 TQFP32 1 IC300
CRYSTAL 32768Hz TC26 1 XT300
IC SFH610A DIL4 1 IC100
TRANSISTOR BC807 SOT23 3 Q100 Q101 Q102
LED BC807 3mm 39 D200 D201 D202 D203 D204 D205 D206 D207 D208 D209 D210 D211 D212 D213 D214 D215 D216 D217 D218 D219 D220 D221 D222 D223 D224 D225 D226 D227 D228 D229 D230 D231 D232 D233 D234 D235 D236 D237 D238
LDR A 9050 13 2.54mm 1 R301
HEADER 2x5pins 2x5 RM2.54mm 2 X300
CAPACITOR 10p 0805 1 C100
CAPACITOR 27p 0805 2 C303 C304
CAPACITOR 100n 0805 3 C300 C301 C302
RESISTOR 15R 0805 1 R104
RESISTOR 360R 0805 14 R200 R201 R202 R203 R204 R205 R206 R207 R208 R209 R210 R211 R212 R213
RESISTOR 10k 0805 1 R302
RESISTOR 100k 0805 5 R100 R101 R102 R103 R300
CASE 1553BTBUBK   1  
GOOSE NECK 2xM8x1AG   1  
Einige Bestellhinweise:
  • Gehäuse: 1553 BTBUBK
  • Schwanenhals: "Flex-Rohr 300mm"
  • Leiterkarte: BetaLayout (www.pcb-pool.com)

Bestückung

Die Bestückungsdrucke liegen im PostScript-Format vor:
Im Prinzip ist die Bestückung nichts besonderes. Vielleicht fällt dem einen oder anderen das Löten von SMD-Bauteilen schwer. Mit dem richtigen Lötkolben und ruhigen Fingern ist das aber nicht so dramatisch. Nur X300 fällt etwas aus dem Rahmen. Der wird seitlich und auf beiden Seiten der Leiterkarte verlötet.
Die LEDs bitte erst ganz am Schluß löten. Vorher unbedingt das Gehäuse bohren! Dafür habe ich im Layout der Karte extra pro LED ein zentrisches Loch vorgesehen. Man kann also die Leiterkarte einfach in den Deckel legen und mit einem 0,8mm Bohrer durch diese Löcher hindurch das Gehäuse bohren. Dann nur noch die vorgebohrten Löcher im Deckel auf die Größe der LEDs aufbohren und fertig. Die Leiterkarte selber ist also die Bohrschablone, die man braucht, um das Gehäuse ordentlich zu bearbeiten.
Etwas kniffelig bleibt das Einlöten der LEDs. Denn hier ist deren Höhe wichtig, weil die Leiterkarte in der Gehäuse-Rückwand verschraubt wird. Ich habe dazu die Leiterkarte in der Rückwand verschraubt, die vier äußeren LEDs eingesetzt, den Deckel aufgesetzt, die LEDs mit einer Pinzette "hochgeschoben" bis sie wie gewünscht durch den Deckel hindurch schauten, den Deckel wieder vorsichtig abgenommen und dann die vier LEDs verlötet. Danach kann man einfach alles wieder auseinander nehmen, die restlichen LEDs stecken, alles auf dem Kopf drehen (also auf die vier bereits verlöteten LEDs als "Beine" stellen), die zusätzlichen LEDs dazu bringen, dass sie wie die anderen vier brav auf der Unterlage aufliegen und dann ebenfalls verlöten.
Ganz perfekt wird es, wenn man die so mit LEDs vollgesteckte Karte umgedreht wieder in den Deckel einsetzt. Dabei werden die LEDs auch gleich sauber in die Löcher im Deckel ausgerichtet und dann so verlötet.
Nicht verzweifeln, wenn es nicht sofort sauber gelingt. Ich habe beim ersten Versuch alle LEDs falsch herum verlötet. Als ich es bemerkte, habe ich Dinge von mir gegeben, die im öffentlichen Fernsehen erst nach 22 Uhr gesendet werden dürfen. Geholfen hat es aber nichts. Nur die Heißluftpistole hat geholfen. Und dann alles nochmal von vorne.

Inbetriebnahme

Reine Elektronik war früher, heute ist immer auch etwas programmierbares dabei. Hier ein Atmega8 Microcontroller. Der braucht eine Toolchain, irgendwas, das aussieht wie ein Programm und ein Programmiergerät. In dieser Reihenfolge.
Das mit dem Programmiergerät überlasse ich jedem selber. Zu beachten ist, daß X300 passend zu meinem MiniDoper (siehe hier) ausgelegt ist. Dessen Belegung beim 10poligen ISP weicht etwas von der Standard-Belegung ab. Wer nur programmieren, aber nicht die Debug-Eigenschaften des Doper verwenden will, kann sich ein 6 auf 10 Kabel quetschen. D.h. die Kontakte 1...6 auf meinem 10poligen Stecker entsprechen dem regulären 6poligen Stecker und seiner weit verbreiteten Belegung.

Entwicklungsumgebung und Toolchain

Es müssen ein paar Voraussetzungen erfüllt werden, um die Firmware in den Zustand zu überführen, wie der Prozessor sie braucht. Wir brauchen also noch ein paar Werkzeuge und vor allem eine Cross-Toolchain.
Für Cross-Toolchain und Erstellung der Firmware verwende ich PTXdist. Dessen Installation ist hier beschrieben. PTXdist wird uns die Toolchain und dann damit die Firmware für die Uhr bauen.

Firmware

Nun kommt der wichtigste Teil: Die Firmware, bzw. Software für die Uhrenfunktion selber. Der fällt aber recht unspektakulär aus, wenn die restlichen Voraussetzungen wie PTXdist und Toolchain geklärt sind. Es beschränkt sich auf das Laden des Projektarchivs von hier.
Dann auspacken, es von PTXdist mit der Toolchain bauen lassen und in den Microcontroller programmieren. Das war die Kurzfassung. Etwas länger sieht es aus wie folgt:
~$ wget http://www.kreuzholzen.de/src/funclock/avr-aclk-1.0.0.tar.gz
~$ tar xf avr-aclk-1.0.0.tar.gz
~$ cd avr-aclk-1.0.0
~/avr-aclk-1.0.0$ ptxdist toolchain /opt/OSELAS.Toolchain-1.99.2/avr/gcc-4.3.2-libc-1.6.2-binutils-2.19/bin
~/avr-aclk-1.0.0$ ptxdist go
~/avr-aclk-1.0.0$ sysroot-host/bin/avrdude -c stk500v2 -P avrdoper -p atmega8 -U hfuse:w:0xc7:m -U lfuse:w:0x23:m
~/avr-aclk-1.0.0$ sysroot-host/bin/avrdude -c stk500v2 -P avrdoper -p atmega8 -U flash:w:images/avr-aclk.hex:i
In diesem Beispiel verwende ich meinen eigenen AVRDoper. Wer ein anderes Programmiergerät sein eigen nennt, muss die avrdude-Zeilen ggf. anpassen.
Sollten Probleme beim Bauen oder Benutzen auftreten, bitte eine Mail an: projects at kreuzholzen dot de

Aktualisierung 27.3.2010:
Es hat sich herausgestellt, dass die Uhr nur mäßig genau ist. Wenn kein DCF-Empfang möglich ist, geht sie sehr stark nach und wenn nur mäßiger DCF-Empfang vorliegt, geht sie teilweise dramatisch vor. Beide Effekte sind durch Käfer in der Software (vielleicht auch Hardware) verursacht:
  • Das dramatische Vorgehen lag daran, dass die interne Referenzsekunde und ein evtl. auftretendes DCF-Signal beides die Sekunden vorgestellt haben. D.h. jede Sekunde wurde in diesem Fall zweimal gezählt.
    Dieser Fehler ist nun dadurch behoben, dass die Uhr jetzt ausschließlich die Referenzsekunden zählt und die DCF-Zeit nur noch die wirkliche Uhrzeit beisteuert.
  • Sowohl die Referenzzeit, als auch die Interrupte für die PWM-Erzeugung wurden bisher aus Timer2 heraus gewonnen. Es hat sich aber inzwischen herausgestellt, dass massiv Overflow-Ereignisse verloren gehen, wenn man ständig das OutputCapture-Register dieses Timers neu beschreibt (Hardware-Fehler?). Das war bisher für die LED-PWM notwendig. Jetzt wird die PWM von Timer0 aus bedient und es geht kein Ereignis des Timer2 mehr verloren.
    Da ich in einem anderen Projekt ebenfalls Timer2 so benutze und dort ebenfalls das OutputCapture-Register ständig neu programmiere, kann das reine Neuprogrammieren nicht die alleinige Ursache dieses massiven Ereignisverlust sein. Evtl. hängt es damit zusammen, dass im anderen Projekt niemals das Overflow- und das Capture-Ereignis zusammenfallen können, was bei dieser Uhr hier durchaus der Fall sein kann. Die wirkliche Ursache gilt es noch zu klären. Also kann der Umstieg auf Timer0 nur als Abhilfe und nicht als wirkliche Lösung angesehen werden. Obwohl Timer0 nun brav seinen Dienst versieht.
Das aktualisierte Firmware-Archiv kann von hier geladen werden: firmware-2010-03-27.tgz