Arduino Einführung - Hochschule Niederrhein
Transcription
Arduino Einführung - Hochschule Niederrhein
Einführung in die Arduino-Programmierung Hochschule Niederrhein University of Applied Sciences Elektrotechnik und Informatik Faculty of Electrical Engineering and Computer Science 1. Blinkende Leuchtdiode (LED) In diesem ersten Versuch werden wir ein Progamm schreiben, dass eine Leuchtdiode zum Blinken bringt. Machen Sie sich mit den zur Verfügung gestellten Bauteilen vertraut und bauen Sie die Schaltung nach Abbildung 1.1 auf. Wenn Sie sich unsicher sind fragen Sie einen der anwesenden Betreuer um Rat. Abbildung 1.1.: Schaltplan für die Ansteuerung einer LED Zum Verbinden der Bauteile nutzen Sie sogenannte Jumper Kabel (oder auch Steckbrücken genannt). Die Farben können dem Entwickler bei der Orientierung helfen und sollten wenn möglich wie gezeichnet verwendet werden. Die Farbe hat allerdings keinen Einfluss auf elektrische Eigenschaften. Der verwendete Widerstand hat einen Wert von 330 Ω und dient als Vorwiderstand zur Begrenzung des Stroms. Diesen Widerstand wegzulassen könnte sowohl die LED als auch den Arduino beschädigen. Die Einbaurichtung ist beliebig. Kaltenecker, Kremer, Radmacher, Toszkowski 2 1. Blinkende Leuchtdiode (LED) Wie Sie aus dem Lötworkshop möglicherweise bereits wissen, ist bei der LED auf die richtige Polarität zu achten. Das kürzere Beinchen und die flache Kante zeigen den negativen Pol der LED an. Flache Kante Kurzes Bein Nun werden wir gemeinsam den Arduino programmieren. Die Bedienung der Arduino IDE1 wird auf den Bildschirmen und/oder auf dem Beamer vom Dozenten gezeigt. Beachten Sie inbesondere die Einstellungen für die Platine (Menü Werkzeuge - Platine - „Arduino Uno“) und die Auswahl des richtigen COM-Ports (Menü Werkzeuge - Port). Folgendes Programm wird erstellt: /* Blink: Eine Leuchtdiode wird periodisch ein- und ausgeschaltet. */ int gruen = 3; // Port der gruenen LED definieren void setup() { // Funktion setup() wird 1x am Anfang ausgeführt pinMode(gruen, OUTPUT); // Port 3 wird zum Ausgang definiert } void loop() { // Funktion loop() wird ständig wiederholt digitalWrite(gruen, HIGH); // Port 3 wird auf 5V geschaltet delay(1000); // eine Sekunde warten (1000 ms = 1 s) digitalWrite(gruen, LOW); // Port 3 wird auf 0V geschaltet delay(1000); // eine Sekunde warten } Nach Eingabe des Programms können Sie es durch einen Klick auf die Schaltfläche „Hochladen“ (der Pfeil →) auf den Arduino überspielen2 . 1 2 IDE: Integrated Development Environment (zu deutsch: Integrierte Entwicklungsumgebung) Falls Sie einen USB-Adapter ohne separate Resetleitung verwenden, so müssen Sie zu Beginn 3 Arduino Einführung 1. Blinkende Leuchtdiode (LED) Nach dem erfolgreichen Upload sollte die LED im Sekundentakt umschalten. Sollte dies nicht funktionieren, so sprechen Sie bitten einen Betreuer an. Aufgaben • Ändern Sie in Ihrem Programm die Blinkfrequenz. Testen Sie, ob es möglich ist den Zustand (High/Low) zu schnell zu wechseln, dass dies mit dem bloßen Auge nicht mehr sichtbar ist. • Erweitern Sie Ihre Schaltung um eine gelbe und eine rote LED. Lassen Sie diese wie bei einer Ampel abwechselnd leuchten. Nutzen Sie für die rote LED Port 6 und für die gelbe LED Port 5 wie in Abbildung 1.2 gezeigt. Abbildung 1.2.: Schaltplan mit drei LEDs des Hochladevorgangs den Resettaster auf dem Arduino gedrückt halten. Im Normalfall sollte dies nicht erforderlich sein. Den richtigen Zeitpunkt zum Loslassen zu treffen erfordert etwas Übung. Schalten Sie in der Arduino IDE unter „Voreinstellungen“ die „Ausführliche Ausgabe“ für Kompilierung ein, um die internen Vorgänge besser zu sehen. 4 Arduino Einführung 2. Analoge Sensorwerte In diesem Versuch werden wir Sensorwerte einlesen und über die serielle Schnittstelle auf dem PC darstellen. Lassen Sie die drei LEDs aus dem vorherigen Teil gesteckt und ergänzen Sie die Schaltung entsprechend Abbildung 2.1. Abbildung 2.1.: Schaltbild LEDs und Potentiometer Das neue Bauteil ist ein sogenanntes Potentiometer. Ein „Poti“ ist ein variabler Widerstand, dessen Widerstandswert sich durch drehen von 0 Ω bis zum Maximalwert (hier: 10 kΩ) einstellen lässt. Angeschlossen wird das Potentiometer an einen der 6 analogen Eingänge des Arduino. Das Potentiometer steht beispielhaft für verschiedene Sensoren (Licht, Temperatur, Lautstärke, ...). Mit dem folgenden Programm können Sie den Sensor auslesen: Kaltenecker, Kremer, Radmacher, Toszkowski 5 2. Analoge Sensorwerte /* Potentiometer */ int int int int gruen = 3; gelb = 5; rot = 6; sensorwert = 0; void setup() { pinMode(gruen, OUTPUT); pinMode(gelb, OUTPUT); pinMode(rot, OUTPUT); Serial.begin(9600); } void loop() { sensorwert = analogRead(A0); Serial.println(sensorwert); delay(1); } Nach dem Upload des Programms auf den Arduino passiert zunächst einmal nichts. Damit man sich die Werte ansehen kann, öffnet man unter dem Menüpunkt „Werkzeuge“ den „Serial Monitor“. Jetzt sollten kontinuierlich Werte angezeigt werden. Da der Mikrocontroller über einen 10 Bit Analog/Digital-Wandler verfügt werden Sie Werte zwischen 0 und 1023 (210 = 1024) beobachten. Aufgaben • Erweitern Sie das Programm derart, dass mit dem Potentiometer die Blinkfrequenz einer oder mehrerer LEDs eingestellt werden kann. Ergänzen Sie das obige Programm dazu um die Ansteuerung der LEDs aus dem ersten Versuch. • Alternativ können Sie den Sensorwert auch nutzen, um einzustellen, welche LED aktiv sein soll. Im unteren Drittel des Wertebereichs leuchtet beispielsweise die rote LED, im mittleren die gelbe LED und im oberen die grüne LED. 6 Arduino Einführung 2. Analoge Sensorwerte 0 341 682 1023 Abbildung 2.2.: Einteilung des Wertebereichs Das Codegerüst für eine dafür nötige Bedingung (if/else) sieht so aus: if (sensorwert >= 0 && sensorwert < 341) { digitalWrite(gruen, HIGH); digitalWrite(gelb, LOW); digitalWrite(rot, LOW); } ... 7 Arduino Einführung 3. Ultraschallentfernungsmessung In diesem Versuch werden wir einen weiteren Sensor kennenlernen. Der HC-SR04 ist ein Ultraschallsensormodul, dass man sehr günstig (ca. 3 €) im Internet erwerben kann. Mit ihm lässt sich die Laufzeit eines kurzen Schallimpulses bestimmen. Dies kann man dann leicht verwenden, um den Abstand des Moduls zum nächsten Hindernis zu berechnen. Diese Technik wird in der Praxis häufig eingesetzt. Beispielsweise funktionieren viele Rückfahrt-Abstandswarnsysteme in Autos nach diesem Prinzip. Zunächst verkabeln wir das Modul wie in Abbildung 3.1 gezeigt. Die bestehende Schaltung für die LEDs aus den vorherigen Versuchen bleibt zusätzlich bestehen. Abbildung 3.1.: Schaltplan Ultraschallsensor und LEDs Lassen Sie Ihren Aufbau anschließend von einem Betreuer prüfen. Jetzt werden wir in der Arduino IDE ein Programm schreiben, dass uns die Entfernungswerte auf den PC Bildschirm ausgibt. Wie Sie sehen ist dieses Programm bereits geringfügig umfangreicher als die letzten Programme. Kaltenecker, Kremer, Radmacher, Toszkowski 8 3. Ultraschallentfernungsmessung /* Ultraschall: Ein Ultraschallsensor liefert Werte zum PC.*/ int echoPin = 4; // Echo Pin int trigPin = 2; // Trigger Pin long laufzeit, entfernung; void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { digitalWrite(trigPin, LOW); // Trigger delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); laufzeit = pulseIn(echoPin, HIGH); entfernung = laufzeit*0.017; // Berechnung der Distanz in cm. Serial.println(entfernung); delay(50); // 50 ms warten } Aufgaben • Halten Sie testweise Ihre Hand und andere Objekte in verschiedenen Entfernungen vor den Sensor, die Werte auf dem Bildschirm sollten entsprechend variieren. • Stellen Sie das Messergebniss mittels LED(s) grafisch dar. Realisieren Sie dazu einen Schwellwertschalter, indem Sie eine LED leuchten lassen sofern der aktuelle Wert kleiner 30 cm beträgt. Nutzen Sie dafür wieder eine Bedingung (if/else). • (optional:) Stellen Sie den Sensorwert mit den drei LEDs dar, wobei jede Farbe eine unterschiedliche Entfernung signalisiert (z.B. Rot - nah). 9 Arduino Einführung 4. Liquid Crystal Display (LCD) Als nächstes widmen wir uns der Darstellung auf LC Displays, wie sie in vielen Geräten zu finden sind. Zur Verfügung steht ein einfaches Modul mit zwei Zeilen und 16 Zeichen pro Zeile. Der verbaute Controller ist kompatibel zum bekannten Hitachi HD44780. Zunächst verbinden Sie das Display bitte wie in Abbildung 4.1 gezeigt mit dem Arduino. Abbildung 4.1.: Schaltplan LCD Das eingezeichnete Potentiometer (10 kΩ) dient als einstellbarer Spannungsteiler. Durch Drehen lässt sich so der Kontrast des LCD verändern. Lassen Sie Ihren Aufbau von einem Betreuer prüfen. Anschließend geben Sie das folgende Programm ein: Kaltenecker, Kremer, Radmacher, Toszkowski 10 4. Liquid Crystal Display (LCD) /* LCDtest: Gebe „Hello World!“ auf einem LCD aus.*/ #include <LiquidCrystal.h> // Einbinden der Bibliothek LiquidCrystal lcd(8, 9, 10, 11, 12, 13); // Pins definieren void setup() { lcd.begin(16, 2); // Anzahl Spalten und Zeilen lcd.print("Hello World!"); // Ausgabe } void loop() { lcd.setCursor(0, 1); // Cursor auf 1. Zeichen in der // 2. Zeile setzen lcd.print(millis()/1000); // Ausgabe der Sekunden // seit dem letzten Reset } Auf dem Display sollte nun der Schriftzug „Hello World!“ in der ersten Zeile und eine sich ändernde Sekundenanzeige sichtbar sein. Aufgaben • Modifizieren Sie das Programm, sodass es Ihren Namen oder einen anderen Text ausgibt. • (optional:) Öffnen Sie Ihr Programm zu Entfernungsmessung aus der vorherigen Aufgabe und ergänzen Sie es so, dass die Messergebnisse auf dem LCD ausgegeben werden. Sie können in der ersten Zeile den Zahlenwert als Text ausgeben (z.B. „Distanz: 40 cm“) und in der zweiten Zeile proportional zur Entfernung schwarze Zeichen auf dem Display darstellen. Falls erforderlich können Sie mit dem Befehl lcd.clear(); die vorherigen Werte auf dem Display löschen. Ein Zeichen mit allen Pixeln aktiviert erhalten Sie beispielsweise mit dem Befehl lcd.print("\377");. 11 Arduino Einführung 4. Liquid Crystal Display (LCD) Exkurs Im HD44780 sind bereits viele Zeichen vorgesehen. Eine kurze Suche im Internet fördert den Zeichensatz zutage. Für besondere Anwendungen ist es zusätzlich auch möglich bis zu 8 eigene Zeichen zu definieren. Die Zeichen haben dabei eine Größe von 5x8 Pixeln. Im folgenden ist der Beispielcode für ein Smiley abgebildet. #include <LiquidCrystal.h> LiquidCrystal lcd(8, 9, 10, 11, 12, 13); byte smiley[8] = { B00000, B10001, B00000, B00000, B10001, B01110, B00000, }; void setup() { lcd.createChar(0, smiley); lcd.begin(16, 2); lcd.write(byte(0)); } void loop() { } Definieren Sie sich doch ein individuelles Zeichen indem Sie den Programmcode entsprechend ändern. 12 Arduino Einführung Weiterführende Informationen Dieser Workshop dient als erster Einstieg in die Arduino-Welt. Wenn Sie sich in einem ähnlichen Stil weiter mit Arduinos beschäftigen möchten, so finden Sie im Internet viele ausführliche Tutorials, beispielsweise bei Adafruit (https://learn.adafruit.com) oder SparkFun (https://learn.sparkfun.com). Auch in der Bibliothek gibt es das Buch „Arduino Workshops“ von John Boxall. Eine wichtige Anlaufstelle für weitergehende Schritte ist natürlich auch die offizielle Seite http://www.arduino.cc. Dort kann man die Entwicklungsumgebung herunterladen und findet auch viel Dokumentation. Leider können wir Ihnen aus Kostengründen die hier verwendeten Komponenten nicht zur Verfügung stellen. Eine Liste der Bauteile mit Bezugsquellen finden Sie hier: http://makerspace.hsnr.de/wiki/index.php/Workshop_2 Für eigene Experimente gut geeignet sind Arduino Starter-Kits die man im OnlineVersandhandel beziehen kann. Diese beinhalten für einen Preis von 30-50 € meist ein Steckboard mit Kabeln sowie eine Sammlung von Sensoren und Aktoren. Kaltenecker, Kremer, Radmacher, Toszkowski 13 Bitwise Operators & (bitwise and) ^ (bitwise xor) << (shift left) | (bitwise or) ~ (bitwise not) >> (shift right) Compound Operators ++ (increment) -- (decrement) += (compound addition) -= (compound substraction) *= (compound multiplication) /= (compound division) &= (compound bitwise and) |= (compound bitwise or) General Operators = (assignment operator) + (add) - (subtract) * (multiply) / (divide) % (modulo) == (equal to) != (not equal to) < (less than) > (greater than) <= (less than or equal to) >= (greater than or equal to) && (and) || (or) ! (not) (persists between calls) (in RAM (nice for ISR)) (make read only) (in flash) Qualifiers static volatile const PROGMEM Arrays int myInts[6]; // array of 6 ints int myPins[]={2, 4, 8, 3, 6}; int mySensVals[6]={2, 4, -8, 3, 2}; myInts[0]=42; // assigning first // index of myInts myInts[6]=12; // ERROR! Indexes // are 0 though 5 (0, 1, true, false) (e.g. 'a' -128 to 127) (-32768 to 32767) (-2147483648 to 2147483647) char (0 to 255) (0 to 255) int (0 to 65535) (0 to 65535) long (0 to 4294967295) (-3.4028e+38 to 3.4028e+38) (currently same as float) Data types void boolean char int long unsigned byte unsigned word unsigned float double Strings char S1[8] = {'A','r','d','u','i','n','o'}; // unterminated string; may crash char S2[8] = {'A','r','d','u','i','n','o','\0'}; // includes \0 null termination char S3[]="Arduino"; char S4[8]="Arduino"; Pointer Access & (reference: get a pointer) * (dereference: follow a pointer) Constants HIGH | LOW INPUT | OUTPUT true | false 143 (Decimal) 0173 (Octal - base 8) 0b11011111 (Binary) 0x7B (Hexadecimal - base 16) 7U (force unsigned) 10L (force long) 15UL (force long unsigned) 10.0 (force floating point) 2.4e5 (2.4*10^5 = 240000) Variables, Arrays, and Data Control Structures if (x < 5) { ... } else { ... } while (x < 5) { ... } do { ... } while ( x < 5); for (int i = 0; i < 10; i++) { ... } break; // exit a loop immediately continue; // go to next iteration switch (myVar) { case 1: ... break; case 2: ... break; default: ... } return x; // just return; for voids Basic Program Structure void setup() { // runs once when sketch starts } void loop() { // runs repeatedly } DC in sugg. 7-12V limit 6-20V RESET Time unsigned long millis() // overflows at 50 days unsigned long micros() // overflows at 70 minutes delay(msec) delayMicroseconds(usec) Advanced I/O tone(pin, freqhz) tone(pin, freqhz, duration_ms) noTone(pin) shiftOut(dataPin, clockPin, [MSBFIRST,LSBFIRST], value) unsigned long pulseIn(pin, [HIGH,LOW]) Digital I/O (pins: 0-13 A0-A5) pinMode(pin,[INPUT, OUTPUT]) int digitalread(pin) digitalWrite(pin, value) // Write HIGH to an input to // enable pull-up resistors Analog In (pins: 0-5) int analogRead(pin) analogReference( [DEFAULT, INTERNAL, EXTERNAL]) PWM Out (pins: 3 5 6 9 10 11) analogWrite(pin, value) Pin Input/Output TX RX L DIGITAL (PWM~) External Interrupts attachInterrupt(interrupt, func, [LOW, CHANGE, RISING, FALLING]) detachInterrupt(interrupt) interrupts() noInterrupts() Type Conversions char() byte() int() word() long() float() Bits and Bytes lowByte(x) highByte(x) bitRead(x, bitn) bitWrite(x, bitn, bit) bitSet(x, bitn) bitClear(x, bitn) bit(bitn) // bitn: 0=LSB 7=MSB Random Numbers randomSeed(seed) // long or int long random(max) long random(min, max) Math min(x, y) max(x, y) abs(x) sin(rad) cos(rad) tan(rad) sqrt(x) pow(base, exponent) constrain(x, minval, maxval) map(val, fromL, fromH, toL, toH) 1 POWER ANALOG IN ATmega382: 16MHz, 32KB Flash (prog.), 2KB SRAM, 1KB EEPROM ICSP ON WWW.ARDUINO.CC - Made in Italy ARDUINO UNO Adapted from: - Original by Gavin Smith - SVG version by Frederic Dufourg - Arduino board drawing original by Fritzing.org by Mark Liffiton Wire (I²C comm.) (#include <Wire.h>) // join a master begin() begin(addr) // join a slave @ addr requestFrom(address, count) beginTransmission(addr) // Step 1 send(myByte) // Step 2 send(char * mystring) send(byte * data, size) endTransmission() // Step 3 int available() // #bytes available byte receive() // get next byte onReceive(handler) onRequest(handler) Servo (#include <Servo.h>) attach(pin, [min_uS, max_uS]) write(angle) // 0 to 180 writeMicroseconds(uS) // 1000-2000; 1500 is midpoint int read() // 0 to 180 bool attached() detach() EEPROM (#include <EEPROM.h>) byte read(intAddr) write(intAddr, myByte) SoftwareSerial (serial comm. on any pins) (#include <softwareSerial.h>) SoftwareSerial(rxPin, txPin) begin(long Speed) // up to 115200 listen() // Only 1 can listen isListening() // at a time. read, peek, print, println, write // all like in Serial library Serial (communicate with PC or via RX/TX) begin(long Speed) // up to 115200 end() int available() // #bytes available byte read() // -1 if none available byte peek() flush() print(myData) println(myData) write(myBytes) SerialEvent() // called if data rdy Libraries Primary source: Arduino Language Reference http://arduino.cc/en/Reference/ Built-in Functions SCL SDA Operators AREF GND 13 12 ~11 ~10 ~9 8 IOREF RESET 3.3V 5V GND GND Vin Structure & Flow Arduino Programming Cheat Sheet int1 int0 7 ~6 ~5 4 ~3 2 TX→1 RX←0 A0 A1 A2 A3 A4 A5 SDA SCL