Menü


Mehr...

Software für den Taschenrechner TI-89 von Texas Instruments findet ihr hier.

News

Kommentare zu meiner Seite könnt ihr im Gästebuch, im Blog oder per E-Mail schreiben. Vielen Dank!

Service

Impressum
Kontakt
Links

Statistiken

Besuche:
1467181
Druckansicht Textbereich maximieren

Nebenuhrsteuerung mit der Conrad C-Control

Vielleicht besitzt der eine oder andere meiner Leser (vor allem unter den [Modell-]Bahn-Fans) eine alte Bahnhofsuhr mit einem sogenannten "Nebenuhrwerk". Diese hat selbst keinerlei Intelligenz, sondern läuft immer nur einen Schritt (1 Minute) weiter, wenn man ihr einen 12-24 Volt Impuls anlegt. Diese Impulse müssen sich auch von Mal zu Mal in ihrer Polarität unterscheiden.
Das rührt daher, dass diese Uhren früher (und auch heute noch) mitunter in wahnsinnig großen Installationen/Betrieben eingesetzt werden. Eine Hauptuhr (Mutteruhr) steuert über eine Nebenuhrlinie bis zu 100 Uhren an. Gibt es nun irgendwelche Störungen auf den Leitungen und wird ein Impuls (der meist ca. 1-2 Sekunden dauert) irgendwie "unterbrochen", so würden die Uhren ja gleich zwei Schritte weiterlaufen. Dadurch, dass sich zwei aufeinanderfolgende Impulse immer in ihrer Polarität unterscheiden müssen, kann das nicht passieren (ein doppelter / unterbrochener Impuls führt nicht zweimal zu einem Weiterschalten).

Nun, was macht man mit so einer Nebenuhr. Entweder

...oder einem gefallen die ersten Lösungen nicht (erstere, weil man da ja nix selber machen muss und die zweite, weil man da ja die schöne, alte Uhr umbauen muss und diese dabei an Authentizität (Minutensprung!) verliert - das wäre ja eine Schande.

So war das auch bei mir, ich wollte einfach selber was bauen.


Meine Nebenuhr, sie ist von "Pragotron"

Ich hatte dann irgendwann auch mal die Idee, eine solche Ansteuerung analog zu bauen, aber das ist mir nie gelungen. Ich hatte mal mit einer Schaltung experimentiert, in der sich ein Kondensator auflädt und über einen Transistor mit dem (invertierten) Signal eines DCF-77 Demodulators kurzgeschlossen wird. Dies passiert jede Sekunde einmal – außer in der 59. Sekunde, in der kein DCF-Signal vorhanden ist. Somit lud sich der Kondensator über eine bestimmte Schwelle auf und sollte dann ein Relais anziehen - in der Theorie. In der Praxis war der entstehende Impuls viel zu kurz und außerdem immer nur in eine Richtung, sodass die Uhr nur ein einziges Mal "gesprungen" wäre und dann nie wieder. Naja, das war vor meiner Studienzeit... Mittlerweile bin ich - als Student der Informations- und Elektrotechnik - natürlich soweit, dass ich sage "So etwas möchte ich gerne mit einem Controller bauen". Und zwar möglichst billig, d.h. mit dem Zeug was ich schon habe. (Auf www.nebenuhrsteuerung.de gibt es einen Bausatz mit vorprogrammierten AVR Controller, aber der kostet EUR 40,- und ich bin im Endeffekt ja nur Bauteile am Einlöten, da lerne ich ja nix bei.) Ich habe bei meinem Vater im Schrank noch etwas gefunden, das nach Motorola-Mikrocontroller aussieht. Mit Motorolas arbeiten wir an der FH (HC11 und 12). Das Teil ist schon über 10 Jahre alt und von Conrad Electronic. Es handelt sich um die sogenannte C-Control I, der ersten Generation der nach wie vor sehr populären Controller-Serie C-Control. Es steckt auf einer Art Evaluationboard mit 2 Relais und einer DCF77-Antenne... genau richtig für meine Zwecke!


Die C-Control im Gehäuse mit eingebautem DCF-77-Empfänger


Mess- und Programmieraufbau

Im Internet habe ich Infos zur C-Control I inklusive der downloadbaren CCBASIC-IDE gefunden. Das ist eigentlich eine ganz, ganz furchtbare Sprache, aber was solls, ist halt einmal da. Mein Programm lässt sich mit der Sprache auch einigermaßen realisieren (man muss halt ohne bedingte Schleifen, mehrzeilige IFs und "echte" Funktionsrückgabewerte verzichten... Es ist mehr so ne Art "Assembler mit Basicbefehlen").

Im folgenden stelle ich den Quellcode meiner Nebenuhrsteuerung kostenlos zur Verfügung. Er läuft natürlich nur auf der C-Control I (CCBASIC). Die Funktionsweise des Programms ist ausführlich im Code dokumentiert. Ein Schaltbeispiel folgt, sobald ich einen ordentlichen Schaltplan gezeichnet habe. Nur soviel vorab, man kommt leider nicht mit den auf dem "Starterboard" vorhandenen 1xUM-Relais aus, man braucht 2 Stück 2xUM-Relais (sonst gibt's schöne Kurzschlüsse)... Ich habe in meiner Schaltung zwei 5V-Relais auf das Lötfeld des Starterboards gelötet, mit je einer kleinen Transistorschaltung zur Ansteuerung. Diese Schaltung ist unbedingt nötig, denn eine direkte Beschaltung der Ausgangsports des Controllers mit der Relaisspule könnte den Ausgang zerstören, und falls nicht, wird das Relais aufgrund des zu niedrigen Stromes wahrscheinlich nicht richtig schalten.

Vom endgültigen Schaltungsaufbau mit den Relais und den Transistorschaltungen habe ich bisher noch keine Fotos gemacht, werde das aber nachholen. Und ja, es wird auch einen Schaltplan geben, den muss ich nur noch zeichnen...

Die Bedienung erläutere ich am Ende der Seite, jetzt erstmal der grundlegende Code (Version 1.0, nicht mehr empfohlen, die neueren Versionen gibt es am Ende der Seite zum Download):

Quellcode zur Nebenuhrsteuerung

'****************************************************************************** ' CCCC : C-Control Clockwork Commander 1.0 : (c) 2007 Fabian Schneider ' DCF77-gesteuerte Ansteuerung einer "Nebenuhr" (Bahnhofsuhr) mit polwendenden ' Minutenimpulsen inklusive Speicherung des letzten Zeigerstandes im EEPROM ' für die automatische Nachführung fehlender Impulse nach einer Spannungs- ' unterbrechung. ' Beim ersten Start oder wenn das EEPROM unsinnige Werte enthält, nimmt das ' Programm den Zeigerstand "Zwölf Uhr" an und stellt, ausgehend von diesem ' Zeigerstand, die Uhr auf die aktuelle DCF77-Zeit. ' Über einen am Port 16 angeschlossenen Taster kann die Uhr minutenweise ' vorgestellt werden, um Differenzen der Zeigerstellung zum gespeicherten ' Zeigerstand zu korrigieren (bei Verwendung des Tasters wird der Wert im ' EEPROM *nicht* verändert). ' Die Relais müssen so angeschlossen werden, dass das Relais an port[7] ' eine positive Spannung von 12-24V (je nach Uhrwerk) schaltet, und das ' Relais an port[8] die entsprechende negative Spannung. Die Länge des ' Minutenimpulses beträgt 1 Sekunde im Normalbetrieb und 0,5 Sekunden im ' Stellbetrieb. Bei Verwendung des Stelltasters wird der Impuls solange ' ausgegeben, bis der Taster losgelassen wird. ' Mehr Informationen unter: www.f-schneider.de.vu '****************************************************************************** ' === Variablendefinitionen =================================================== define currpos word[1] ' Aktuelle Zeigerposition (0 = 12:00 bis 719 = 11:59) define savedpos word[2] ' Zeigerposition im EEPROM (s.o.) define dcfpos word[3] ' Zeigerposition von DCF77 (Sollzeit) define polarity bit[65] ' Polarität des LETZTEN gesendeten Impulses ' (ON = positiv, OFF = negativ) define imp_done bit[66] ' Impuls in der 00. Sekunde abgearbeitet? define set_done bit[67] ' Zeitkorrektur in der 23. Minute abgearbeitet? ' --- Portdefinitionen -------------------------------------------------------- define imp_pos port[7] ' Digitalport für den positiven Minutenimpuls define imp_neg port[8] ' Digitalport für den negativen Minutenimpuls define sw1 port[16] ' Taster zum Vorstellen der Uhr. ' === Hauptprogramm =========================================================== ' Polarität des letzten Impulses sowie der letzten Zeigerstellung vor ' Wiederanlegen der Spannung aus dem EEPROM lesen. imp_pos = OFF imp_neg = OFF open# for read input# polarity input# savedpos if (savedpos > 719) or (savedpos < 0) then savedpos = 0 ' Reset-Routine: Nach Anschließen der Spannung piepst der Beeper für ~2 Sek. ' Wird während dieser Zeit die Spannung wieder entfernt, sind alle Werte ' auf Null und die Uhr geht beim nächsten Start von der Zeigerposition 0 aus. beep 25,0,0 open# for write print# 0 print# 0 pause 85 beep 0,0,0 open# for write print# polarity print# savedpos ' Ende der Reset-Routine ------------------------------------------------------ pause 16383 ' Auf den DCF77-Empfänger warten (~6 Minuten) ' ----------------------------------------------------------------------------- ' Wir nehmen an dass die Zeiger da stehen, wo sie vor Unterbrechung der ' Spannung standen. Auf dieser Annahme basiert die ganze Logik. Wenn das ' Uhrwerk zwischendurch anderweitig verstellt wurde, wird sich die Uhr ' letztendlich auf eine falsche Zeit einstellen und annehmen diese sei ' richtig. Wenn sie diesen Zustand eingenommen hat, kann mit dem Taster ' die Position der Zeiger wiederum an den Stand im EEPROM angeglichen werden! ' Also hier die Annahme: currpos = savedpos #setclock ' Loop zum Stellen der Uhr. ' Zeigerposition aus DCF77-Zeit errechnen gosub getpos ' Wenn Zeigerpositionen stimmen, direkt in den Hauptloop springen. ' Dies ist der Fall wenn setclock mindestens einmal durchlaufen wurde oder ' aber die Zeigerposition zufällig schon stimmt (sehr unwahrscheinlich). ' Falls die Zeigerposition maximal 200 Minuten "vorgeht", wird die Uhr ' nicht gestellt, sondern die entsprechende Anzahl an Minuten gewartet. ' Das spart Strom und Schreibzyklen und schont die Mechanik. if (currpos > dcfpos) and ((currpos - dcfpos) <= 200) then gosub drink_tea if (currpos < 60) and (dcfpos > 620) then gosub drink_tea if (currpos > dcfpos) and ((currpos - dcfpos) > 200) then dcfpos = dcfpos + 720 if currpos = dcfpos then set_done = ON if currpos = dcfpos then goto clockwork for currpos = savedpos + 1 to dcfpos gosub short_imp pause 10 next currpos = currpos mod 720 dcfpos = dcfpos mod 720 open# for write print# polarity print# currpos savedpos = currpos goto setclock ' Programmschleife (CLOCKWORK) ------------------------------------------------ ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #clockwork ' Wenn Minute voll, dann Impuls ausgeben if (second = 0) and (not imp_done) then gosub impuls if second = 2 then imp_done = OFF ' Zu jeder 23. Minute schauen wir nach, ob unsere Zeit noch stimmt. if (minute = 23) and (not set_done) then goto setclock if minute = 25 then set_done = OFF ' Wenn Stelltaster gedrueckt, dann Impuls ausgeben if not sw1 then gosub man_imp ' Schleife wiederholen goto clockwork ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' === Unterprogramme ========================================================== ' --- impuls ------------------------------------------------------------------ ' Stellt die Uhr eine Minute weiter und sichert Zeigerposition im EEPROM ' ----------------------------------------------------------------------------- #impuls imp_neg = OFF ' Erst einmal beide Relais ausschalten, da sich die imp_pos = OFF ' Ports vorher im hochohmigen Zustand befunden haben. if polarity = ON then imp_neg = ON if polarity = OFF then imp_pos = ON pause 50 ' Länge des Impulses: 1 Sekunde imp_neg = OFF imp_pos = OFF ' Polarität für den nächsten Impuls invertieren. polarity = not polarity ' Zeigerposition um 1 erhöhen. Falls 12:00-Stellung (720) erreicht ist, ' wieder auf Null zurücksetzen. currpos = currpos + 1 if currpos = 720 then currpos = 0 ' Polarität und Zeigerposition im EEPROM speichern. open# for write print# polarity print# currpos savedpos = currpos ' Damit wir wissen: Der Wert im EEPROM ist aktuell. imp_done = ON return 'impuls ' --- man_imp ----------------------------------------------------------------- ' Stellt die Uhr eine Minute weiter und sichert NICHT die Zeigerposition! ' Die Polarität wird jedoch gespeichert. ' ----------------------------------------------------------------------------- #man_imp imp_neg = OFF ' Erst einmal beide Relais ausschalten, da sich die imp_pos = OFF ' Ports vorher im hochohmigen Zustand befunden haben. if polarity = ON then imp_neg = ON if polarity = OFF then imp_pos = ON ' Wir halten den Impuls solange, bis die Taste wieder losgelassen wird! ' Somit ermöglichen wir dem Benutzer, die Uhr so schnell zu stellen wie ' die Trägheit der Mechanik dies ermöglicht: wait sw1 ' = off imp_neg = OFF imp_pos = OFF ' Polarität für den nächsten Impuls invertieren. polarity = not polarity ' Polarität im EEPROM speichern. open# for write print# polarity savedpos = currpos ' Damit wir wissen: Der Wert im EEPROM ist aktuell. return 'man_imp ' --- short_imp --------------------------------------------------------------- ' Gibt einen kürzeren Minutenimpuls aus (0,5 Sekunden) für den Stellbetrieb. ' Es wird nicht die Zeigerposition gespeichert. ' ----------------------------------------------------------------------------- #short_imp imp_neg = OFF ' Erst einmal beide Relais ausschalten, da sich die imp_pos = OFF ' Ports vorher im hochohmigen Zustand befunden haben. if polarity = ON then imp_neg = ON if polarity = OFF then imp_pos = ON pause 25 ' Länge des Impulses: 0,5 Sekunden imp_neg = OFF imp_pos = OFF ' Polarität für den nächsten Impuls invertieren. polarity = not polarity return 'short_imp ' --- getpos ------------------------------------------------------------------ ' Berechnet aus dem aktuellen Wert der Echtzeituhr (DCF77-Empfänger) die ' Sollposition für das Uhrwerk. Diese wird in dcfpos gespeichert. ' ----------------------------------------------------------------------------- #getpos dcfpos = (hour mod 12) * 60 + minute return 'getpos ' --- drink_tea --------------------------------------------------------------- ' "Abwarten und Tee trinken": Wir warten einfach ab, bis die Zeigerposition ' wieder stimmt. Anstatt die Uhr z.B. bei der Winterzeitumstellung 11 Stunden ' vorzustellen, warten wir doch lieber 1 Stunde ab. ' ----------------------------------------------------------------------------- #drink_tea #loop gosub getpos ' Wenn Stelltaster gedrueckt, dann Impuls ausgeben if not sw1 then gosub man_imp if dcfpos <> currpos then goto loop imp_done = ON return 'drink_tea

Erläuterungen zum Quellcode

Der oben aufgeführte Quellcode gehört zur allerersten Version des Projekts und soll hauptsächlich dessen grundsätzliche Funktion demonstrieren. Er ist aber voll läuffähig und kann im Grunde direkt hier kopiert und in die CCBASIC-IDE eingefügt werden.

Ich empfehle aber, eine der neueren Versionen (s.u.) herunterzuladen. Es steht auch eine neuere Version zur Verfügung (1.3), in der ich zusätzlich noch ein "Schlagwerk" eingeführt habe. Dieses erzeugt über einen am BEEP-Port (Pins 1 und 11 an der oberen Steckerleiste des Starterboards) angeschlossenen Piezo-Piepser zu jeder vollen, halben, Viertel- und Dreiviertelstunde einen Big Ben-ähnlichen Gong, der natürlich jeweils eine unterschiedliche Melodiekombination und -länge aufweist. Zu jeder vollen Stunde "schlägt" die Uhr danach eine der aktuellen Stunde entsprechende Anzahl an Schlägen. Über Jumper zwischen Port 9 bzw. Port 10 kann das Schlagwerk konfiguriert werden (Nachtabschaltung, immer aus, immer an). Nähreres dazu steht am Beginn des Quellcodes.

Diese Version des Programms belegt natürlich mehr Platz im seriellen EEPROM der C-Control (ca. 1490 Bytes) als die Versionen ohne Gong. Wer also das Schlagwerk nicht braucht und auf dem CCCC-Programm aufbauend noch weitere, eigene Ideen realisieren will, die viel Platz benötigen, ist wahrscheinlich mit Version 1.5 am besten bedient, in der das Schlagwerk wieder entfernt wurde. Die älteren Versionen 1.0 bis 1.3 empfehle ich nicht für den täglichen Einsatz, da diese den Zeigerstand nach jeder Minute abspeichern, was mir im Nachhinein als nicht sonderlich EEPROM-schonend erschien.

CCCC Version 1.1 (11 KB, 678 Bytes compiliert): CCCC-11.bas
» Wie 1.0, aber manuelles Stellen jetzt auch während Wartephase möglich, Stromsparfunktionen eingebaut

CCCC Version 1.3d (15 KB, 1496 Bytes compiliert): CCCC-13d.bas
» Wie Version 1.1, jedoch zusätzliche Gong-Ausgabe (abschaltbar). Code-Größe optimiert. Verbesserter DCF-Empfang, Impulslänge per Konstante definierbar. Update 1.3d: Bug beim Umstellen der Uhr von Sommer- auf Winterzeit beseitigt, der in einigen Fällen auftrat.
» Empfohlen, wenn Gong-Ausgabe erwünscht!




CCCC Version 1.5d (12 KB, 800 Bytes compiliert): CCCC-15d.bas
» Neuer Code-Branch wieder ohne Gong-Ausgabe zwecks besserer Übersichtlichkeit und Erweiterbarkeit (Speicherplatz!) Außerdem wurde die Logik für das Speichern des Zeigerstandes geändert: Dieser wird jetzt nur noch bei Druck auf den Debug-Taster bzw. Jumper an Port 11 im EEPROM gespeichert, da das EEPROM laut Datenblatt nur 100000 Schreibzyklen hat. Update 1.5d: Bug beim Umstellen der Uhr von Sommer- auf Winterzeit beseitigt, der in einigen Fällen auftrat.
» Empfohlen, wenn keine Gong-Ausgabe erwünscht!

Bedienung

Vor der ersten Inbetriebnahme muss die Uhr manuell auf Zeigerstellung 12 Uhr gebracht werden. Dann muss einfach die Spannung eingeschaltet und sofort der Reset-Taster der C-Control gedrückt werden (noch während der eventuell angeschlossene Beeper piepst). Das stellt sicher, dass die Uhr intern bei 0 startet.
Jetzt einfach warten, bis sich die Uhr auf das DCF-Signal synchronisiert und nach ca. 10 Minuten beginnt, sich auf die aktuelle Uhrzeit einzustellen. Es sind normalerweise keine weiteren Bedienungsschritte nötig. Die Umstellung auf Sommer-/Winterzeit erfolgt automatisch. Es gibt aber die Möglichkeit, bei einem eventuellen Nachgehen der Uhr manuell einzelne Impulse auszugeben. Dazu den an port[16] angeschlossenen Taster betätigen.

Bei Versionen 1.1 und 1.3: Nach einem Stromausfall die Uhr nicht manuell weiterstellen! Nach ca. 10 Minuten der DCF-Synchronisation stellt das Programm automatisch die Uhr nach.

Bei Versionen ab 1.4: Nach Stromausfall geht die Uhr davon aus, dass sie bei 12:00 steht, wenn nicht vorher per Druck auf den Stelltaster (port[16]) die Position gesichert wurde (z.B. bei kontrolliertem Trennen der Spannung). Will man verhindern, dass in einem solchen Falle die Uhr beginnt, von der (unbekannten) Position "alias 12:00" aus loszustellen, muss nach der DCF-Synchronisierung, während ein Ton (3 Sekunden) ertönt, der Taster an port[11] gedrückt werden. Es wird dann einfach nicht nachgestellt und die Uhr läuft von der aktuellen Position aus normal los. Zur Bestätigung ertönt kurz ein tiefer Ton.

Wenn es was Neues gibt, werde ich diese Seite aktualisieren!

Letztes Update: 17.04.2010

Viel Spaß!