Einführung in Mikrocontroller – Der Arduino als Steuerzentrale Arbeitsheft für Schülerinnen und Schüler Dieses Heft gehört _______________________ Inhalt 1. Was ist ein Mikrocontroller? ....................................................................................................... 1 2. Hardware: Der Arduino ............................................................................................................... 2 3. Software: Die Arduino-Entwicklungsumgebung.......................................................................... 3 4. Jetzt geht’s los: Dein erstes Programm ....................................................................................... 5 5. Verwendung einer Steckplatine .................................................................................................. 8 6. Vorwiderstände von LEDs ............................................................................................................ 9 7. Farbcodes von Widerständen .................................................................................................... 10 8. Lautsprecher am Arduino betreiben ......................................................................................... 12 9. Rückmeldungen an den Nutzer – Serial Monitor ...................................................................... 14 10. Verwendung von Variablen ....................................................................................................... 16 11. Etwas mehr Theorie zu Variablen .............................................................................................. 17 12. endlich viele Wiederholungen: for-Schleife .............................................................................. 19 13. endlich viele Wiederholungen: while-Schleife .......................................................................... 21 14. Dimmen einer LED - Pulsweitenmodulation ............................................................................. 22 15. Jetzt kommt Bewegung in die Sache! 16. Der Arduino bekommt Sinne ..................................................................................................... 25 17. Hell oder dunkel? Der Arduino wird zum Messgerät ................................................................ 28 18. Spannungsteiler ......................................................................................................................... 30 19. Potentiometer ........................................................................................................................... 32 20. Jetzt wird’s heiß! Der Arduino als Thermometer .................................................................. 33 21. Die if-Bedingung Der Arduino reagiert auf seine Umwelt .................................................... 35 22. Unterprogramme Programmieren mit Bausteinen .............................................................. 39 23. Ultraschall-Entfernungsmesser ................................................................................................. 41 24. Reflexoptokoppler – eine besondere Lichtschranke ................................................................. 43 25. Bewegungsmelder 26. LC-Display .................................................................................................................................. 45 27. Servo-Motor für genaue Drehwinkel......................................................................................... 46 28. Motortreiber.............................................................................................................................. 47 29. Anhang A Verwendete Bauteile ............................................................................................ 49 30. Anhang B Installation der Arduino-Software sowie des Treibers ......................................... 50 Motoren mit dem Arduino steuern .......................... 24 Der Arduino als „Wachhund“ ................................................................. 44 1. Was ist ein Mikrocontroller? Viele Geschäfte besitzen an ihrem Eingang eine Schiebetür, die sich öffnet sobald sich ein Kunde nähert, der das Geschäft betreten oder verlassen möchte. Aufgabe 1.1: a) Beschreibe in Stichworten, was die Schiebetür können muss, damit der Kunde mit ihr zufrieden ist b) Fertige mit deinem bisherigen physikalischen bzw. technischen Wissen eine Konstruktionsskizze einer Schiebetür an. Sie soll sich öffnen wenn eine Person in ihre Nähe kommt und sich anschließend wieder schließen. Wie funktioniert eigentlich eine solche Schiebetür genau? Sicherlich steckt in ihr eine ganze Menge Elektronik. Doch ein Computer hätte darin keinen Platz und wäre auch viel zu teuer und zu „gut“ für eine solche relativ einfache Steuerung. Man verwendet hierzu Mikrocontroller. Mikrocontroller sind wie kompakte Computer, jedoch mit viel geringerer Leistungsfähigkeit. Sie vereinen verschiedene Bauteile wie Recheneinheit (CPU), Speicher, Schnittstellen wie USB, Display-Controller und Analog-Digital-Wandler auf einem einzigen Chip. Der hier verwendete Mikrocontroller hat den Name „ATmega328“. Der Vorteil von Mikrocontrollern ist, dass sie speziell für ihre Aufgabe konzipiert werden können und relativ günstig sind. Dieses Arbeitsheftes ermöglicht es dir, weitestgehend eigenständig das Programmieren eines Mikrocontrollers zu erlernen. Der Mikrocontroller, den wir verwenden, heißt Arduino Uno bzw. nur Arduino. Für das Wort „Mikrocontroller“ verwendet man oft die Abkürzung μC. „μ“ (sprich: mü) ist ein griechischer Buchstabe und wird als Abkürzung für „Mikro“ verwendet. Der Name Arduino stammt von einer Kneipe, in der sich die Erfinder des Arduino 2005 oft trafen. Seite 1 2. Hardware: Der Arduino Im Folgenden lernst du das Arduino Uno-Board, mit dem du in Zukunft arbeiten wirst, etwas genauer kennen: USB-Schnittstelle für die Verbindung zum PC. Er dient als Datenleitung und Stromversorgung für den Mikrocontroller. Die Ports 0 bis 13 sind sogenannte digitale Ports. Das heißt, sie können nur zwei Zustände unterscheiden: „ein“ oder „aus“ bzw. „high“ oder „low“. In der Computersprache entspricht das den Zahlen 0 oder 1. Das Herz unseres Arduino: Der eigentliche Mikrocontroller heißt „ATmega328“. Seine Anschlüsse werden Pins genannt. ATmega328 hat 28 Pins. Manche dieser Pins dienen als Ein- und Ausgänge für elektrische Signale. Dies sind die sogenannten Ports. Der USB-Anschluss oben liefert nur 5V. Wenn angeschlossene Geräte mehr brauchen, kann man hier eine externe Spannungsquelle anschließen (bis 12 V). Die Anschlüsse dienen zur Stromversorgung der Verbraucher und liefern unterschiedliche Spannungswerte. Die Ports A0 bis A5 sind sogenannte analoge Eingänge. An ihnen können Spannungen zwischen 0 V und 5 V gemessen werden. Als Hardware bezeichnet man allgemein die mechanischen und elektronischen Bauteile eines Mikrocontrollers bzw. PCs (im Prinzip alles, was man „in die Hand nehmen“ kann). Der Begriff „hardware“ kommt aus dem Englischen und bedeutet übersetzt ursprünglich „Eisenwaren“. Diese Bedeutung hat der Begriff im englischsprachigen Raum auch heute noch. Zusätzlich hat er sich aber weltweit auch als allgemeiner Überbegriff für die Bauteile eines Computersystems verbreitet. Auf der Platine unseres Arduino sind neben dem Mikrocontroller noch viele kleine Bauteile (Widerstände, Spannungswandler, Strombegrenzer, …) und viele verschiedene Anschlüsse angebracht. Arduino vs. Handy Bei Computern oder Handys wird oft die Taktfrequenz des Prozessors angegeben. Damit ist die Geschwindigkeit gemeint, mit der Daten verarbeitet werden können. Der Atmega328 unseres Arduino besitzt eine Taktfrequenz von 16 MHz und 32 Kilobyte Speicherplatz. Ein Vergleich mit dem iPhone 5 lässt den Arduino dagegen alt aussehen: Es hat einen Prozessor mit 1,3 GHz (das sind 1300 MHz) Taktfrequenz und 1 GB (das sind 1.000.000 Kilobyte) Arbeitsspeicher. Beachte jedoch: Beim Flug zum Mond half Neil Armstrong ein Computer mit 4 Kilobyte Arbeitsspeicher und einem 1 MHz-Prozessor. Seite 2 3. Software: Die Arduino-Entwicklungsumgebung Um den Arduino zum Leben zu erwecken, muss er mit dem PC verbunden werden. Streng genommen ist der Arduino jedoch nicht sehr „klug“. Er kann nicht eigenständig denken, sondern nur Befehle der Reihe nach abarbeiten. Eine Abfolge von solchen Befehlen heißt Programm. Programmiert wird der Arduino in einer sogenannten Entwicklungsumgebung. Dort schreibt man das Programm für den Arduino in der entsprechenden Programmiersprache. Diese ist so ähnlich wie die berühmte Programmiersprache „C“. Streng genommen spricht der Arduino aber noch eine andere Sprache. Bevor das geschriebene Programm über das Datenkabel auf den Arduino übertragen wird, übersetzt es ein elektronischer Dolmetscher in Maschinensprache. Dieser Vorgang heißt Kompilieren. Es ist übrigens ganz hilfreich für uns, dass wir nicht die eigentliche Sprache des Arduino lernen müssen, um mit ihm zu kommunizieren. Diese ist nämlich sehr kompliziert. Zum Beispiel würde die Rechnung c = a + b in Maschinensprache so aussehen: 8B 45 F8 8B 55 FC 01 D0 In welcher Sprache auch immer: Ein vom Arduino ausführbares Programm bezeichnet man als Software. Aufgabe 3.1: Starte die Entwicklungsumgebung, indem du das Programm arduino.exe öffnest. Menüleiste Das Pfeil-Symbol macht zweierlei: Es kompiliert zuerst und übertragt anschließend das Programm auf den Arduino. Ein Klick auf das Symbol kompiliert das Programm und zeigt eventuelle Fehler an. Im weißen Hauptfenster schreibt man das Programm für den Arduino. Das schwarze Fenster zeigt dir die Dateigröße bzw. beim Kompilieren aufgetretene Fehler an. Statuszeile für den Anschluss des Arduino an den Rechner. Wenn das Kompilieren nicht funktioniert, ist ein häufiger Fehler, dass die Nummer des COM-Ports falsch ist (Einstellen unter Tools serieller Port richtigen COM-Port anklicken) Seite 3 Die Lupe öffnet einen Bildschirm, auf dem der Arduino Infos an den Computer zurückschicken kann. Aufgabe 3.2: Verbinde den Arduino über das USB-Kabel mit dem PC. Öffne anschließend den Windows-Gerätemanager (Windows-Taste Systemsteuerung Hardware und Sound GeräteManager) und schaue nach, an welchem COM-Port der Arduino angeschlossen ist. Stelle diesen Port im Programm über Tools Serieller Port ein. Bevor du eine Schaltung nachbaust und vom Arduino steuern lässt, musst du allerdings sicherstellen, dass dein Mikrocontroller richtig mit dem PC kommuniziert. Dazu übertragen wir ein „leeres“ Programm auf den PC. Alle Programme haben dabei den gleichen Aufbau. Dieser Programmteil wird einmal durchlaufen. Im setup()-Teil werden die Ein- und Ausgänge (und andere Grundeinstellungen) festgelegt. void setup() { // Grundeinstellungen; } void loop() { // Anweisungen; } Dieser Programmteil wird unendlich oft wiederholt (loop – engl.: Schleife). Hier befindet sich das eigentliche Programm. An den Stellen // Grundeinstellungen; und // Anweisungen; steht im echten (d.h. nicht leeren) Programm später dein Programmcode. Es kommt übrigens später oft vor, dass man in sein Programm etwas hineinschreibt, z.B. als Erklärung oder Hinweis für seine Mitschülern. Dieser „eigene“ Text soll und kann später beim Kompilieren des Programms nicht übersetzt werden. Dafür gibt es sogenannte Kommentarstellen: Alles, was in einer Zeile nach zwei Schrägstrichen // geschrieben wird, wird beim Kompilieren nicht beachtet. Anschaulich erkennt man Kommentare daran, dass sie vom Programm grau geschrieben werden. Aufgabe 3.3: Schreibe und kompiliere zunächst das leere Programm von oben und übertrage es anschließend auf den Arduino (siehe Kapitel 3). Nach erfolgreichem Übertragen meldet das Ereignis-Fenster: Finde heraus, was die Zahl „8“ (bei dir kann auch eine andere Zahl stehen) unten links bedeutet. Was bedeutet eigentlich das Wort „void“? void kann mit Leerstelle oder Loch übersetzt werden. Es bedeutet nicht 0, sondern einfach nichts. Es sagt aus, dass das Programm an dieser Stelle keinen Wert anAufrufer zurückliefert. Seite 4 4. Jetzt geht’s los: Dein erstes Programm Jetzt lernst du, wie man den Arduino nutzen kann, um Lichter (LEDs) gezielt zu steuern. Dazu kann man die 20 Anschlussports des Arduino nutzen (0 – 13 und A0 bis A5). Sie sind wie kleine anschaltbare Steckdosen. Bei jeder Steckdose gibt es immer einen Anschluss mit dem Potenzial 0 V. Das ist beim Arduino der Anschluss GND (Ground). Für den zweiten Anschluss mit dem hohen Potenzial lassen sich beim Arduino die Ports zwischen 5 V und 0 V an- und ausschalten. Erinnerung an die Physik: Das elektrische Potenzial ist eine Art „elektrischer Druck“ auf einem Kabel. Ganz ähnlich wie auch in einer Wasserleitung ein hoher oder tiefer Wasserdruck herrschen kann. Verbindet man eine Leitung hohen Drucks mit einem Bereich, in dem ein tiefer Druck herrscht, dann fließt Wasser. Genauso beim Strom: Nur wenn es einen Potenzialunterschied gibt, werden Elektronen fließen. Der Potenzialunterschied ist die bekannte Spannung. Achtung: Weil sowohl das Potenzial als auch der Potenzialunterschied die Einheit Volt haben, werden die Begriffe Spannung und Potenzial oft verwechselt!!! Mit der folgenden Schaltung wollen wir eine LED zum Leuchten bringen: Aufgabe 4.1: Was glaubst du wohl macht dieses Programm? void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13,HIGH); delay(5000); digitalWrite(13,LOW); delay(5000); } Seite 5 Aufgabe 4.2: Baue die Schaltung nach und teste deine Vermutungen. Dabei musst du darauf achten, die LED richtig herum einzusetzen (Anode – das längere Bein der LED – ans höhere Potenzial, also 5V). Was tun, wenn‘s nicht klappt? Sind die einzelnen Befehle richtig geschrieben? (Groß- und Kleinschreibung beachten!) Endet jede Befehlszeile mit einem Semikolon (Strichpunkt)? Meist hilft dir bei einem Fehler im Programmcode das schwarze Fenster. Dort steht (leider nur auf Englisch), welches Problem beim Kompilieren aufgetreten ist. Aufgabe 4.3: Kommentiere nun die einzelnen Programmzeilen. void setup() { pinMode(13, OUTPUT); } // void loop() { digitalWrite(13,HIGH); delay(5000); digitalWrite(13,LOW); delay(5000); } // // // // // // Aufgabe 4.4: Bislang blinkt die LED nur ganz langsam. Lass sie schneller blinken. Aufgabe 4.5: Nimm noch eine grüne LED dazu und schließe sie zusätzlich zur roten LED an das Board an. Verändere das Programm so, dass die beiden LEDs abwechselnd blinken. Aufgabe 4.6: Schaffst du noch zwei weitere LEDs? (Tipp: Die Ports können ja HIGH oder LOW geschaltet werden) Aufgabe 4.7: Mit diesem Programm blinkt die angeschlossene LED nicht. Erkläre warum! Seite 6 void loop() { digitalWrite(13,HIGH); delay(500); digitalWrite(13,LOW); } Aufgabe 4.8: Baue absichtlich Fehler in deinen Programmcode von Aufgabe 4.1 ein (z.B. Verwechslung von Komma Strichpunkt; Kleinschreibung Großschreibung; Schreibfehler, usw.) und kompiliere es. Notiere anschließend, was die unterschiedlichen Fehlermeldungen bedeuten. Aufgabe 4.9: Das Programmbeispiel lässt sich um vier Anweisungen kürzen, ohne dass sich etwas am Ergebnis ändert. Streiche sie durch. void loop() { digitalWrite(13,HIGH); delay(500); digitalWrite(13,LOW); delay(500); digitalWrite(13,HIGH); delay(500); digitalWrite(13,LOW); delay(500); } Aufgabe 4.10: Lege ein Vokabelblatt an, auf dem du alle Befehle, die du im Laufe der Zeit kennen lernst, aufschreibst. Dieses Blatt darfst du in der Klassenarbeit verwenden. Projekt 4.11: Wie klein kann die delay-Zeit gewählt werden, damit dein Auge das Blinken gerade noch wahrnimmt? Berechne aus dieser Zeit die maximale Bildrate deines Auges (in Hertz) Vergleiche den Wert mit deinem Nachbarn und mit der Bildfrequenz bei Kinofilmen (24 – 48 Hz). Seite 7 5. Verwendung einer Steckplatine Bei den Aufgaben 4.5 und 4.6 hast du sicherlich gemerkt, dass der Platz auf dem Arduino für mehrere LEDs irgendwann knapp wird. Generell verwendet man deshalb, wenn man mehrere Bauteile an den Arduino anschließen will, so genannte Steckplatinen (auch Breadboards genannt) . Auf einer Steckplatine steht mehr Platz zur Verfügung, um elektrische Schaltungen aufzubauen. Die Bauteile können dabei einfach – wie Elektrische Verbindungen des Breadboard der Name schon sagt – in die Steckplatine hineingesteckt werden. Das Besondere an der Steckplatine ist, dass die Steckplätze untereinander auf eine bestimme Weise leitend miteinander verbunden sind. Die Verbindung sind den Abbildungen links und oben dargestellt. So können die einzelnen Bauteile sehr einfach miteinander verbunden werden. Zum Anschluss an den Arduino gibt es zwei Möglichkeiten: Man benutzt eine separate Steckplatine und schließt sie an den Arduino über Jumper-Kabel an. Eleganter ist manchmal die Verwendung eines sog. Breadboard-Shields für den Arduino, das Platz für eine Mini-Steckplatine bietet. Nachteil: Die Steckplatine ist sehr klein. Ampelschaltung auf Breadboard-Shield Ampelschaltung auf separater Steckplatine Aufgabe 5.1: Programmiere mit einer grünen, einer gelben und einer roten LED eine Ampel. Verwende zum Aufbau deiner Ampelschaltung eine Steckplatine. Projekt 5.2: Erweitere deine Ampelschaltung durch zwei zusätzliche Funktionen, die du dir selbst überlegst. Seite 8 6. Vorwiderstände von LEDs Die Leuchtdiode, die wir verwenden, betreibt man idealerweise mit einer Stromstärke von 15 mA. Würde man eine LED direkt an 5 V anschließen, würde jedoch ein größerer Strom als die 15 mA (die eine LED verträgt) fließen. Als Folge davon würde die LED nach einiger Zeit kaputt gehen. Um die LED nicht zu zerstören, benötigt sie bei 5 V Spannung einen Vorwiderstand von 220 Ohm. Wenn du mit dem Ohmschen Gesetz die Stromstärke berechnest, die in deiner Schaltung fließt, so stellst du fest, dass der 220 Ohm-Widerstand nicht genau passt: Trotzdem wird dir jeder Elektroniker sagen, dass der Widerstand richtig gewählt ist. Der Grund liegt darin, dass eine LED in ihrem Inneren eine Spannung von etwa 1,5 V aufhebt. Man sagt auch: Eine LED hat eine Vorwärtsspannung von 1,5 V. Um diesen Betrag werden die anliegenden 5 V also reduziert. Dann ergibt sich ein „guter“ Wert für die Stromstärke: ( ) Aufgabe 6.1: Den Widerstand, den man beim Einsatz einer LED immer benötigt, bezeichnet man als Vorwiderstand der LED. Spielt es eine Rolle, ob man den Widerstand „vor“ oder „nach“ der LED einsetzt? (Denke an das Wassermodell des elektrischen Stromkreises) Probiere es anschließend aus. Aufgabe 6.2: Berechne jeweils den passenden Vorwiderstand, falls die LED a) an eine Spannungsquelle mit 9 V, b) an eine normale Steckdose, c) an eine Hochspannungsleitung (110 kV) angeschlossen werden soll. Aufgabe 6.3: a) Erkläre in eigenen Worten, weshalb eine LED einen Vorwiderstand benötigt. b) Wie sieht die - -Kennlinie einer LED aus? Finde es heraus, zeichne ein solches Diagramm in dein Heft und erkläre es kurz. Aufgabe 6.4: Drei gleiche LEDs sollen an einer Spannungsquelle mit 9 V a) in Reihe geschaltet b) parallel geschaltet betrieben werden. Zeichne jeweils einen Schaltplan und berechne den passenden Vorwiderstand. c) Warum ist es möglicherweise besser, bei der Parallelschaltung für jede LED einen eigenen Widerstand zu verwenden? Seite 9 7. Farbcodes von Widerständen Der Farbcode auf Widerständen besteht aus vier oder fünf Ringen. Damit man weiß, wo man mit dem ablesen anfangen muss, hat der letzte Ring einen etwas größeren Abstand von den anderen. schwarz schwarz braun rot braun rot orange orange gelb gelb grün grün blau violett blau violett grau grau weiß weiß gold silber kein Ring 4 Ringe: 5 Ringe: Quellen: http://www.bildung-niedersachsen.de/elektrotechnik/e_grundlagen_kap_04_4v5.html (16.02.2014) und http://www.kurcz.at/doc/widerstand/fuenffach.png (16.02.2014) Die ersten zwei bzw. drei Ringe geben jeweils Ziffern an. Jeder Ring steht für eine Ziffer der Zahl gemäß diesem Farbcode. Beim ganz oben abgebildeten Widerstand also: 47. Der Ring vor dem etwas größeren Abstand gibt an, wie viele Nullen angefügt werden müssen. Die Anzahl ergibt sich aus derselben Farbtabelle. Beim Widerstand ganz oben müssen (roter Ring = 2) zwei Nullen angehängt werden; so ergibt sich der Wert des Widerstands zu . Der Ring ganz rechts (meist in silber oder gold) gibt an, wie genau die Angabe des Widerstands ist. Hier (gold = 5%) bedeutet das, dass der tatsächliche Wert unseres Wiederstand im Bereich von bis liegen kann. Seite 10 Aufgabe 7.1: a) Welchen Farbcode hätte ein Widerstand mit 350 Ω und einer Toleranz von 5%? b) Bestimme den Widerstandswert eines Widerstandes mit der folgenden Farbkombination: grün – orange – lila – gold c) Ein Freund ruft dich an und fragt dich nach dem Wert seines Widerstandes: silber – rot – blau – lila. Was sagst du ihm? Aufgabe 7.2: Bestimme die Widerstandwerte aller Widerstände in deinem Set und notiere diese mit der entsprechenden Farbkombination. (Tipp: Lege einen beschrifteten Zettel in das jeweilige Fach mit den Widerständen, dann musst nicht jedes Mal erneut die Farbcodes auslesen) Es gibt auch Internetseiten und Computerprogramme, mit deren Hilfe man zu einer Farbkombination den entsprechenden Widerstandswert ermitteln kann (z.B. http://www.umrechnung.org/elektrischerwiderstand-farbcode/widerstand-farbcode-rechner-tabelle.htm). Außerdem kann er auch ganz leicht mit einem Multimeter gemessen werden. Diese Variante wird häufig bei älteren Widerständen genutzt, bei denen die einzelnen Farbringe nicht mehr so gut sichtbar sind. Seite 11 8. Lautsprecher am Arduino betreiben Mit dem Arduino kann man auch Töne und sogar Melodien an einem kleinen Lautsprecher abspielen. Der Lausprecher wird dabei mit einem digitalen Port und GND verbunden. Der zugehörige Befehl beim Arduino heißt tone: tone(Port, Frequenz, Dauer des Tones in ms); Der Port, an den der Lautsprecher angeschlossen wird, muss nicht extra als OUTPUT definiert werden. Auch dies erledigt der tone-Befehl. void loop() { tone(11,440,1000); delay(2000); } Port 11 wird 440 Mal pro Sekunde an und ausgeschaltet und das ganze für 1000 Millisekunden (1 Sekunde) Aufgabe 8.1: Was wirst du hören, wenn du einen Lautsprecher an Port 11 anschließt und das Programm auf den Arduino überträgst? Überlege zuerst und überprüfe anschließend deine Vermutung. Aufgabe 8.2: Schalte nacheinander verschiedene Widerstände (100 , 220 , 1 k, 10 k) in Reihe zum Lautsprecher. Was stellst du fest? Erkläre deine Beobachtung. Aufgabe 8.3: Bestimme den Hörbereich deines Ohres. Vergleiche mit deinem Nachbarn. Wie funktioniert ein Lautsprecher? Lautsprecher sind aufgebaut aus einem Permanentmagnet und einer Spule, die als Elektromagnet fungiert. Sobald durch die Spule Strom fließt, entsteht ein Magnetfeld. Dreht man die Stromflussrichtung um, so kehrt sich auch die Richtung des Magnetfeldes um. Je nach Richtung ihres Magnetfeldes wird die Spule vom Permanentmagnet entweder angezogen oder abgestoßen. Ändert man die Stromflussrichtung sehr schnell, so schwingt die Spule ständig vor und zurück. www.leifiphysik.de/themenbereiche/akustische-phaenomene/ausblick#Schallquellen Da die Spule mit einer dehnbaren Membran verbunden ist, wird die Luft vor dem Lautsprecher ebenfalls in Schwingung versetzt. Bei Schwingfrequenzen zwischen etwa 20 Hertz und 20.000 Hertz nehmen wir die Luftschwingungen mithilfe unserer Ohren als Ton wahr. Da der Arduino nur Gleichstrom ausgegeben kann, kann der Strom durch den Lautsprecher immer nur in eine Richtung fließen. Um trotzdem einen Ton zu erhalten, wird der Lautsprecher immer wieder ein- und ausgeschaltet. Weil die gedehnte Membran dann nicht mehr abgestoßen wird, bewegt sie sich von alleine in ihre Ausgangsposition zurück. Wird der Stromfluss nun schnell hintereinander an- und abgeschaltet, so bewegt sich die Membran ebenfalls schnell vor und zurück. Allerdings nicht ganz so stark, wie wenn man Wechselstrom verwendet. Der Ton ist deshalb nicht ganz so laut. Seite 12 Aufgabe 8.4: Schreibe ein Programm, ohne den tone-Befehl zu verwenden: Der Lautsprecher soll einen Ton mit 500 Hz spielen. Tipp: Du musst den Lautsprecher mit der passenden Frequenz immer wieder ein- und ausschalten. void loop() { tone(9,220,1000); delay(150); tone(9,440,1000); delay(150); tone(9,660,1000); delay(150); } Aufgabe 8.5: Was ist bei folgendem Programm zu hören? Aufgabe 8.6: (Die erforderlichen Tonfrequenzen findest du bei der Tastatur unten) a) Schreibe ein Programm, das immer den Kammerton a' (440 Hz), dann das eine Oktave höher liegende a'' abspielt und dann eine Pause macht (alles jeweils eineinhalb Sekunden). b) Programmiere ein Martinshorn. c) Programmiere das Kinderlied „Alle meine Entchen“. Frequenz: (in Hz) Ton: A H C D E F G AHC D E F G A H C D E F G A H C D E F G A H C D E F G A H C D E F G A H C D E F G A H C Frequenz: Quelle: http://www.sengpielaudio.com/Rechner-notennamen.htm Wie du sicher schon bemerkt hast, wartet das Programm nach einem tone-Befehl nicht, bis der gesamte Ton abgespielt ist, sondern bearbeitet sofort die nächste Programmzeile. Deshalb ist immer ein delayBefehl notwendig um sicherzustellen, dass ein Ton auch wirklich in der ganzen Länge abgespielt wird. Es gibt auch einen Befehl und die Tonausgabe abzuschalten: noTone(Port); Seite 13 9. Rückmeldungen an den Nutzer – Serial Monitor In verschiedenen Situationen kann es sinnvoll sein, dass der Mikrocontroller eine Rückmeldung auf einen Ausgabebildschirm gibt. Ursprünglich wurde diese Funktion für die Fehlersuche in Programmen eingesetzt: Wenn an bestimmten Stellen im Programm eine Rückmeldung einprogrammiert war, wusste man bei Erscheinen des Textes, dass das Programm bis zu dieser Stelle fehlerfrei durchgelaufen war. Der Arduino kann über den Serial Monitor Daten, die vom Arduino gesammelt oder produziert werden, anzeigen. Schließe dazu an Port 13 eine LED mit Vorwiderstand an und übernehme folgendes Programm: int i=0; void setup() { Serial.begin(9600); pinMode(13,OUTPUT); } void loop() { i=i+1; digitalWrite(13,HIGH); Serial.print(“Anzahl:”); Serial.println(i); delay(500); digitalWrite(13,LOW); delay(500); } Definiert eine Variable i als „integer“, d.h. als ganze Zahl, mit dem (momentanen) Wert 0. Legt die Übertragungsrate für den Ausgabebildschirm fest. Bei uns immer 9600 (Bit pro Sekunde). Der Text zwischen den Anführungszeichen wird auf dem Ausgabebildschirm angegeben. Der Wert der Variablen 𝑖 wird auf dem Ausgabebildschirm angegeben. In der Programmierumgebung des Arduino findest du oben rechts den Button gabebildschirm (den „Serial Monitor“) öffnen kannst. , mit dem du den Aus- Aufgabe 9.1: Notiere drei Situationen, in denen bei Verwendung des Arduinos die Ausgabe eines Anzeigetextes auf einem Bildschirm sinnvoll sein kann. Aufgabe 9.2: a) Was ist der Unterschied zwischen Serial.print(″i″); und Serial.print(i); ? b) Was ist der Unterschied zwischen Serial.print(); und Serial.println(); ? c) Was bewirkt das Programm von oben? Seite 14 Aufgabe 9.3: a) Lass einen beliebigen Text einmal auf dem Bildschirm anzeigen. b) Derselbe Text soll nun jede Sekunde noch einmal dazukommen. Aufgabe 9.4: Schreibe ein Programm, das ein Muster auf dem Ausgabebildschirm erzeugt. Beispiele: xxxxxx x x xx x x xxxxxx oder _\|/_ x x O \___/ Erfinde auch eigene Muster! Seite 15 10. Verwendung von Variablen Variablen können ein Programm vereinfachen und tragen dazu bei, die Übersicht zu behalten. Verschiedenen Anschlüssen können über Variablen konkrete Namen zugeordnet werden, sodass im späteren Programm sehr einfach mit diesen Namen gearbeitet werden kann. Wenn man später mehrere Bauteile gleichzeitig verwendet, behält man einen besseren Überblick, weil man keine Zahlen (Ports des Arduino), sondern Namen (der Bauteile) verwendet. Tipp: Es dürfen keine Umlaute oder Sonderzeichen verwendet werden. Beispiel eines Programmes mit 2 LEDs: Ohne Variablen Mit Variablen /* Abwechselndes Blinken Rote LED an Port 13, Grüne LED an Port 12 */ /* Abwechselndes Blinken Rote LED an Port 13, Grüne LED an Port 12 */ void setup() { pinMode(13, OUTPUT); pinMode(12, OUTPUT); } int ledgruen = 13; int ledrot = 12; void loop() { digitalWrite(13, digitalWrite(12, delay(1000); digitalWrite(13, digitalWrite(12, delay(1000); } HIGH); LOW); LOW); HIGH); void setup() { pinMode(ledgruen, OUTPUT); pinMode(ledrot, OUTPUT); } void loop() { digitalWrite(ledgruen, HIGH); digitalWrite(ledrot, LOW); delay(1000); digitalWrite(ledgruen, LOW); digitalWrite(ledrot, HIGH); delay(1000); } Aufgabe 10.1: Wie viele Befehle musst du jeweils umschreiben, wenn du die LEDs statt an den Ports 12 und 13 an den Ports 10 und 11 anschließen willst? Vergleiche! Aufgabe 10.2: Führe in dem Beispiel rechts oben eine zusätzliche Variable ein, mit deren Hilfe du die Blinkdauer einfacher einstellen kannst? Aufgabe 10.3: Programmiere eine Ampelschaltung mit 3 LEDs. Verwende dazu Variablen. Seite 16 11. Etwas mehr Theorie zu Variablen Prinzipiell wird in einem Mikrocontroller alles digital, das heißt mit zwei Werten (0 oder 1) verarbeitet und gespeichert. Dabei bedeutet → 1 Bit = eine 0 oder eine 1 („Informationshäppchen“ / Speicherplatz mit Eintrag 0 oder 1) → 1 Byte = 8 Bit, also 8 Plätze, auf denen 0 oder 1 gespeichert werden kann. Zahlen werden im sogenannten Zweiersystem (Binärsystem) gespeichert. Variablen sind in fast allen Programmiersprachen mit das Wichtigste überhaupt. Im Prinzip ist eine Variable ein Stück Speicherplatz, auf den über den Namen der Variable zugegriffen werden kann. Im letzten Abschnitt hast du die Variablenart „integer“ kennengelernt. Wenn in deinem Programm int x; steht, bedeutet dies: Lieber C-Compiler, reserviere mir im Speicher meines Controllers ein Stück Speicherplatz der Größe int und lass mich auf diesen Speicher über den Namen x zugreifen. „Int“ ist die Abkürzung für „integer“ und integer ist das englische Wort für „ganze Zahl“. Die Größe des für int reservierten Speicherplatzes beträgt bei unserem Arduino 16-Bit, also 2 Byte, d.h. es gibt 16 Plätze mit 0 oder 1 zum Speichern der ganzen Zahl. Der erste Platz ist für das Vorzeichen reserviert. → Variablen werden meist vor dem setup()-Teil definiert. Der Befehl dazu lautet z.B. int a; → Werte können einer Variablen mit einem Gleichzeichen zugewiesen werden, z.B. a=5; → Man kann die Variablendefinition und Wertzuweisung auch in einem Befehl machen: int a=5; Folgende Variablentypen gibt es unter anderem in der Programmiersprache C: Type Bits / Bytes Inhalt Beschreibung 0 bis 255 (0 bis 28–1) byte 8 Bit / 1 Byte natürliche Zahl int 16 Bit / 2 Bytes –32768 bis 32767 (–215 bis 215–1) long 32 Bit / 4 Bytes –2147483648 bis 2147483647 (–2 31 bis 2 31–1) ganze Zahl mit Vorzeichen float 32 Bit / 4 Bytes etwa sechs Dezimalen Genauigkeit ganze Zahl mit Vorzeichen rationale Zahl Neben den Variablen für Zahlen gibt es in der Programmiersprache auch Variablen, die sich Text merken können. Diese Variable heißt char. Ein char kann einen Buchstaben speichern. Aufgabe 11.1: a) Erkläre was der serielle Monitor anzeigt, wenn das Programm rechts abläuft. Führe das Programm an deinem Arduino erst aus, nachdem du deine Antwort notiert hast. b) Ersetze in dem Programm „int“ durch „float“ und wiederhole a). Erkläre den Unterschied! int i=2; void setup() { Serial.begin(9600); } void loop() { Serial.print(“aktueller Wert von i:”); Serial.println(i); i = i*i; delay(1000); } Seite 17 Aufgabe 11.2: Stell dir vor es gibt eine 4-Bit-Variable, die horst heißt. Mit welchen Zahlen kann horst rechnen? Aufgabe 11.3: a) Schreibe ein Programm, in dem du dir am Anfang zwei int-Variablen „a“ und „b“ und zwei floatVariablen „c“ und „d“ definierst. Weise der Variablen a eine ganze Zahl zu, der Variablen c eine Kommazahl (Punkt statt Komma verwenden!). Welche Ergebnisse gibt der Arduino auf dem Serial Monitor aus, wenn sowohl b als auch d jeweils berechnet werden durch a+c? Findest du eine Erklärung dafür? b) Was passiert, wenn eine Byte-Variable einen Wert > 255 hat? Was passiert, wenn eine Integer-Variable einen sehr großen Wert (z.B. 40 000) hat? c) Wie geht der Arduino mit negativen Zahlen um? d) Finde heraus, ob der Arduino die Punkt-vor-Strich-Regel beherrscht. Aufgabe 11.4: a) Definiere die Variablen a, b und c als byte-Variablen. Weise den Variablen a und b die Werte 3 und 4 zu und berechne c=a*b. Kompiliere das Programm und achte auf den verwendeten Speicherplatz für das Programm. b) Ändere das Programm von Teil a) so ab, dass a, b und c nun float-Variablen sind. Kompiliere das Programm erneut und achte auf den verwendeten Speicherplatz für das Programm. Was fällt dir auf? Was ist die Konsequenz daraus für einen „guten“ Programmierer? Projekt 11.5: Programmiere dir einen Noten-Rechner, der dir deine NWT-Note als Kommazahl auf dem seriellen Monitor ausgibt. Seite 18 12. endlich viele Wiederholungen: for-Schleife Du hast schon gelernt, dass alle Befehle, die innerhalb der geschweiften Klammern von void loop(){} stehen, endlos wiederholt werden. Manchmal möchte man aber, dass eine Programmschleife nur genau fünfmal abläuft und danach etwas anderes passiert. In diesem Kapitel lernst du, wie man mithilfe einer for-Schleife einen Programmteil wiederholen kann, ohne dass dieser endlos abläuft. Die for-Schleife ist deshalb eine endliche Schleife. An folgendem Beispiel soll die Bedeutung erklärt werden: Die for-Schleife besteht aus drei Teilen: int led=10; int i=1; void setup() { pinMode(led,OUTPUT); } void loop() { for( i; i<6; i=i+1) { digitalWrite(led,HIGH); delay(500); digitalWrite(led,LOW); delay(500); } } Diese Programmzeilen werden so lange wiederholt, bis die Bedingung nicht mehr erfüllt ist. Damit das Programm weiß, welche Zeilen mit der for-Schleife wiederholt werden sollen, werden diese Zeilen in eigenen geschwungenen Klammern zusammengefasst. 1. Definition der Zählvariablen: int i=1 Einmalig zu Beginn der Schleife wird festgelegt, um welchen Variablentyp es sich handelt und welchen Startwert die Zählvariable hat. Hier im Beispiel ist die Variable i vom Typ integer. Der Startwert beträgt 1. 2. Zustand/Bedingung: i<6 Bei jedem Durchgang der Schleife wird überprüft, ob die Bedingung(i <6) erfüllt ist. Wenn ja, wird die Schleife ausgeführt, wenn nein, wird sie nicht mehr ausgeführt. Hier wird die Schleife ausgeführt, solange der Wert von i kleiner als 6 ist (also für i = 1; 2; 3; 4 und 5) 3. Änderung: i=i+1 Nach jedem Durchgang wird der Wert der Zählvariable i neu festgelegt. Hier wird der Wert von i nach jedem Durchgang um 1 erhöht. Man kann die Zählvariable auch direkt im for-Befehl definieren: for(int i=1; i<6; i=i+1). Dann wird die Zählvariable nach jedem loop-Durchlauf wieder auf den alten Wert zurückgesetzt. Beachte, dass der Ausdruck i=i+1 hier keine mathematische Gleichung darstellt! Statt diesem Ausdruck kann man auch einfach i++ schreiben. Aufgabe 12.1: Was wird man beobachten, wenn man an Port 10 eine LED anschließt und anschließend das Beispielprogramm auf den Arduino überträgt? Seite 19 Aufgabe 12.2: Was wird man bei folgendem Programm beobachten, wenn an Port 1 eine LED angeschlossen ist? Überlege zunächst und probiere es anschließend aus. Aufgabe 12.3: Was zeigt der serielle Monitor bei diesem Programm an? void setup() { pinMode(1,OUTPUT); } void loop() { for(int i=15; i>1; i=i-1) { digitalWrite(1,HIGH); delay(i*100); digitalWrite(1,LOW); delay(500); } delay(5000); } void setup() { Serial.begin(9600); } void loop() { for(int u=0; u<=10; u=u+2) { Serial.print(u*5); delay(20); } } Aufgabe 12.4: Ändere das Programm so ab, dass die LED genau 10 mal im Abstand von einer Sekunde blinkt und dann für 15 Sekunden aus ist, bevor sie wieder 10 mal blinkt. Aufgabe 12.5: Was wird man beobachten, wenn man an die Ports 1 bis 4 LEDs anschließt und anschließend das Beispielprogramm auf den Arduino überträgt? void setup() { pinMode(1,OUTPUT); pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); } void loop() { for(int i=1; i<5; i++) { digitalWrite(i,HIGH); delay(500); digitalWrite(i,LOW); delay(500); } } Aufgabe 12.6: Programmiere eine auf- und absteigende Sirene, bei der die Tonhöhe mithilfe einer for-Schleife automatisch geändert wird. Tipp: Gib im tone-Befehl als Tonhöhe die Zählvariable multipliziert mit einer ganzen Zahl an, z.B. i*100. Seite 20 13. endlich viele Wiederholungen: while-Schleife Eine andere Möglichkeit einen Programmteil endlich oft zu wiederholen, bietet die while-Schleife oder die do-while-Schleife. Sie wird so oft wiederholt, solange eine bestimmte Bedingung erfüllt ist. Als Beispiel lassen wir den Arduino mithilfe des Befehls random eine Zahl „würfeln“. Sobald er eine 6 würfelt, soll er dies melden und eine Pause machen. while-Schleife: do-while-Schleife: int a; int a; void setup() { Serial.begin(9600); } void setup() { Serial.begin(9600); } void loop() { while(a != 6) // != bedeutet ungleich { a = random(1,7); delay(300); Serial.println(a); } Serial.println("Treffer!"); delay(2000); a=0; } void loop() { do { a = random(1,7); delay(300); Serial.println(a); } while(a != 6); Serial.println("Treffer!"); delay(2000); a=0; } Der Unterschied zwischen der while- und der do-while-Schleife liegt darin, dass bei der while-Schleife vor jedem Durchlauf die Bedingung geprüft wird, bei der do-while-Schleife nach jedem Durchlauf. Somit wird die do-while-Schleife auf jeden Fall mindestens ein Mal durchlaufen, auch wenn die Bedingung von Anfang an nicht erfüllt ist. Bei der while-Schleife würde in diesem Fall kein Durchlauf erfolgen und die Schleife überhaupt nicht ausgeführt werden. Aufgabe 13.1: Schreibe die Programmtexte, die zu den Aufgaben 12.2 bis 12.5 gehören, so um, dass sie eine while-Schleife anstatt einer for-Schleife enthalten. Der Arduino soll aber dasselbe Ergebnis liefern. Der random-Befehl erzeugt eine ganze Zufallszahl aus dem Zahlenbereich, der durch die zwei Argumente in der Klammern festgelegt wird. Beispiel: random(10,20) erzeugt eine ganze Zufallszahl zwischen 10 und 19. Die größtmögliche Zufallszahl ist also die zweite Zahl minus 1. Projekt 13.2: Konstruiere durch eine Schleife einen Lottozahlengenerator, der dir 6 Zufallszahlen zwischen 1 und 49 ausgibt. Seite 21 14. Dimmen einer LED - Pulsweitenmodulation Bisher hast du die Ports als digitale Ausgänge verwendet. Digitale Ports haben zwei Zustände. Aufgabe 14.1: Benenne die beiden Zustände der digitalen Ausgänge: Anweisung zum Aufrufen Bezeichnung des Zustands des Zustands Wert des elektrischen Potenzials Pulsweitenmodulation – der „analoge“ Ausgang: Der Arduino besitzt keinen analogen Ausgang an sich, der alle Spannungen zwischen 0V und 5V bereitstellt, Er liefert, wie du gerade gesehen hast entweder 0V (low) oder 5V (high). Es gibt aber dennoch die Möglichkeit das Potenzial, das ein Ausgang liefert, zu verändern. Das geschieht durch schnelles Ein- und Ausschalten (Wechsel zwischen high und low), die sogenannte Pulsweitenmodulation (PWM). Die Ports auf dem Arduino, die mit (~) versehen sind, sind in der Lage, ein PWM-Signal zu erzeugen. PWM-Ports können 256 verschiedene Zustände einnehmen. Das heißt, dass die maximale Leistung eines PWM-Ports (beginnend bei Null) in 256 Schritten erreicht wird. Aufgabe 14.2: Notiere alle PWM-Ports: ___________________________________________ Der folgende Befehl erzeugt solch ein PWM-Signal: analogWrite(pin, Wert); Der zeitliche Verlauf am Ausgang sieht bei verschiedenen Werten dann wie folgt aus: 5V Leistung PWM-Wert 25 0V 5V Leistung PWM-Wert 128 0V Leistung 5V PWM-Wert 230 0V Seite 22 Aufgabe 14.3: Teste das Programm mit verschiedenen Werten zwischen 0 und 255. Was passiert, wenn du Werte größer als 255 eingibst? int LED = 9; // PWM Port 9 für LED void setup() {} void loop() { analogWrite(LED,255); // PWM-Wert zwischen 0-255 } Hinweis: Der PWM-Port muss nicht im setup() als OUTPUT definiert werden. Aufgabe 14.4: Verwende eine Zählschleife um die Helligkeit der LED von 0 auf 255 zu steigern. Aufgabe 14.5: Kannst du die LED im Anschluss auch wieder langsam abdunkeln? Lass dir zusätzlich den PWM-Wert am seriellen Monitor anzeigen. Lass Projekt 14.6: Obwohl die LED in obigem Versuch gleichmäßig heller geschaltet wird, hat man den Eindruck, dass die Beleuchtung nicht gleichmäßig zunimmt. Dies kommt daher, dass das Auge schwaches Licht weniger intensiv wahrnimmt als helles Licht. Dieser Eindruck lässt sich verhindern, wenn man zu Beginn die Beleuchtungsstärke etwas stärker macht. Dies gelingt mit einem array, einer Art Schublade für mehrere Werte der gleichen Variablenart. Die Deklaration erfolgt mit: const int wert[5] = {23, 47, 67, 128, 255}; In wert[0] ist dann die Zahl 23 gespeichert, in wert[1] die Zahl 47 usw. Schreibe ein Programm, bei dem mit Hilfe eines 32-stelligen arrays die LED so langsam angeschaltet wird, dass der Eindruck entsteht, die LED wird gleichmäßig heller. Seite 23 15. Jetzt kommt Bewegung in die Sache! Motoren mit dem Arduino steuern Wenn wir eine Schiebetür öffnen oder schließen wollen, so muss ein Motor die Schiebetür antreiben. Mit Hilfe des Arduinos können wir einen Motor regeln, der eine Schiebetür schneller oder langsamer öffnet oder auch schließt. In Kapitel 4 haben wir bereits den Befehl digitalwrite() verwendet, mit dem man eine LED an- bzw. ausschalten kann. Ein kleiner Motor lässt sich damit auch ganz leicht ansteuern. Aufgabe 15.1: Schreibe ein Programm, das den Motor 5 Sekunden einschaltet und dann für 2 Sekunden ausschaltet. Aufgabe 15.2: Das folgende Programm steuert ebenfalls einen Motor, was passiert dabei genau. Kommentiere: int Motoranschluss1 = 2; int Motoranschluss2 = 7; void setup() { pinMode(Motoranschluss1, OUTPUT); pinMode(Motoranschluss2, OUTPUT); } void loop() { digitalWrite(Motoranschluss1, HIGH); digitalWrite(Motoranschluss2, LOW); delay(4000); digitalWrite(Motoranschluss1, LOW); digitalWrite(Motoranschluss2, HIGH); delay(4000); } // // // // // // Aufgabe 15.3: Im vorherigen Kapitel hast du gelernt, wie man eine LED heller und dunkler leuchten lassen kann. Mit dem gleichen Vorgehen lässt sich ein Motor schneller und langsamer drehen. Verändere das Programm aus Aufgabe 15.2 so, dass der Motor immer schneller wird, dann wieder langsamer wird und sobald er zum stehen kommt die Drehrichtung ändert. Sinnvoll wäre hier auch, den Bereich auszublenden, bei dem der Motor noch nicht anläuft. Seite 24 16. Der Arduino bekommt Sinne Bisher hat der Mikrocontroller immer nur etwas GETAN. Er hat die Anweisungen ausgeführt, die du ihm gegeben hast. Wenn Menschen sich so verhalten würden, wäre die Welt eintönig – wir müssten nur tun was man uns sagt und wären gleichzeitig taub, blind und gefühllos. Abhilfe: Alle Ports die du bisher als AUSGÄNGE kennengelernt hast, lassen sich auch als EINGÄNGE benutzen. Statt digitalWrite() und analogWrite() wird dazu der Begriff digitalRead() oder analogRead() benutzt. Das einzige, was ein Mikrocontroller allerdings lesen kann, sind elektrische Potenziale (siehe Kapitel 4). Aufgabe 16.1: Erinnere dich: Welche Potenziale können zu einer Spannung von 230 Volt führen? Gib drei verschiedene mögliche Kombinationen an. (Tipp: Ein bisschen gefühllos bleibt der Arduino allerdings trotzdem. Mit dem Befehl digitalRead() kann er lediglich Gib entscheiden, ob ein Eingang an ist oder aus. Alles, was über 1,4 Volt ist, wird vom Arduino als „an“, „high“ bzw. „1“ wahrgenommen, Potenziale unter 1,4V spürt er als „aus“, „low“ bzw. 0. Solch ein Mikrocontrollereingang, der nur zwei Zustände (0 oder 1) unterscheidet, heißt Digitaleingang. int Wahrnehmung; void setup() { pinMode(13, INPUT); } void loop() { Wahrnehmung = digitalRead(13); } Setzt den Modus für Port 13 auf „Eingang“ Definiert eine Variable Wahrnehmung und gibt ihr den Wert 1 oder 0 Aufgabe 16.2: Verändere das obige Programm so, dass der Wert für Wahrnehmung auf dem seriellen Monitor ausgegeben wird. Gib Aufgabe 16.3: Verbinde mit einem Kabel gezielt den Input-Pin mit unterschiedlichen Potenzialen am Arduino. Verwende auch einen PWM-Port als Ausgang und beschalte ihn mit unterschiedlichen Potenzialen (Erinnerung: variiere dazu den Wert in analogWrite(pin, Wert)). Überprüfe damit, ob die Theorie stimmt. Gib Seite 25 Damit ein digitaler Input-Pin nicht zufällig 1 oder 0 ist, muss man sicherstellen, dass er immer entweder mit hohem oder tiefem Potenzial verbunden ist. Diese Funktion liefert ein sogenannter Umschalter oder „Wechseltaster“. Der Umschalter funktioniert wie eine Weiche: Entweder ist der Mittelkontakt mit dem einen oder dem anderen Ausgang verbunden. Das zugehörige Bauteil sieht so aus Aufgabe 16.4: a) Zeichne einen Schaltplan, der Port 13 über einen Umschalter wahlweise mit 5 V oder mit 0 V verbindet. b) Baue deine Schaltung auf und nutze das Programm aus Aufgabe 16.2, um zu testen, ob die Umschaltung funktioniert. Gib Achtung: Der Umschalter muss unbedingt richtig angeschlossen sein! Wer den Wechselschalter nicht wie unten im Bild anschließt, macht den Arduino kaputt! Vor dem Stecken unbedingt nachfragen! Aufgabe 16.5: Verbinde den dreipoligen Schalter wie dargestellt mit dem Arduino. Konfiguriere z.B. Port 9 als Eingang. Definiere eine Variable und weise dieser den Wert „digitalRead(9)“ zu (welches ist die geeignetste Variablenart?). Lasse dir den Wert der Variablen auf dem seriellen Monitor anzeigen. Port 5V Seite 26 GND Bislang kann der Arduino nur zwischen zwei Zuständen (1 bzw. „an“ und 0 bzw. „aus“) unterscheiden. Das ist so, als ob du deine Umgebung nur in schwarz-weiß sehen würdest. Wenn du den Arduino mehr als nur 1 und 0 wahrnehmen lassen möchtest, hilft dir die Tatsache, dass die Ports A0 bis A5 nicht nur zwei, sondern 1024 verschiedene Potenzialwerte einlesen können. Je nachdem, welches Potenzial an den Ports anliegt, wird ein Wert zwischen 0 und 1023 ausgegeben. Die Schrittweite („Auflösung“) beträgt dabei 5V : 1023 ≈ 0,005V. Damit ergibt sich die nebenstehende Tabelle. Potenzial am Port 0V 0,005 V 0,010 V … 1,00 V … 5,00 V analoger Wert 0 1 2 … 205 … 1023 Der Bereich von 0V bis 5V wird dabei von einem Analog-Digital-Wandler in 1024 Stufen zerlegt. Man spricht von einer 10-Bit-Genauigkeit, da 210 = 1024. Die Zahlen von 0 bis 1023 lassen sich binär mit 10 Stellen schreiben (z.B. (16)10 = (10000)2 oder (56)10 = (111000)2 oder (1023)10 = (1111111111)2) int Wahrnehmung; Wichtige Infos: Für das analoge Einlesen ist keine InputDefinition nötig. Die Portnummer bezieht sich jetzt auf den analogen Port mit der Beschriftung A3. Die analogen Ports können auch als digitale Eingänge genutzt werden. Den Eingang A3 kann man mit dem Befehl digitalRead(A3) auslesen. void setup() {} void loop() { Wahrnehmung = analogRead(A3); } Aufgabe 16.7: Verändere das Programm wieder so, dass es den Wert der Wahrnehmung im seriellen Monitor ausgibt. Verbinde mit den Potenzialwerten 0 V; 3 V und 5 V und überprüfe das Ergebnis mit der obigen Tabelle. Projekt 16.8: Baue eine Schiebetür, die sich öffnet, sobald ein Taster gedrückt wird. Seite 27 17. Hell oder dunkel? Der Arduino wird zum Messgerät In modernen Häusern (oder auch bei neuen Autos) wird die Beleuchtung automatisch gesteuert. Bei Dämmerung möchte man das Licht noch nicht voll aufgedreht haben. Die Helligkeit der Beleuchtung soll stufenweise den Lichtverhältnissen draußen angepasst werden. Um den Lichteinfall zu messen verwenden wir einen lichtabhängigen Widerstand (LDR, engl. Light Dependent Resistor). Der Widerstandswert eines LDR ändert sich, je nachdem, wie viel Licht auf ihn einfällt: je mehr Licht, desto geringer der Widerstandswert. Diese Eigenschaft kann man dazu benutzen, einen LDR als Lichtsensor zu verwenden. Dazu muss man mit ihm einen sogenannten Spannungsteiler aufbauen (die genaue Erklärung des Spannungsteilers folgt im nächsten Kapitel). Unser Lichtsensor ist ein Spannungsteiler, der aus dem LDR (veränderlicher Widerstand) und einem Festwiderstand besteht. Schaltplan: Anschluss an den Arduino: Programmcode: int LDR = 1; // Sensoreingang int Helligkeit; // Wert des LDR Aufgabe 17.1 Erstelle die Schaltung und das Programm, lass dir den Helligkeitswert am seriellen Bildschirm darstellen und bestimmt folgende Widerstandswerte: void setup() { Serial.begin(9600); } Maximale Beleuchtung des Sensors (also keine Abdunklung) Minimale Beleuchtung des Sensors (volle Abdunklung mit der Hand) Hat die Wahl des Festwiderstandes Einfluss auf die Empfindlichkeit des Sensors? void loop() { Helligkeit = analogRead(LDR); Serial.println(Helligkeit); delay(200); } Seite 28 Aufgabe 17.2 Erstelle einen einfachen Helligkeitsanzeiger: Je nach Helligkeit soll ein LED schneller oder langsamer blinken. Aufgabe 17.3 Vertausche Widerstand und LDR und beschreibe deine Beobachtungen. Aufgabe 17.4 Benenne die Variablen um (LDR in Sensor, Helligkeit in Sensorwert) und speichere das Programm unter „Sensorabfrage“. So kannst du es in Zukunft als Vorlage für alle Sensorabfragen verwenden. Aufgabe 17.5 Wie funktioniert ein LDR? Was passiert auf Atomebene? Wovon hängt es ab, ob der elektrische Widerstand eines LDR groß oder klein ist? folgende Internetseite kann helfen: http://www.ulfkonrad.de/physik/geraete/ldr.htm Projekt 17.6: „Dämmerungsschaltung“ Schreibe ein Programm, welches eine LED je nach Helligkeit am LDR heller oder dunkler werden lässt. Tipp: Du musst den Messbereich des LDR (mit analogRead(A0) am seriellen Monitor anzeigen lassen!) in den Helligkeitsbereich 0 – 255 der LED umrechnen. Führe dazu eine Variable helligkeit ein, die das erledigt. void loop() { helligkeit = hier steht deine Umrechnung; analogWrite(led, helligkeit); } Projekt 17.7: „Alarmanlage“ Baue eine Durchlichtschranke, wie sie z.B. bei Geschwindigkeitskontrollen der Polizei verwendet wird. Die Lichtschranke soll einen Durchgang kontrollieren. Wird die Lichtschranke unterbrochen soll ein Alarmzeichen (blinkende rote LED) erfolgen. Bauteile 2 LED (rot und blau) 220 Widerstand 10k Widerstand LDR Seite 29 18. Spannungsteiler Oft handelt es sich bei Sensoren um Widerstände, die ihren Wert ändern, wenn sich z.B. die Temperatur oder Beleuchtungsstärke ändert. Um dies registrieren zu können, haben wir im letzten Kapitel für unseren Helligkeitssensor den LDR in einer sogenannten Spannungsteilerschaltung verwendet. Diese lernst du nun genauer kennen und verstehen. Vorüberlegung Was geschieht, wenn man einen Eingangsport sowohl an ein Potential von 5V als auch an ein Potential von 0V anschließt? Wird der Port dann HIGH der LOW sein? Wenn man einen Port ganz direkt sowohl mit 5V als auch mit 0V verbindet, erzeugt man einen Kurzschluss. Das ist keine gute Idee: Der Spannungsregler des Arduino wird überhitzen und sich hoffentlich rechtzeitig abschalten, bevor etwas kaputt geht. Interessanter wird es, wenn man die beiden Verbindungen vom Port zu 5V bzw. vom Port zu 0V jeweils mit Widerständen erzeugt (siehe Abbildung links). So entsteht kein Kurzschluss, da nur ein schwacher Strom durch die beiden Widerstände fließt. Diese Schaltung bezeichnet man als Spannungsteiler mit einem Mittelkontakt. Widerstand R1 und der Widerstand R2 teilen sich die Gesamtspannung entsprechend ihrer Anteile am Gesamtwiderstand in die Spannung U1 und U2 auf. Das Potential am Port des Arduino entspricht U2 und lässt sich aus den Widerstandswerten und der Gesamtspannung berechnen. Die Spannung lässt sich mit folgender Formel berechnen: Sind zwei Widerstände dass und in Reihe geschaltet, so teilt sich die angelegte Gesamtspannung so auf, gilt. Das Verhältnis der Spannungen und zueinander ist dasselbe, wie das Verhältnis der Widerstände Beispiel: Wenn und doppelt so groß wie zueinander: ist, so ist auch . doppelt so groß wie . Herleitung der Formel für Wir verwenden die bekannten Gesetzen für Stromkreise: Da der Stromfluss in Reihe immer gleich ist, gilt: Für Ohmsche Widerstände gilt Mit . Also auch : erhält man Seite 30 | Aufgabe 18.1: Berechne für und die zugehörigen Spannungen und . Aufgabe 18.2: Baue eine Spannungsteilerschaltung mit den Widerständen 220 Ω und 1 kΩ auf. Berechne mit Hilfe der Formel . Lass dir den Wert von mithilfe eines Analogeingangs auf dem seriellen Monitor anzeigen und vergleiche mit deinem berechneten Ergebnis. Aufgabe 18.3: Baue und programmiere ein Gerät, das bei Dunkelheit automatisch eine LED anschaltet. Bei Helligkeit soll die LED ausgeschaltet sein. Verwende hierfür eine while-Schleife. Aufgabe 18.4: Baue und programmiere ein Gerät, das Helligkeit und leichte Dämmerung durch eine grüne LED anzeigt. Deutliche Dämmerung soll durch eine gelbe LED angezeigt werden und bei Dunkelheit soll eine rote LED leuchten. Projekt 18.5: Die Schiebetür aus Projekt 16.8 soll sich öffnen, wenn eine Person vor ihr steht und sich wieder schließen, wenn diese eingetreten ist. Seite 31 19. Potentiometer An vielen elektronischen Geräten findet man Regler, an denen man drehen oder schieben kann, um beispielsweise die Lautstärke zu ändern. Dahinter stecken meist Potentiometer, kurz „Poti“ genannt. Das sind regelbare Widerstände und haben meist drei Anschlüsse. Ihr Schaltsymbol sieht entsprechend so aus: Zwischen den beiden äußeren Anschlüssen herrscht ein konstanter Widerstand (z.B. ). Über den Drehknopf kann der Widerstand zwischen dem mittleren Anschluss und den beiden äußeren Anschlüssen verändert werden. Der Gesamtwiderstand wird hierbei aufgeteilt (z.B. in und ). Das Poti besteht im Prinzip also aus zwei regelbaren Widerständen in einem Bauteil. Schaltplan Anschluss an der Arduino Aufgabe 19.1: Baue die obige Schaltung auf. Lasse dir den Wert des von dir verwendeten Analogeingangs auf dem seriellen Monitor anzeigen, wenn du an dem Potentiometer drehst (Tipp: Verwende dein Programm „Sensorabfrage“) Aufgabe 19.2: Baue in deine Sirene eine Lautstärkeregelung mit einem Potentiometer ein: oder Aufgabe 19.3: a) Verwende einen Poti, um die Blinkfrequenz einer LED zu steuern. b) Verwende einen Poti, um die Tonhöhe eines Lautsprechers zu steuern. Seite 32 20. Jetzt wird’s heiß! Der Arduino als Thermometer Im Folgenden sollst du verstehen, wie ein Digital-Thermometer funktioniert und diesen aus seinen Grundbestandteilen aufbauen und programmieren. Wir verwenden hier als Temperatursensor einen sog. NTC-Widerstand (engl. NegativeTemperatur Coeffizient). Unser NTC-Widerstand heißt NTC-0,2 10K. Ein NTC-Widerstand wird auch als Heißleiter bezeichnet, da gilt: Je größer seine Temperatur ist, desto kleiner wird sein elektrischer Widerstand und desto besser leitet er den elektrischen Strom. Der NTC wird wie der LDR in einer Spannungsteilerschaltung (siehe Kapitel 17) verwendet. Aufgabe 20.1: a) Baue die entsprechende Schaltung mit unserem NTC und einem 10k-Widerstand auf. b) Lass dir die Sensorwerte auf dem seriellen Monitor anzeigen. (Tipp: Zum Auslesen der Sensorwerte kannst du das Programm zum Helligkeitssensor verwenden) c) Messe zeitgleich mit einem Referenzthermometer die Temperatur und protokolliere drei Wertepaare (Analogwert | Referenztemperatur). d) Stelle die Wertepaare in einem Diagramm dar (x-Achse: Analogwert des Arduino; y-Achse: Referenztemperatur). Überlege dir eine Umrechnungsfunktion y = f(x). e) Der Arduino kann die Umrechnung durchführen. Wenn die Umrechnungsfunktion z.B. f(x) = x/9.0 – 19 lautet, dann sieht das Programm so aus: int Wert; double Temp; void loop() { Wert = analogRead(A0); Temp = (Wert/9.0 – 19); Serial.print(“Wert an A0: Serial.println(Wert); Serial.print(“Temperatur: Serial.println(Temp); delay(200); } ”); ”); f) Schreibe ein Programm, so dass die Temperatur in °C angezeigt wird. Seite 33 Statt der Umrechungsfunktion kann man bei linearen Zusammenhängen auch den map-Befehl verwenden: y = map(Wert, a1, a2, b1, b2) Rechnet einen Wert vom Intervall [a1;a2] in das Interval l (b1;b2] um. Beispiel: y = map(20, 0, 50, 0, 100) Die Umrechnung erfolgt linear und das Ergebnis sind immer ganzzahlige Werte (integer). Der map- Befehl ist immer dann sinnvoll, wenn Skalen ineinander umgerechnet werden müssen: Mit dem Befehl analogRead() bekommt man immer Werte zwischen 0…1023. Für analogWrite() werden Werte zwischen 0…255 benötigt: a Aufgabe 20.2: Schreibe das Programm aus Aufgabe 20.1 mithilfe des map-Befehls um. Aufgabe 20.3: Verwende den map-Befehl, um die Dämmerungsschaltung aus Projekt 17.6 ohne Umrechnungsformel zu realisieren. Seite 34 21. Die if-Bedingung Der Arduino reagiert auf seine Umwelt Den Schirm aufmachen, wenn es regnet, Trinken, wenn man Durst hat – die Welt steckt voller Reaktionen auf Bedingungen. Hier lernst du, wie man den Mikrocontroller auf Dinge von außen reagieren lässt. Bis jetzt hast du beides getrennt gelernt: wie der Arduino Ausgänge steuern und wie er Sensorwerte auslesen kann. Nun soll beides miteinander verknüpft werden. Eine Reaktion oder Entscheidung heißt in der Programmiersprache: „Bedingungsschleife“. Sie lautet allgemein: if (Bedingung ) {Reaktion} In Worten: Wenn die Bedingung in der runden Klammer erfüllt ist, werden die Befehle aus der geschweiften Klammer abgearbeitet. Das gilt auch umgekehrt: Wenn die Bedingung nicht erfüllt ist, werden die Befehle in der geschweiften Klammer ignoriert. Mit der if – Bedingung kann man den Arduino dazu bringen, eine Reaktion auszuführen, wenn eine bestimmte Bedingung erfüllt ist, z.B soll er eine LED anschalten, wenn die Helligkeit der Umgebung abnimmt. Die Bedingung wäre hierbei also, dass die Helligkeit unter einen bestimmten Wert fällt, die Reaktion wäre, die LED anzuschalten. Das Programm „wenn die Helligkeit unter 300 ist, dann schalte die LED an, ansonsten schalte sie aus“ heißt in der Sprache des Arduino: … void loop() { helligkeit = analogRead(LDR); if (helligkeit < 300) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } } Erster Teil: Bedingung (wenn / if): Zu Beginn wird geprüft, ob die Bedingung erfüllt ist. Hier ist dies der Fall, wenn der Befehl analogRead(LDR) einen Wert kleiner als 300 liefert. Zweiter Teil: Bedingung erfüllt (dann / then): Ist die Bedingung erfüllt, dann führt der Arduino das Programm in den ersten geschwungenen Klammern aus. Im Beispiel wird eine LED angeschaltet. Dritter Teil: Bedingung nicht erfüllt (ansonsten/else): Ist die Bedingung nicht erfüllt, dann führt der Arduino das Programm in den zweiten geschwungenen Klammern aus. Vor diese wird der Befehl else geschrieben. Hier im Beispiel wird die LED ausgeschaltet. Allgemein sieht eine if – Bedingung so aus: if (Bedingung) {Reaktion 1;} else {Reaktion 2;} Der Arduino kann natürlich Bedingungen nur mathematisch abfragen, indem er Variablen miteinander vergleicht. Für die Abfrage der if-Bedingung gibt es folgende logische Operatoren: < kleiner bzw. > größer <= kleiner oder gleich bzw. >= größer oder gleich == gleich bzw. != ungleich Seite 35 Aufgabe 21.1: Vervollständige das Programm von oben und erstelle die zugehörige Schaltung. Aufgabe 21.2: Verändere deine Ampelschaltung aus Aufgabe 5.1 bzw. 10.2 so, dass die Ampel bei Tagbetrieb normal funktioniert, nach Einbruch der Dunkelheit aber nur noch die gelbe LED blinkt (Nachtbetrieb). Aufgabe 21.3: Die meisten Ampeln haben auch noch eine Fußgängerampel. Erstelle eine Schaltung für eine Fußgängerampel mit „Grünanforderung“. Wenn der Fußgänger auf einen Knopf drückt, schaltet die Autofahrerampel auf rot und die Fußgängerampel auf grün. Nach 3 Sekunden schaltet die Fußgängerampel wieder auf rot und die Autos dürfen wieder fahren. Schreibe das entsprechende Programm. Aufgabe 21.4 Erkläre die einzelnen Abschnitte im folgenden Programm: int Eingang = 13; int LED = 8; void setup() { pinMode(LED, OUTPUT); pinMode(Eingang, INPUT); } void loop() { int entscheidung = digitalRead(Eingang); if (entscheidung = = 1) { digitalWrite(LED, HIGH); } else { digitalWrite(LED; LOW); } delay(10); } Aufgabe 21.5: Baue und programmiere eine „Musik-Box“. Nach einem Knopfdruck sollen zwei LEDs angehen und eine Melodie abgespielt werden. Seite 36 Wichtige Zusatzfunktionen: Mit elseif(zweite Bedingung) {noch andere Reaktion} lassen sich noch zuätzliche Bedingungen abfragen. Über die Befehle „&&“ (bedeutet „und“) bzw. „||“ (bedeutet „oder“) lassen sich darüber hinaus auch noch zwei Bedingungen in einer runden Klammer verknüpfen. Aufgabe 21.6: Stell dir vor, man müsste menschliche Reaktionen nach dem Muster des Arduino programmieren und dein „Programm“ würde so lauten. if (draußen ist es kalt && draußen regnet es) {Jacke anziehen} Was würdest du tun, wenn es regnet? Was, wenn es kalt ist? Was, wenn es kalt ist und regnet? Aufgabe 21.7: Wie sähen die drei Fälle aus, wenn dein „Programm“ so lautet: if (draußen ist es kalt || draußen regnet es) {Jacke anziehen} Aufgabe 21.8: a) Baue zwei Spannungsteilerschaltungen mit jeweils einem Schalter auf. Wenn nur Schalter 1 gedrückt ist, soll eine grüne LED leuchten, wenn nur Schalter zwei gedrückt ist, soll eine gelbe LED leuchten. Wenn beide Schalter gedrückt sind, soll einer rote LED leuchten. b) Zeichne einen passenden Schaltplan. Projekt 21.9: „Lüftungsanlage“ Baue eine Lüftungsanlage, die einen Propellor in Gang setzt, sobald es in einem Raum zu warm wird. (Hinweis: Verwende den Solarmotor mit Propellor und den NTC-Widerstand) Seite 37 Aufgabe 21.10: Für folgendes Programm sind an den Ports 4, 5, 6 und 7 jeweils eine LED und ein Vorwiderstand angeschlossen. Trage in untenstehender Tabelle ein, welche LED(s) jeweils leuchtet/n. void setup() { pinMode(1,INPUT); pinMode(2,INPUT); pinMode(3,INPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(7,OUTPUT); } void loop() { digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); if(digitalRead(1)==0||digitalRead(2)==1) { if(digitalRead(3)==0) {digitalWrite(5,HIGH);} else if(digitalRead(2)==1) {digitalWrite(6,HIGH);} } else if(digitalRead(3)==1) {digitalWrite(7,HIGH);} else {digitalWrite(4,HIGH);} delay(200); } Port 1 0 0 0 1 0 1 1 1 Port 2 0 0 1 0 1 0 1 1 Port 3 0 1 0 0 1 1 0 1 Seite 38 LED leuchtet? 22. Unterprogramme Programmieren mit Bausteinen Deine beiden Ampelprogramme aus dem letzten Kapitel sollen kombiniert werden. Die Fußgängerampel mit dem Tag-und Nachtbetrieb. int LED; int Button=6; int Buttonstate; Ganz schnell wird das Programm sehr unübersichtlich. Um es einfacher zu gestalten kann man einzelne „Programmbausteine“ (Funktionen) einsetzen. Das Blinken für den Nachtbetrieb gibt einen eigenen Programmbaustein und der Tagbetrieb einen anderen. Diese Programmbausteine werden als „void“ definiert und zwischen „void setup()“ und „void loop()“ geschrieben. Aufgerufen werden sie dann im Hauptprogramm an der Stelle, an der das Unterprogramm ausgeführt werden soll. void setup() { pinMode(3, OUTPUT); pinMode(4, OUTPUT); } Das Beispiel zeigt eine Alarmanlage. Wird ein Taster gedrückt, soll eine LED für eine Sekunde aufleuchten. Dieses Aufleuchten wird als Unterprogramm „Warnblink()“ geschrieben, der Aufruf erfolgt im Hauptprogramm (mit Strichpunkt, da es sich um eine Anweisung handelt). void Warnblink() { digitalWrite(LED, HIGH); delay(1000); digitalWrite(LED, LOW); delay(1000); } void loop() { Buttonstate=digitalRead(Button); if (Buttonstate==HIGH) { Warnblink(); } else {} } Allgemein sieht das so aus: void Unterprogramm() { Anweisung 1; } void loop() Aufgabe 22.1: Kombiniere die Programme für die Fußgängerampel (Tagbetrieb) mit dem Programm, das zwischen Tag- und Nachtbetrieb wechselt. Definiere dazu die entsprechenden Unterprogramme und kopiere die dazugehörigen Befehle hinein. { Unterprogramm(); } Unterschied zwischen „=“ und „==“ Bei der Schreibweise „A=1“ handelt es sich um eine Zuordnung: Der Variablen A wird der Zahlenwert 1 zugeordnet. Die Schreibweise „A==1“ dagegen wird oft in Bedingungsschleifen verwendet. An dieser Stelle wird überpüft, ob A den Wert 1 besitzt. Das „==“ kann deshalb mit „ist gleich?“ übersetzt werden. Seite 39 Unterprogramme für Profis Bisher stehen die Unterprogramme für sich und können nur vom Hauptprogramm aus als unveränderlicher Baustein aufgerufen werden. Es gibt allerdings auch die Möglichkeit, Werte vom Hauptprogramm in das Unterprogramm hineinzugeben. Im nebenstehenden Beispiel wird das Unterprogramm 2mal nacheinander aufgerufen. Beim ersten Mal wird die rote LED angeschaltet, beim zweiten Mal die gelbe. Außerdem wird definiert, dass das Unterprogramm einen Wert aus dem Hauptprogramm übernimmt (im ersten Fall 500, im zweiten Fall 1000) und diesen der Variable Zeit im Unterprogramm zuordnet. Aufgabe 22.2: Beschreibe genau, was das rechts dargestellte Programm macht. Aufgabe 22.3: Was macht folgendes Programm? void Licht_an(int Zeit) { digitalWrite(LED;HIGH); delay(Zeit); digitalWrite(LED;LOW); delay(2 * Zeit); } void loop() { LED=3; Licht_an(500); LED=4; Licht_an(200); } Seite 40 23. Ultraschall-Entfernungsmesser Problemstellung: Mit Hilfe des Arduino soll ein digitaler Entfernungsmesser aufgebaut werden. Die Entfernung soll auf dem seriellen Monitor angezeigt werden. Zur Verfügung stehen dir: Ein PING-Ultraschall-Sensor der Firma Parallax Lineal (1 m) Der PING-Sensor besitzt drei Anschlüsse: Zwei für die Spannungsversorgung (5V und GND = 0V) und einen für das Signal (SIG). Aufgabe des Ping))) – Sensors (Bild rechts) ist es, den Abstand zu einem Gegenstand zu bestimmen. Das Funktionsprinzip dieses Sensors ist dabei denkbar einfach: Nach dem Starten des Sensors sendet dieser ein Ultraschall-Signal aus, welches am Objekt reflektiert wird und schließlich wieder zum Sensor gelangt. Beim Aussenden des Signales schaltet der SIG-Ausgang auf HIGH, wenn das Signal wieder ankommt, geht SIG wieder auf LOW. Wenn man nun weiß, wie schnell sich der Schall ausbreitet, kann die Distanz zum Objekt sehr genau bestimmt werden! Anschluss an den Arduino: Aufgabe 23.1: Schließe den PING-Sensor an den Arduino an. Verwende den Programmcode auf der nächsten Seite. Miss anschließend die Entfernungen zu verschiedenen Objekten. Funktioniert der Ultraschallsensor auch bei durchsichtigen Materialien? In welchem Entfernungsbereich funktioniert der Ultraschallsensor zufriedenstellend? Erkennt der Sensor auch einen einzelnen Bleistift? Seite 41 Vorsicht: Achte unbedingt darauf, dass du den Ultraschallsensor richtig anschließt. Ansonsten kann er kaputt gehen! Lass deine Schaltung im Zweifelsfall nochmals durch deinen Lehrer überprüfen. Programmcode: */ Der PING-Sensor misst die Zeit, die ein reflektierter Ultraschallimpuls zum Objekt und zurück benötigt und rechnet die Zeitspanne in die Entfernung um. */ int PING = 7; long duration, cm; // zwei Variablen können in einer Zeile definiert werden void setup() { Serial.begin(9600); } void loop() { pinMode(PING, OUTPUT); digitalWrite(PING, LOW); delayMicroseconds(2); digitalWrite(PING, HIGH); delayMicroseconds(5); digitalWrite(PING, LOW); pinMode(PING, INPUT); // nun wird der PING-Port als Eingang geschaltet und gemessen, wie lange es dauert, bis das Echo ankommt dauer = pulseIn(PING, HIGH); // Zeit bis Signal zurückkehrt in s cm = 0,0343 * dauer / 2; // Zeit in Entfernung umrechnen; s = v * t // Schallgeschwindigkeit: 343 m/s = cm/s Serial.print(cm); Serial.println("cm"); delay(100); } Aufgabe 23.2: a) Erkläre die Formel zur Umrechnung Zeit Entfernung (cm = 0,0343 * dauer / 2) b) Ändere das Programm so ab, dass die Enternung in inch (1 inch = 2,54 cm) ausgegeben wird. Projekt 23.3: Bei den hier verwendeten Funktionen wurde als Schallgeschwindigkeit immer 343 m/s gewählt. Die Schallgeschwindigkeit ist jedoch abhängig von der Temperatur. Dies muss berücksichtigt werden, wenn man genauere Ergebnisse erhalten möchte. Schallgeschwindigkeit c = 331,5 + 0,6 · ϑ (c in m/s, ϑ in °C) Verbessere deine Entfernungsmessung, indem du zusätzlich einen Temperatursensor, verwendest und in einem Zwischenschritt jeweils die aktuelle Schallgeschwindigkeit berechnest. Projekt 23.4: „Blitzer“ Die Geschwindigkeit eines Fahrzeuges, das sich dem Ultraschallsensor nähert, soll bestimmt werden. Wenn das Fahrzeug eine bestimmte Geschwindigkeit überschreitet, soll eine rote LED leuchten. Seite 42 24. Reflexoptokoppler – eine besondere Lichtschranke Reflexoptokoppler können die Helligkeit von Flächen detektieren. Sie werden z.B. als Liniensensor oder Lichtschranke eingesetzt. Hier verwenden wir den Reflexoptokoppler CNY70. Generell besteht jede Jede Lichtschranke aus einem Sender und einem Empfänger. Im Reflexoptokoppler befinden sich Sender (eine Infrarot-LED als Lichtquelle) und ein Empfänger (ein Fototransistor) im gleichen Gehäuse. Das ausgesendete Licht muss also reflektiert oder zurückgestreut werden, damit es den Empfänger trifft. Dazu genügt ein helles Objekt, das sich in wenigen Millimetern Abstand vor dem Reflexoptokoppler befindet: ein (sauberer!) Finger oder ein weißes Blatt Papier. Der Sender ist eine InfrarotLED, die für das Auge unsichtbares Infrarot-Licht aussendet (blau durchscheinender Kreis) Der Empfänger ist ein sogenannter Fototransistor; je mehr Infrarot-Licht auf ihn fällt, desto geringer wird sein Widerstand (schwarzer Kreis) Aufgabe 24.1: Schließe den CNY 70 nach nebenstehendem Schaltplan an (Trick beim Einsetzen: schief einsetzen, so dass die beiden Pins, die mit GND verbunden werden sollen, in einer Reihe auf dem Board liegen – diese Reihe muss dann natürlich nur einmal mit GND verbunden werden). a) Überprüfe, ob die Infrarot-LED wirklich IRLicht aussendet. Betrachte dazu die blaue LED durch eine Handy-Kamera. b) Konfiguriere Port 2 als Input und lasse dir die Werte dieses Digitaleingangs auf dem seriellen Monitor anzeigen. Halte anschließend verschiedene Objekte vor den CNY 70. Projekt 24.2: „Alarmanlage“ Konstruiere mit Hilfe des Reflexoptokoppler eine (optische / akustische) Alarmanlage, die anschlägt, sobald etwas in die Nähe der Reflexoptokoppler kommt. Seite 43 25. Bewegungsmelder Der Arduino als „Wachhund“ Du kennst sicherlich die Bewegungsmelder, die an beinahe jedem Haus zu finden sind und dafür sorgen, dass nachts das Außenlicht eingeschaltet wird, wenn sich jemand dem Hauseingang nähert. Einen solchen Bewegungsmelder kann man mithilfe eines PIR-Sensor (Passiv-Infrarot) bauen. Er reagiert beim Eintritt einer Person in das „Blickfeld“ des Sensors. Funktionsweise Jeder Mensch strahlt aufgrund seiner Körpertemperatur Infrarotstrahlung aus, die wir jedoch mit unserem Auge nicht wahrnehmen können. Basis eines PIR-Detektors sind Lithium-Tantalatkristalle. Diese Kristalle erzeugen bei Änderung der einfallenden Strahlung, die durch eine Temperaturänderung ausgelöst wird, eine elektrische Spannung. Diese liegt im Bereich von einigen μV. Der Bewegungsmelder soll aber natürlich nicht bereits durch eine kalte Windböe ausgelöst werden. Dazu sind in jedem PIR-Sensor zwei Kristalle antiparallel geschaltet. Einer der Kristalle gibt bei Auftreffen von IRStrahlung einen positiven, der andere einen negativen Spannungsimpuls ab. Änderungen der Strahlung, die gleichzeitig und mit gleicher Intensität (z.B. durch durch eine kühle Windböe) auf beide Kristalle einwirken, lösen so keinen Erfassungsvorgang aus. Dadurch ist ein Auslösen bei Intensitätsänderungen der Strahlung durch die Umgebung weitgehend ausgeschlossen.Anders verhält es sich bei schnellen Bewegungen. Die Kristalle geben, entsprechend der Bewegung und der dadurch hervorgerufenen Strahlungsänderung, ihre Impulse zeitversetzt ab. Dieses elektrische Ausgangssignal wird verstärkt und führt zu einem Wechsel der Ausgangsspannung von 0V auf 5V. Wird ein PIR an einen digitalen Eingang angeschlossen, so wechselt bei schnellen räumlichen Änderungen der IR-Strahlung das Signal von LOW auf HIGH. Anschluss laut Beschriftung auf der Unterseite des PIR-Sensor): links 5V; mitte Port 2; rechts GND int PIR = 2; void setup() { pinMode(PIR, INPUT); } void loop() { int Wert = digitalRead(PIR); if(Wert == HIGH) { Reaktion } } Aufgabe 25.1: a) Schließe den PIR an den Arduino an und lass dir die Werte des Ports 2 auf dem Monitor anzeigen. b) Experimentiere: Welche Bewegungen erkennt der PIR-Sensor, welche nicht? c) Überprüfe, ob der PIR auch auf die Bewegung von Nicht-Lebewesen (z.B. langer Stab) reagiert. Aufgabe 25.2: Baue und programmiere mithilfe eines PIR-Sensors eine (akustische / optische) Alarmanlage. Seite 44 26. LC-Display Wenn man ein Programm auf den Arduino übertragen hat, kann man den Arduino anschließend vom Computer trennen und ihn mithilfe einer externen Spannugnsquelle (z.B. einer 9V-Blockbatterie) betreiben. Leider steht dann aber natürlich der serielle Monitor nicht mehr zur Verfügung. Um dennoch Rückmeldungen vom Arduino empfangen zu können, kann man ein LC-Display (kurz: LCD; engl. Liquid Crystal Display) verwenden. Wir verwenden ein Display mit, das in zwei Zeilen jeweils 16 Zeichen darstellen kann. Hier lernst du, wie man ein solches Display am Arduino betreibt: Achtung: Falsches Anschließen kann das Display zerstören. Lass deine Schaltung vom Lehrer überprüfen. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Vss -> GND Vdd -> +5V V0 (Kontrast) -> Mittelkontakt Drehpoti RS ( Befehle/Daten) -> Digital 12 R/W (Read/Write) -> Digital 11 E (Enable) -> Digital 10 D0 (Datenbit 0) D1 (Datenbit 1) D2 (Datenbit 2) D3 (Datenbit 3) D4 (Datenbit 4) -> Digital 7 D5 (Datenbit 5) -> Digital 6 D6 (Datenbit 6) -> Digital 5 D7 (Datenbit 7) -> Digital 4 A (Beleuchtung) -> über Vorwiderstand an +5V K (Beleuchtung) -> GND Drehpotentiometer rechts -> +5V Drehpotentiometer links -> Ground Wenn alles verbunden wurde und der Strom eingeschaltet ist, sollten weiße Balken auf blauem Hintergrund angezeigt werden. Erscheint trotz korrektem Anschluss nichts, so kann das am Kontrast des LCD-Displays liegen. Die Balken werden dann zwar angezeigt, sind aber nicht sichtbar, weil der Kontrast zu hoch ist. Abhilfe schafft es hier, wenn man die Spannung am Schleifer des Potis nachmisst und in Richtung 0V verstellt. Zwischen 1V und 0V hat man den optimalen Kontrast so dass die Balken gut sichtbar sein sollten. Programmcode: #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 10, 7, 6, 5, 4); // Hier die Ports angeben an denen // das Display angeschlossen wurde void setup() { lcd.begin(16, 2); // Art des Displays lcd.print("Hallo Welt"); // hier können auch Messwerte ausgegeben werden } void loop() { lcd.setCursor(0, 1); lcd.print(millis()/1000); } Seite 45 27. Servo-Motor für genaue Drehwinkel Im Modellbau und bei Robotern werden oft sog. Servo-Motoren verwendet. Diese werden mit PWM-Signalen gesteuert. Servos haben drei Anschlüsse. Es gibt zwei Arten von Servos: - solche, die je nach PWM-Wert einen bestimmten Winkel drehen und stehen bleiben. - solche, die sich je nach PWM-Wert schneller oder langsamer drehen (360°-Servos). Hier lernst du, wie man mit einem Servo-Motor einen bestimmten Winkel zwischen 0° und 180° ansteuert. Die „Servo-Library“ macht dies sehr einfach: #include <Servo.h> Servo servo1; void setup() { servo1.attach(Port); } void loop() { servo1.write(GRAD); } rot = 5V schwarz = GND gelb = PPM-Signal // stellt die Befehle aus der „Servo-Library“ bereit // benennt den Servo als servo1 // als Anschluss-Ports sind nur PWM-Ports möglich // Steuerwert: 0 GRAD 180 Vorsicht: Achte unbedingt darauf, dass du den Servo-Motor richtig anschließt. Ansonsten kann er kaputt gehen! Lass deine Schaltung im Zweifelsfall nochmals durch deinen Lehrer überprüfen. Aufgabe 27.1 Baue die Schaltung auf. Lass den Servo verschiedene Winkel anfahren. Aufgabe 27.1 a) Steuere den Servo mithilfe eines Potis. (Hinweis: Verwende den map-Befehl aus Kapitel 20) b) Baue mit einem Servo ein Zeigerinstrument, das die Helligkeit einer LED anzeigt. Seite 46 28. Motortreiber Bislang haben wir einen Solarmotor und einen Servomotor zum Laufen gebracht. Diese Motoren laufen bei geringer Stromstärke. Der Arduino liefert allerdings eine Stromstärke von maximal 40 mA – für einen ordentlichen Motor, mit dem man beispielsweise einen Roboter bauen oder ein Fahrzeug antreiben kann, ist das viel zu wenig. Deshalb benutzt man einen zusätzlichen Chip (einen sog. IC, engl: integrated curcuit), einen sogenannten Motortreiber. Der Motortreiber, den wir benutzen, heißt L293D. An ihn können bis zu zwei Motoren angeschlossen werden, die sich jeweils vor- und rückwärts drehen lassen. Funktion des L293D Pinbelegung L293D 4, 5, 12, 13 16 1 und 9 8 3 und 6 11 und 14 2 und 7 10 und 15 Bedeutung Erdung (0V) Energieversorgung des IC (5V) Enable-Pin des IC. Ist dieser mit 5V verbunden, sind die Motor-Pins 3 und 6 bzw. 11 und 14 aktiv. Energieversorgung des Motors (5V) Anschluss Motor 1 Anschluss Motor 2 Steuerung der Drehrichtung des Motors 1: Pin2: HIGH Pin7: LOW Motor dreht sich Pin2: LOW Pin7: LOW Motor dreht sich nicht Pin2: LOW Pin7: HIGH Motor dreht sich umgekehrt Pin2: HIGH Pin7: HIGH Motor dreht sich nicht Steuerung der Drehrichtung des Motors 2 (analog zu den Pins 2 und 7 von Motor 1) Aufgabe 28.1: Baue die Schaltung wie in der folgenden Abbildung auf. a) Schreibe ein Programm, das den Port zur Aktivierung des ICs (hier Port 9) auf HIGH setzt und einen der Ports zur Steuerung der Drehrichtung (hier Port 5 und 6) auf HIGH und den anderen auf LOW. Der Motor sollte sich jetzt in eine Richtung drehen. b) Vertausche die Zustände der beiden Steuerungs-Ports (high ↔ low). Der Motor sollte sich jetzt in die andere Richtung drehen. Seite 47 Kerbe Aufgabe 28.2: a) Schreibe ein Programm, dass sich der Motor sekundenweise abwechselnd in die eine und die andere Richtung dreht. b) Schreibe ein Programm, dass sich der Motor 3 mal hintereinander (Befehl: for) jeweils 2 Sekunden in eine Richtung und nach einer Pause von 1 Sekunde 2 Sekunden in die andere Richtung dreht. c) Schließe einen zweiten Motor an das IC an. Schreibe ein Programm, dass sich die Motoren zunächst in die gleiche Richtung, in die umgekehrte Richtung und anschließend in verschiedene Richtungen drehen. (Pause 1 Sekunde) Erzeuge eine Ausgabe auf dem seriellen Monitor, die über die Drehrichtung der einzelnen Motoren informiert. Aufgabe 28.3: a) Schreibe für das Vorwärts- und Rückwärtsdrehen ein Unterprogramm. Es soll den Namen „Motor“ haben und als Argumente die Zustände (1 bzw. 0 für HIGH bzw. LOW) der drei Ports haben. Insgesamt also drei Variablen. Anstatt „HIGH“ oder „LOW“ kannst du im Befehl „digitalWrite“ auch die Zahl „1“ für „HIGH“ und „0“ für „LOW“ schreiben. Das vereinfacht deine Funktion sehr. b) Schreibe mithilfe des Unterprogramms ein Programm, das den Motor 1 Sekunde vorwärts, ½ Sekunde rückwärts laufen lässt und ihn dann für zwei Sekunden stoppt. Aufgabe 28.4: Um die Geschwindigkeit des Motors zu steuern, kann man den „enable Pin“ 1 (bzw. bei Verwendung von zwei Motoren zusätzlich Port 9) des L293D an einen PWM-Ausgang des Arduino anschließen. Damit lässt sich die Leistung des L293D drosseln, indem man ihn z.B. nur 50% der Zeit aktiviert. a) Lass deinen Motor langsamer als im bisherigen „Normalbetrieb“ laufen. b) Lass deinen Motor aus dem Stand bis zur maximalen Drehzahl anfahren. Drossle anschließend die Drehzahl wieder bis zum Stillstand des Motors. c) Regle die Geschwindigkeit des Motors mit Hilfe eines Potis. Erzeuge eine Ausgabe auf dem seriellen Monitor, die die Leistung der Motoren in Prozent angibt. Projekt 28.5: „Line-Follower“ Konstruiere ein Fahrzeug, das entlang einer schwarzen Linie fährt. (Reflexoptokoppler verwenden) Seite 48 29. Anhang A Verwendete Bauteile Bauteil Abbildung Funktion Preis (Firma) Arduino Uno Mikrocontroller 20-25 € (Elmicro/Watterott) Breadboard Shield Aufsatz mit Steckplatine 14 € (Elmicro/Sparkfun) LED 3 mm Leuchtdioden (LED) 0,08 – 0,2 € (Conrad) 100 , 220, 1 k, 10k elektr. Widerstand 0,1 – 0,2 € (Conrad) Kabel Verbindungskabel 6 € / 10 Stk. (Conrad) BL 45 Lautsprecher 1 € (Reichelt) RK09K111-LIN10K Potentiometer 1 € (Reichelt) TASTER 3301 Drucktaster 0,1 € (Reichelt) LDR Fotowiderstand 2 € (Reichelt) RF 300 Solarmotor mit Propeller 3 € (Solexpert) Modelcraft RS 2 JR Servomotor 6 € (Conrad) CNY 70 Reflexlichtschranke 1 € (Reichelt) KTY 81-110 NTC-Temperatursensor 1 € (Reichelt) Parallax PING))) Ultraschallsensor 25 € (Reichelt) PIR-Sensor Bewegungsmelder 10 € (Adafruit) L293D Motortreiber 5 € (Conrad) HD44780 1602 LCD LCD Display 4 € (Amazon) Summe ca. 100 € (pro Set) Seite 49 30. Anhang B Installation der Arduino-Software sowie des Treibers Download Die Software kann unter folgendem LINK als zip-Datei herunter geladen werden: http://arduino.cc/en/Main/Software Download Die Dateien und Verzeichnisse werden nach c:\programme\arduino entpackt. Das Verzeichnis muss evtl. neu erstellt werden. Die entpackten Dateien der Arduino-Version 1.0.5 sieht man rechts. Am besten erstellt man nun eine Verknüpfung der Anwendung arduino auf den Desktop. Beim erstmaligen Anschließen des Boards öffnet sich evtl. der Assistent zur Hardware. Die Installation erfolgt jedoch automatisch. Ab Arduino UNO sind keine Treiber mehr erforderlich! Im Ordner libraries findet man die „Bedienungsanleitungen“ für den Arduino, auf die man bei der Programmierung zurückgreifen kann. Hier wird nichts verändert! Seite 50 Um den Arduino verwenden zu können, muss der PC wissen, an welchen USB-Eingang der Arduino angeschlossen ist. Den richtigen COM-Port findet man unter Windows im Gerätemanager. Dieser wird folgendermaßen aufgerufen: Windows-Taste Rechte Maustaste auf Computer Verwalten Unter Anschlüsse (COM & LPT) findet man den Eintrag Arduino UNO (COMx) Das x entspricht dann dem verwendeten COM-Port! Einstellen des richtigen COM-Ports in der Arduino Software In der Menuleiste unter Tools wählt man im Menupunkt Serialports die entsprechende Schnittstelle aus: Man findet anschließend den eingestellten COM-Port im Arduino-Programm-Fenster rechts unten! Einstellen des richtigen Arduino Boards In der Menuleiste Tools wählt man das entsprechende Board (hier: Arduino UNO) aus. Der Arbeit mit dem Arduino steht nun nichts mehr im Wege! Seite 51