Tinkercad Übung 7 - LED Lauflicht (1)
Animiere ein LED-Blinkmuster
In dieser Übung animierst du 10 LEDs, dokumentierst deinen Programmcode und machst ihn konfiguierbar.
- Empfohlenes Vorwissen: Bedienung Tinkercad Circuits, Pin als Ausgang konfigurieren sowie ein- und ausschalten
- Neue Inhalte: Code-Kommentare schreiben, #define, Konstanten
Schritt 1 - Alle LEDs einschalten
Baue folgende Schaltung auf oder kopiere sie von hier:https://www.tinkercad.com/things/lF842Kx57rx-kkg-robotik-ubung-7-lauflicht-1-starter
![]() |
Abbildung 1 - Schaltung mit 10 LEDs und 1 Taster |
Die LEDs sind an Pins 4 bis 13 angeschlossen.
Schreibe ein Programm, dass alle LEDs als Ausgang konfiguriert und dann einschaltet.
Schritt 2 - Kommentare
Du wirst bemerken: Das Programm wird schon ein bisschen größer. Und das ist erst der Anfang!Ganz nach der Devise „Hast du Kopf wie Sieb, musst du aufschreiben!“, hinterlässt man oft Kommentare im Programm-Code, die beschreiben, was dort genau passiert. Oft kommentiert man sogar einzelne Befehlszeilen und beschreibt, was sie bewirken. Das hilft auch anderen, wenn sie Teile deines Programms verstehen müssen.
Kommentare werden bei der Ausführung des Programms übersprungen. Man kann dort fast jeden Text verfassen und sogar Umlaute sowie ß verwenden.
Einzeiliges Kommentar (beginnt mit // ):
// das hier ist ein einzeiliges Kommentar
hier ist das Kommentar aber schon wieder zu Ende
tonAbspielen(A5, 1, 100, 0); // hier därf ich sogär Umläüte benützen
// tonAbspielen(A5, 1, 100, 0); Diese Befehlszeile wird ignoriert
Wie oben gezeigt, kann man auch einzelne Befehlszeilen auskommentieren und so „überspringen“, wenn man den Code nicht löschen will, aber auch nicht will, dass er ausgeführt wird. (Zum Testen nützlich.)
Mehrzeiliges Kommentar (Beginn: /* , Ende: */ ):
/* das hier
ist ein
mehrzeiliges
Kommentar. */
Mehrere auskommentierte Befehlszeilen (werden übersprungen):
/*
tonAbspielen(A5, 1, 100, 0);
tonAbspielen(A5, 1, 100, 0);
*/
Hinterlasse Kommentare im Programmcode, damit dein Ich der Zukunft noch etwas damit anzufangen wüsste (also z.B. generell was das Programm macht und dann einige Programmzeilen, wozu sie da sind).
Schritt 3 - Animation
Schreibe nun ein Programm im, dass nacheinander einzelne LEDs ein- und ausschaltet (den Verzögerungsbefehl delay() nicht vergessen). Das Programm wird recht umfangreich. Kommentiere dein Programm ausführlich. Verschiebe deine Animation in den loop()-Bereich, damit sie immer wiederholt wird.Zur Inspiration hier ein paar Beispiel-Animationen:
Streifen
Lösungsvorschlag: https://www.tinkercad.com/things/7KDfrHr9pcB-kkg-robotik-ubung-7-lauflicht-1-streifen
Einfaches Lauflicht
Lösungsvorschlag: https://www.tinkercad.com/things/eQYXrSrdYUI-kkg-robotik-ubung-7-lauflicht-1-rundum
Einfaches Lauflicht An/Aus
Lösungsvorschlag: https://www.tinkercad.com/things/iptR6sW2GSQ-kkg-robotik-ubung-7-lauflicht-1-rundum-anaus
Doppeltes Lauflicht:
Lösungsvorschlag: https://www.tinkercad.com/things/9yXqzgRDgFt-kkg-robotik-ubung-7-lauflicht-1-rundum-doppelSchritt 4 - Geschwindigkeit einstellen
Dein Programm enthält jetzt sehr viele Verzögerungsbefehle, z.B.:delay(100);
Wenn du jetzt die Animationsgeschwindigkeit ändern wollen würdest, müsstest du alle diese Zeilen ändern. Um die Animation doppelt so langsam zu machen z.B.:
delay(200);
Bei größeren Programmen tritt dieses Problem andauernd auf. Zum Glück können wir den Parameter "Verzögerungsdauer" des delay()-Befehls nicht nur als Zahl angeben, sondern auch einen Platzhalter verwenden.
Dafür gibt es 2 Möglichkeiten.
1. Präprozessor-Makros:
Das sind streng genommen keine echten Programmier-Befehle, sondern sie werden ausgewertet, bevor das Programm in Maschinencode übersetzt (kompiliert) wird. Mit ihnen kann man Textmanipulation vornehmen. Diese Makros beginnen immer mit einem Hashtag (#).
Das Präprozessor-Makro, dass für uns momentan in Frage kommt, heißt #define und man kann damit Text suchen und ersetzen.
#define GESUCHTER_TEXT ERSETZTER_TEXT
ersetzt alle Vorkommnisse von GESUCHTER_TEXT durch ERSETZTER_TEXT.
Damit kann man ganz spaßige Dinge tun, z.B. kann man sich seine eigene Programmiersprache schreiben:
setup() {
pinMode(4, OUTPUT);
}
kann man zum Beispiel so umschreiben:
#define tom_tom setup
#define konfiguriere pinMode
#define AUSGANG OUTPUT
konfiguriere(4, AUSGANG);
}
Sind alle Vorkommnisse von tom_tom, konfiguriere und AUSGANG durch ihre jeweiligen Ersetzungstexte ersetzt worden, ist der Programmcode wieder korrekt und kann kompiliert werden.
Die #defines müssen definiert werden, bevor sie verwendet werden. Das Programm wird von oben nach unten gelesen. Die #defines stehen am besten also immer am Anfang des Programms. Das ist auch übersichtlicher so.
Das ist hier in dem Lösungsvorschlag für Schritt 1 einmal demonstriert:
https://www.tinkercad.com/things/86oYTt9ibs7-kkg-robotik-ubung-7-lauflicht-1-alle-an
Sinnvoll ist dies allerdings im Fall von delay():
delay(100);
delay(100);
delay(100);
Sowas wie die "100" Millisekunden nennt man "Magic Numbers". Das sind alle unveränderlichen (konstanten) Zahlen und Texte, die direkt im Programmcode auftauchen und nicht vorher schon definiert wurden. Es ist guter Stil, Magic Numbers generell zu vermeiden, wenn es nicht zu viel Arbeit macht.
Im Beispiel von delay() könnte das so aussehen:
// Einstellungen:
// Animationsgeschwindigkeit
#define WARTEZEIT_MS 100 // Wartezeit in Millisekunden
delay(WARTEZEIT_MS);
delay(WARTEZEIT_MS);
delay(WARTEZEIT_MS);
Baue dein Programm so um, dass alle Verzögerungszeiten durch ein #define ersetzt werden. Jetzt kannst du die Animationsgeschwindigkeit schnell verändern, indem du nur eine einzige Zahl änderst. Probiere dies aus.
Schritt 5 - Konstanten
Eine weitere Möglichkeit sind Konstanten. Diese sind keine Präprozessor-Makros, sondern echte Programm-Befehle, die kompiliert werden. Sie können unter einem Namen einen Wert im RAM des Mikrocontrollers abspeichern, in unserem Fall 100 Millisekunden. Dieser kann mit dem Namen wieder nachgeschlagen werden.// Einstellungen:
// Animationsgeschwindigkeit
const int WARTEZEIT_MS = 100; // Wartezeit in Millisekunden
delay(WARTEZEIT_MS);
delay(WARTEZEIT_MS);
delay(WARTEZEIT_MS);
- const sagt dem Compiler, dass es sich um eine Konstante handelt, der Wert sich also nie ändern wird. Kann man aber auch weglassen.
- int ist ein Datentyp (dazu später mehr). Wir haben bisher die Datentypen "Zahl" und "Text" verwendet. "int" sagt dem Compiler, dass unsere Konstante eine Zahl abspeichern soll.
- WARTEZEIT_MS: Der Name der Konstante. Es ist Konvention, dass man alles, was konstant ist (also nicht den Wert ändern kann), mit Großbuchstaben benennt. Das muss man nicht so machen, aber es machen die meisten Programmierer so.
- = 100 der Wert der Konstante.
Der Vorteil gegenüber #define ist hier eindeutig der Datentyp. Mit #define geht alles und es ist leicht Fehler zu machen, die man schwer findet. Im Falle von "const int" weiß aber der Compiler, dass es sich um eine Zahl handelt und wird rummeckern, wenn wir zum Beispiel folgendes schreiben würden:
const int WARTEZEIT_MS = "Wartezeit in Millisekunden";
Man kann einen Text nicht in einer Konstante vom Typ int (Zahl) abspeichern. Der Compiler denkt mit und sagt uns das in der Fehlermeldung.
Baue dein Programm so um, dass es anstatt von #define eine Konstante zur Geschwindigkeitseinstellung verwendet.
Zusammenfassung
In dieser Übung hast du eine LED-Animation erstellt, dein Programm kommentiert und Magic Numbers entfernt. Dein Code ist nun wesentlich besser verständlich.
Kommentare
Kommentar veröffentlichen