Arduino: Unterschied zwischen den Versionen
Zeile 15: | Zeile 15: | ||
Die Sprache ist an [https://de.wikipedia.org/wiki/C%2B%2B c++] angelehnt, doch man braucht sich nicht um Header-Dateien zu kümmern, sondern schreibt einfach das gewünschte Programm. Die Datei ist reiner Text und wird mit der Endung .ino gespeichert. Die Programmierung ist ähnlich wie [[Python]] und die Initialisierung der Hardware ähnlich wie beim [[Raspberry Pi]]. | Die Sprache ist an [https://de.wikipedia.org/wiki/C%2B%2B c++] angelehnt, doch man braucht sich nicht um Header-Dateien zu kümmern, sondern schreibt einfach das gewünschte Programm. Die Datei ist reiner Text und wird mit der Endung .ino gespeichert. Die Programmierung ist ähnlich wie [[Python]] und die Initialisierung der Hardware ähnlich wie beim [[Raspberry Pi]]. | ||
=== Bibliotheken verwenden === | |||
Die IDE hat schon diverse Bibliotheken drin (Sketch -> Include Library). Möchte man aber für Sensoren externe Bibliotheken einbinden, so kann man das [https://www.heise.de/make/artikel/Arduino-Bibliotheken-einbinden-und-verwalten-3643786.html Tutorial von Heise verwenden]. | |||
=== Taster einlesen und LED einschalten === | === Taster einlesen und LED einschalten === |
Version vom 6. September 2021, 12:51 Uhr
Einführung
Der Arduino ist ein Mikrokontroller, welcher über eine Entwicklungsumgebung programmiert und geladen wird. Anschliessend läuft das Programm (Sketch genannt) selbständig auf dem Kontroller. Im Gegensatz zu einem Minicomputer wie dem Raspberry Pi kann aber immer nur ein Programm gleichzeitig auf dem System laufen.
Der Arduino sollte auf gewisse Maximalströme beschränkt werden: Siehe dazu die Antwort im Diskussionsforum.
Installation und Programmierung
Programme für den Arduino werden in der Entwicklungsumgebung (Download) geschrieben, dann auf den Arduino übertragen und dort ausgeführt. Für die Installation des USB-Treibers wird der Arduino nach der Installation der IDE mit dem PC verbunden. Installiert man das Ganze in eine virtuelle Maschine, so muss man das Gerät anschliessend darauf mappen. Danach fragt das Betriebsystem nach einem Treiber, der sich im Unterverzeichnis der IDE befindet, falls WIndows den Treiber nicht selbständig installiert.
Für die Verbindung zum Gerät findet man anschliessend den virtuellen Comport in der Computerverwaltung.
Die Sprache ist an c++ angelehnt, doch man braucht sich nicht um Header-Dateien zu kümmern, sondern schreibt einfach das gewünschte Programm. Die Datei ist reiner Text und wird mit der Endung .ino gespeichert. Die Programmierung ist ähnlich wie Python und die Initialisierung der Hardware ähnlich wie beim Raspberry Pi.
Bibliotheken verwenden
Die IDE hat schon diverse Bibliotheken drin (Sketch -> Include Library). Möchte man aber für Sensoren externe Bibliotheken einbinden, so kann man das Tutorial von Heise verwenden.
Taster einlesen und LED einschalten
// button.ino - light a led by pressing button // (c) BotBook.com - Karvinen, Karvinen, Valtokari // globale Variablen definieren, die in loop() und setup() bekannt sein müssen int buttonPin = 2; // Die Pin-Nummern sind auf dem Arduino direkt ersichtlich. int ledPin = 13; // Die eingebaute LED ist mit dem Pin 13 gekoppelt. int buttonStatus = LOW; // Initialisierung des Status void setup() { // Diese Routine wird beim Start einmalig durchlaufen und dient zur Initialisierung der Hardware. pinMode(ledPin, OUTPUT); // Pin als Output definieren pinMode(buttonPin, INPUT); // Pin als Input definieren digitalWrite(buttonPin, HIGH); // Den internen Pull-Up-Widerstand aktivieren. // Die vorherigen zwei Befehle können folgendermassen zusammengefasst werden: pinMode(buttonPin, INPUT-PULLUP); } // end setup() void loop() { // Diese Schleife wird bis zum Abschalten des Arduino unendlich abgearbeitet buttonStatus = digitalRead(buttonPin); // Den Status des Tasters einlesen if (LOW == buttonStatus) { // Wenn der Widerstand auf GND gezogen wird, ist der Taster gedrückt. // Dadurch dass man die Konstante nach vorne nimmt, verhindert man Fehler, falls man ein = vergisst. digitalWrite(ledPin, HIGH); // LED einschalten } // end if else { digitalWrite(ledPin, LOW); // sonst die LED ausschalten } // end else } // end loop()
Das Programm kann von der Webseite vom Sensorbuch heruntergeladen werden.
Serielle Schnittstelle
Der Arduino kann über die digitalen Pins 0 und 1 seriell mit einem Gerät kommunizieren. Möchte man aber nur Werte vom Arduino auslesen oder debuggen, so kann man dies direkt über das USB-Verbindungskabel erledigen.
Hier ein Beispiel für die Ausgabe eines analogen Wertes über die serielle Schnittstelle. Ausführliche Kommentare stehen im Abschnitt oben.
// squeeze_serial.ino - flexiforce squeeze level to serial // (c) BotBook.com - Karvinen, Karvinen, Valtokari int squeezePin = A0; int force = -1; // Da die analoge Schnittstelle Werte von 0-1023 liefert sieht man, ob Werte ankommen void setup() { Serial.begin(9600); // Verbindung mit 9600 bit/s herstellen. Im Arduino Monitor ist dies die Standard-Geschwindigkeit. } // end setup() void loop() { force = analogRead(squeezePin); Serial.println(force); // Den Wert auf die serielle Schnittstelle ausgeben. delay(500); } // end loop()
Sensoren
Genau wie beim Raspi gibt es analoge und digitale Sensoren für den Arduino. Dieser hat aber direkt fünf analoge Eingänge, so dass diese Sensoren direkt verarbeitet werden können. Beim 5V-Arduino werden alle Pegel > 3V als HIGH und alle < 1.5V als LOW angesehen. Zustände dazwischen sind undefiniert und sollten nicht für digitale Pins verwendet werden. Damit nicht alle Sensoren und Aktoren doppelt unter dem Raspi und dem Arduino geführt werden, auch wenn das Auslesen schlussendlich ähnlich ist, verweise ich jeweils auf den anderen Abschnitt und erfasse nur die jeweiligen Unterschiede. Für weitere Infos also unter dem Raspi nachschauen.
Druck (Kraft)
Der Anschluss wird beim Raspi beschrieben und das Einlesen findet sich im Abschnitt über den Potentiometer.
Infrarot (Entfernung)
Sensor / Schranke
Hier sendet eine eine Infrarot-Diode Licht aus, das reflektiert und von der lichtempfindlichen Empfängerdiode wieder aufgefangen wird. Starkes Sonnenlicht oder sehr dunkle Oberflächen können aber dazu führen, dass der Empfänger den ausgesendeten Strahl nicht detektiert. Je nach Gerät kann man die Empfindlichkeit mit einem kleinen Trimm-Poti einstellen.
Fürs verarbeiten des Signals kann man das gleiche Programm wie für den Taster einlesen verwenden, da der Sensor nur ein digitales Signal schaltet, kann man nicht erkennen, wie weit man von etwas entfernt ist, sondern nur, dass sich etwas im eingestellten Bereich des Senders befindet. Um den (genauen) Abstand zu detektieren braucht es einen analogen Abstandsmesser.
Abstandsmesser
Für analoge Abstandswerte kann man den [GP2Y0A] verwenden, der im Bereich von 10-80cm arbeitet. Da hier das Sonnenlicht oder extrem dunkle oder gestreute Fläche Falschmessungen liefern können, gibt es als Alternative Ultraschallsensoren.
Potentiometer
Dieser variable WIderstand fungiert als Spannungsteiler. Entsprechend wird eine Seite mit 5V gespiesen und die andere Seite an GND angeschlossen. Der mittlere Pin hingegen an A0. Entsprechend der Stellung ist die Differenzspannung nun grösser oder kleiner. Diese Spannung wird dann umgerechnet und man erhält einen Wert zwischen 0 und 1023. Je nach Auflösung des Analogbausteines kann der Wert noch verfeinert werden. Es ist egal, wie man das Poti anschliesst. Je nach Anschluss sind einfach die ma. und min. Werte vertauscht. In einem Programm muss man dies dann halt kalibrieren oder das Poti umgekehrt anschliessen.
Dieses Verfahren wird bei allen analogen Sensoren verwendet. Man muss dabei nur wissen, welche Stellung welchen Wert liefert, um die Sensoren korrekt auszuwerten. Wenn der Sensor feine Werte liefert, muss man evtl. einen zusätzlichen Analogbaustein verwenden, welcher diese Werte besser auflöst als der interne Baustein des Arduino, der 10 Bit liefert.
Um den Arduino nicht zu überlasten, sollte das Potentiometer einen Mindestwert von 50 nicht unterschreiten, damit nicht mehr als 100mA fliessen. Allgemein sollte mit möglichst grossen Widerständen gearbeitet werden, um den thermischen Verlust möglichst klein zu halten. Entsprechend kann man gut ein 10k-Poti einsetzen.
// pot.ino - control LED blinking speed with potentiometer // (c) BotBook.com - Karvinen, Karvinen, Valtokari // Es wird nur "neues" kommentiert. Grundlegende Kommentare im Abschnitt Programmierung int potPin = A0; // Analoge Eingänge werden mit Ax gekennzeichnet int ledPin = 13; int poti = 0; // Mögliche Werte von 0 bis 1023 void setup() { pinMode(ledPin, OUTPUT); } // end setup() void loop() { poti = analogRead(potPin); // Die Funktion liest den Wert am gegebenen Pin ein digitalWrite(ledPin, HIGH);// LED einschalten delay(poti/10); // Warten um den Wert / 10 Millisekunden digitalWrite(ledPin, LOW); delay(poti/10); } // end loop()
Schall
Sensoren und ein Link mit Anwendungen befinden sich beim Raspi. Hier noch ein möglicher Besipielcode, bei dem man die Berechnungen sieht.
// hc-sr04.ino - distance using ultrasonic ping sensor // (c) BotBook.com - Karvinen, Karvinen, Valtokari int trigPin = 2; // löst die Messung aus int echoPin = 3; // beendet die Messung float v = 331.5 + 0.6 * 20; // Schallgeschwindigkeit bei 20°C in m/s. Mit einem Temperaturfühler könnte man hier auch die Variable anpassen. void setup() { Serial.begin(115200); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } // end function setup() float distanceCm(){ digitalWrite(trigPin, LOW); // Trigger-Pin-Flanke generieren delayMicroseconds(3); // Warten, damit die Flanken sauber generiert werden digitalWrite(trigPin, HIGH); delayMicroseconds(5); digitalWrite(trigPin, LOW); float tUs = pulseIn(echoPin, HIGH); // Die Funktion liefert die gemessene Zeit in Mikrosekunden float t = tUs / 1000.0 / 1000.0 / 2.0; // Die Zeit in Sekunden umrechnen return t * v * 100; // Distanz in cm zurückliefern } // end function distanceCm() void loop() { int d = distanceCm(); // Rückgabewert in ganze cm Serial.println(d, DEC); // Wert als Dezimalzahl auf der ser. Konsole ausgeben delay(200); } // end function loop()
Temperatursensor
Damit können Temperaturen direkt eingelesen werden. Ein Beschrieb findet sich beim Raspi. Vollständige Kommentare zum Programm im Abschnitt zum Potentiometer. Infos zur ser. Schnittstelle im entsprechenden Abschnitt.
// temperature_lm35.ino - LM35 temperature in Celcius to serial // (c) BotBook.com - Karvinen, Karvinen, Valtokari int lmPin = A0; void setup() { Serial.begin(9600); } // end setup() float tempC() { float raw = analogRead(lmPin); // Dieser Wert könnte auch direkt im loop ausgelesen und als Parameter der Funktion übergeben werden. float percent = raw / 1023.0; // Prozentwert des Rohwertes als Floatzahl berechnen float volts = percent * 5.0; // Beim LM35 ergibt sich damit die absolute Spannung in Millivolt. Diese hängt von der Reverenzspannung (5V) ab. return 100.0 * volts; // Jetzt hat man die Temeperatur in °C } // end tempC() void loop() { Serial.println(tempC()); delay(200); } // end loop()