POV-Display
In diesem Artikel wird die Realisierung eines POV-Displays (engl. persistence of vision) beschrieben. Diese sind auch als propeller clock bzw. Propelleruhr bekannt. Der besondere Effekt eines solchen Displays liegt darin, dass das Bild erst durch die Trägheit des Auges entsteht. Bei Bauarten wie dieser kann damit ein Bild mehr oder weniger schwebend in der Luft erzeugt werden. Die Technik wird in verschiedensten Varianten eingesetzt, beispielhaft wird hier ein Globus mit 40 RGB-LEDs gezeigt.
Der Artikel soll vor allem Anregungungen zum Aufbau, zu speziellen Details und Bauteilen bieten wie auch als Codegrundlage dienen.
Demoanwendung mit einigen Animationen: http://youtu.be/ziD_1fVdDWQ
Randdaten
- 40 RGB LEDs, Bildfläche 80x40 Pixel mit 7 Farben (+ echtem Alphachannel)
- Globus mit 20cm Durchmesser
- ATMega644
- selbstregelnde Refresh-Rate über optischen Sensor
- ca. 1/2 ASCII-Text Support
- Bildkonverter
Mechanische Konstruktion
Es gibt neben dem hier beschriebenen Rotor auch noch weitere Techniken wie geschlitzte Abdeckungen.
Rotor
Grundsätzlich sind 3 Arten von Rotoren typisch: flach, zylindrisch und kugelförmig. Zylindrische und flache Rotoren sind recht simpel zu bauen, wobei bei letzterem natürlich noch der Softwareaufwand für die Umrechnung kartesisch->polar hinzukommt.
Kugelförmige Rotoren haben das Problem, dass es unter einer gewissen Groesse kaum möglich ist, Treiber und LEDs auf eine Platine zu setzen. Mein Rotor war mit d=20cm dafür zu klein, deshalb kommt hier eine etwas wüste, fliegende Konstruktion zum Einsatz.
Bei allen Rotoren ist natürlich auf eine mechanisch stabile Auslegung zu achten, besonders bei größeren Durchmessern. Ein Rotor mit einem Durchmesser von 50cm hat bei 25Hz bereits eine Zentrifugalbeschleunigung von 4g im Rand! Dementsprechend wichtig ist auch das genaue Auswuchten des fertigen Rotors.
Antrieb
Am besten würde sich natürlich ein Antrieb eignen, der seine Drehzahl sehr genau halten kann, was aber zumindest eine entsprechende Regelstrecke voraussetzt.
Als einfache Alternative habe ich deshalb einen Speed 700BB 12V verwendet, der für meinen Rotor ausreicht wenn er aktiv gekühlt wird. Ein guter Richtwert für die Drehzahl sind etwa 20-25Hz. Die statische Steuerung erfolgt über eine unspektakuläre PWM aus einem ATTiny45 und grossem FET. Da die Drehzahl bei dieser Methode nicht konstant ist, wird eine Regelung der Bildwiederholrate notwendig.
Stromversorgung
Die Stromversorgung des Rotors lässt sich am einfachsten über Schleifkontakte bewerkstelligen. Wenn man auf eine Spannungsregelung auf der Controllerplatine verzichten will muss die Spannung dort unbedingt gut gepuffert werden. Dazu mehr im entsprechenden Abschnitt.
Ich habe 2 Schleifringe aus Messingrohr mit Epoxy aufgeklebt, gross genug um darunter das Kabel des darunterliegenden Schleifrings verlegen zu können. Die schwarze Kunststoffplatte drückt die 2 Schleifkontakte dagegen. Man könnte natürlich kleinere Ringe nehmen und das 2. Kabel im Trägerrohr verlegen.
Wer etwas mehr Geschick hat, kann die Wicklungen des Rotors in einem Bürstenmotor anzapfen, denn diese werden bereits über die normalen Schleifringe mit Energie versorgt. Allerdings muss man dahinter noch eine Gleichrichterdiode und einen Pufferkondensator schalten. Die Drähte muss man durch das Lager des Rotors nach außen führen.
Eine verschleiß- und geräuschfreie Alternative wären Induktionsspulen, siehe Royer Converter.
Als Stromquelle dient die 5V Schiene eines Computernetzteils.
Gehäuse
Das Gehäuse ist bei mir reines Mittel zum Zweck (wie man vermutlich sieht). Ich habe dicke Spanplatten verbaut, um es verwindungssteif und gleichzeitig schwer zu machen, da ein 100%iges Auswuchten fast unmoeglich ist.
LEDs und Treiber
Als LEDs kamen die verbreiteten RGB-LEDs der Bauform 5050 zum Einsatz, die sich sehr gut in den Punkten Helligkeit, Abstrahlwinkel, Farbmischung und Ansteuerbarkeit (keine gemeinsame Anode/Kathode) eignen.
Um die LEDs gleichmäßig aufzukleben habe ich einen Papierstreifen zugeschnitten, mit Bleistift Markierungen gesetzt und diesen mit Sekundenkleber (getränkt) auf den Ring aufgeklebt. Die LEDs wurden dann mit etwas Epoxy darauf geklebt.
Getrieben wird alles mit 15 Schieberegistern 74HC595, diese sind pro Farbe auf jeweils 5 in Serie aufgeteilt. Siehe dazu den -> Schaltplan für eine "Stufe" aus 8 LEDs, dort sind auch die entsprechenden Ausgangspins am Atmel angegeben. Da die Schieberegister auf Vcc und GND nur 70mA aushalten, habe ich den auch schon im AVR-Tutorial: Schieberegister Trick angewendet und jeweils 4 LEDs mit Anoden links und 4 mit Kathoden links abgewechselt.
Dadurch treten allerdings 3 Effekte auf: Zum einen liegen die einzelnen Chips in den LEDs nicht mehr exakt auf einer Linie, was bei genauerer Betrachtung bzw. ohne zusätzlichen Diffusor auffällt. Zum anderen muss das jeweilige Vertauschen von Blau und Grün entweder in der Verkabelung oder im Code (meine Methode) beachtet werden, genau wie die Tatsache, dass dann je 4 LEDs active high und 4 active low sind.
Versorgungs- und Steuerleitungen habe ich im Trägerrohr verlegt. Nach dem Funktionstest habe ich die fliegende Konstruktion noch mit einer entsprechenden Menge Epoxy vergossen.
Controllerplatine
Die Controllerplatine befindet sich im Gehäuse und ist sehr simpel gehalten, sie beinhaltet im wesentlichen den ATMega644 mit ISP-Header und Anschlüssen für die Schieberegister, einer Pufferung für die Versorungsspannung und 2 OPAMP-Stufen, die mit einer Fotodiode + Schmitt-Trigger den externen Interrupt aktivieren. Die Pufferung ist wichtig, da die Schleifkontakte keine saubere Versorgung gewährleisten können.
Zu meiner Dektektorschaltung noch ein Hinweis: Am besten vorher am Breadboard die Werte prüfen und danach auch am Controller testen ob die Triggerung auf steigende oder fallende Flanke besser funktioniert. Ausserdem könnte man noch einen kleinen Kondensator parallel zu R9 schalten (Tiefpass).
Layout und der Bestückungsplan (von Kupferseite aus gesehen) finden sich im .tgz. Auch die Platine sollte ausgewuchtet werden.
Firmware
Die Firmware ist für den AVR-GCC geschrieben worden. Als Buffer für das aktuelle Bild dient das uint8_t globe[80][5][3] Array, welches in x-Position (in Drehrichtung), Zeile und Farbindex unterteilt ist. Das Byte repräsentiert die 8 vertikalen Bits einer Zeile, ähnlich wie bei einem graphischen LCD.
Anpassung der Bildwiederholrate
Ich habe den 16bit-Timer-Overflow als Zeitgeber missbraucht, der im Sollfall 320x (80 x-Werte x4) so schnell auslöst wie die Rotordrehzahl. Die vierfache Zählgeschwindigkeit dient dabei der Anpassung der Geschwindigkeit an die tatsächliche Drehzahl. Bei jedem 4. Timerüberlauf wird dann der entsprechende Längengrad auf die Register geschoben. Die ISR ist natürlich sehr lang, dafür muss aber bei komplexeren Transformationen/Animationen nicht auf Laufzeiten geachtet werden. Wichtig dabei: Alle anderen Operationen werden als nicht zeitkritisch betrachtet.
Eine weitere ISR wird beim Auftreten des Detektorinterrupts ausgelöst. Diese setzt Index und Zählerregister zurück und korrigiert die Wiederholrate anhand des tatsächlich erreichten Index.
Bildkonverter
Um ganze Bilder, wie z.B. die Weltkarte einfach auf den Globus zu bekommen, habe ich einen kleinen quick&dirty (!) Bildkonverter mit perl und perl-imagemagick geschrieben, der direkt einen passenden Header (PROGMEM) generiert. Das Script befindet sich ebenfalls im .tgz und sollte hoffentlich mit perl auch unter Windows funktionieren. Ein Bild benötigt etwas über 1,2kB Flash. In der animations.c befindet sich die passende Ladefunktion + Beispielaufruf.
Es sei darauf hingewiesen, dass das Programm ungefragt die Zieldateien überschreibt! Erwartet wird 80x40pix Bild, am besten als .bmp.
Im Script oben können die Schwellenwerte für die Farben eingestellt werden (0-1, Werte >1 blenden die Farbe komplett aus), dazu wird noch ein Bild generiert, um diese Werte testen zu können, ohne es live auf dem Globus ausprobieren zu müssen.
Aufruf: img2globe.pl image.bmp <Name des Arrays>
Was aufgefallen ist/weitere Hinweise
- Zur Videoaufnahme: Es ist recht schwer richtige Lichtverhältnisse zu finden, da die Kamera ständig nachregeln will. Beste Erfahrungen habe ich mit sehr viel Licht gemacht. Ausserdem sollte dazu die Drehzahl etwas hochgefahren werden, um schwarze Balken zu vermeiden.
- Der Atmel ist mal wieder sehr an seiner Grenze. Würde ich nochmal einen Globe bauen, käme vermutlich ein Cortex-M3 rein.