Hier erfährst du einige wichtige Grundlagen zum Programmieren von Arduino. Bevor du mit der Arbeit mit Arduino beginnst, macht es Sinn, die ersten beiden Abschnitte aufmerksam durchzulesen und die weiteren Abschnitte zu überfliegen.
Hier erfährst du einige wichtige Grundlagen zum Programmieren von Arduino. Bevor du mit der Arbeit mit Arduino beginnst, macht es Sinn, die ersten beiden Abschnitte aufmerksam durchzulesen und die weiteren Abschnitte zu überfliegen.
Ein Programm ist eine Reihe von Anweisungen, die ein Computer ausführt, um eine bestimmte Aufgabe zu erledigen. Ein Programm kann mit einem Rezept verglichen werden. So wie ein Rezept vorgibt, welche Zutaten benötigt werden und welche Schritte in welcher Reihenfolge auszuführen sind, gibt ein Programm dem Computer vor, was zu tun ist und in welcher Reihenfolge die Anweisungen abgearbeitet werden sollen.
Ein einfaches Beispiel für ein Arduino-Programm ist das Blink-Programm. Dieses Programm enthält Anweisungen, die eine LED an- und ausschalten. Das Arduino führt die folgenden Schritte aus: Zuerst wird die LED eingeschaltet ( digitalWrite(LED_BUILTIN, HIGH);), dann wartet das Arduino eine Sekunde (delay(1000);), danach wird die LED wieder ausgeschaltet (digitalWrite(LED_BUILTIN, LOW);) und es wird erneut eine Sekunde gewartet ( delay(1000);). Dann springt das Programm zurück zum Anfang der Loop Klammer. So werden diese Schritte immer wieder wiederholt, sodass die LED blinkt.
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // Schaltet die LED ein (setzt den Pin auf HIGH)
delay(1000); // Wartet eine Sekunde (1000 Millisekunden)
digitalWrite(LED_BUILTIN, LOW); // Schaltet die LED aus (setzt den Pin auf LOW)
delay(1000); // Wartet eine Sekunde (1000 Millisekunden)
}
Unten siehst du das gleiche Programm als Blockdarstellung.
Bevor das Programm ausgeführt werden kann, muss es compiliert werden. Beim Compilieren wird der Programmcode, der in einer Programmiersprache geschrieben ist, in eine Sprache übersetzt, die der Computer direkt verstehen kann. Dieser Vorgang wandelt den menschenlesbaren Code in Maschinensprache um. Nach dem Compilieren wird das Programm auf dem Computer oder Mikrocontroller gespeichert und kann ausgeführt werden. Sobald das Programm gestartet ist, beginnt die LED zu blinken, wie im Programm festgelegt.
Um erste Erfahrungen im Programmieren zu sammeln, kann es sinnvoll sein, mit Tools wie Scratch oder Turtlestitch zu experimentieren.
Ein Arduino-Programm besteht aus zwei Teilen. Einem Setup-Teil und einem Loop-Teil. Der Setup-Teil wird nur einmal, beim Start des Arduinos, ausgeführt. Der Loop-Teil wird fortlaufend ausgeführt, wenn alle Befehle in diesem Teil abgearbeitet sind, beginnt die Abarbeitung wieder am Start des Loop-Teils. Text, nach einem doppelten Schrägstrich ist ein Kommentar, der keinen Einfluss auf die Funktion des Programmes hat. Er dient lediglich dazu, das Programm besser nachvollziehbar zu machen. Manchmal sehen vor dem Setup noch weitere Anweisungen, die für das ganze Programm gültig sind, wie die Einbindung von Libraries oder es werden Variabeln erstellt.
LED_BUILTIN ist Pin 13. An Pin 13 ist eine LED fix eingebaut.
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Initialisiert den eingebauten LED-Pin als Ausgang
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // Schaltet die LED ein (setzt den Pin auf HIGH)
delay(1000); // Wartet eine Sekunde (1000 Millisekunden)
digitalWrite(LED_BUILTIN, LOW); // Schaltet die LED aus (setzt den Pin auf LOW)
delay(1000); // Wartet eine Sekunde (1000 Millisekunden)
}
Programmcodes zusammenführen
Manchmal kann es nötig sein, zwei Teilprogramme zusammenzuführen: Kopiere dazu den Code des eine Programmes in den entsprechenden Block des anderen Programmes. Je nachdem, ob es sich um einmalige Initialisierungen (setup) oder wiederkehrende Aktionen (loop) handelt. Anweisungen, die nur einmal zu Beginn ausgeführt werden (z. B. Pin-Initialisierungen), gehören in den setup()-Block. Wiederholt auszuführende Befehle (z. B. Schaltvorgänge) werden in den loop()-Block eingefügt. Zusätzliche Anweisungen wie die Einbindung von Libraries werden vor den setup()- und loop()-Blöcken am Anfang des Programmes platziert.
Eine if-Anweisung entscheidet, ob ein bestimmter Code ausgeführt wird, abhängig davon, ob eine Bedingung erfüllt ist. Zum Beispiel: "Wenn es regnet, nimm einen Regenschirm." Eine for-Schlaufe wiederholt einen Codeabschnitt so oft, wie es nötig ist. Zum Beispiel: "Lege 10 Äpfel nacheinander in einen Korb." Beide Konzepte helfen dabei, Programme flexibler und effizienter zu gestalten.
if: Führt den Code einmalig aus, abhängig davon, ob die Bedingung erfüllt ist.
for: Führt den Code eine festgelegte Anzahl von Malen aus, gesteuert durch eine Zählvariable.
if-Anweisung
Funktion: Führt einen Codeblock basierend auf einer Bedingung einmal aus.
Verwendung: Um Entscheidungen zu treffen und eine bestimmte Aktion nur dann auszuführen, wenn eine Bedingung wahr (true) ist.
Struktur:
if (Bedingung) {
// Codeblock, der ausgeführt wird, wenn die Bedingung wahr ist
}
Beispiel:
if (sensorWert > 500) {
digitalWrite(LED_BUILTIN, HIGH); // LED einschalten
}
Erläuterung:
In diesem Beispiel wird der Wert einer Variablen sensorWert überprüft. Wenn der Wert größer als 500 ist, wird eine LED eingeschaltet, indem das eingebaute LED-Pin auf HIGH gesetzt wird. Falls der Wert 500 oder kleiner ist, passiert nichts.
Funktion: Wiederholt einen Codeblock eine festgelegte Anzahl von Malen.
Verwendung: Um eine Aktion eine bestimmte Anzahl von Malen zu wiederholen. Die Schleife verwendet oft eine Zählvariable, um die Wiederholungen zu steuern.
Struktur:
for (initialisieren; Bedingung; Inkrement) {
// Codeblock, der bei jedem Durchlauf ausgeführt wird
}
Beispiel:
for (int i = 0; i < 10; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
Erläuterung:
In diesem Beispiel wird eine LED zehn Mal ein- und ausgeschaltet. Die Schleife läuft 10 Mal, wobei die Zählvariable i jedes Mal um 1 erhöht wird. Die LED wird jedes Mal für 500 Millisekunden eingeschaltet und dann wieder ausgeschaltet.
Ein Arduino-Programm erscheint erst mal sehr kryptisch. Hier findest du die wichtigsten Operatoren, die dir beim Entziffern helfen können.
Zuweisungsoperator (=): Weist einer Variablen einen Wert zu. Beispiel: int x = 5;
Vergleichsoperator (==): Vergleicht zwei Werte auf Gleichheit. Beispiel: if (x == 5)
Inkrementoperator (++): Erhöht den Wert einer Variablen um 1. Beispiel: x++;
Dekrementoperator (--): Verringert den Wert einer Variablen um 1. Beispiel: x--;
Mathematische Operatoren (+, -, /, *):
Addition (+): Addiert zwei Werte. Beispiel: int y = x + 2;
Subtraktion (-): Subtrahiert einen Wert von einem anderen. Beispiel: int y = x - 2;
Multiplikation (*): Multipliziert zwei Werte. Beispiel: int y = x * 2;
Division (/): Teilt einen Wert durch einen anderen. Beispiel: int y = x / 2;
Logische Operatoren (&&, ||):
Und (&&): Wahr, wenn beide Bedingungen wahr sind. Beispiel: if (x > 0 && y > 0)
Oder (||): Wahr, wenn eine der Bedingungen wahr ist. Beispiel: if (x > 0 || y > 0)
HIGH und LOW: Zustände, die häufig in digitalen Ein-/Ausgängen verwendet werden.
HIGH: Entspricht einem hohen Spannungspegel (meist 5V oder 3.3V). Beispiel: digitalWrite(pin, HIGH);
LOW: Entspricht einem niedrigen Spannungspegel (0V). Beispiel: digitalWrite(pin, LOW);
Semikolon (;): Markiert das Ende einer Anweisung. Beispiel: int x = 5;
Nicht-Operator (!): Invertiert den Wahrheitswert einer Bedingung. Beispiel: if (!x)
Vergleichsoperatoren (<, >, <=, >=): Vergleicht zwei Werte.
Beispiel: if (x < 5), if (x >= 3)
11. Klammern ((), {}):
Runde Klammern (()): Werden für Funktionsaufrufe und zur Gruppierung von Ausdrücken verwendet. Beispiel: if (x > 0), digitalWrite(pin, HIGH);
Geschweifte Klammern ({}): Markieren den Anfang und das Ende eines Codeblocks. Beispiel: if (x > 0) { // Codeblock }
Libraries, oder Bibliotheken, sind Sammlungen von vorgefertigtem Code, welche die Programmierung erleichtern. Man kann sich das als Sammlung von Unterprogrammen vorstellen, die mit einem Befehl gestartet werden können. Ein Beispiel dafür ist die Melody-Library, mit welcher Melodien erzeugt werden können. Wird mit der library gearbeitet, kann anstatt tone(pin1, 440); der Befehl melody.play("A1"); verwendet werden.
Eine Fehlermeldung wie
Compilation error: melody.h: No such file or directory
deutet darauf hin, dass eine im Programmcode verwendete Library nicht installiert ist. Klicke dann auf das Bibliotheks-Icon, suche nach der Library und installiere sie.
Ein vollständiger Code mit der libray melody kann so aussehen:
#include <Melody.h>
// Erstelle ein Melody-Objekt
Melody melody;
// Definiere den Pin für den Buzzer
const int buzzerPin = 8;
void setup() {
// Initialisiere den Buzzer-Pin
melody.begin(buzzerPin);
// Setze das Tempo auf 120 BPM
melody.setTempo(120);
// Spiele eine einfache Melodie mit unterschiedlichen Notenlängen
melody.play("C4/4 D4/4 E4/4 F4/4 G4/4 A4/4 B4/4 C5/2");
}
void loop() {
// Die Melodie läuft im Hintergrund und benötigt keine weiteren Aktionen im Loop
}
LLMs (large language models) wie ChatGPT oder https://www.duinocodegenerator.com/ sind sehr gut darin, Arduino-Code zu erzeugen. Das hat den Vorteil, dass damit schnell Resultate erzielt werden können, aber auch den Nachteil, dass der Code nicht verstanden wird, was Anpassungen schwierig macht und die eigenen Kompetenzen weniger stark erweitert werden. Wiederum positiv ist, dass die LLMs auch gut darin sind, Arduino-Code zu erklären oder bei Fehlermeldungen weiterzuhelfen. Wenn mit diesen Tools gearbeitet wird, sollten die von https://www.duinocodegenerator.com/ verfassten Hinweise unten beachtet werden. Ob diese Tools eingesetzt werden, ist eine persönliche Entscheidung. Wichtig ist, dass deren Einsatz in Abgaben deklariert wird.
Gib der KI möglichst viel Kontext. Sie weiss zum Beispiel nicht, dass du vielleicht noch nie mit Arduino gearbeitet hast, also teile ihr deine Erfahrung mit. Sie weiss auch nicht, mit welchem Board du genau arbeitest und an welchen Anschlüssen du was angeschlossen hast.
Für beste Ergebnisse:
Sei spezifisch: Gib Details zu deinem Projekt an, einschliesslich des Arduino-Board-Typs, der Sensoren, Motoren und anderer Komponenten, die du verwenden möchtest.
Teile auf: Wenn dein Prompt komplex ist, überlege, ihn in kleinere, handhabbare Teile zu zerlegen, um es dem Tool leichter zu machen, ihn zu verarbeiten.
Teste und verfeinere: Teste deinen Prompt. Wenn das Ergebnis nicht deinen Erwartungen entspricht, versuche, deinen Input anzupassen.
Gute Beispiele:
Einfach: „Programmiere ein Arduino Uno, um eine LED, die an Pin 13 angeschlossen ist, alle 500 ms blinken zu lassen.“
Spezifisch: „Lies einen DS18B20-Temperatursensor aus, der mit einem Arduino Uno verbunden ist, und zeige die Temperatur in Celsius auf einem DFR0063-LCD-Bildschirm an.“
Detailliert: „Steuere ein automatisches Bewässerungssystem mit einem Arduino Mega, einem Bodenfeuchtigkeitssensor und einer Wasserpumpe. Der Code sollte die Sensordaten auslesen und die Pumpe aktivieren, wenn die Bodenfeuchtigkeit unter einen im Code festgelegten Schwellenwert fällt.“
Schlechte Beispiele:
Nicht geeignet für Arduino: „Führe einen maschinellen Lernalgorithmus aus, um Obst mit einer Kamera zu klassifizieren.“
Zu vage: „Programmiere einen Roboter, um mein Zimmer zu reinigen.“
Benötigt mehr Details: „Steuere ein Ampelsystem, das die Farben zu verschiedenen Tageszeiten basierend auf einem vorprogrammierten Zeitplan ändert.“
Digitale Signale sind binäre Signale, die nur zwei Zustände haben: "0" (LOW) und "1" (HIGH). Diese Zustände repräsentieren typischerweise niedrige (z.B. 0 Volt) und hohe Spannungen (z.B. 5 Volt) und eignen sich für klare, eindeutige Aktionen wie das Ein- oder Ausschalten von Geräten. Beispiel: digitalWrite(13, HIGH); // Schaltet Pin 13 auf HIGH (5V)
Analoge Signale hingegen können einen kontinuierlichen Bereich von Werten annehmen, im Gegensatz zu den binären Zuständen digitaler Signale. Sie repräsentieren Spannungen, die stufenlos zwischen einem Minimum (z.B. 0 Volt) und einem Maximum (z.B. 5 Volt) variieren können. Diese Signale sind ideal für Anwendungen, bei denen es auf fein abgestufte Informationen ankommt, wie z.B. das Messen von Sensorwerten (Temperatur, Lichtintensität, etc.). Beispiel: int sensorValue = analogRead(A0); // Liest einen analogen Wert von Pin A0
Der Serial Monitor in der Arduino-IDE ermöglicht es dir, Daten in Echtzeit zwischen deinem Arduino und deinem Computer auszutauschen. Du kannst damit Nachrichten, Sensorwerte oder andere Daten anzeigen lassen, was besonders hilfreich bei der Fehlersuche und Überwachung deines Programms ist. Den Serial Monitor findest du unter Werkzeuge > Serieller Monitor (oder über die Lupe oben rechts) oder durch Klicken auf das Lupensymbol in der rechten oberen Ecke.
Der Serial Plotter ist ein weiteres Tool in der Arduino-IDE, das Daten grafisch darstellt. Er ist nützlich, um Trends und Veränderungen in Echtzeit zu verfolgen, beispielsweise bei Sensorwerten. Den Serial Plotter findest du unter Werkzeuge > Serieller Plotter. Mit ihm kannst du Daten als Diagramm anzeigen und so Muster und Veränderungen leichter erkennen.
Hier ist ein einfacher Beispielcode, um die Werte eines lichtabhängigen Widerstands (LDR) im Serial Monitor anzuzeigen und im Serial Plotter darzustellen:
void setup() {
Serial.begin(9600); // Starte die serielle Kommunikation mit 9600 Baud
}
void loop() {
int sensorValue = analogRead(A0); // Lese den Wert vom Lichtsensor (angeschlossen an A0)
Serial.println(sensorValue); // Sende den Wert an den Serial Monitor und Plotter
delay(100); // Warte 100 Millisekunden vor der nächsten Messung
}
"Blink without delay" ist eine Methode, um eine LED blinken zu lassen, ohne die Funktion delay() zu verwenden. Der Nachteil von delay() ist, dass der Arduino während der Wartezeit blockiert wird und keine anderen Befehle ausführen kann. Stattdessen ermöglicht millis() die Messung der verstrichenen Zeit, ohne das Programm zu stoppen, sodass der Arduino andere Aufgaben gleichzeitig ausführen kann.
int ledState = LOW; // Variable, die den aktuellen Zustand der LED speichert (LOW = aus, HIGH = ein)
unsigned long previousMillis = 0; // Speichert die letzte Zeit, zu der die LED umgeschaltet wurde
void setup() {
pinMode(13, OUTPUT); // Setze Pin 13 als Ausgang, an dem die LED angeschlossen ist
}
void loop() {
unsigned long currentMillis = millis(); // Speichert die aktuelle Zeit in Millisekunden seit Programmstart
// Überprüfen, ob 1 Sekunde (1000 Millisekunden) vergangen ist
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis; // Aktualisiert den Zeitpunkt des letzten Umschaltens
// Umschalten des LED-Zustands: Wenn die LED aus ist, wird sie eingeschaltet, und umgekehrt
if (ledState == LOW) {
ledState = HIGH; // Schaltet die LED ein
} else {
ledState = LOW; // Schaltet die LED aus
}
digitalWrite(13, ledState); // Setzt den neuen Zustand der LED auf Pin 13
}
}
Mit diesem Code lässt sich die LED im regelmäßigen Takt ein- und ausschalten, während der Arduino weiterhin andere Aufgaben erledigen kann, ohne durch delay() blockiert zu werden.
Variablen sind Speicherplätze im Arduino, in welche du Daten wie Zahlen, Texte oder Zustände speichern und später wiieder zugreifen kannst.
Der Datentyp einer Variablen bestimmt, welche Art von Daten sie speichern kann. Zum Beispiel speichert der Datentyp int ganze Zahlen, während float für Dezimalzahlen verwendet wird. Jede Variable hat einen Namen, den du frei wählen kannst. Dieser Name sollte beschreiben, wofür die Variable verwendet wird, zum Beispiel temperature, um die aktuelle Temperatur zu speichern.
Um eine Variable zu erstellen, gibst du ihren Datentyp und Namen an, zum Beispiel int temperature;, und weist ihr einen Startwert zu, wie in int temperature = 25;.
Beispiel:
int temperature = 25; // Erstelle eine Variable, die die gemessene Temperatur speichert
In diesem Beispiel wird die Variable temperature erstellt und mit dem Wert 25 gefüllt. Dieser Wert kann im Programm aufgerufen oder verändert werden.