Schönen guten Abend zusammen! Ich möchte in meinem Projekt gern eine Analoguhr darstellen. Für mein Projekt verwende ich die letzte Version von Holger Klabunde für KS0108 (Pollin Display).In meinem Programm habe ich die Variablen h 0-24(Stunden) und m 0-60(Minuten) gespeist von einer DCF77 Routine. Nun sitze ich schon 4 Abende vor meinem Rechner und grübel über eine Lösung nach. Hat sowas schon mal jemand von Euch versucht? Ich komme einfach auf keinen Lösungsweg. P.S. Einen Kreis kann ich schon darstellen... ;-) Gruß Holger
Man sollte Threads auch zuende lesen... Aber mit Hilfe des Bresenham-Algorithmus solltest du zu einem Ergebnis kommen. Aber wie, weiß ich jetzt auch nicht.
Ich wuerde das Zifferblatt als Bitmap am PC erstellen und diese Daten auf dem Display ausgeben. Denn Zeiger kannst du dann mit dem Bresenham algorythmus darstellen. Wenn du die Bitmap am PC erstellst hast du viel mehr moeglichkeiten ein schoenes Zifferblatt hinzubekommen als wenn du es mit dem Bresenham Kreisalgo. im Controller zurecht zimmern wuerdest. Gruss Helmi
STK500-Besitzer wrote:
> kommen. Aber wie, weiß ich jetzt auch nicht.
Das weitere ist im Grunde relativ einfach:
Die Zeit (egal ob Minuten oder Stunden) ist ja im Grunde
nichts anderes als ein Winkel am Display. Man zeichnet
dann eine Linie (mit dem Bresenham) vom Mittelpunkt des
Kreises zum endsprechenden Endpunkt am Kreis.
Woher wissen wir die Koordinaten des Endpunktes?
Wie gesagt: Die Zeit ist nichts anderes als ein Winkel.
-> Hier kommt Trigonometrie zum Einsatz.
x_end = x_mitte + radius * cos( Winkel );
y_end = y_mitte + radius * sin( Winkel );
und dann wird eine Linie von x_mitte/y_mitte nach x_end/y_end
gezeichnet.
Bleibt nur noch die Bestimmung des Winkels:
Na, wenn 60 Minuten (am Beispiel des Minutenzeigers) einem Vollkreis,
also 360 Grad, bzw. 2*PI entsprechen, welchen Winkel legt der Zeiger
dann in 1 Minute zurück?
60 .... 2*PI
1 .... x
2 * PI
x = ----------
60
(oder gerechnet in Grad, da man dann schönere Zahlen hat: x = 360 / 60 =
6)
d.h. wenn der Minutenzeiger auf 1 Minute steht, dann hat er einen Winkel
von 6 Grad. Steht er auf 2 Minuten, hat er 12 Grad, bei 3 Minuten auf
18 Grad, etc.
Was es jetzt noch zu berücksichtigen gilt:
Die Kreisfunktionen arbeiten entgegen dem Uhrzeiger. Der Minutenzeiger
dreht sich aber im Uhrzeiger. Da wird also wohl irgendwo eine
Vorzeichenumkehr notwendig sein.
Bei der üblichen Sichtweise der Kreisfunktionen liegt 0 Grad auf
der X-Achse waagrecht. Bei einer Uhr ist aber der 0 Punkt oben
(also dort wo bei den Kreisfunktionen 90 Grad liegt). Da wird
also auch noch eine Anpassung notwendig.
Die trigonometirschen Funktionen sin und cos wollen ihren Winkel
in Radianten und nicht in Grad.
Alles in allem ist das nicht weiter kompliziert. Sobald du eine
Linie von einem beliebigen Pixel zu einem beliebigen Pixel
ziehen kannst (dafür brauchst du den Bresenham) ist eine Uhr
weiter kein grosses Problem mehr sobald du die Stunden und
Minuten sauber vorliegen hast.
Wie immer!!!! Sekunden nach einer Anfrage - kompetente Antwort. Danke! Ich glaube mit Bresenham brauch ich mich nicht weiter zu beschäftigen, die Lib kann alle möglichen Linien (auch von x1y1 nach x2y2) zeichnen. Werde ich gleich mal ausprobieren. x1y1 ist ja dann immer der Mittelpunkt. x2y2 zu berechnen sollte mir jetzt auch nicht mehr schwer fallen... jetzt bleibt nur noch ein Punkt: ich habe die Minuten und zugehörig x2y2. Wie lege ich das jetzt elegant ab? Ich würde es mal mit einer switch(m) versuchen. Ist aber bestimmt kein guter Programmierstil.... Gruß Holger
Holger Gerwenat wrote: > fallen... jetzt bleibt nur noch ein Punkt: ich habe die Minuten und > zugehörig x2y2. Wie lege ich das jetzt elegant ab? Ich würde es mal mit > einer switch(m) versuchen. Wenn schon, dann würde man das mit einer Tabelle machen, aber ... > Ist aber bestimmt kein guter > Programmierstil.... ... wenn die Uhr das einzige ist, was in dem µC abläuft, dann hast du von einem Hinzeichnen zum nächsten Hinzeichnen genau 1 Sekunde Zeit. Weist du wieviele sin() / cos() dein µC in dieser Zeit berechnen kann? Zwar nicht Millionen wie ein PC aber ein paar Hundert kriegt er auch hin. -> Wenn also ausser der Uhr nichts anderes laufen soll, dann lohnt sich der ganze Aufwand nicht. Berechne die Position einfach neu, wenn du sie brauchst.
Es geht auch einfacher. Jede Minute den Endpunkt mit einer Rotationsmatrix multiplizieren um den neuen Endpunkt zu bekommen. Wegen Rundungsfehlern muß man allerdings jede Stunde den Zeiger neu Initialisieren. Ich habe eine Exceldatei zur Demonstration angehängt. Die Zahlen 1018 und 107 sind Konstanten und müßen im Controller nicht Berechnet werden. So sind jede Minute nur 4 Multiplikationen und ein paar Additionen notig. Mfg Michael
Ich hab das mal Testweise mit einer Lookuptable (aus einem Excel Dokument) gemacht. Für ein T6963c Das Excel Sheet, was beiliegt erzeugt zwei Tabellen (Für den kurzen und für den Langen Zeiger jeweils eine). Du kannst im Excelsheet einfach die Zellen markieren, kopieren und im Code-Editor deiner Wahl richtig eingerückt einfügen.
Vielen Dank für Eure Antworten! und daß Ihr mir immer so geduldig helft Ich werde am Wochenende mal beide Varianten (direkte Berechnung und Tabelle) probieren. Mal sehen, wie weit meine beschränkten Progammierkenntnisse reichen. Ich werde berichten... Bis dahin Gruß Holger
Sehe ich es richtig, dass man bei (spartanischen) Zeigern eigentlich nur pro Zeiger eine Tabelle mit 60 (Koordinaten-)Werten haben müsste? Das sollte ja amchbar sein...
STK500-Besitzer wrote: > Sehe ich es richtig, dass man bei (spartanischen) Zeigern eigentlich nur > pro Zeiger eine Tabelle mit 60 (Koordinaten-)Werten haben müsste? > Das sollte ja amchbar sein... Das siehst du richtig.
STK500-Besitzer wrote: > Sehe ich es richtig, dass man bei (spartanischen) Zeigern eigentlich nur > pro Zeiger eine Tabelle mit 60 (Koordinaten-)Werten haben müsste? > Das sollte ja amchbar sein... Sofern die Pixel quadratisch sind, reichen 3 Stundenzeiger und je 15 Minuten- und Sekundenzeiger. 90° Drehung (X,Y bzw. Vorzeichen vertauschen) ist ja kein Rechenaufwand. Peter
Es gibt aber bei einer Analoguhr mehr als 12 Stellungen des Stundenzeigers. Der ist nämlich, wie der Name schon sagt, analog.
>Sofern die Pixel quadratisch sind, reichen 3 Stundenzeiger und je 15 >Minuten- und Sekundenzeiger. >90° Drehung (X,Y bzw. Vorzeichen vertauschen) ist ja kein Rechenaufwand. Da war wohl noch Optimierungspotential vorhanden... Das wäre dann eine Variante des Bresenham bzw. die Anwendung des gleichen...
@ der mechatroniker (Gast) >Es gibt aber bei einer Analoguhr mehr als 12 Stellungen des >Stundenzeigers. Der ist nämlich, wie der Name schon sagt, analog. Jaja, die Haarspalter mal wieder. Schon mal was von Quantisierung gehört? MfG Falk
Falk Brunner wrote: > @ der mechatroniker (Gast) > >>Es gibt aber bei einer Analoguhr mehr als 12 Stellungen des >>Stundenzeigers. Der ist nämlich, wie der Name schon sagt, analog. > > Jaja, die Haarspalter mal wieder. Schon mal was von Quantisierung > gehört? Also das würde ich nun keinesfalls als Haarspalterei bezeichnen. Einfaches Beispiel: 7:59 Wenn der Stundenzeiger immer noch präzise auf der Sieben hockt, dann ist es nicht so leicht zu erkennen, ob es jetzt fast 8:00 oder eher 7:00 ist, besonders bei einem eher kleinen Radius des Zeigers und etwas Abstand zum Display. Also wenigstens 48 Schritte würde ich dem Stundenzeiger schon spendieren, dann kannst du daran auch noch Viertelstunden noch mehr oder weniger ablesen.
@ Philipp Burch (philipp_burch) >Also das würde ich nun keinesfalls als Haarspalterei bezeichnen. >Einfaches Beispiel: 7:59 Wenn der Stundenzeiger immer noch präzise auf >der Sieben hockt, dann ist es nicht so leicht zu erkennen, ob es jetzt >fast 8:00 oder eher 7:00 ist, besonders bei einem eher kleinen Radius Ach so! Ja, stimmt natürlich. MfG Falk
der mechatroniker wrote: > Es gibt aber bei einer Analoguhr mehr als 12 Stellungen des > Stundenzeigers. Der ist nämlich, wie der Name schon sagt, analog. Dann eben 12 Stundenzeiger für 1/4h Anzeige. Ob nun 33 oder 42 Zeigerbilder im Flash, dürfte ja kein großer Unterschied sein. Die Bilder hätten außerdem den Vorteil, daß man 3 beliebig geformte Zeiger definieren kann (ohne, mit Bauch, dick, dünn, spitz, gerade usw.) Die verschiedenen Formen machen es einfacher, übereinander liegende Zeiger zu unterscheiden. Peter
Hallo Holger, habe Dir mal meine Uhrendarstellung angehängt. Das Ganze ist nicht besonders dokumentiert, ich hoffe, es reicht Dir. Die Darstellung beruht auf dem Bresenham-Algorythmus, ich habe den in der Wikipedia gefundenen etwas geändert. Das Array uhr[] ist für die 12 kleinen Aussenstriche zuständig. Die Zeiger haben jeweils nur 15 Einträge, die restlichen 3 Quadranten werden aus diesen 15 Werten berechnet. Der Minutenzeiger ist nur 1 Pixel breit, Der Stundenzeiger ist 2 Pixel breit. Ich verwende ein 128 * 64 Graphik-LCD, bei größeren Displays musst Du ggf. manche Werte von uint8_t auf uint16_t ändern. Die einzige Routine, die aus der Graphikbibliothek (ich benutze meine eigene) verwendet wird, ist setpixel(x, y); Das musst Du ggf. an die verwendete lib anpassen. Viel Spaß und viele Grüße, Stefan
Ich bitte vielmals um Entschuldigung! Ich hatte mir eine schlimme Erkältung zugezogen und hinterher war so viel dienstliche Arbeit da, daß ich überhaupt nicht zum programmieren gekommen bin und mein Projekt einfach stehen blieb. @ Stefan: Gestern Abend habe ich den Code mal ausprobiert. - Genial! Genau das hatte ich gesucht und mich dann schon selber dran versucht. Vielen Dank Stefan - funktioniert prima. P.S. den Kreis hab ich zugefügt Gruß Holger
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.