In diesem Tutorial wollen wir uns ganz dem Thema Licht widmen. Dazu stehen uns auf dem RoverROM B3000 zwei weiße LEDs als Frontscheinwerfer und eine rote LED als Heckleuchte zur Verfügung. In der ganz neuen Version kommen LED-Module der Böcker Systemelektronik zum Einsatz.
Diese Module haben speziell für den Einsatz im RoverROM B3000 einige Vorteile:
1. Die 4 Befestigungsbohrungen erlauben eine flexibel Montage.
2. Die Anschlussbeinchen sind bewusst lang gelassen, um die LEDs genau ausrichten zu können.
3. Die Module verfügen auf der Rückseite über einen Transistor, der eine Überlastung der I/O-Anschlüsse verhindert und den Betrieb von Lasten mit bis zu 1 A bzw. 1,3 W erlaubt.
4. Über das kleine Potenziometer (gelber Kreis) kann die Helligkeit der LEDs variabel eingestellt werden.
Die 3 LED-Module sind an den digitalen Anschlüssen 11 (LED links), 12 (LED rechts) und 13 (rote LED) angeschlossen. Damit wir uns die Anschlussnummern nicht merken müssen, werden wir sie mit entsprechenden #define-Statementes festlegen:
Außerdem müssen wir noch die Treiberrichtung bestimmen, die für alle 3 LEDs in der setup-Funktion auf "Output" setzen.
Jetzt haben wir alle Voraussetzungen erfüllt, um unsere LEDs direkt anzusteuern. Dazu schreiben wir eine "1" auf den entsprechenden Ausgang (LED leuchtet) oder eine "0", um die LED auszuschalten. Wir wollen zunächst die weißen LEDs als Dauerlicht und die rote LED als Blinklicht programmieren.
Da die weißen LEDs kontinuierlich leuchten sollen, können wir diese Statements in der setup-Funktion durchführen. In der loop-Funktion schalten wir die rote LED im Sekundentakt ein und aus. In Verbindung mit der delay-Funktion können wir beliebige Blitz- und Alarmbeleuchtungen realisieren. Dazu das folgende Beispiel:
Die setup-Funktion bleibt identisch, nur der loop-Teil ändert sich. In einer for-Schleife wird zunächst "led_rot" eingeschaltet und alle anderen aus. Danach wird nur led_links aktiviert und im dritten Block nur die rechte LED. Die 3 Blocks können natürlich in jewelis 2 Zeilen gekürzt werden, weil sich ja nur immer der Zustand von 2 LEDs ändert. Ich habe allerdings immer alle 3 LEDs angesprochen, damit es übersichtlicher ist. Der Compiler optimiert solche Dinge eh nachher aus. Zwischen den Zustandsänderungen erfolgt jeweils eine sehr kurze Pause von 30 ms. Ein stellt also praktisch ein kurzes Aufblitzen aller 3 LEDs dar. Danach (Zeilen 37 bis 39) werden alle LEDs ausgeschaltet und es folgt eine Pause von 500 ms, bevor die Schleife neu startet.
Wie schon beschrieben, können die LEDs zwar mittels der Potenziometer in der Helligkeit eingestellt werden, aber damit ist eine Änderung der Helligkeit im Programm nicht durchführbar. Da der Atmega328 auf unserem Romeo-Board keine D/A-Wandler besitzt, müssen wir uns anders behelfen. Dazu greifen wir auf den gleichen Trick zurück, den wir schon bei der Regulierung der Motordrehzahl verwendet haben, der Pulsweiten-Modulation (die Beschreibung dazu finden Sie in diesem Tutorial).
Wir steuern dabei die LED mit mehr oder weniger langen Lichtimpulsen an und wenn wir dies schnell genu machen, dann erscheint die LED eher dunkel (kurze Lichtpulse, längere Pausen) oder mit maximaler Helligkeit (Lichtpulse ohne Pause, also permanenter Pegel von 5 V). Wir können einen PWM-Funktion recht einfach selbst programmieren, doch das hat entscheidende Nachteile wie Sie in dem oben erwähnten Tutorial nachlesen können. Deshalb nutzen wir die integrierte PWM-Funktion des Atmel328. Damit müssen wir die Pulsweitenmodulation nur einmal konfigurieren und sie läuft neben der CPU automatisch ab. Das funktioniert allerdings nicht an allen I/O-Ports, beim Atmel328 stehen PWM-Ausgänge an den Pins 3, 5, 6, 9, 10, 11 und 13. Da wir standardmäßig für die LEDs Pin 11, 12 und 13 nutzen, können wir in dieser Konfiguration die PWM-Funktion an der weißen LED links und der roten LED nutzen. Ist sie an allen gewollt, kann die rechte LED von Pin 12 z. B. auf Pin 9 gelegt werden.
Für die PWM-Funktion müssen wir beim Atmel328 ein paar Registereinträge für die Timer vornehmen und das Ganze dann starten. Doch hier nimmt uns das Arduino-System mal wieder ein Stück Arbeit ab. Wir benötigen lediglich den Befehl "analogWrite(pin, value)". Dabei ist pin der Anschluss, den wir ansteuern wollen und mit value geben wir einen Wert zwischen 0 (Puls = 0, Pause = max) und 255 (Puls = max, Pause = 0) ein. Das ergibt sich aus der Tatsache, dass es sich um 8-Bit-Timer handelt, wir können also die Einschaltdauer pro Periode mit einer Auflösung von 256 angeben.
Um die PWM-Funktion zu testen, laden wir das folgende Programm in unseren RoverROM:
Zunächst leuchtet die linke LED mit voller Helligkeit und die rechte LED wird langsam heller. Hat die rote LED den Maximawert erreicht, wird die weiße LED wieder langsam dunkler. Ist sie ganz ausgeschaltet, folgt die rote LED ihrem Beispiel und so weiter. Durch Ändern der Verzögerungszeit von 20 ms kann das Dimmen verlangsamt oder beschleunigt werden. Wie das Ganze live aussieht, können Sie im folgenden Video sehen:
Um die Umgebungshelligkeit messen zu können, verfügt der RoverROM B3000 über einen Phidgets-Lichtsensor. Der dort verwendete Baustein ist ein APDS-9002. Die meisten preisgünstigen Lichtsensoren arbeiten in einem anderen spektralen Empfindlichkeitsbereich als das menschliche Auge. Es kann also durchaus vorkommen, dass das für uns wahrnehmbare Licht heller erscheint, der Sensor aber fallende Werte anzeigt, wenn sich das Spektrum verschiebt.
Das Lichtsensor-Modul von Phidgets liefert ein Spannungssignal von 0 bis ca. 4,1 V zur Verfügung. Bei 4,1 V beträgt der Wert des AD-Wandlers 4,1 V / 5 V * 1024 = 839. Bei diesem Wert ist der Sensor in der Sättigung (1000 Lux), höhere Lichtstärken werden also nicht mehr erkannt. 1000 Lux sind für eine Innenbeleuchtung schon sehr hell, das ist ungefähr der Wert, der in einem Fernsehstudio oder in einer Werkstatt für Detailarbeiten gewählt wird.
In einem ersten Beispiel wollen wir den Sensorwert erfassen und über die serielle Schnittstelle ausgeben:
Der Lichtsensor befindet sich am analogen Eingang A4. Über den pinMode-Befehl konfigurieren wir diesen Anschluss als Eingang. Danach initialisieren wir die serielle Schnittstelle, um den Wert auszugeben. In der loop-Funktion lesen wir über analogRead() den Wert am Anschluss "lightSensor" (A4) ein, geben ihn aus und warten dann 1 Sekunde.
Das Ergebnis sieht bei mir dann im seriellen Monitor so aus:
Zunächst erhalte ich den Wert für mein Umgebungslicht, was zugegeben mit 13 recht dunkel ist. Danach decke ich den Sensor mit dem Finger ab und er sinkt auf den Wert 0 und anschließend leuchte ich mit einer hellen LED-Taschenlampe direkt auf den Sensor und erreiche mit 832 wohl auch den Sättigungswert.
Da wir im vorigen Beispiel die Helligkeit der LED gesteuert haben, bietet es sich ja an, diese Werte jetzt mit dem Lichtsensor zu messen. Dazu müssen wir den Sensor abschrauben und möglichst dicht vor die LED bringen und dann die unterschiedliche Helligkeitswerte einstellen. Wir wollen das wieder in einer Schleife tun und der Sensorwert müsste dann ja kontinuierlich steigen und fallen.
Das Programm dazu sieht folgendermaßen aus:
Der erste Teil dürfte mittlerweile klar sein. In der loop-Funktion wird innerhalb der Schleife der PWM-Wert für die LED geschrieben und während der Schleifendurchläufe hoch gezählt. Nachdem der neue Wert gesetzt ist, wird der Sensor eingelesen und danach werden der gesetzte Helligkeitswert und der gemessene Sensorwert in einer Zeile auf dem seriellen Monitor ausgegeben. So haben wir die korrekte Zuordnung immer im Blick.
Nachdem wir das Programm in den RoverROM geladen und gestartet haben, öffnen wir den seriellen Monitor und prüfen das Ergebnis:
Das ist nicht das, was wir eigentlich erwartet hatten!? Der erste Messwert bei einer Helligkeit von 0 mit 839 könnte ja noch irgendwie logisch erscheinen. Bis die PWM reagiert vergeht eine gewisse Zeit und die LED bleibt in dieser Zeit vielleicht noch auf maximaler Helligkeit, selbst wenn sie auf 0 gesetzt ist. Aber die Helligkeit steigt rasant an und hat schon bei sehr niedrigen Werten nahezu den Maximalwert. Aber sie sinkt z. B. ab einer Helligkeit von 18 sogar von 775 auf 710, danach springt sie auf über 800 und sinkt dann wieder. Wie kommt es zu diesem seltsamen Verhalten?
Die Lösung lautet: Wir können unseren Augen eben nicht immer trauen. Genau das haben wir uns ja zunutze gemacht, denn die Pulsweitenmodulation steuert ja nicht wirklich die Helligkeit der LEDs, sondern lässt sie nur schnell genug flackern. Den Sensor können wir mit diesem Trick allerdings nicht überlisten. Je nachdem, ob er in der Dunkel- oder in der Leuchtphase misst, erhalten wir einen sehr geringen oder fast den maximalen Wert. Erfolgt die Messung genau im Einschalt- oder Ausschaltvorgang, liegen die Werte irgendwo im gesamten Messbereich. Wir müssen uns also immer vor Augen halten, um was für eine Lichtquelle es sich handelt, wenn wir mit einem solchen nicht integrierenden Lichtsensor messen wollen.
Sie können den Lichtsensor sehr gut einsetzen, um festzustellen, ob Ihr RoverROM z. B. unter einen Schrank oder eine Stufe gefahren ist. Sie können ihn auch nach dem Licht ausrichten, so dass er sich selbsttätig einen Platz an der Sonne sucht ;-).
Im nächsten Tutorial werden wir uns mit einer sehr ähnlichen Technik beschäftigen: dem Line-Tracking.
Für weitere Informationen und Bestellungen des
RoverROM-B3000
Sie wollen Arduino-Profi werden? Dann ist unser Video Mikrocontroller-Lehrgang MC1 genau das Richtige für Sie!
Falls Sie Fragen zum Thema haben, wenden Sie sich einfach an uns.
Wir helfen Ihnen gern weiter!
Ihr Team von Böcker Systemelektronik
Hinweis: Unser Tutorialangebot wird in unregelmäßigen Abständen erweitert. Wenn Sie sofort über eine Neuerscheinung informiert werden möchten, tragen Sie sich bitte hier in unsere Benachrichtigungsliste "Tutorials" ein. Sie können diesen unverbindlichen Service jederzeit in Ihrem Kundenkonto oder per E-Mail wieder abbestellen.
Copyright © Böcker Systemelektronik