Forum: Compiler & IDEs HDD Clock - Wie geht's?


von Leo B. (luigi)


Lesenswert?

Servus Programmierfreaks und -könner,

ich hab im Internet vor einiger Zeit dieses Projekt hier entdeckt:
http://i8t.de/119k2i9j
falls der 1.Link nicht funktioniert, das Gleiche nochmal:
http://tinyurl.com/6ktq63
Bei google findet man unter "HDD Clock" auch einiges dazu, nur finde ich 
keine Beschreibung, wie das im Code aussieht/gemacht wird. Ich habe zwar 
schon einen Code dazu gefunden, aber dieser beinhaltete auchnoch ein 
Touchscreen und war mir damit eindeutig zu kompliziert. Kurz ich bin 
keineswegs durchgestiegen!

Was ich eigentlich wissen will ist, wie das im Code gemacht wird, mit 
der Drehzahl-Syncronisierung. Klar es wird mit einem Signal/Interrupt 
pro Umderhung die Drehzahl sowie ein "Nullpunkt" festgelegt (Jeder 
dieser Interrupts liest den Wert eines Timer/Counter, bestimmt daraus 
die Drehzahl und setzt den Timer/Counter auf null zurück), aber wie 
geht's dann wieter?
Ich steh seit einem Monat aufm Schlauch und find auch nix dazu.
Wie wird unabhängig von der Drehzahl bei meinetwegen genau 350° die LED 
für genau 5° eingeschalten?
Oder besser gefragt. Wie wird von Grad (Winkel auf der Scheibe) in Zeit 
(Schaltzeitpunkte für die LEDs) drehzahlunabhängig umgerechnet?
Und wenn zeiten ausgerechnet sind, wie wird das dann verwirklicht, dass 
die LED auch angeht wenn sie soll. Über interrupts in einem 
Timer/Counter? Das geht evtl. mit einer LED aber mit 3 LEDs/Farben? 3 
Timer/Counter???

Wer kann und will mir helfen?
Ich bin um jede konstruktive Idee Dankbar!!!

von Karl H. (kbuchegg)


Lesenswert?

Hans Wurst schrieb:

> Bei google findet man unter "HDD Clock" auch einiges dazu, nur finde ich
> keine Beschreibung, wie das im Code aussieht/gemacht wird. Ich habe zwar
> schon einen Code dazu gefunden, aber dieser beinhaltete auchnoch ein
> Touchscreen und war mir damit eindeutig zu kompliziert. Kurz ich bin
> keineswegs durchgestiegen!

Im Grunde funktioniert das sehr simpel.
Der Raum unter der Scheibe kann durch Leds in einer bestimmten Farbe 
ausgeleuchtet werden. In der Scheibe ist ein Schlitz. Durch diesen 
Schlitz kann dann das Licht nach oben entweichen.
Die Steuerung hat daher 'nur' die Aufgabe, die Leds genau dann in einer 
bestimmten Farbe leuchten zu lassen, wenn der Schlitz an einer 
bestimmten Position ist.

> Was ich eigentlich wissen will ist, wie das im Code gemacht wird, mit
> der Drehzahl-Syncronisierung. Klar es wird mit einem Signal/Interrupt
> pro Umderhung die Drehzahl sowie ein "Nullpunkt" festgelegt (Jeder
> dieser Interrupts liest den Wert eines Timer/Counter, bestimmt daraus
> die Drehzahl

viel zu kompliziert. Der tatsächliche Wert der Drehzahl interessiert 
nicht weiter.

Die Scheibe braucht für eine komplette Umdrehung (also für 360°) sagen 
wir mal 36 Millisekunden. Wie lange braucht sie daher für 10°?

Ist ein simpler Dreisatz.

Du brauchst dazu lediglich einen Sensor, der feststellt, wann der 
Schlitz an einer bestimmten Position ist. Dadurch hast du eine 
Nullposition. Zusätzlich misst du auch noch in welcher Zeit eine 
Umdrehung durchgeführt wird. Da sich diese Zeit von einer Umdrehung zur 
nächsten nicht wesentlich ändern wird, kann man zumindest für die 
nächste Umdrehung mit derselben Zeit rechnen (und gleichzeitig deren 
Dauer messen). Aus der Zeit, die eine Umdrehung benötigt, kann man 
umgekehrt den Zeitbedarf für einen bestimmten Winkel ausrechnen und 
klarerweise auch, wann diese Zeitspanne beginnen muss, relativ zum 
Nullpunktssignal.

Das ganze ist also eine reine Zeitsteuerung. Zum richtigen Zeitpunkt 
muss die richtige Led eine definierte Zeitspanne eingeschaltet sein. Das 
ist alles. Berechnbar aus der Zeitdauer der vorhergehenden Umdrehung und 
der Vorgabe in welcher Winkelposition der Schlitz sein soll und welchen 
Winkelbereich der Schlitz erleuchtet überstreichen soll.

> Und wenn zeiten ausgerechnet sind, wie wird das dann verwirklicht,
> dass die LED auch angeht wenn sie soll. Über interrupts in einem
> Timer/Counter?

Müsste man nachrechnen. Aus dem Bauch heraus sollte das aber kein 
Problem sein.

Bei 5000 U/min macht die Scheibe 83 Umdrehungen pro Sekunde oder anders 
ausgedrückt: Eine Umdrehung dauert 12 Millisekunden. Für einen µC ist 
das schon fast Super-Zeitlupe.

> Das geht evtl. mit einer LED aber mit 3 LEDs/Farben? 3
> Timer/Counter???

Kein Problem. Man kann die notwendigen Schaltzeiten ja im Vorfeld 
berechnen und aufsteigend sortieren. Selbst wenn man pro 1° einen 
Interrupt auslösen lässt, bleibt da noch genug Zeit während einer 
Umdrehung um die Daten der nächsten Umdrehung zu berechnen.

von Leo B. (luigi)


Lesenswert?

Karl heinz Buchegger schrieb:
> Im Grunde funktioniert das sehr simpel.
> Der Raum unter der Scheibe kann durch Leds in einer bestimmten Farbe
> ausgeleuchtet werden. In der Scheibe ist ein Schlitz. Durch diesen
> Schlitz kann dann das Licht nach oben entweichen.
> Die Steuerung hat daher 'nur' die Aufgabe, die Leds genau dann in einer
> bestimmten Farbe leuchten zu lassen, wenn der Schlitz an einer
> bestimmten Position ist.
>
Hardware war mir klar, aber trotzdem Danke.

>> Was ich eigentlich wissen will ist, wie das im Code gemacht wird, mit
>> der Drehzahl-Syncronisierung. Klar es wird mit einem Signal/Interrupt
>> pro Umderhung die Drehzahl sowie ein "Nullpunkt" festgelegt (Jeder
>> dieser Interrupts liest den Wert eines Timer/Counter, bestimmt daraus
>> die Drehzahl
>
> ...
>
> Die Scheibe braucht für eine komplette Umdrehung (also für 360°) sagen
> wir mal 36 Millisekunden. Wie lange braucht sie daher für 10°?
>
> Ist ein simpler Dreisatz.
>
> ...
>
> Das ganze ist also eine reine Zeitsteuerung. Zum richtigen Zeitpunkt
> muss die richtige Led eine definierte Zeitspanne eingeschaltet sein. Das
> ist alles. Berechnbar aus der Zeitdauer der vorhergehenden Umdrehung und
> der Vorgabe in welcher Winkelposition der Schlitz sein soll und welchen
> Winkelbereich der Schlitz erleuchtet überstreichen soll.

Das klingt höchst logisch und plausibel und sowas in der Richtung dachte 
ich mir schon, was ich jedoch nicht Verstehe ist jetzt der Übergang in 
die Programmiersprache bzw. auf die uC Hardware.
Ich meine ich habe ein paar Timer/Counter, paar Interrupts und einige 
viele Prozessortakte zur Verfügung. Aber was fange ich damit an?

Ich nutze einen externen Interrupt um die Drehzahl in Countertakten 
(meinetwegen 8bit, 256 Takte) anzugeben. Und bei einem Externen 
interrupt wird mein Counter auf null zurück gesetzt. Damit ist meine 
Scheibe quasi in 0 - xx Teile geteilt (xx ist dabei dann der 
Counterstand beim Interrupt).
Wunderbar, dann hänge ich gleich an die Interruptroutine noch ein paar 
Rechnungen dran und berechne die ein-/ausschalt -zählerstände der LEDs.
So schön und gut. Jetzt bin ich nen schritt weiter, aber wie gehts jetz 
wieter? muss ich jetz vom Hauptprogramm aus dern Counter pollen und dann 
im richitgen Moment die Ausgänge ein/ausschalten?
Ich hab ja keine x Counter zur Verfügung und pro Counter kann ich bei 
den mir bekannten ATmels nur max 2 Interrupts (die Compare Match 
Interrupts) einstellen (Timer/Counter Overflow hilft mir ja nicht 
viel)?!

von Karl H. (kbuchegg)


Lesenswert?

Hans Wurst schrieb:

> Ich meine ich habe ein paar Timer/Counter, paar Interrupts und einige
> viele Prozessortakte zur Verfügung. Aber was fange ich damit an?
>
> Ich nutze einen externen Interrupt um die Drehzahl in Countertakten
> (meinetwegen 8bit, 256 Takte) anzugeben. Und bei einem Externen
> interrupt wird mein Counter auf null zurück gesetzt. Damit ist meine
> Scheibe quasi in 0 - xx Teile geteilt (xx ist dabei dann der
> Counterstand beim Interrupt).

Ja, super.
Auf einem AVR bietet sich dabei sofort der Input Capture an: Bei 
Auftreten eines externen Signales an einem Pin wird der momentane 
Zählerstand in ein spezielles Register kopiert. Der Zähler läuft und 
läuft und läuft und jedesmal, wenn der SChlitz an einer bestimmten 
Position ist, lässt man sich den Zählerstand geben. Die Differenz aus 2 
aufeinanderfolgenden Zählerständen ist dann ein Mass für die Zeit einer 
Umdrehung.

> Wunderbar, dann hänge ich gleich an die Interruptroutine noch ein paar
> Rechnungen dran und berechne die ein-/ausschalt -zählerstände der LEDs.

Ne, das machst du nicht.
Die Ein/Ausschaltzeiten rechnest du ganz normal im Hauptprogramm. Wenn 
die Berechnung fertig ist, setzt du ein Flag für .....

> So schön und gut. Jetzt bin ich nen schritt weiter, aber wie gehts jetz
> wieter?

... einen anderen Timer, der ein regelmässiges Zeitsignal auslöst.
In dessen Interruptbehandlung arbeitest du den nächsten Schritt aus der 
berechneten Zeitentabelle ab. Natürlich nur, wenn das Flag gesetzt ist, 
dass eine Zeittabelle vorliegt.

> muss ich jetz vom Hauptprogramm aus dern Counter pollen und dann
> im richitgen Moment die Ausgänge ein/ausschalten?

Aber geh. Der zweite Timer läuft doch viel schneller, als sich die 
Scheibe dreht. Wenn du da einen 8 Bit Timer nimmst, den mit vollem 
Prozessortakt laufen lässt, kriegst du bei 1 Mhz rund 3900 Overflow 
Interrupts in der Sekunde. Oder anders gesagt: Der Interrupt teilt dir 
mit, dass wieder mal 0.2 ms vergangen sind. Wenn 0.2ms nicht reichen, 
dann lässt man den µC eben nicht mit 1Mhz sondern mit 10Mhz laufen. Und 
schon werden aus den 0.2 ms ganze 0.02 ms. Dauert eine komplette 
Scheibendrehung 12ms, dann kannst du damit immerhin schon auf 0.6° genau 
die Ein/Aus Zeiten festlegen.

> Ich hab ja keine x Counter zur Verfügung und pro Counter kann ich bei
> den mir bekannten ATmels nur max 2 Interrupts (die Compare Match
> Interrupts) einstellen (Timer/Counter Overflow hilft mir ja nicht
> viel)?!

Wozu brauchst du x Counter?
Du brauchst doch nur in der 2.ten ISR mitzählen.
Wird sie (nach der NUllpunktserkennung) das erste mal aufgerufen, sind 
0.2ms vergangen. Beim nächsten Aufruf sind 0.4ms vergangen, beim 
nächsten 0.6ms usw. Wenn deine Led also von Millisekunde 1.6 bis zur 
Millisekunde 2.4 leuchten soll, heisst das, dass sie vom 8.ten ISR 
AUfruf bis zum 12. ISR Aufruf leuchten soll.

ISR( ... )
{
  counter++;

  if( counter > start && counter < end )
    led_einschalten
  else
    led_ausschalten
}

Jetzt überlegst du dir noch, wie du die Ein und Ausschaltzeiten in einer 
Tabelle organsisierst und dann hast du das Geheimnis schon zu 80% 
gelöst.

von Roland Praml (Gast)


Lesenswert?

Ich denke es gibt keinen "Sensor". Das ist ein Brushless DC Motor (etwa 
mit einem 3 Phasen Schrittmotor vergleichbar) welcher direkt vom 
Controller angesteuert wird. Somit weiß der Controller immer, wo der 
Schlitz ist.

Gruß
Roland

von Karl H. (kbuchegg)


Lesenswert?

Roland Praml schrieb:
> Ich denke es gibt keinen "Sensor". Das ist ein Brushless DC Motor (etwa
> mit einem 3 Phasen Schrittmotor vergleichbar) welcher direkt vom
> Controller angesteuert wird. Somit weiß der Controller immer, wo der
> Schlitz ist.

Möglich.
Vom Youtube Video wird auf eine 'Ideen-Seite' verlinkt. Auf der ist von 
einem Indexsensor mit einem selbst gebohrtem Index-Loch die Rede.

http://alan-parekh.com/projects/hard-drive-clock/

Ich denke nicht, dass sich wer die Arbeit macht einen BC Controller im 
PIC nachzubauen, wenn die noch funktionsfähige Motorregelung der Platte 
die Drehzahl im Auge behält.

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
Noch kein Account? Hier anmelden.