Hallo alle zusammen, ich möchte in diesem Beitrag meine Version einer Binäruhr vorstellen. Ja ja, ich höre schon einige Stimmen die sagen "schon wieder so'n Ding". Aber trotzdem möchte ich gerne Feedback zu diesem Projekt haben. Die Hardware ist ziemlich einfach gehalten, ich benutze einen Atmel ATmega8, 18 rote low-current LEDs und einen einzelnen Taster zur Eingabe. Die LEDs werden per Multiplex angesteuert, dazu wird die aktuelle Wert von Sekunden/Minute/Stunde an einen Port gelegt und die jeweilige "Zeile" (also s/m/h) auf Masse gelegt. Die Uhr verwendet pro Zeile 6 LEDs, die 6. LED in der Stundenzeile wird zur Statusanzeige benutzt. Da ich die Uhr mit einem Satz Akkus betreibe habe ich zusätzlich eine Überwachung der Spannungsversorgung eingebaut. Diese soll eine schwache Versorgungsspannung anzeigen, bevor die Brown-Out Erkennung zuschlägt. Für die Spannungsüberwachung verwende ich den eingebauten Komparator mit der eingebauten Referenzspannung. Die Versorgungsspannung wird über einen Spannungsteiler an den Eingangsport gelegt, bei etwa 7,3V fängt die Status-LED an zu blinken. Die Überwachung der Spannung wird zu Beginn einer Minute durchgeführt. Um Strom zu sparen wird der Controller in der Idlezeit in einen Powerdown-Modus geschaltet, dieser wird durch den Timerinterrupt dann wieder verlassen. Im aktuellen Design wird die Versorgungsspannung die ganze Zeit über an den Spannungsteiler gelegt. Ich arbeite aber an einer Lösung um die Spannung nur anzulegen wenn sie auch gemessen werden soll. Um der Uhr ein einfaches und klares Design zu geben habe ich nur einen Taster vorgesehen. Es werden jeweils kurze und lange Tastendrücke erkannt, damit manövriert man durch das Einstellungsmenü: - Dimmer an/aus - Einstellen der Minuten - Einstellen der Stunden - Einstellen der Alarmminuten - Einstellen der Alarmstunden Wenn durch einen langen Tastendruck zum nächsten Menüpunkt geschaltet wird blinkt die Status-LED kurz auf. Neben der frei wählbaren Alarmzeit ist auch eine (beinahe) beliebige Anzahl an Alarmzeiten im Flash vorgesehen. Ein Alarm wird durch Blinken der Uhr angezeigt. Und nun komme ich zu dem Teil, zu dem ich die meisten Kommentare erwarte: ich benutze den internen Oszillator mit 1MHz Taktrate. Damit eine Sekunde auch eine Sekunde ist benutze ich einen Softwareteiler zusätzlich zum Teiler des Hardware- timers. Meine Begründung für diese Entscheidung ist relativ einfach: ich möchte mit dieser Uhr weder Industrie- noch Automotive- noch Militäranforderungen erfüllen. Das soll heißen, dass ich die Uhr nur in geschlossenen Räumen bei Temperaturen zwischen 18°C und 30°C betreiben will. Nach mehreren Versuchen kann ich sagen, dass die Abweichung der Uhr erst dann zu groß wird wenn auch der Akku leer ist. Die Abstimmung wird am einfachsten mit einem Oszilloskop durchgeführt, dazu wird in der Software ein Debugpin aktiviert, der mit jeder Sekunge toggelt. Über den Softwareprescaler wird das Feintuning vorgenommen. Um zeitabhängig Funktionen auszuführen sie die Software sogenannte Hookfunktionen vor, damit kann jeweils vor und nach der Berechnung von s/m/h eine Funktion ausgeführt werden. Die Software wird auf zwei Dateien aufgeteilt, zum einen die eigentliche Impementierung der Uhr (binclock.c), zum anderen die Parameter zur individuellen Steuerung (settings.h). Im Header werden die folgenden Einstellungen durchgeführt: - die festen Alarmzeiten - Dauer des Blinkens zur Alarmanzeige - Initialzustand des Dimmers - Entprellzeit zur Tastendruckerkennung - Softwareteiler für die Feinabstimmung der Uhr - Aus-/Einschalten des Debugpins zur Messung der Sekundenzeit Zu guter Letzt noch eine Zusammenfassung der Features: - Binäruhr auf Basis eines Atmel ATmega8 - Nutzung des internen Oszillators mit 1MHs - Betrieb mit 9V Akku - 18 rote low-current LEDs, Multipleansteuerun - ein Taster zur Steuerung - Eingabe einer variablen Alarmzeit - beliebig viele feste Alarmzeiten - Alarmanzeige durch Blinken - Überwachung der Versorgungsspannung - Hookfunktionen zur zeitabhängigen Funktionssteuerung - Powerdown des Prozessors während der Idlezeit Was noch geplant ist: - Ablage der festen Alarmzeiten im EEPROM - Ablage der Blinkdauer für den Alarm im EEPROM - Ablage des Dimmerzustands im EEPROM - Ablage der Tastenentprellungszeit im EEPROM - Ablage des Softwareteilers im EEPROM - Ablage des Debugzustandes im EEPROM - Aktivierung der UART zur Steuerung der Uhr - An-/Ausschalten des Spannungsteilers zur Spannungsmessung Im Anhang zu diesem Beitrag finden sich die Sourcen, der Schaltplan und ein Foto, so bekommt ihr einen ersten Eindruck. Ich hoffe auf zahlreiches Feedback von euch und nehme gerne Ideen in die TODO-Liste auf. Viele Grüße, Daniel
hallo, bei isr-routinen sollte man darauf achten veränderliche variable als volatile type name; zu deklariren. Läuft den Programm ohne sauber? Ich mache diese Define so:
1 | #define TURE (1==1)
|
2 | #define FALSE !TRUE
|
siehst Du den Vorteil? Man kann dem Kompiler helfen und einge Funktionen zusätzlich noch als static anstatt inline deklarieren, dann kann er besser optimieren.
Wieder ein Beispiel für "Warum sollte mans einfach machen, wenn es auch komplizierter geht"...
Uwe S. schrieb: > Ich mache diese Define so:#define TURE (1==1) > #define FALSE !TRUE TURE sollte bestimmt ein TRUE werden.
Daniel Bremenkamp schrieb: > Und nun komme ich zu dem Teil, zu dem ich die meisten Kommentare > erwarte: ich > benutze den internen Oszillator mit 1MHz Taktrate. Die Frequenz ist egal, hauptsache Du benutzt einen Quarz und das tust Du ja laut Schaltplan (1MHz). Dann kannst Du die Uhr sehr genau einstellen. Ich lasse die Uhr <4Wochen laufen und ermittele aus der Abweichung die genaue Quarzfrequenz. Dann trage ich die in die Source ein und compiliere neu. Danach läuft sie stabil (<1min/Jahr). Der interne RC-Oszillator taugt dagegen bestenfalls als Eieruhr. Daniel Bremenkamp schrieb: > dass die Abweichung der Uhr erst dann zu groß wird wenn > auch > der Akku leer ist. Das ist ja merkwürdig. Ein Quarz schwingt entweder fast spannungsunabhängig oder garnicht. Daniel Bremenkamp schrieb: > Um Strom zu sparen wird der Controller in der Idlezeit in einen > Powerdown-Modus > geschaltet Nützt bloß nichts, wenn schon der Spannungsregler (5mA) deutlich mehr verbraucht, als der MC (1mA). Nimm lieber 3 Mignon (4,5V) und verzichte ganz auf den Spannungsregler. Und mit nem Uhrenquarz (32kHz) kannst Du wirklich Strom sparen (~1µA). Peter
> Ich arbeite aber an einer Lösung um die Spannung nur > anzulegen wenn sie auch gemessen werden soll Brauchst du nicht. Du darfst den Spannungsteiler VIEL hochohmiger machen (2M2 statt 2k2) wenn du von TP2 nach Masse einen mindestens 10nF Kondensator legst, Folienkondensator. > bei etwa 7,3V fängt die Status-LED an zu blinken Der Mindesteingangsspannung des 78L05. Nimm lieber einen LP2950-5 als Spannungsregler. erstens regelt der auch noch, wenn der 9V Batterieblock leer ist (6V), zum anderen braucht der Regler VIEL weniger Strom als die 5mA Eigenbedarf des 78L05, sondern nur noch Mikroampere. Kondensatoren ans Datenblatt anpassen. > ich benutze den internen Oszillator mit 1MHz Taktrate. Du erwartest Kommentare, du bekommst Kommentare: Der ATmega hat gar nicht so viel zu rechnen, daß er so schnell sein müsste. Du kannst ihn problemlos auch mit 32.768khZ laufen lassen, Diese Quartze sind genauer und der ATmega braucht bei so nedriger Frequenz DEUTLICH weniger Strom. Bleiben nur noch die bei dir von im Schnitt mit 1mA durchflossenen LEDs. Dazu nimmst du ein LCD Glas z.B. aus einem Tamagotchi-Spielzeug, und schliesst das direkt an den uC an. Sozusagen nächste Lernstufe, LED durch LCD ersetzen, du ahst genügend Anschlüsse verfügbar. Dann braucht die Schaltung fast gar keinen Strom mehr und läuft jahrelang an der Batterie (bzw. kann aus einer CR2320 Lithiumzelle versorgt werden).
Hallo, erstmal Danke für eure Kommentare. Dann fange ich mal an zu Antworten: @Uwe S. Ja, TRUE als das Ergebnis einer boolschen Operation zu belegen verstehe ich. Ich habe mich für FALSE = 0 entschieden in der Annahme, dass der Compiler für die Bedingungen dann nur die entsprechende Variable laden muss und dann das Zero Flag prüft. Außerdem nahm ich an, dass der Compiler den Wert FALSE auch als = 0 setzt. Aber ich gebe dir natürlich vollkommen Recht, die eindeutige Definition sollte so sein wie du es beschrieben hast. Die volatile Deklaration der in der isr benutzten Variablen sehe ich auch ein, mein Programm läuft bei mir aber trotzdem sauber. Könnte es nicht auch helfen die Variablen mit dem Schlüsselwort register zu deklarieren? Aber nicht jeder Compiler folgt dieser Anweisung... Was ich nicht ganz verstehe ist der Vorteil die Funktionen als static anstelle inline zu deklarieren. Bei inline wird der Code doch vom Compiler an die entsprechende Stelle kopiert, oder? @Jonas Quinn Ich bin durchaus offen für Kritik, aber pauschal zu schreiben "sowas kompliziertes braucht man nicht" finde ich nicht ganz ok. Wenn ich es einfach haben will schaue ich auf meine Armbanduhr. Aber verstehe mich bitte nicht falsch: ich möchte dich hier nicht angreifen und ich möchte auch keine Diskussion über die Antworten die ich mir wünsche starten. @Peter Dannegger Im Schaltplan habe ich den Quarz als optional markiert (siehe Kommentarfeld). Und ich gebe dir auch vollkommen Recht, im Moment benutze ich die Uhr auch eher als Gimmick denn als "echte" Uhr. Ums wirklich genau zu haben würde ich natürlich auch einen Oszillator und evtl. einen Trimkondensator verwenden, damit die Frequenz wirklich korrekt ist. Das der Oszillator nicht spannungsabhängig ist weiß ich. Ich meinte mit meinem Kommentar, dass die Ungenauigkeit der Uhr erst wirklich merkbar wird wenn der Akku alle ist, und dann muss ich sie sowieso neu stellen. :-) Ich habe auch schon überlegt einen anderen Controller und drei Mignonzellen zu nehmen um mir den Spannungsregler zu sparen. Ich benutze den 1MHz Quarz, damit die Anzeige nicht flackert. Aber da lässt sich mit den richtigen Parametern sicher was machen. @MaWin Ich habe die Werte für den Spannungsteiler so gewählt um mir keine Antenne zu bauen (so sagte mir ein Kollege). Aber die Lösung mit dem Kondensator ist natürlich so einfach wie wirksam. Danke für die Info! Für die LEDs habe ich mich bewusst entschieden, weil ich die LEDs schon als Designelement verstehe. Wie würdest du denn die Zeit auf so einem LCD anzeigen (ich meine hier nicht die Ansteuerung sondern das Design der Anzeige)? Und zum Schluss an alle: danke für eure Beiträge, hätte nicht gedacht dass in so kurzer Zeit schon so viele Beiträge kommen. Ich habe hier ja keine Frage im Sinne von "ich brauche schnelle Hilfe" gestellt. Super! Schönen Abend beisammen, Daniel
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.