www.mikrocontroller.net

Forum: Compiler & IDEs Analog Uhr, GLCD, ?


Autor: Holger Gerwenat (holli1195)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon mal was von "Bresenham" gehört?

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Holger Gerwenat (holli1195)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Michael (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Simon K. (simon) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Holger Gerwenat (holli1195)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt aber bei einer Analoguhr mehr als 12 Stellungen des 
Stundenzeigers. Der ist nämlich, wie der Name schon sagt, analog.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Kleinwort (_sk_)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Holger Gerwenat (holli1195)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.