Arduino Kurs – #2 – Grundlagen der Programmierung, I/O Ports

Im zweiten Teil des Arduino-Kurses werden wir anfangen, Programme zu schreiben. Zunächst werden wir natürlich die kompletten Grundlagen behandeln.

Der Arduino arbeitet mit einer plattformangepassten C-Sprache. Dieser Artikel führt daher in die Grundlagen der Programmierung in C ein und zeigt deren praktische Anwendung am Beispiel von I/O-Ports.
Bestellen Sie ein Set mit Elementen und beginnen Sie mit dem Lernen in der Praxis! Hier gehts zum Shop >>

Grundlegendes Arduino-Software-Framework

Jedes Computerprogramm ist eine Sammlung von Befehlen. Ein spezieller Schaltkreis, der Befehlszähler, ruft die Befehle einen nach dem anderen auf. In der Sprache C werden alle Befehle, die wir ausführen wollen, in der Main-Funktion platziert (mehr über Funktionen später), die wie folgt aussieht:

				
					int main() {
   //Inhalt des Programms
}
				
			

Hinweis: Das musst du dir merken!
Die Symbole „//“ kennzeichnen Kommentare. Das sind Informationen, die in einer einzigen Zeile enthalten sind und dem Benutzer helfen, das Programm zu verstehen. Sie werden beim Kompilieren weggelassen. Wenn Sie einen längeren Kommentar einfügen wollen, sollten Sie ihn /* in solche Symbole */ einfügen.

Kommentare sind sehr wichtig! Denk daran, den Code zu kommentieren, auch wenn du nur Programme für deinen eigenen Gebrauch schreibst.

Beim Arduino sind bestimmte Dinge vereinfacht. Nun, in jedem Programm werden zunächst einige Befehle einmal ausgeführt und dann andere in einer Schleife.

				
					void setup() {
 //Befehle, die einmal ausgeführt werden
}

void loop() {
 //Befehle, die in einer Schleife ausgeführt werden
}
				
			
In der Praxis wird die erste Funktion normalerweise einige Einstellungen enthalten. Damit werden bestimmte Mikrocontroller-Pins als Eingänge oder Ausgänge festgelegt. Wir aktivieren die fortgeschrittenen Peripheriegeräte und führen Aktionen aus, die nur einmal, nämlich beim Einschalten der Stromversorgung, ausgeführt werden sollen.

In der zweiten Funktion platzieren wir den eigentlichen Anwendungscode, der ständig ausgeführt wird (in einer Schleife). Anhand der folgenden praktischen Beispiele lässt sich dies viel leichter nachvollziehen.

Funktionen - was bedeuten diese Einträge?

Man kann die Funktionen selbst schreiben oder fertige Funktionen verwenden, die von Herstellern oder Programmierfreaks zur Verfügung gestellt werden, die bereit sind, ihren eigenen Code zu teilen. Zu Beginn des Kurses werden wir uns darauf konzentrieren, die in den Bibliotheken enthaltenen Funktionen zusammen mit dem Arduino-Kompilierer zu verwenden. Ein paar Details zu diesen Funktionen können jedoch nicht schaden.

In der Sprache C gibt es das Konzept der Funktionen. Die Parallele zur Mathematik ist hier treffend. Nun, es stellt sich heraus, dass eine Funktion in Programmiersprachen ein Block (Liste) von bestimmten, aus dem Hauptcode extrahierten Befehlen ist, deren Ausführung ein bestimmtes Ergebnis liefert.

Für uns ist das praktisch, denn sobald eine Funktion definiert ist, können wir sie beliebig oft aufrufen, ohne mühsam dieselben Codezeilen zu duplizieren – wir brauchen nur den Funktionsnamen.

Jede Funktion kann eine Reihe von Argumenten aufnehmen und (standardmäßig) ein Ergebnis zurückgeben. Der Programmierer kann festlegen, welche Ergebnis- und Eingabewerte verwendet werden sollen. Jede Funktion hat einen Typ (d. h. die Art des Ergebnisses, das sie zurückgibt) – es kann eine Zahl, ein Zeichen oder etwas anderes sein. Es gibt auch einen speziellen Funktionstyp, der kein Ergebnis zurückliefert (er hat das Kürzel void).

Konzentrieren wir uns auf die wichtigsten Funktionen in Programmen, die mit dem Arduino geschrieben wurden.
				
					void setup() {
}
				
			

Die Setup-Prozedur ist so konzipiert, dass der in ihr enthaltene Befehlsblock einmal ausgeführt wird. Wie der Name schon sagt, ist sie hauptsächlich für die Einrichtung gedacht. In ihr wird der Prozessor initialisiert, die Peripheriegeräte werden konfiguriert usw.

				
					void loop() {
}
				
			

Eine Loop-Funktion (Prozedur) ist eine Endlosschleife. Sie enthält Anweisungen, die in einer Schleife ausgeführt werden sollen (immer wieder). Kommen wir nun zu praktischen Beispielen.

Fertige Sets für Forbot-Kurse
 Satz von Elementen   Garantierte Unterstützung   Versand in 24 Stunden

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 MeisterRobotik Meister

ArduinoUNO-Anschlüsse

Wie im vorigen Teil erwähnt, können über spezielle Anschlüsse externe Komponenten wie Dioden und Taster an den Arduino angeschlossen werden. Bevor wir dazu kommen, müssen wir jedoch die Beschreibung der Pinbelegung kennen. Unten sehen Sie eine Zeichnung mit den wichtigsten Signalen, die aus dem Arduino UNO kommen:

In Dunkelgrün (Nr. 0 bis 19) sind die universellen digitalen Eingangs-/Ausgangsstifte (I/O) markiert. Wenn sie als Ausgänge verwendet werden, können sie 0V (logisch 0, niedriger Zustand) oder 5V (logisch 1, hoher Zustand) an sie anlegen. Wenn sie als Eingänge konfiguriert sind, können sie den Anschluss eines Pins an 0 V oder 5 V erkennen.

Die analogen Eingänge (A0-A5) sind hellgrün hervorgehoben. Dies sind einzigartige Pins, die eine Spannungsmessung (im Bereich von 0-5V) ermöglichen. Wie man sehen kann, stimmt die Nummerierung dieser Eingänge mit den Universalpins (Nummern 14 bis 19) überein. Der analoge Betrieb ist eine zusätzliche Funktion dieser Pins.

Denke daran: Die analogen Pins A0-A5 können auch als normale I/O-Pins arbeiten.

Alternative Funktionen für einzelne Signale sind blau hervorgehoben. Das bedeutet, dass sie nicht nur eine Standardeingabe oder -ausgabe sein können, sondern auch komplexere Funktionen erfüllen können. Auf diese werden wir später eingehen, im Moment reicht eine grundlegende Erläuterung aus:

  • SDA, SCL – Pins des I²C-Busses, die z.B. für die Kommunikation mit fortschrittlicheren Sensoren verwendet werden, die Pins sind dupliziert (sie befinden sich in der unteren linken und oberen rechten Ecke der Platine – es sind genau die gleichen Signale),
  • TX, RX – UART-Schnittstelle, hauptsächlich für die Kommunikation mit dem Computer verwendet,
  • PWM – Pins, an denen man ein rechteckiges Signal mit variabler Füllung erzeugen kann. Eine sehr nützliche Funktion z.B.: bei der Steuerung von Servomechanismen,
  • LED – eine Leuchtdiode, die fest in den Arduino integriert ist und an Pin 13 angeschlossen wird.
Die Leitungen in Orange sind nicht programmierbar. Sie sind hauptsächlich für die Stromversorgung der Schaltung verantwortlich. Sie werden ausführlicher besprochen, wenn es an der Zeit ist, sie zu verwenden.

Die in der obigen Grafik als ICSP bezeichneten Anschlüsse dienen der direkten Programmierung der beiden Mikrocontroller, die sich auf dem Arduino UNO-Board befinden. Diese Anschlüsse werden in sehr speziellen Fällen verwendet und es ist absolut nicht notwendig, sie in diesem Stadium zu behandeln.

Ausgänge in der Praxis - LED

Jetzt kümmern wir uns um die einfachste Sache, wir schalten die LED ein. Wie oben beschrieben, können wir dafür einen beliebigen I/O-Pin verwenden. Für den Anfang wählen wir den digitalen Ausgang Nr 8. Digitaler Ausgang – das ist ein Ausgang, den wir auf einen von zwei Zuständen einstellen können. Niedrig oder hoch. Im Falle des Arduino ist dies 5V oder 0V.

Die Schaltung sollte wie unten gezeigt angeschlossen werden. Wir schließen die LED in Reihe mit einem Widerstand (330R) an. Das längere Bein der Diode (die Anode) wird dann an Pin 8 angeschlossen, das andere Bein über einen Widerstand an Masse, die sich im Stromanschluss befindet (als GND bezeichnet). Auf der Platine gibt es 3 Leitungen, die als GND bezeichnet sind. Wir können jede davon wählen.

ACHTUNG!


Denken Sie daran, die meisten Peripheriegeräte (LEDs, Buzzer) über Widerstände an den Arduino anzuschließen! Entsprechende Informationen finden Sie in unseren Übersichtszeichnungen.

Wenn ein Widerstand fehlt, könnte dies zu einer BESCHÄDIGUNG der angeschlossenen Komponenten und sogar des Arduinos führen!

Anschluss der LED-Diode an den Arduino.

Die Software-Aktivierung der Diode ist sehr einfach. Schließe den Arduino über ein USB-Kabel an den Computer an. Starte Arduino-IDE und schreibe den unten stehenden Code ab. Lade ihn dann auf das Board hoch. Eine Beschreibung dieses Schrittes findest du im ersten Teil des Kurses.

Versuche, die Codes abzuschreiben! Kopieren ist schneller, aber man lernt weniger!

				
					void setup() {
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
}

void loop() {
}
				
			

Mit der Funktion pinMode (Pin, Modus) können Sie festlegen, ob ein Pin ein Eingang oder ein Ausgang ist. Der Pin kann eine ganze Zahl zwischen 0 und 13 sein, der Modus ist:

  • INPUT,
  • OUTPUT,
  • INPUT_PULLUP.
Wenn wir den Ausgang steuern wollen, verwenden wir immer den Modus Output. Die anderen Modi werden später besprochen.

Mit dieser Konfiguration können wir den logischen Zustand am Ausgang einstellen (und damit die Diode einschalten). Zu diesem Zweck wird die Funktion digitalWrite(Pin, Zustand) verwendet. Zustand ist ein logischer Zustand, der HIGH oder LOW sein kann.

In unserem Beispiel ist die LED bereits mit der Masse verbunden, so dass der Arduino sie in einen hohen Zustand bringen muss, also digitalWrite(8, HIGH);.

Beenden Sie jeden Befehl mit einem Strichpunkt (Semikolon)!

Sobald der Pin einmal auf „high“ gesetzt wurde, ändert sich sein Wert nicht mehr, bis wir ihn selbst auf einen anderen Wert setzen. Daher lässt ein Programm wie das obige die LED ständig leuchten.

Programmverzögerungen - LED blinkt

Dieses Mal werden wir die LED blinken lassen. Dazu brauchen wir eine neue Funktion, deren Aufgabe es sein wird, eine Verzögerung einzuführen – Delay. Der Schaltplan ist genau der gleiche wie im ersten Fall. Allerdings wird der Code wie folgt aussehen:

				
					void setup() {
  pinMode(8, OUTPUT); //Konfiguration von Pin 8 als Ausgang
}

void loop() {
  digitalWrite(8, HIGH); //Diode einschalten
  delay(1000); //1 Sekunde warten
  digitalWrite(8, LOW); //Diode ausschalten
  delay(1000); //1 Sekunde warten
}
				
			

Der Zustand des Ausgangs ändert sich hier ständig in einer Endlosschleife. Im Programm wurden mit Hilfe der Funktion delay(Zeit) Verzögerungen eingefügt (damit das Blinken sichtbar ist). Diese Funktion erhält als Argument die Anzahl der zu wartenden Millisekunden.

Ohne die eingefügten Verzögerungen würde die Schaltung den Zustand ihres Ausgangs so schnell ändern, dass es unmöglich wäre, die Änderungen mit dem bloßen Auge zu erkennen. Man kann ein solches Experiment durchführen, indem man die Verzögerung auf 0 ms setzt.

Hausaufgabe 1.1

Finde heraus, bei welchem kleinsten Verzögerungswert du das Blinken der Diode wahrnehmen kannst! Was passiert, wenn die Diode zu schnell blinkt?

Hausaufgabe 1.2

Wähle einen freien Pin und schließe daran eine zweite LED an. Schreibe ein Programm, das beide LEDs zum Leuchten bringt. Dann schreibe ein Programm, das beide LEDs abwechselnd blinken lässt.

Eingänge der Schaltung in der Praxis - bedingte Anweisung

Sehr oft wollen wir, dass die programmierte Schaltung auf externe Signale reagieren kann. Dieses Mal werden wir zusätzlich zur LED-Diode einen Schalter an den Arduino anschließen.

Dies soll nach dem unten stehenden Beispiel geschehen. Eine Seite des Schalters ist mit der Masse (Minus) verbunden, die andere mit Anschluss Nr. 7.
Anschließen des Schalters an den Arduino.

Achtung!
Die Schalter, die den Sets beiliegen, haben 2 statt 4 Anschlüsse, damit sie besser auf die Kontaktplatte passen. Man muss sich keine Sorgen machen, dass der Schalter auf der Grafik 4 Ausgänge hat.

Die Aufgabe wird einfach sein, aber wir müssen etwas Neues verwenden – bedingte Anweisungen. Unser Ziel ist es, ein Programm zu erstellen, das eine LED einschaltet, wenn eine Taste gedrückt wird.

Kommen wir nun zur Umsetzung der Aufgabe. Wir erwarten, dass sich das Programm ständig in einem von zwei Zuständen befindet – LED an oder aus. Zunächst ist es notwendig, den logischen Zustand abzulesen, der an dem Eingang mit dem Schalter auftritt.

Hier triffst du zum ersten Mal auf die Eingangs-Konfiguration. Beachte den bereits erwähnten INPUT_PULLUP-Modus. Wir werden ihn jedes Mal verwenden, wenn wir einen Schalter an den Arduino anschließen.

Der erste Teil des Namens (input) bedeutet natürlich Eingang, während der zweite Teil (pullup) auf die Einschaltung eines internen Pull-up-Widerstands für den Eingang hinweist.

Nun müssen wir den Zustand des Eingangs ablesen. Dazu benötigen wir die Funktion digitalRead(pin), die je nach Zustand einen HIGH- oder LOW-Wert zurückgibt. In unserer Schaltung schließt der Schalter den Arduino-Eingang mit der Masse (LOW) kurz. Das bloße Lesen des Eingangs nützt uns nichts, wir müssen das Programm von dieser Information abhängig machen können.

Daher die bedingte Anweisung (allgemein als if oder condition bezeichnet). Diese Anweisung ist sehr beliebt. Sie ermöglicht es uns, einen bestimmten Teil des Codes auszuführen, wenn bestimmte Umstände eintreten. Zum Beispiel: Wenn eine Taste gedrückt wird.
				
					[...]
void loop()
{
 //Code, der bei jedem Schleifendurchlauf ausgeführt wird

  if ( BEDINGUNG ) {
    /* Code, der nur ausgeführt wird, wenn in einer Schleife die BEDINGUNG erfüllt ist */
  }

 //Code, der bei jedem Schleifendurchlauf ausgeführt wird
}
				
			

Diese Anweisung kann sehr einfach um einen Codeteil erweitert werden, die nur ausgeführt wird, wenn die Bedingung nicht erfüllt ist. Hierfür wird die else-Anweisung verwendet.

				
					[...]
void loop()
{
 //Code, der in jedem Schleifendurchlauf ausgeführt wird

  if ( BEDINGUNG ) {
    /* Code, der nur ausgeführt wird, wenn in einem Schleifendurchlauf eine BEDINGUNG erfüllt ist */
  } else {
    /* Code, der nur ausgeführt wird, wenn eine Bedingung in einem Schleifendurchlauf NICHT erfüllt ist*/
  }

 //Code, der in jedem Schleifendurchlauf ausgeführt
}
				
			

Durch die Kombination der gewonnenen Erkenntnisse können wir ein Programm erstellen, das unsere Aufgabe erfüllt. Analysiert es und ladet es dann auf den Arduino hoch.

				
					void setup() {
  pinMode(8, OUTPUT); //Diode als Ausgang
  pinMode(7, INPUT_PULLUP); //Taste als Eingang
  digitalWrite(8, LOW); //Diode ausschalten
}

void loop()
{
  if (digitalRead(7) == LOW) { //Wenn Taste gedrückt
    digitalWrite(8, HIGH); //Diode einschalten
  } else { //Wenn Bedingung nicht erfüllt ist (Taste nicht gedrückt)
    digitalWrite(8, LOW); //Diode ausschalten
  }
}
				
			

Ein solches Programm ist jedoch wenig nützlich. Wozu brauchen wir einen Lichtschalter, der nur funktioniert, wenn wir ihn mit dem Finger gedrückt halten? Wäre es nicht besser, wenn bei Betätigung des Schalters die LED für eine bestimmte Zeit aufleuchtet?

Beispiel - Lichtschalter mit "Timer"

Nehmen wir an, wir wollen das obige Beispiel so umgestalten, dass die LED nach dem Drücken der Taste 10 Sekunden lang leuchtet. Danach soll sie ausgeschaltet werden, natürlich nur so lange, bis die Taste erneut gedrückt wird.

Kannst du ein solches Programm schon selbst schreiben? Ich hoffe es! Wenn du irgendwelche Probleme hast, kannst du dir meinen Code ansehen:

Beispiel - Verkehrsampeln

Unsere nächste Schaltung wird eine geschaltete Verkehrsampel sein. Unser Hauptziel ist es, ein Programm zu schreiben, das beim Drücken einer Taste die nächste korrekte Ampelsequenz darstellt. Gehen wir von einem solchen Ampelzyklus aus:

				
					void setup() {
  pinMode(8, OUTPUT); //Diode als Ausgang
  pinMode(7, INPUT_PULLUP); //Taste als Eingang
  digitalWrite(8, LOW); //Diode ausschalten
}

void loop()
{
  if (digitalRead(7) == LOW) { //Wenn Taste gedrückt 
    digitalWrite(8, HIGH); //Diode einschalten
    delay(10000); //10 Sekunden warten
    digitalWrite(8, LOW); //Diode ausschalten
  }
}
				
			

[…] -> Grün -> Orange -> Rot -> Rot + Orange[…].

Wenn wir die Taste drücken, sollte das System die Lichter in die nächste Sequenz schalten. Wir werden dies in mehreren Schritten erreichen. Zuerst verbinden wir die 3 LEDs und den Schalter wie unten gezeigt.

Verbindung der Verkehrsampel Schaltung

Bereiten wir die Grundstruktur des Programms vor, mit dem wir arbeiten werden. Seine Aufgabe besteht lediglich darin, die Ein- und Ausgänge zu konfigurieren.

				
					void setup() {
  pinMode(10, OUTPUT); //Rote Diode
  pinMode(9, OUTPUT); //Gelbe Diode
  pinMode(8, OUTPUT); //Grüne Diode

  pinMode(7, INPUT_PULLUP); //Taste

  digitalWrite(10, LOW); //Diode ausschalten
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
}

void loop()
{
 //Hier wird unser Programm sein
}
				
			

Vergessen wir nun den Schalter und schreiben wir ein Programm, das die Lichter automatisch jede 1 Sekunde wechselt. Es sollte wie das folgende aussehen:

				
					void setup() {
  pinMode(10, OUTPUT); //Rote Diode
  pinMode(9, OUTPUT); //Gelbe Diode
  pinMode(8, OUTPUT); //Grüne Diode

  pinMode(7, INPUT_PULLUP); //Taste

  digitalWrite(10, LOW); //Diode ausschalten
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
}

void loop()
{
  digitalWrite(10, LOW); //Rot
  digitalWrite(9, LOW); //Orange
  digitalWrite(8, HIGH); //Grün
	
  delay(1000); //1 Sekunde warten
	
  digitalWrite(10, LOW); //Rot
  digitalWrite(9, HIGH); //Orange
  digitalWrite(8, LOW); //Grün
	
  delay(1000); //1 Sekunde warten
	
  digitalWrite(10, HIGH); //Rot
  digitalWrite(9, LOW); //Orange
  digitalWrite(8, LOW); //Grün
	
  delay(1000); //1 Sekunde warten
	
  digitalWrite(10, HIGH); //Rot
  digitalWrite(9, HIGH); //Orange
  digitalWrite(8, LOW); //Grün
	
  delay(1000); //1 Sekunde warten
}
				
			

Lade das Programm auf den Arduino hoch und prüfe, ob es funktioniert. Wir müssen sicherstellen, dass alles richtig angeschlossen ist, bevor wir weitermachen.

While-Schleife

Bisher haben wir nur die notwendige „Schleife“ im Arduino loop()-Code verwendet. Jetzt ist es an der Zeit, etwas über Schleifen zu lernen, die wir innerhalb unserer Programme verwenden können.

Wir werden eine Reihe von verschiedenen Schleifen zur Verfügung haben. Wir werden uns in späteren Teilen des Kurses mit ihnen befassen.

Wir werden nun die while()-Schleife besprechen, die so lange läuft, bis eine Bedingung erfüllt ist. Ihre Funktionsweise ist im folgenden Code dargestellt:

				
					[...]
void loop()
{
 //Code, der bei jedem Druchlauf der Haupt Loop-Schleife ausgeführt wird

  while ( BEDINGUNG ) {

    /* Code der in einer Schleife ausgeführt wird, bis die BEDINGUNG nicht mehr erfüllt ist */

  }

 //Code, der jedes Mal ausgeführt wird,wenn die Haupt Loop-Schleife ausgeführt wird
				
			
Zur Verdeutlichung: Die while()-Schleife führt immer nur den Code aus, der zwischen den Klammern steht (oben orange markiert). Alle anderen Codes werden dann nicht ausgeführt.

Nehmen wir die gerade zusammengebaute Schaltung mit der Ampel und schreiben wir ein Programm, das eine LED nur dann blinken lässt, wenn wir den Knopf gedrückt haben.

Wahrscheinlich hast du hier an die bedingte if-Anweisung gedacht. Aber wie willst du das Blinken der LED realisieren? Dies ist, trotz des Anscheins, eine schwierigere Aufgabe als das Dauerlicht, das wir vorhin geschrieben haben.Der beste Weg, dieses Programm zu implementieren, ist die Verwendung einer while()-Schleife, die wie folgt aussieht:
				
					void setup() {
  pinMode(10, OUTPUT); //Rote Diode
  pinMode(9, OUTPUT); //Gelbe Diode
  pinMode(8, OUTPUT); //Grüne Diode

  pinMode(7, INPUT_PULLUP); //Taste

  digitalWrite(10, LOW); //Dioden ausschalten
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
}

void loop() {

	while (digitalRead(7) == LOW) { // Wenn die Taste gedrückt ist
		digitalWrite(10, LOW); //Rot aus
		delay(1000);
		digitalWrite(10, HIGH); //Rot an
		delay(1000);
	}
	
}
				
			
Wenn du den obigen Code verstehst, können wir mit der Ausführung unserer ursprünglichen Aufgabe fortfahren. Das heißt, das automatische Umschalten der Lichter.

Diesmal sollen die Sequenzen so lange angezeigt werden, bis wir den Schalter drücken (dann soll der Wechsel erfolgen). Dabei gehen wir davon aus, dass wir die Taste sehr schnell drücken und wieder loslassen. Das fertige Programm sollte so aussehen wie das untenstehende:
				
					void setup() {
  pinMode(10, OUTPUT); //Rote Diode
  pinMode(9, OUTPUT); //Gelbe Diode
  pinMode(8, OUTPUT); //Grüne Diode

  pinMode(7, INPUT_PULLUP); //Taste

  digitalWrite(10, LOW); //Ausschalten der Dioden
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
}

void loop()
{
  digitalWrite(10, LOW); //Rot
  digitalWrite(9, LOW); //Orange
  digitalWrite(8, HIGH); //Grün
	
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
	
  digitalWrite(10, LOW); //Rot
  digitalWrite(9, HIGH); //Orange
  digitalWrite(8, LOW); //Grün
	
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
	
  digitalWrite(10, HIGH); //Rot
  digitalWrite(9, LOW); //Orange
  digitalWrite(8, LOW); //Grün
	
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
	
  digitalWrite(10, HIGH); //Rot
  digitalWrite(9, HIGH); //Orange
  digitalWrite(8, LOW); //Grün
	
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
}
				
			

In diesem Fall wurde die Schleife auf eine recht seltsame Weise verwendet. Wie man sieht, befindet sich nichts in den Klammern! Warum funktioniert das Programm dennoch? Weil das Programm Schleifen benutzt, um zu stoppen.


Wie funktioniert das?


Wir starten die LED-Leuchten nach einer bestimmten Sequenz,
wir gehen in die while()-Schleife, die sich direkt darunter befindet,
die Schleife ist leer, also läuft das Programm im Kreis, und…. tut nichts,
erst wenn die Taste gedrückt wird (Bedingung nicht erfüllt), verlässt das Programm die Schleife,
eine weitere Sequenz wird eingeschaltet und die Situation wiederholt sich.


Schauen wir uns an, wie das Programm in der Praxis funktioniert!


Was passiert da eigentlich? Funktioniert alles so, wie es soll? Nein! Auch wenn wir die Taste nur ganz kurz drücken, funktioniert das Programm manchmal richtig und manchmal springt es ein paar Positionen weiter. Warum passiert das?


Wie du dich aus dem ersten Teil erinnern solltest, führt der Prozessor, um es einfach auszudrücken, etwa 16 Millionen Operationen pro Sekunde aus. Folglich schafft er es, alle Zustände unserer Signalisierung zu durchlaufen (und das nicht nur einmal…), wenn die Taste gedrückt wird. Die verschiedenen Effekte beim Loslassen des Knopfes sind nur das Ergebnis einer zufälligen „Aktion“ in einer bestimmten Sequenz.


Wie lässt sich dieses Problem lösen? Ganz einfach. Es genügt, das Programm so zu überarbeiten, dass der Wechsel der Lichter nicht öfter als z.B. jede Sekunde stattfindet. Wir können dafür die bereits bekannte Funktion delay() verwenden.

				
					void setup() {
  pinMode(10, OUTPUT); //Rote Diode
  pinMode(9, OUTPUT); //Gelbe Diode
  pinMode(8, OUTPUT); //Grüne Diode

  pinMode(7, INPUT_PULLUP); //Taste

  digitalWrite(10, LOW); //Ausschalten der Dioden
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
}

void loop()
{
  digitalWrite(10, LOW); //Rot
  digitalWrite(9, LOW); //Orange
  digitalWrite(8, HIGH); //Grün
	
  delay(1000); //Anhalten des Programms vor Eintritt in die Schleife für 1 Sekunde
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
	
  digitalWrite(10, LOW); //Rot
  digitalWrite(9, HIGH); //Orange
  digitalWrite(8, LOW); //Grün
	
  delay(1000); //Anhalten des Programms vor Eintritt in die Schleife für 1 Sekunde
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
	
  digitalWrite(10, HIGH); //Rot
  digitalWrite(9, LOW); //Orange
  digitalWrite(8, LOW); //Grün
	
  delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
	
  digitalWrite(10, HIGH); //Rot
  digitalWrite(9, HIGH); //Orange
  digitalWrite(8, LOW); //Grün
	
  delay(1000); //Anhalten des Programms vor Eintritt in die Schleife für 1 Sekunde
  while (digitalRead(7) == HIGH) {} //Warten auf Tastendruck
}
				
			

Jetzt sollte alles richtig funktionieren!

Es ist erwähnenswert, dass die Bedingungen in der while()-Schleife kombiniert und viel umfangreicher sein können, aber wir werden auf dieses Thema zurückkommen, wenn wir die Variablen besprochen haben.

Denkt daran, dass das Set von Komponenten, das für alle Übungen benötigt wird, bei Botland erhältlich ist. Mit dem Kauf der Sets unterstützt ihr zukünftige Veröffentlichungen zu Forbot!

Zusammenfassung

Nachdem du die Programme in diesem Abschnitt durchgesehen und verstanden hast, solltest du keine Probleme mehr mit den wichtigsten Mikrocontroller-Peripheriegeräten und I/O-Ports haben. Ich hoffe, du hast auch gemerkt, dass es oft sinnvoll ist, das Programm in mehrere Schritte aufzuteilen, anstatt gleich die „volle Funktionalität“ zu schreiben.

Im nächsten Teil geht es um die Kommunikation mit dem Computer über USB. Dies wird es einfacher machen, spätere, erweiterte Programme zu testen.
Bestellen Sie ein Set mit Elementen und beginnen Sie mit dem Lernen in der Praxis! Hier gehts zum Shop >>
Nach oben scrollen