Es ist Zeit für den versprochenen zusätzlichen Teil unseres Arduino-Kurses. Diesmal werden wir einige Dinge behandeln, die eure Programmierung verbessern werden.
Wir sprechen unter anderem über die Kombination von Bedingungen und Zufallszahlen. Außerdem schauen wir uns an, wie einfach es ist, die Informationen, die in den PC gehen, als Diagramm darzustellen!
Bestellen Sie ein Set mit Elementen und beginnen Sie mit dem Lernen in der Praxis! Hier gehts zum Shop >>
Arduino - Diagramme zeichnen
Natürlich ändert sich die Arduino IDE mit der Zeit. Vor kurzem gab es dort eine sehr praktische Option, mit der man schnell Diagramme aus den über den UART gesendeten Informationen zeichnen kann.
Um dieses Tool zu verwenden, benötigen wir eine neue Version der Arduino IDE. Wenn du sie kürzlich installiert hast und im Tool-Menü zwei Optionen siehst: “ Serieller Monitor“ und „Serieller Port Monitor“, dann brauchst du nichts mehr zu tun.
Leider sind aber die Namen der beiden Optionen in der deutschen Version der IDE, gelinde gesagt, unintuitiv und verwirrend.
Wenn du nur eine Option dieses Typs siehst, dann aktualisiere deine IDE. Die neueste Version ist natürlich kostenlos auf der Projekt-Webseite erhältlich.
Um das Diagramm zu zeichnen, müssen wir, vorzugsweise in regelmäßigen Abständen, Zahlen in einer neuen Zeile an den Computer senden. Zunächst erstellen wir eine Schaltung, die ein Diagramm der am Eingang A5 gemessenen Spannung zeichnet, an die wir ein Potentiometer in der Funktion eines Spannungsteilers anschließen.
Fertige Sets für Forbot-Kurse
Sie können jetzt ein Set von mehr als 70 Elementen, die für die Kursübungen notwendig sind, bei unseren Händlern kaufen!
Beliebtes Paket: Arduino Meister – Robotik Meister
Der Anschlussplan für die Schaltung sieht wie folgt aus:
Eine Standardversion des Programms, das Daten an das Terminal sendet, würde wie folgt aussehen:
int ausgelesenerWert = 0;
void setup() {
Serial.begin(9600); //Start der Kommunikation über USART
}
void loop() {
ausgelesenerWert = analogRead(A5); //Lesen des Spannungswertes
Serial.println(ausgelesenerWert); //Wir schicken ihn an das Terminal
delay(200); //Wir warten, um die Ergebnisse bequemer zu lesen
}
Wenn man die Option „Serieller Monitor“ verwendet, sieht man beim Drehen des Potentiometers diesen Effekt:
Nicht sehr gut lesbar, oder? Schaltet man jedoch die zweite Option, “ Serieller Port-Monitor“, ein, erscheint ein viel deutlicheres Ergebnis für unsere Augen. Dies wird ein Diagramm sein, ein Beispiel für Messungen, als ich die Potentiometereinstellungen manuell geändert habe:
Das ist doch viel klarer, oder? Wann sind solche Optionen in der Praxis nützlich? Natürlich bei der Verwendung von Sensoren (Abstand, Temperatur, usw.). Zufälligerweise haben wir im vorherigen Teil des Arduino-Kurses den Umgang mit dem Abstandssensor HC-SR04 besprochen. Versuchen wir also, ein Diagramm der gemessenen Entfernung zu zeichnen!
Arduino - Hindernis-Abstandsdiagramm
Hierfür kehren wir zum Anschlussplan aus dem vorherigen Artikel zurück:
Wir führen auch den in der vorherigen Lektion geschriebenen Code aus. Es müssen nur zwei Änderungen vorgenommen werden. Die erste besteht darin, das Ergebnis in einer neuen Zeile ohne die Einheit anzuzeigen. Die zweite besteht darin, die Messfrequenz ein wenig zu erhöhen – dadurch wird das Diagramm glatter.
#define trigPin 12
#define echoPin 11
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT); //Pin, an den wir Trig als Ausgang anschließen
pinMode(echoPin, INPUT); //und das Echo als Eingang
}
void loop() {
long Zeit, Entfernung;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Zeit = pulseIn(echoPin, HIGH);
Entfernung = Zeit / 58;
Serial.println(Entfernung);
delay(100);
}
Fertig? Es ist an der Zeit, das Werkzeug zum Zeichnen von Diagrammen zu verwenden. Hier kann es unterschiedlich sein – manchmal funktioniert es und manchmal nicht. Und warum?
Bei der Verwendung solcher Sensoren besteht immer das Risiko,
dass wir eine Störung auffangen.
Im Falle dieses Entfernungssensors kann eine Störung dazu führen, dass er eine Meldung über eine fehlerhafte Messung an den Computer sendet. Auf dem Screenshot unten sieht man, dass eine der ersten Messungen eine Entfernung von 2000 cm anzeigte.
Dies ist nicht möglich, wenn der Hersteller ein Maximum von 400 cm angegeben hat.
Dies hat zu einer automatischen Skalaauswahl in der Grafik geführt, die es schwierig macht, die späteren, korrekten Ergebnisse zu lesen. Wie kann man dies beheben? Das geht am besten durch Programmierung. Fügen wir eine einfache Bedingung hinzu, die überprüft, welchen Wert wir an den Computer senden. Sie könnte zum Beispiel so aussehen:
if (Entfernung > 400) { //Wenn der berechnete Abstand größer ist als 400
Entfernung = 400; //dann setze ihn auf 400 (vom Hersteller angegebener Höchstwert)
}
Dadurch wird sichergestellt, dass wir niemals einen Wert an den Computer senden, der außerhalb des Bereichs des Sensors liegt. Die Abstandsvariable wurde als positive Zahl deklariert, so dass wir nur den oberen Bereich überprüfen müssen. Den unteren Bereich brauchen wir nicht zu überprüfen. Das gesamte Programm sieht nach den Änderungen wie folgt aus:
#define trigPin 12
#define echoPin 11
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT); //Pin, an den wir Trig als Ausgang anschließen
pinMode(echoPin, INPUT); //und das Echo als Eingang
}
void loop() {
long Zeit, Entfernung;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Zeit = pulseIn(echoPin, HIGH);
Entfernung = Zeit / 58;
if (Entfernung > 400) { //Wenn der berechnete Abstand größer ist als 400
Entfernung = 400; //dann setze ihn auf 400 (vom Hersteller angegebener Höchstwert)
}
Serial.println(Entfernung);
delay(100);
}
Jetzt wird das Diagramm immer korrekt aussehen:
Während ich die Messungen aufzeichnete, habe ich das Hindernis vor dem Sensor schnell versetzt. Wie man sieht, hat uns die Beschränkung mehrmals vor fehlerhaften Messungen bewahrt. Übrigens ist es bemerkenswert, wie das Zeichnen eines Diagramms es einfacher macht, Probleme mit der Qualität der Sensormessungen zu erkennen! Hier zum Beispiel: Man sieht relativ große Rauschwerte, die Messwerte sind nicht stabil.
Arduino - Diagramm mit mehreren Werten
Mit der beschriebenen Funktion zum Zeichnen von Diagrammen können auch mehrere Werte gleichzeitig in ein Diagramm gezeichnet werden. Um diese Option zu nutzen, muss man die Zahlen in der gleichen Zeile senden, getrennt durch ein Tabulatorzeichen, und am Ende sollte ein Zeilenumbruch stehen.
In der Praxis sieht der Code wie folgt aus:
Serial.print(Wert1);
Serial.print("\t"); // Tabulatorzeichen
Serial.print(Wert2);
Serial.print("\t"); // Tabulatorzeichen
Serial.print(Wert3);
Serial.print("\t"); // Tabulatorzeichen
Serial.print(Wert4);
Serial.println(""); // Sprung in eine neue Zeile
Andererseits wird ein Diagramm nach dem Ersetzen von Zufallswerten zum Beispiel so aussehen:
Das Zeichnen von Diagrammen kann auch bei der Verwendung von Beschleunigungs- oder Positionssensoren besonders nützlich sein. Ich empfehle Ihnen, meinen Artikel zu lesen, in dem ich gezeigt habe, wie man den neuesten Genuino 101 verwendet, um seine Position abzubilden!
Dort habe ich das gleichzeitige Zeichnen von Diagrammen für mehrere Werte verwendet:
Hausaufgabe 10.1
Setze die Fähigkeit, mehrere Diagramme gleichzeitig zu zeichnen, in die Praxis um. Schließe zwei Fotowiderstände an den Arduino an – das haben wir schon in anderen Lektionen gemacht. Miss dann die Spannung, die den Lichteinfall auf jeden Sensor widerspiegelt. Stelle beide Werte in einem einzigen Diagramm dar.
Arduino - Zufallszahlen
Manchmal erwarten wir, dass ein Programm auf „unvorhersehbare“ Weise funktioniert. Ein praktisches Beispiel? Ein Roboter, der sich um einen zufälligen Winkel dreht, wenn er ein Hindernis entdeckt, oder ein einfaches Spiel, bei dem der Computer seine Bewegung mit einer unvorhersehbaren Verzögerung ausführt. Im vorherigen Beispiel habe ich genau solche Werte verwendet, um das gleichzeitige Zeichnen von Diagrammen für verschiedene Daten zu demonstrieren.
Hier ist eine Funktion, die einen Zufallswert liefert, sehr nützlich. Um ehrlich zu sein, wird diese Zahl jedoch nicht völlig unvorhersehbar sein. Im Falle von Computern/Mikrocontrollern spricht man daher von Pseudozufallszahlen. Das ist ein recht umfangreiches Thema, auf das wir hier nicht eingehen werden.
Es ist jedoch zu bedenken, dass die von einem Computer gezogenen Werte aus statistischer Sicht nicht vollkommen zufällig sind (um es ganz einfach auszudrücken).
Die RandomFunktion();, die zwei Argumente annehmen kann, ist für die Rückgabe eines Zufallswertes verantwortlich. Dank dieser Argumente können wir den Bereich festlegen, aus dem die Zahlen ausgelost werden. In der Praxis verwenden wir die Funktion in der Regel auf eine von zwei Arten. Wenn nur der obere Bereich angegeben wird:
random(500); //Zufallszahl im Bereich 0-499
Dann ist der zurückgegebene Wert eine Zahl zwischen 0 und einer Zahl, die um eins kleiner ist als die in Klammern angegebene. Wir können auch die untere Grenze des Bereichs beeinflussen. Dazu fügen wir einfach ein zweites Argument hinzu:
random(100, 500); //Zufallszahl im Bereich 100-499
Merke!
Die maximale Zahl, die gezogen wird, ist immer um 1 kleiner als der von uns angegebene obere Bereich!
Nun ist es an der Zeit, die Funktion in der Praxis zu testen. Zu diesem Zweck schreiben wir das einfachste Programm, das man erstellen kann. Seine Aufgabe ist es, Zahlen in Intervallen von 1 Sekunde zu auszulosen und sie im Terminal anzuzeigen (Option „Serieller Monitor“ im Menü „Extras“):
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(random(300));
delay(1000);
}
Wie im Terminal angekündigt, erwarten wir zufällige Werte. Überprüfen wir das:
Wir wollten Zufallsdaten und haben sie bekommen. Jetzt lassen wir das hochgeladene Programm noch ein paar Mal laufen. Wie erwartet, sollten die Zufallszahlen jedes Mal anders sein, richtig?
Leider erhalten wir jedes Mal eine identische Folge. Wie ich schon schrieb, ist die „Zufälligkeit“ der zurückgegebenen Zahlen ein wenig betrügerisch. Der Mikrocontroller an Bord des Arduino ist ein sehr präziser Chip, der nacheinander programmierte Operationen ausführt. In seiner Welt gibt es keine zufälligen Werte.
Wie man sich denken kann, erzeugt der Arduino Zufallszahlen, indem er bestimmte Operationen an einem zuvor gezogenen Wert durchführt.
Der gleiche Anfang macht also die nachfolgenden Zahlen identisch.
Um das Ergebnis des Zufallsalgorithmus zu verbessern, wäre es am besten, vor jedem Start mit einem anderen Wert als diesem ersten, anfänglichen Wert zu beginnen.
Diese Zahl, aus der die nachfolgenden Zahlen generiert werden, wird als Samen/Saatgut bezeichnet, im Englischen wird sie als random seed bezeichnet. Mehr zu diesem Thema findest du auf Wikipedia (Eintrag: Zufallszahlengenerator). Für uns ist das Wichtigste, dass es ein solches Konzept auch in der Arduino-Sprache gibt – wir haben eine Wirkung auf diesen Seed. Dazu wird die Funktion verwendet:
randomSeed(Anfangs_wert);
In seinem Argument, das hier als Anfangs_wert gekennzeichnet ist, müssen wir jedes mal…. einen Zufallswert angeben. Aber ich habe es durcheinander gebracht, nicht wahr? Um Zahlen auszulosen, brauchen wir einen Zufallswert. Hast du eine Idee, wie man ihn erhält? Wenn nicht, schau dir mal diese Lektion über den ADC im Arduino an.
Was passiert, wenn wir kein Signal an den Leseeingang anschließen? Dann sammeln wir „Müll“ aus der Umgebung, der…. einfach zufällig. Bis jetzt war das ein Problem für uns. Aber hier werden wir diese Werte für einen guten Zweck verwenden.
Um unseren Arduino dazu zu bringen, „mehr zufällige“ Zahlen zu verwenden, können wir zunächst folgendes tun:
randomSeed(analogRead(A0));
Damit wird die Zufallsspannung gemessen, die bei jedem Programmstart am Eingang A0 anliegt. Außerdem wird dieser Wert als Seed für den Pseudo-Zufallszahlengenerator verwendet.
Natürlich funktioniert das Ganze am besten, wenn der A0-Eingang nicht als Standardeingang/-ausgang verwendet wird.
Lasst uns schnell unser Programm verbessern und es in der Praxis testen:
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
}
void loop() {
Serial.println(random(300));
delay(1000);
}
Von nun an werden wir nach jedem Durchlauf andere Werte erhalten:
Natürlich ist er immer noch kein perfekter Zufallszahlengenerator, aber in dieser Form ist er für die meisten Arduino-basierten Projekte ausreichend.
Hausaufgabe 10.2
Finde heraus, was passiert, wenn anstelle des am Analogeingang abgelesenen Seeds ein konstanter Wert dort eingegeben wird. Wie verhält sich der Pseudo-Zufallszahlengenerator dann?
Hausaufgabe 10.3
Schreibe ein Programm, das wie ein elektronischer Würfel funktioniert. Schließe einen Knopf an den Arduino an. Jedes Mal, wenn er gedrückt wird, soll er einen gezeichneten Wert an den Computer senden (über den UART) – natürlich im Bereich von 1 bis 6.
Zufälliges Blinken der Diode
Verwenden wir die gewonnenen Erkenntnisse, um ein Programm zu schreiben, das die im Arduino eingebaute LED nach dem Zufallsprinzip blinken lässt. Wir nehmen an, dass die Dauer des Leuchtens zwischen 100ms und 990ms variieren soll. Die Zeit, in der die LED aus ist, wird zwischen 50-490ms liegen. Beide Werte sollen sich in Intervallen von 10 ms ändern.
Hierfür benötigen wir zwei Zufallswerte:
int ZeitEin = random(100, 1000);
int ZeitAus = random(50, 500);
Wir könnten solche gezeichneten Werte in die Verzögerungsfunktion einfügen, aber dann könnte die Verzögerung z.B. Werte von 100 bis 999 annehmen, d.h. wir würden die angenommenen Intervalle von 10ms nicht einhalten. Wie lässt sich dies beheben?
Wir brauchen nur 10 mal kleinere Werte zu zeichnen, die wir mit 10 multiplizieren, bevor wir sie in die Verzögerungsfunktion einfügen:
int ZeitEin = random(10, 100); //Wert von 10 - 99
int ZeitAus = random(5, 50); //Wert von 5 - 49
ZeitEin = ZeitEin * 10; //Wert von 100 - 990, in 10er-Schritten
ZeitAus = ZeitAus * 10; //Wert von 50 - 490, in 10er-Schritten
Diese Werte können nun in das Programm eingesetzt werden:
void setup() {
pinMode(13, OUTPUT);
randomSeed(analogRead(0));
}
void loop() {
int ZeitEin = random(10, 100); //Wert von 10 - 99
int ZeitAus = random(5, 50); //Wert von 5 - 49
ZeitEin = ZeitEin * 10; //Wert von 100 - 990, in 10er-Schritten
ZeitAus = ZeitAus * 10; //Wert von 50 - 490, in 10er-Schritten
digitalWrite(13, HIGH);
delay(ZeitEin);
digitalWrite(13, LOW);
delay(ZeitAus);
}
In der Praxis blinkt die Diode so, wie wir es wollten, d.h. völlig zufällig!
Kombinieren von bedingten Anweisungen
Gleich zu Beginn des Arduino-Kurses haben wir uns mit bedingten Anweisungen beschäftigt, die dazu dienen, den Ablauf eines Programms in Abhängigkeit von bestimmten Informationen zu steuern. Meistens haben wir nur eine Bedingung überprüft, wie z.B.: „Ist der Knopf gedrückt worden?“. Im Programm sah dies wie folgt aus:
if (digitalRead(7) == LOW) { //Wenn die Taste gedrückt ist
//etwas tun
} else { //Wenn die Bedingung nicht erfüllt ist (Taste nicht gedrückt)
//Etwas anderes tun...
}
In der Praxis kommt es oft vor, dass wir zwei Bedingungen gleichzeitig prüfen wollen. Das einfachste Beispiel wäre, zu prüfen, ob der Benutzer mehr als eine Taste gedrückt hat.
Das kann natürlich auch auf traditionelle Weise geschehen:
if (digitalRead(7) == LOW) { //Wenn die erste Taste gedrückt wird, prüfen...
if (digitalRead(8) == LOW) { //...ob die zweite Taste auch gedrückt ist
//Etwas tun
}
}
Die Lösung ist effektiv, aber es wird einige Probleme mit der Lesbarkeit dieser Notation geben, wenn wir noch mehr Bedingungen gleichzeitig überprüfen wollen. Deshalb ist es sicher einfacher, wenn wir zwei logische Operatoren kennenlernen:
- Boolesches Produkt – &&
- Logische Summe – ||
Ich habe diese Möglichkeit bereits im vorherigen Teil des Arduino-Kurses erwähnt.
Wir werden dieses Thema nun vertiefen.
Wir werden die erste verwenden, wenn wir prüfen wollen, ob:
Bedingung eins und Bedingung zwei erfüllt sind
if (Bedingung1 == 1 && Bedingung2 == 1)
Die zweite hingegen wird verwendet, um zu prüfen, ob:
Bedingung eins oder Bedingung zwei (oder beide) erfüllt sind
if (Bedingung1 == 1 || Bedingung2 == 1)
Kombinierte Bedingungen in der Praxis
Zu diesem Zweck schließen wir zwei LEDs (grün und rot) und zwei Tasten an den Arduino an. Der Schaltplan sieht wie folgt aus:
Nun wollen wir ein Programm schreiben, das die grüne LED einschaltet, wenn eine der beiden Tasten gedrückt wird. Der Code könnte z.B. so aussehen:
void setup() {
pinMode(10, INPUT_PULLUP); //Taste als Eingang
pinMode(9, INPUT_PULLUP); //Przycisk jako wejście
pinMode(8, OUTPUT); //Grüne Diode als Ausgang
pinMode(7, OUTPUT); //Rote Diode als Ausgang
digitalWrite(8, LOW); //Grüne Diode ausschalten
digitalWrite(7, LOW); //Rote Diode ausschalten
}
void loop() {
if (digitalRead(9) == LOW || digitalRead(10) == LOW) { //Wenn die erste oder zweite Taste
digitalWrite(8, HIGH); //Grüne Diode einschalten
} else {
digitalWrite(8, LOW); //Grüne Diode ausschalten
}
}
In der Praxis beschränkt sich der wichtigste Teil dieses Programms auf eine einzige Zeile. Nämlich die Bedingung, in der wir die Zustände von zwei Tasten auf einmal überprüfen. Wenn mindestens eine von ihnen gedrückt wurde, wird die LED eingeschaltet.
Unser Programm prüft, ob mindestens eine Bedingung erfüllt ist. Deshalb leuchtet die LED auch auf, wenn beide Tasten gleichzeitig gedrückt werden.
Erweitern wir das Programm ein wenig und fügen eine separate Bedingung hinzu, die die rote LED nur einschaltet, wenn beide Tasten gleichzeitig gedrückt werden:
void setup() {
pinMode(10, INPUT_PULLUP); //Taste als Eingang
pinMode(9, INPUT_PULLUP); //Taste als Eingang
pinMode(8, OUTPUT); //Grüne Diode als Ausgang
pinMode(7, OUTPUT); //Rote Diode als Ausgang
digitalWrite(8, LOW); //
Grüne Diode ausschalten
digitalWrite(7, LOW); //Rote Diode ausschalten
}
void loop() {
if (digitalRead(9) == LOW || digitalRead(10) == LOW) { //Wenn die erste oder zweite Taste
digitalWrite(8, HIGH); //Grüne Diode einschalten
} else {
digitalWrite(8, LOW); //Grüne Diode ausschalten
}
if (digitalRead(9) == LOW && digitalRead(10) == LOW) { //Wenn die erste und zweite Taste
digitalWrite(7, HIGH); //Grüne Diode einschalten
} else {
digitalWrite(7, LOW); //Grüne Diode ausschalten
}
}
Die Funktionsweise der endgültigen Fassung des Programms ist im folgenden Video zu sehen:
Praktisches Beispiel - Abstandssensor
Die obigen Beispiele haben gezeigt, dass das Layout funktioniert, waren aber nicht sehr nützlich. Versuchen wir nun, etwas Praktischeres zu machen. Schließen wir einen Knopf, einen Abstandssensor und einen Summer an den Arduino an. Die Schaltung soll einen Summton erzeugen, der ertönt, wenn das Hindernis zwischen 20 und 40 cm entfernt ist, oder wenn der Knopf gedrückt wird.
Um dies zu tun, müssen wir zuerst den benötigten Schaltkreis anschließen. Um es etwas schwieriger zu machen, gebe ich dieses Mal anstelle eines Schaltplans eine Liste der Verbindungen + ein Hilfsfoto. In diesem Stadium des Kurses sollte jeder bereits in der Lage sein, eine solche Schaltung selbst zusammenzubauen:
- trigPin des Abstandssensors an Pin Nr. 12
- echoPin des Abstandssensors an Pin 9
- Summer an Pin 11
- Taste an Pin 10
Außerdem muss natürlich die Vcc-Spannungsversorgung (positive Schiene) mit dem Abstandssensor verbunden werden, und Masse mit dem Summer, Taste und natürlich auch mit dem Sensor. Bei mir sah es in der Praxis so aus:
Zeit, das Programm zu schreiben. Wir wissen bereits, wie wir die Entfernung ablesen können, so dass die Überprüfung des Zustands der Taste für uns kein Problem mehr darstellt. Daher werden wir uns auf die Analyse der Bedingung konzentrieren. Wie ich schon geschrieben habe, wollen wir den Summer einschalten, wenn der gelesene Abstand zwischen 20 und 40 cm liegt.
Dazu müssen wir prüfen, ob der abgelesene Wert gleichzeitig größer als 20 und kleiner als 40 cm ist. Wir werden dies natürlich in einer Bedingung tun:
if (Entfernung > 20 && Entfernung < 40) {
digitalWrite(11, HIGH); //Summer einschalten
} else {
digitalWrite(11, LOW); //Summer ausschalten
}
Nun ist es an der Zeit, die Taste zu behandeln. Natürlich könnten wir dies in zwei separate Bedingungen aufteilen:
if (Entfernung > 20 && Entfernung < 40) {
digitalWrite(11, HIGH); //Summer einschalten
} else {
digitalWrite(11, LOW); //Summer ausschalten
}
if (digitalRead(10) == LOW) { //Wenn Taste gedrückt
digitalWrite(11, HIGH); //Summer einschalten
} else {
digitalWrite(11, LOW); //Summer ausschalten
}
Aber wozu? Wir sollten nicht dieselben Teile des Codes duplizieren, wenn wir es nicht müssen. In diesem Fall ist es unnötig, den Summer ein- und wieder auszuschalten. Können wir die Bedingung nicht zu einer einzigen zusammenfassen? Natürlich können wir das!
Überprüfen wir, ob:
(die gemessene Entfernung größer als 20 und kleiner als 40 ist) oder (ob eine Taste gedrückt wurde).
Übersetzt man dies in eine für Computer verständliche Sprache, ergibt sich folgendes Bild:
if ((Entfernung > 20 && Entfernung < 40) || digitalRead(10) == LOW) {
digitalWrite(11, HIGH); //Summer einschalten
} else {
digitalWrite(11, LOW); //Summer ausschalten
}
Das gesamte Programm stellt sich also wie folgt dar:
#define trigPin 12
#define echoPin 9
void setup() {
pinMode(trigPin, OUTPUT); //Pin, an den wir Trig als Ausgang anschließen
pinMode(echoPin, INPUT); //und das Echo als Eingang
pinMode(10, INPUT_PULLUP); //Taste als Eingang
pinMode(11, OUTPUT); //Summer als Ausgang
digitalWrite(11, LOW); //Summer ausschalten
}
void loop() {
long Zeit, Entfernung;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Zeit = pulseIn(echoPin, HIGH);
Entfernung = Zeit / 58;
if ((Entfernung > 20 && Entfernung < 40) || digitalRead(10) == LOW) {
digitalWrite(11, HIGH); //Summer einschalten
} else {
digitalWrite(11, LOW); //Summer ausschalten
}
}
In der Praxis funktioniert das Programm genau so, wie wir es vorausgesagt haben. Im Video unten sieht man, dass der Summer ertönt, wenn sich das Hindernis in der richtigen Entfernung befindet oder wenn eine Taste gedrückt wird:
Erinnerst du dich an die früheren Diagramme, die aus den Messwerten dieses Sensors erstellt wurden? Es sind die Interferenzen/Pieptöne, die manchmal dazu führen, dass wir leise Pieptöne hören. Natürlich können diese programmatisch herausgefiltert werden, wir werden irgendwann darauf zurückkommen!
Die Verwendung von logischen Operatoren zur Verknüpfung von Bedingungen ist sehr einfach, und wenn man sie richtig einsetzt, kann man wirklich komplizierte Probleme lösen. Ich empfehle euch, die erweiterten Bedingungen selbst zu üben, und sei es nur, indem ihr die folgende Hausaufgabe löst.
Hausaufgabe 10.4
Schreibe Programme, die eine Zahl aus dem Bereich 0-100 auslosen und dann prüfen, ob der ausgeloste Wert:
- kleiner als 10 oder größer als 90
- größer als 50, aber nicht zwischen 70 und 85
- gleich 50, 40, 30 oder 20
- zwischen 10 und 40 oder zwischen 60 und 100
In jedem Fall muss die gezogene Zahl auf dem PC angezeigt werden und ob sie die Bedingung erfüllt.
Zusammenfassung
Ich hoffe, dass das Wissen, das du durch die Übungen in diesem Teil des Kurses erworben hast, dir helfen wird, noch interessantere Programme zu schreiben. Sehr oft wirst du die Kombination von Bedingungen und das Zeichnen von Diagrammen für deinen eigenen Komfort verwenden.
Nimm dir die nötige Zeit, um diesen Stoff zu beherrschen.
Bestellen Sie ein Set mit Elementen und beginnen Sie mit dem Lernen in der Praxis! Hier gehts zum Shop >>