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 |
|
|
Unterseite, CAD |
Unterseite, 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
|