Grundlagen · 15 Min. Lesezeit

Arduino-Befehle: Liste mit Syntax, Beispielen und Fehlern

Arduino-Befehle erklärt: pinMode, digitalWrite, analogRead, analogWrite, millis, Serial, map, tone, pulseIn und attachInterrupt mit Beispielen und Fehlern.

Arduino-Befehle sind fertige Funktionen, die dem Board sagen, was es tun soll: pinMode() macht einen Pin zum Ausgang, digitalWrite() schaltet eine LED ein, analogRead() liest einen Sensor und Serial.println() schickt eine Nachricht an den Computer. Die meisten Arduino-Sketches bestehen eigentlich nur aus rund zwanzig Grundbefehlen, die unterschiedlich kombiniert werden. Wenn du diese Befehle und ihre Bedeutung einmal richtig verstanden hast, kannst du jeden Code lesen, vom Blinken einer LED bis zum Roboterauto, und dein eigenes Projekt von Grund auf schreiben.

In dieser Anleitung haben wir die meistgenutzten Arduino-Befehle in vier Gruppen eingeteilt: Ein- und Ausgabe, Zeit, Mathematik und Kommunikation. Zu jedem Befehl findest du die Syntax, die Bedeutung der Parameter, ein kurzes Beispiel, das auf einem Arduino Uno kompiliert und läuft, und den Fehler, den Einsteiger am häufigsten machen. In den letzten Abschnitten sehen wir uns außerdem an, wie sich dieselben Befehle auf dem ESP32 anders verhalten und wie ihre MicroPython-Entsprechungen auf dem Raspberry Pi Pico aussehen.

Arduino-Uno-Board mit digitalen und analogen Pins
Arduino Uno: Die digitalen Pins 0–13, die analogen Eingänge A0–A5 und die mit ~ markierten PWM-Pins reichen aus, um alle Befehle in diesem Artikel auszuprobieren.

Was ist ein Arduino-Befehl und wie läuft ein Sketch ab?

Arduino-Code basiert auf C/C++; das meiste, was wir „Befehle“ nennen, sind eigentlich Funktionen, die dir der Arduino-Core fertig bereitstellt. Eine Funktion bekommt Parameter in Klammern (zum Beispiel eine Pinnummer und einen Wert), und manche liefern ein Ergebnis zurück: digitalRead() den Zustand eines Pins, millis() die vergangene Zeit. Jeder Arduino-Sketch hat zwei Pflichtfunktionen: setup() läuft nur einmal, wenn das Board eingeschaltet oder zurückgesetzt wird, und loop() wiederholt sich danach endlos. Vorbereitungen wie Pin-Einstellungen und Serial.begin() gehören in setup(), alles, was ständig passieren soll, in loop().

Arduino (C++)
1// Her Arduino programı bu iki fonksiyondan oluşur / Every Arduino sketch has these two functions
2void setup() {
3  // Açılışta ya da resetten sonra bir kez çalışır / Runs once at power-up or after reset
4  pinMode(13, OUTPUT);      // dahili LED pini çıkış / built-in LED pin as output
5}
6
7void loop() {
8  // Sonsuza kadar tekrar eder / Repeats forever
9  digitalWrite(13, HIGH);   // LED'i yak / turn the LED on
10  delay(500);               // 500 ms bekle / wait 500 ms
11  digitalWrite(13, LOW);    // LED'i söndür / turn the LED off
12  delay(500);
13}

Wenn du drei Regeln von Anfang an beachtest, ersparst du dir viele Kompilierfehler: Befehle unterscheiden Groß- und Kleinschreibung (schreibst du digitalwrite, bekommst du den Fehler „'digitalwrite' was not declared in this scope“), jede Anweisung endet mit einem Semikolon, und Text steht in doppelten, einzelne Zeichen in einfachen Anführungszeichen. Zu Variablentypen und Strukturen wie if und for schau dir die Grundlagen der Arduino-Programmierung an.

Liste der Arduino-Befehle: Tabellen nach Kategorien

Die vier Tabellen unten fassen fast alle Befehle zusammen, die du in alltäglichen Projekten brauchst. Die erste Gruppe sind die Ein- und Ausgabebefehle; sie legen die Aufgabe eines Pins fest, geben eine Spannung aus oder lesen einen Wert ein. Die Pinnummern deines Boards findest du im Werkzeug Pinout.

BefehlSyntaxWas er machtBeispiel
pinModepinMode(pin, modus)Macht einen Pin zum Ein- oder AusgangpinMode(13, OUTPUT);
digitalWritedigitalWrite(pin, wert)Setzt einen Pin auf HIGH (5 V) oder LOW (0 V)digitalWrite(13, HIGH);
digitalReaddigitalRead(pin)Liest, ob ein Pin HIGH oder LOW istint b = digitalRead(2);
analogReadanalogRead(pin)Wandelt 0–5 V in eine Zahl von 0 bis 1023 umint v = analogRead(A0);
analogWriteanalogWrite(pin, wert)Erzeugt ein PWM-Signal von 0 bis 255analogWrite(9, 128);
analogReferenceanalogReference(typ)Wählt die Referenzspannung für analogReadanalogReference(INTERNAL);
tone / noTonetone(pin, frequenz, dauer)Erzeugt einen Ton per Rechtecksignal, noTone stoppt ihntone(8, 440, 500);
pulseInpulseIn(pin, wert, timeout)Misst die Länge eines Impulses in µspulseIn(10, HIGH, 30000);
shiftOutshiftOut(datenPin, taktPin, reihenfolge, byte)Schiebt ein Byte Bit für Bit hinaus (z. B. an einen 74HC595)shiftOut(11, 12, MSBFIRST, 255);
attachInterruptattachInterrupt(interrupt, funktion, modus)Ruft sofort eine Funktion auf, wenn sich ein Pin ändertattachInterrupt(digitalPinToInterrupt(2), say, FALLING);

Die zweite Gruppe sind die Zeitbefehle. Den Unterschied zwischen delay(), das wartet, und millis() sowie micros(), die Zeit messen, zu verstehen, ist der Schlüssel zu einem flüssig laufenden Sketch.

BefehlSyntaxWas er machtAchtung
delaydelay(ms)Wartet die angegebenen MillisekundenDas Programm steht in dieser Zeit still
delayMicrosecondsdelayMicroseconds(us)Wartet einige MikrosekundenGenau zwischen 3 und 16383 µs
millismillis()Liefert die Millisekunden seit dem Startunsigned long; läuft nach etwa 49,7 Tagen über
microsmicros()Liefert die Mikrosekunden seit dem StartAuf dem Uno in 4-µs-Schritten, Überlauf nach etwa 70 Minuten

Die dritte Gruppe sind die Mathematikbefehle; mit ihnen rechnest du einen Sensorwert in einen anderen Bereich um, begrenzt ihn oder erzeugst eine Zufallszahl. Die vierte Gruppe, die Kommunikationsbefehle, sorgt dafür, dass das Board Daten mit dem Computer und anderen Geräten austauschen kann.

BefehlSyntaxWas er machtBeispielergebnis
mapmap(x, vonMin, vonMax, nachMin, nachMax)Rechnet einen Bereich in einen anderen ummap(512, 0, 1023, 0, 255) → 127
constrainconstrain(x, unten, oben)Hält einen Wert zwischen zwei Grenzenconstrain(300, 0, 255) → 255
min / maxmin(a, b) / max(a, b)Liefert den kleineren oder größeren Wertmin(7, 3) → 3
absabs(x)Betrag (Absolutwert)abs(-12) → 12
pow / sqrt / sqpow(basis, exponent), sqrt(x), sq(x)Potenz, Quadratwurzel, Quadratpow(2, 10) → 1024.0
randomrandom(min, max)Zufällige Ganzzahl (max nicht enthalten)random(1, 7) → 1 bis 6
randomSeedrandomSeed(startwert)Ändert den Startpunkt der ZufallsfolgerandomSeed(analogRead(A3));
BefehlWas er machtBeispiel
Serial.begin(geschwindigkeit)Öffnet die serielle Schnittstelle mit der angegebenen BaudrateSerial.begin(9600);
Serial.print(daten)Gibt Daten aus und bleibt in derselben ZeileSerial.print(temperatur);
Serial.println(daten)Gibt Daten aus und springt in die nächste ZeileSerial.println("Hallo");
Serial.available()Liefert die Anzahl der Bytes, die auf das Lesen wartenif (Serial.available() > 0)
Serial.read()Liest ein Byte, liefert -1, wenn keine Daten da sindchar c = Serial.read();
Serial.readStringUntil(z)Liest Text bis zu einem bestimmten ZeichenString s = Serial.readStringUntil('\n');
Serial.parseInt()Holt eine Ganzzahl aus dem empfangenen Textint n = Serial.parseInt();
Serial.write(byte)Sendet ein rohes ByteSerial.write(65); // 'A'
Wire.begin()Startet den I2C-Bus (Wire.h)Wire.begin();
SPI.begin()Startet den SPI-Bus (SPI.h)SPI.begin();

pinMode(): die Aufgabe eines Pins festlegen

pinMode(pin, modus) legt fest, ob ein digitaler Pin Ein- oder Ausgang ist, und steht meist einmal in setup(). Es gibt drei Modi: OUTPUT macht den Pin zum Ausgang (für LED, Summer oder Relais), INPUT zu einem hochohmigen Eingang (für Schaltungen mit externem Pull-up- oder Pull-down-Widerstand), und INPUT_PULLUP macht ihn zum Eingang und verbindet einen internen Widerstand von etwa 20–50 kΩ mit 5 V. Auch die analogen Pins (A0–A5) lassen sich mit pinMode als Digitalpins nutzen; pinMode(A0, OUTPUT) ist zum Beispiel ein gültiger Befehl.

Vergisst du pinMode(pin, OUTPUT) und benutzt digitalWrite(pin, HIGH), wird der Pin nicht zum Ausgang; auf dem Uno schaltet der Befehl dann nur den internen Pull-up-Widerstand ein. Die LED leuchtet zwar, aber sehr schwach, weil der Strom durch einen Widerstand von 20–50 kΩ muss. Leuchtet deine LED nur schwach, prüfst du zuerst die pinMode-Zeile in setup().

digitalWrite() und digitalRead(): digitale Aus- und Eingabe

digitalWrite(pin, HIGH) legt einen Ausgang auf dem Uno auf 5 V, digitalWrite(pin, LOW) auf 0 V. Bis zu 20 mA pro Pin sind unbedenklich (der absolute Grenzwert liegt bei 40 mA); schließe eine LED immer mit Vorwiderstand an, den passenden Wert findest du mit dem LED-Vorwiderstandsrechner. digitalRead(pin) prüft die Spannung am Pin und liefert HIGH oder LOW; auf dem Uno gilt grob alles über 3 V als HIGH und alles unter 1,5 V als LOW. Im folgenden Beispiel leuchtet die eingebaute LED, wenn du den Taster an D2 drückst:

Arduino (C++)
1const int BUTON_PIN = 2;   // buton: bir ucu D2, diğer ucu GND / button: one leg to D2, the other to GND
2const int LED_PIN = 13;    // dahili LED / built-in LED
3
4void setup() {
5  pinMode(BUTON_PIN, INPUT_PULLUP);   // dahili pull-up direnci açık / internal pull-up resistor enabled
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  int durum = digitalRead(BUTON_PIN); // HIGH ya da LOW döner / returns HIGH or LOW
11  if (durum == LOW) {                 // pull-up ile basılı = LOW / with pull-up, pressed = LOW
12    digitalWrite(LED_PIN, HIGH);
13  } else {
14    digitalWrite(LED_PIN, LOW);
15  }
16}

Mit INPUT_PULLUP ist die Logik umgekehrt: Ist der Taster losgelassen, liest der Pin dank des internen Widerstands HIGH, wird er gedrückt, liest er LOW, weil er mit GND verbunden ist. Schließt du den Taster ohne Widerstand im Modus INPUT an, hängt der Pin in der Luft und digitalRead() liefert zufällige Werte; schon wenn du die Hand näherst, kann sich das Ergebnis ändern. Zum Prellen und zur richtigen Beschaltung lies Taster am Arduino anschließen.

analogRead() und analogWrite(): analoge Eingabe und PWM

analogRead(pin) wandelt mit einem 10-Bit-Wandler (ADC) eine Spannung zwischen 0 und 5 V an den Pins A0–A5 in eine Zahl von 0 bis 1023 um. Eine Messung dauert etwa 100 µs, du schaffst also rund 10.000 Messungen pro Sekunde. Um die Zahl in eine Spannung umzurechnen, nimmst du Wert × 5,0 / 1023; ein Messwert von 512 bedeutet zum Beispiel etwa 2,5 V. Die Referenzspannung lässt sich mit analogReference() ändern: Die Option INTERNAL nutzt beim Uno die interne 1,1-V-Referenz und verbessert die Auflösung bei kleinen Spannungen. Mehr zu Auflösung und Referenz findest du unter ADC und Analog-Digital-Wandlung.

Trotz seines Namens erzeugt analogWrite(pin, wert) keine echte analoge Spannung. Es schaltet den Pin sehr schnell ein und aus und erzeugt so ein PWM-Signal: 0 heißt immer aus, 255 immer an und 127 etwa zur Hälfte an. Aus diesem Mittelwert ergibt sich, dass eine LED für unser Auge halb hell wirkt und ein Motor langsam dreht. Auf dem Uno liefern nur die mit ~ markierten Pins 3, 5, 6, 9, 10 und 11 PWM; die Frequenz beträgt an den meisten Pins 490 Hz, an den Pins 5 und 6 980 Hz. analogWrite() schaltet den Pin selbst auf Ausgang, pinMode ist also nicht nötig. Der folgende Code stellt die Helligkeit einer LED mit einem Potentiometer ein und schreibt den Messwert samt Spannung in den seriellen Monitor; Details zu Tastgrad und Frequenz findest du unter Was ist PWM?.

Arduino (C++)
1const int POT_PIN = A0;   // potansiyometrenin orta bacağı / potentiometer wiper
2const int LED_PIN = 9;    // ~9 PWM pini + 220 ohm direnç / ~9 PWM pin + 220 ohm resistor
3
4void setup() {
5  Serial.begin(9600);
6}
7
8void loop() {
9  int ham = analogRead(POT_PIN);         // 0-1023 arası / between 0 and 1023
10  float volt = ham * (5.0 / 1023.0);     // sayıyı gerilime çevir / convert the reading to volts
11  analogWrite(LED_PIN, ham / 4);         // 0-1023 -> 0-255 PWM parlaklığı / 0-1023 -> 0-255 PWM brightness
12
13  Serial.print(F("Ham / raw: "));
14  Serial.print(ham);
15  Serial.print(F("  Gerilim / voltage: "));
16  Serial.print(volt, 2);                 // 2 ondalık basamak / 2 decimal places
17  Serial.println(F(" V"));
18  delay(200);
19}
An einem Pin ohne PWM kann analogWrite() keine Zwischenwerte erzeugen: Bei Werten unter 128 setzt es den Pin auf LOW, ab 128 auf HIGH. Auch die Pins A0–A5 des Uno liefern kein PWM, und der klassische Uno R3 hat keinen echten Analogausgang (DAC); analogWrite(A0, 100) ergibt keine 2 V. Brauchst du eine echte analoge Spannung, nimm ein Board mit DAC (etwa den Uno R4, der an A0 einen DAC hat) oder setze einen RC-Filter an einen PWM-Ausgang.

delay(), millis() und micros(): Zeitbefehle

delay(ms) wartet die angegebenen Millisekunden, und in dieser Zeit läuft keine andere Zeile in loop(); delay(1000) ist eine volle Sekunde Pause. Für kurze Wartezeiten im Mikrosekundenbereich gibt es delayMicroseconds(), das zwischen 3 und 16383 µs genau ist. millis() dagegen wartet nicht, sondern liefert die Zeit seit dem Start des Boards in Millisekunden. Speichere das Ergebnis immer in einer Variable vom Typ unsigned long: Nimmst du int, läuft der Wert auf dem Uno über, sobald er 32.767 übersteigt, also nach etwa 33 Sekunden, und deine Zeitsteuerung gerät durcheinander. millis() springt etwa alle 49,7 Tage auf null zurück; die Subtraktionsmethode unten funktioniert auch über diesen Überlauf hinweg korrekt.

Arduino (C++)
1const int LED_PIN = 13;
2const unsigned long ARALIK = 500;   // yanıp sönme aralığı (ms) / blink interval (ms)
3unsigned long oncekiZaman = 0;      // son değişim anı / time of the last toggle
4
5void setup() {
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  unsigned long simdi = millis();
11  if (simdi - oncekiZaman >= ARALIK) {               // taşmada da doğru çalışır / safe across overflow
12    oncekiZaman = simdi;
13    digitalWrite(LED_PIN, !digitalRead(LED_PIN));    // LED'i tersine çevir / toggle the LED
14  }
15  // Burada buton, sensör ve ekran işleri de yapılabilir / button, sensor and display tasks can run here
16}

Bei diesem Muster bleibt loop() nie stehen; während die LED weiter blinkt, kannst du in derselben Schleife einen Taster lesen, einen Sensor messen und ein Display aktualisieren. micros() funktioniert genauso in Mikrosekunden; auf dem Uno zählt es in 4-µs-Schritten und läuft nach etwa 70 Minuten über. Wie du mehrere Aufgaben gleichzeitig erledigst, erklären wir ausführlich in Arduino millis() statt delay().

Serial.begin(), Serial.print() und Serial.read(): serielle Kommunikation

Mit den Serial-Befehlen spricht der Arduino über das USB-Kabel mit deinem Computer, und sie sind dein wichtigstes Werkzeug zur Fehlersuche. Serial.begin(9600) öffnet die serielle Schnittstelle mit 9600 Bit pro Sekunde; stimmt die Geschwindigkeit im seriellen Monitor nicht überein, siehst du nur wirre Zeichen. Serial.print() gibt Daten aus und bleibt in derselben Zeile, Serial.println() springt nach der Ausgabe in die nächste Zeile. Mit einem zweiten Parameter wählst du das Format: Serial.print(78, HEX) gibt „4E“ aus, Serial.print(78, BIN) „1001110“, und Serial.print(3.14159, 3) zeigt „3.142“ (bei Kommazahlen sind standardmäßig 2 Nachkommastellen eingestellt). Feste Texte in F("...") zu schreiben spart Platz in den 2 KB RAM des Uno.

Zum Lesen prüfst du zuerst mit Serial.available(), ob Bytes im Puffer warten; der Empfangspuffer des Uno ist 64 Byte groß. Serial.read() holt ein einzelnes Byte aus diesem Puffer und liefert -1, wenn nichts zu lesen ist. Der folgende Code schaltet die LED mit den Zeichen 1 und 0 ein und aus, die du über den seriellen Monitor sendest:

Arduino (C++)
1const int LED_PIN = 13;
2
3void setup() {
4  Serial.begin(9600);                    // Seri Monitör de 9600 olmalı / Serial Monitor must be 9600 too
5  pinMode(LED_PIN, OUTPUT);
6  Serial.println(F("1: LED açık / on, 0: LED kapalı / off"));
7}
8
9void loop() {
10  if (Serial.available() > 0) {          // tamponda bayt var mı? / any bytes waiting?
11    char c = Serial.read();              // ilk baytı al / read the first byte
12    if (c == '1') {                      // '1' karakteri, 1 sayısı değil / the character '1', not the number 1
13      digitalWrite(LED_PIN, HIGH);
14      Serial.println(F("LED açık / on"));
15    } else if (c == '0') {
16      digitalWrite(LED_PIN, LOW);
17      Serial.println(F("LED kapalı / off"));
18    }
19    // '\n' ve '\r' gibi diğer karakterler atlanır / other characters such as '\n' and '\r' are ignored
20  }
21}

Beachte, dass mit '1' verglichen wird (einfache Anführungszeichen, also ein Zeichen): Die 1, die du auf der Tastatur eingibst, entspricht in der ASCII-Tabelle der Zahl 49, deshalb ist die Bedingung c == 1 nie wahr. Für mehrstellige Zahlen kannst du Serial.parseInt() verwenden, für eine ganze Zeile Serial.readStringUntil('\n'). Zu Zeilenende-Einstellungen, Baudrate und seriellem Plotter lies Seriellen Monitor des Arduino benutzen.

map() und constrain(): Werte umrechnen und begrenzen

map(wert, vonMin, vonMax, nachMin, nachMax) überträgt eine Zahl proportional von einem Bereich in einen anderen. Dahinter steckt diese Formel: (x − vonMin) × (nachMax − nachMin) / (vonMax − vonMin) + nachMin. map(512, 0, 1023, 0, 255) ergibt zum Beispiel 127 und nicht 127,6, weil map() nur mit Ganzzahlen rechnet und den Nachkommaanteil abschneidet. Indem du den Zielbereich umdrehst, erhältst du einen umgekehrten Zusammenhang: map(x, 0, 1023, 255, 0). map() begrenzt das Ergebnis nicht; liegt der Eingang außerhalb des angegebenen Bereichs, liegt auch der Ausgang außerhalb. Deshalb kombiniert man es meist mit constrain(x, unten, oben).

Arduino (C++)
1const int LDR_PIN = A0;   // LDR + 10k gerilim bölücü / LDR + 10k voltage divider
2const int LED_PIN = 9;    // ~9 PWM pini / ~9 PWM pin
3
4void setup() {
5  pinMode(LED_PIN, OUTPUT);
6}
7
8void loop() {
9  int isik = analogRead(LDR_PIN);           // odada ölçülen aralık ~200-800 / measured range in the room ~200-800
10  int pwm = map(isik, 200, 800, 255, 0);    // karanlıkta parlak, aydınlıkta sönük / bright in the dark, dim in the light
11  pwm = constrain(pwm, 0, 255);             // aralık dışı değerleri kes / clip out-of-range values
12  analogWrite(LED_PIN, pwm);
13  delay(20);
14}

In diesem Beispiel liefert der LDR im Zimmer Werte zwischen 200 und 800. Fällt der Wert nachts auf 100, berechnet map() 297; ohne constrain() bekäme analogWrite() diesen Wert außerhalb des Bereichs 0–255. Auf dem Uno führt so ein Wert je nach Pin zu unterschiedlichen, unerwarteten Ergebnissen: An den Pins 3, 5, 6 und 11, die 8-Bit-Timer nutzen, läuft 297 über und verhält sich wie 41, sodass die LED bei völliger Dunkelheit fast ausgeht, statt hell zu leuchten. Weil constrain(), min(), max() und abs() auf dem Uno als Makros definiert sind, schreib kein x++ und keinen anderen Funktionsaufruf in die Klammern; der Ausdruck kann mehrfach ausgewertet werden und unerwartete Ergebnisse liefern. Die Beschaltung des LDR findest du unter LDR-Lichtsensor.

tone() und noTone(): Töne mit dem Summer erzeugen

tone(pin, frequenz, dauer) erzeugt an einem Pin ein Rechtecksignal mit 50 % Tastgrad und bringt einen passiven Summer oder einen kleinen Lautsprecher in dieser Frequenz zum Klingen. Die Dauer wird in Millisekunden angegeben und ist optional; ohne sie klingt der Ton, bis du noTone(pin) aufrufst. Ein wichtiges Detail: tone() wartet nicht, sondern startet den Ton und springt sofort zur nächsten Zeile. Spielst du mehrere Noten nacheinander, brauchst du deshalb nach jedem tone()-Aufruf ein delay(), das mindestens so lang ist wie die Note, sonst hörst du nur die letzte.

Arduino (C++)
1const int BUZZER_PIN = 8;   // pasif buzzer'ın + ucu / passive buzzer + leg
2
3void setup() {
4  int notalar[] = {262, 294, 330, 349, 392};   // Do Re Mi Fa Sol (Hz) / C D E F G (Hz)
5  for (int i = 0; i < 5; i++) {
6    tone(BUZZER_PIN, notalar[i], 200);         // 200 ms çal / play for 200 ms
7    delay(250);                                // tone() beklemez, sen bekle / tone() does not wait, so you do
8  }
9  noTone(BUZZER_PIN);                          // sesi kapat / stop the sound
10}
11
12void loop() {
13}
  • Frequenzgrenzen: Auf dem Uno lassen sich keine Töne unter 31 Hz erzeugen, die Obergrenze liegt bei 65.535 Hz; mit einem Summer ist der sinnvolle Bereich etwa 100–5000 Hz.
  • Nur ein Ton: Es kann immer nur ein Pin gleichzeitig einen Ton spielen; für einen Ton an einem anderen Pin musst du den vorherigen erst mit noTone() stoppen.
  • PWM-Konflikt: Auf dem Uno nutzt tone() den Timer2, deshalb funktioniert analogWrite() an den Pins 3 und 11 nicht richtig, solange ein Ton läuft.
  • Aktiver Summer: Weil er einen eigenen Oszillator hat, lässt sich seine Frequenz nicht mit tone() ändern; einen aktiven Summer schaltest du einfach mit digitalWrite() ein und aus. Die Unterschiede erklärt Was ist ein Buzzer?.

pulseIn(): Impulslängen messen

pulseIn(pin, HIGH) wartet, bis der Pin HIGH wird, misst, wie lange er HIGH bleibt, und liefert das Ergebnis in Mikrosekunden; es kann Impulse von 10 µs bis 3 Minuten Länge messen. Die bekannteste Anwendung ist der Ultraschall-Abstandssensor HC-SR04: Der Sensor gibt einen Impuls aus, der so lang ist wie die Laufzeit des Schalls hin und zurück. Schall breitet sich in Luft mit etwa 343 m/s aus, also 0,0343 cm/µs; da der Weg hin und zurück führt, gilt Abstand = Dauer × 0,0343 / 2.

Arduino (C++)
1const int TRIG_PIN = 9;
2const int ECHO_PIN = 10;
3
4void setup() {
5  Serial.begin(9600);
6  pinMode(TRIG_PIN, OUTPUT);
7  pinMode(ECHO_PIN, INPUT);
8}
9
10void loop() {
11  digitalWrite(TRIG_PIN, LOW);
12  delayMicroseconds(2);
13  digitalWrite(TRIG_PIN, HIGH);            // 10 µs tetik darbesi / 10 µs trigger pulse
14  delayMicroseconds(10);
15  digitalWrite(TRIG_PIN, LOW);
16
17  unsigned long sure = pulseIn(ECHO_PIN, HIGH, 30000UL);   // en fazla 30 ms bekle / wait at most 30 ms
18  if (sure == 0) {
19    Serial.println(F("Menzil dışı / out of range"));
20  } else {
21    float mesafe = sure * 0.0343 / 2.0;    // ses hızı 343 m/s, gidiş-dönüş / speed of sound 343 m/s, round trip
22    Serial.print(mesafe, 1);
23    Serial.println(F(" cm"));
24  }
25  delay(100);
26}

Der dritte Parameter, das Timeout, ist sehr wichtig. Fehlt er, wartet pulseIn() bei ausbleibendem Impuls 1 Sekunde und liefert 0; löst sich das Sensorkabel, friert das ganze Programm in jedem Durchlauf eine Sekunde ein. Ein Timeout von 30000 µs entspricht etwa 5 Metern und reicht für die 4 Meter Reichweite des HC-SR04. Anschluss und Genauigkeit des Sensors erklärt HC-SR04 Ultraschallsensor.

attachInterrupt(): sofort reagieren mit Interrupts

attachInterrupt(digitalPinToInterrupt(pin), funktion, modus) führt die angegebene Funktion in dem Moment aus, in dem sich ein Pin ändert, ganz egal, was loop() gerade tut. Diese Funktion heißt Interrupt-Service-Routine (ISR). Der Modus kann vier Werte haben: RISING löst beim Wechsel von LOW nach HIGH aus, FALLING beim Wechsel von HIGH nach LOW, CHANGE bei jeder Änderung und LOW, solange der Pin LOW bleibt. Auf dem Uno und Nano können nur die Pins D2 und D3 so einen Interrupt auslösen; beim Mega sind es die Pins 2, 3, 18, 19, 20 und 21. Das ist ideal, um einen schnell drehenden Drehgeber, die Impulse eines Windmessers oder einen sehr kurzen Tastendruck nicht zu verpassen.

Arduino (C++)
1const int BUTON_PIN = 2;            // Uno'da kesme pinleri: 2 ve 3 / interrupt pins on the Uno: 2 and 3
2volatile unsigned long sayac = 0;   // ISR'de değişen değişken volatile olmalı / variables changed in an ISR must be volatile
3
4void say() {                        // kesme fonksiyonu (ISR): kısa tut / interrupt service routine: keep it short
5  sayac++;
6}
7
8void setup() {
9  Serial.begin(9600);
10  pinMode(BUTON_PIN, INPUT_PULLUP);
11  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), say, FALLING);   // HIGH'dan LOW'a geçişte / on a HIGH-to-LOW edge
12}
13
14void loop() {
15  noInterrupts();                   // 4 baytlık değeri güvenle kopyala / copy the 4-byte value safely
16  unsigned long kopya = sayac;
17  interrupts();
18
19  Serial.print(F("Basma sayısı / presses: "));
20  Serial.println(kopya);
21  delay(500);
22}
Deklariere jede Variable, die du in einer ISR änderst, als volatile und halte die Funktion so kurz wie möglich. In einer ISR funktioniert delay() nicht, millis() zählt nicht weiter und Serial.print() kann das Programm blockieren; setze nur ein Flag oder einen Zähler und erledige die eigentliche Arbeit in loop(). Mechanische Taster prellen, deshalb kann der Zähler bei einem einzigen Druck mehrmals hochzählen; wie du das löst und alles Weitere zu Interrupts findest du unter Interrupts beim Arduino.

random() und randomSeed(): Zufallszahlen erzeugen

random(max) liefert eine zufällige Ganzzahl zwischen 0 und max−1, random(min, max) eine zwischen min und max−1; die Obergrenze ist im Ergebnis nicht enthalten. Für einen Würfel von 1 bis 6 schreibst du deshalb random(1, 7). Der Arduino erzeugt keinen echten Zufall, sondern berechnet eine Zahlenfolge mit einer festen Formel; rufst du randomSeed() nicht auf, siehst du nach jedem Start dieselben Zahlen in derselben Reihenfolge. Das Rauschen eines unbeschalteten Analogpins als Startwert zu nutzen, löst das in der Praxis:

Arduino (C++)
1void setup() {
2  Serial.begin(9600);
3  randomSeed(analogRead(A3));     // boştaki A3 pininin gürültüsü / noise from the unconnected A3 pin
4}
5
6void loop() {
7  int zar = random(1, 7);         // 1-6 arası; üst sınır dahil değil / 1 to 6; the upper bound is exclusive
8  Serial.print(F("Zar / dice: "));
9  Serial.println(zar);
10  delay(1000);
11}

Arduino-Befehle auf dem ESP32: worauf du achten musst

Der ESP32 wird in der Arduino IDE mit denselben Befehlen programmiert, und der meiste Code in diesem Artikel läuft direkt, sobald du die Pinnummern anpasst. Weil die Hardware anders ist, verhalten sich manche Befehle aber anders. Der wichtigste Unterschied ist die Spannung: Die Pins des ESP32 arbeiten mit 3,3 V, digitalWrite(pin, HIGH) gibt 3,3 V aus, und 5-V-Signale dürfen nicht direkt an die Pins. Mehr über das Board erfährst du unter Was ist der ESP32?.

BefehlArduino UnoESP32
digitalWrite(pin, HIGH)5 V3,3 V
analogRead()10 Bit, 0–1023, A0–A512 Bit, 0–4095; bei aktivem WLAN nur die ADC1-Pins (GPIO 32–39)
analogWrite()Nur die ~-Pins (3, 5, 6, 9, 10, 11), 490/980 HzFast jeder ausgangsfähige GPIO; Frequenz über ledcAttach(pin, frequenz, aufloesung)
attachInterrupt()Nur D2 und D3Alle GPIOs; die ISR bekommt IRAM_ATTR
tone()Nutzt Timer2, stört PWM an 3 und 11Läuft über die LEDC-Hardware
Serial.begin()Meist 9600Meist 115200 (auch die Bootmeldungen kommen mit dieser Geschwindigkeit)
delay()Hält den Prozessor komplett im WartenGibt die Zeit an FreeRTOS ab; WLAN läuft im Hintergrund weiter
Arduino (C++)
1const int POT_PIN = 34;     // ADC1 pini, Wi-Fi açıkken de okur / ADC1 pin, works with Wi-Fi on
2const int LED_PIN = 2;      // çoğu DevKit'te dahili LED / onboard LED on most DevKits
3const int BUTON_PIN = 4;    // butonun diğer ucu GND / other button leg to GND
4
5volatile bool basildi = false;
6
7void IRAM_ATTR butonISR() { // ESP32'de ISR IRAM'e yerleşmeli / on the ESP32 the ISR should live in IRAM
8  basildi = true;
9}
10
11void setup() {
12  Serial.begin(115200);
13  pinMode(BUTON_PIN, INPUT_PULLUP);
14  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), butonISR, FALLING);   // her GPIO kesme destekler / every GPIO supports interrupts
15}
16
17void loop() {
18  int ham = analogRead(POT_PIN);                     // 0-4095 (12 bit)
19  analogWrite(LED_PIN, map(ham, 0, 4095, 0, 255));   // 8 bit PWM / 8-bit PWM
20  if (basildi) {
21    basildi = false;
22    Serial.println("Butona basıldı / button pressed");
23  }
24  Serial.println(ham);
25  delay(200);
26}

Da analogRead() auf dem ESP32 Werte von 0 bis 4095 liefert, ändert sich auch der map()-Bereich entsprechend. Das IRAM_ATTR vor der ISR legt den Code in den schnellen internen Speicher; fehlt es, kann das Board in manchen Situationen mit einem „Guru Meditation Error“ neu starten. Die Analogmessungen des ESP32 sind an den Rändern des Bereichs (um 0 V und 3,3 V) nicht linear; brauchst du eine genauere Messung, liefert die Funktion analogReadMilliVolts() einen kalibrierten Wert in Millivolt.

Raspberry Pi Pico: MicroPython-Entsprechungen der Arduino-Befehle

Programmierst du den Raspberry Pi Pico mit der Arduino IDE (Core arduino-pico), funktionieren alle Befehle aus diesem Artikel unter demselben Namen; analogRead() liefert standardmäßig 10 Bit und analogWrite() erzeugt 1 kHz PWM. Meist wird der Pico jedoch mit MicroPython genutzt. Dort schreibst du die Befehle mit Objekten aus den Modulen machine und time; die Logik ist dieselbe, nur die Syntax ändert sich. Auch die Pins des Pico arbeiten mit 3,3 V, die analogen Eingänge sind GP26, GP27 und GP28. Für den Einstieg lies Was ist der Raspberry Pi Pico?.

Arduino-BefehlMicroPython-EntsprechungHinweis
pinMode(15, OUTPUT)led = Pin(15, Pin.OUT)Das Pin-Objekt wird einmal angelegt
pinMode(14, INPUT_PULLUP)btn = Pin(14, Pin.IN, Pin.PULL_UP)Interner Pull-up-Widerstand
digitalWrite(15, HIGH)led.value(1)led.on() geht auch
digitalRead(14)btn.value()Liefert 0 oder 1
analogRead(A0)ADC(26).read_u16()Liefert 0–65535
analogWrite(15, 128)PWM(Pin(15)).duty_u16(32768)Tastgrad von 0 bis 65535
delay(500)time.sleep_ms(500)time.sleep(0.5) geht auch
millis()time.ticks_ms()Differenzen mit time.ticks_diff()
Serial.println(x)print(x)Erscheint in der Thonny-Shell
tone(pin, 440)pwm.freq(440) und pwm.duty_u16(32768)Stumm schalten mit duty_u16(0)
pulseIn(pin, HIGH, 30000)machine.time_pulse_us(pin, 1, 30000)Liefert bei Timeout einen negativen Wert
attachInterrupt(...)btn.irq(trigger=Pin.IRQ_FALLING, handler=f)f bekommt das Pin-Objekt als Parameter
random(1, 7)random.randint(1, 6)Obergrenze ist enthalten
map() / constrain()Nicht eingebaut, du schreibst sie selbstFür constrain: min(max(x, 0), 255)
MicroPython
1from machine import Pin, ADC, PWM
2import time
3
4led = PWM(Pin(15))                       # pinMode + analogWrite karşılığı / pinMode + analogWrite equivalent
5led.freq(1000)                           # 1 kHz PWM
6buton = Pin(14, Pin.IN, Pin.PULL_UP)     # INPUT_PULLUP karşılığı / INPUT_PULLUP equivalent
7pot = ADC(26)                            # GP26 = ADC0
8
9def map_deger(x, giris_min, giris_max, cikis_min, cikis_max):   # Arduino map() karşılığı / Arduino map() equivalent
10    return (x - giris_min) * (cikis_max - cikis_min) // (giris_max - giris_min) + cikis_min
11
12onceki = time.ticks_ms()                 # millis() karşılığı / millis() equivalent
13while True:
14    ham = pot.read_u16()                 # 0-65535 (analogRead)
15    led.duty_u16(ham)                    # parlaklık / brightness (analogWrite)
16    if buton.value() == 0:               # digitalRead; basılı = 0 / pressed = 0
17        print("Butona basıldı / button pressed")
18    if time.ticks_diff(time.ticks_ms(), onceki) >= 1000:   # saniyede bir / once a second
19        onceki = time.ticks_ms()
20        print("Yüzde / percent:", map_deger(ham, 0, 65535, 0, 100))
21    time.sleep_ms(50)                    # delay(50)

Wie die Tabelle zeigt, schließt random.randint(1, 6) in MicroPython die Obergrenze ein und liefert dasselbe Ergebnis wie random(1, 7) beim Arduino; time.ticks_diff() bietet dieselbe Überlaufsicherheit wie die millis()-Subtraktion. Genau diese kleinen Unterschiede sorgen beim Wechsel zwischen den beiden Plattformen am häufigsten für Verwirrung. Weitere Grundbefehle von MicroPython findest du unter MicroPython-Grundlagen.

Projektideen mit diesen Befehlen

  • Ampel: Schalte mit pinMode(), digitalWrite() und delay() drei LEDs nacheinander; Schritt für Schritt erklären wir das in Arduino-Ampel.
  • Digitaler Würfel: Erzeuge mit random() eine Zahl von 1 bis 6 und zeige das Ergebnis per Tastendruck mit LEDs oder auf einer 7-Segment-Anzeige an.
  • Einparkhilfe: Miss den Abstand mit pulseIn(), rechne ihn mit map() in einen Pieptakt um und gib mit tone() einen Warnton aus.
  • Automatisches Nachtlicht: Lies die Helligkeit mit analogRead() und stelle mit map() und constrain() die Helligkeit über analogWrite() ein.
  • Fernbedienung über die serielle Schnittstelle: Steuere mit Serial.read() und Befehlen vom Computer eine LED, ein Relais oder einen Servomotor.
  • Reaktionstest: Lass mit random() zu einem zufälligen Zeitpunkt eine LED aufleuchten und miss deine Reaktionszeit mit attachInterrupt() und millis() auf die Millisekunde genau.

Häufige Fehler und ihre Lösungen

FehlerSymptomLösung
pinMode() vergessenDie LED leuchtet sehr schwach oder gar nichtpinMode(pin, OUTPUT) in setup() schreiben
Taster ohne Widerstand im Modus INPUTdigitalRead() liefert zufällig 0 und 1INPUT_PULLUP verwenden; gedrückt ergibt LOW
Tippfehler im Befehlsnamen'digitalwrite' was not declared in this scopeAuf Groß- und Kleinschreibung achten: digitalWrite
Baudrate passt nichtWirre Zeichen im seriellen MonitorGeschwindigkeit des seriellen Monitors an Serial.begin() anpassen
analogWrite() an einem Pin ohne PWMDie LED ist nur ganz an oder ganz ausEinen Pin mit ~ nehmen (3, 5, 6, 9, 10, 11)
millis() in einer int-VariableDie Zeitsteuerung versagt nach etwa 33 Sekundenunsigned long verwenden
Würfel mit random(1, 6)Die 6 kommt nierandom(1, 7) schreiben; die Obergrenze ist ausgeschlossen
Kommazahlen von map() erwartenDas Ergebnis ist immer ganzzahlig, kleine Änderungen gehen verlorenBei Bedarf eine eigene float-Formel schreiben
pulseIn() ohne TimeoutOhne Sensor friert jeder Durchlauf 1 Sekunde ein30000 als dritten Parameter übergeben
delay() oder Serial in einer ISRDas Programm hängt oder verhält sich seltsamIn der ISR nur ein volatile-Flag setzen
Wenn du nicht genau weißt, was ein Befehl tut, schreib einen kleinen Test-Sketch und gib das Ergebnis mit Serial.println() aus; in der Arduino IDE 2 kannst du außerdem mit einem Rechtsklick auf den Befehlsnamen „Gehe zu Definition“ wählen und dir den Quellcode ansehen. Kompiliert dein Code nicht, zeigt die erste Zeile der Fehlermeldung meist die Ursache; die häufigsten Meldungen und ihre Lösungen findest du unter Arduino-Kompilierfehler.

Die Befehle in diesem Artikel sind die Bausteine der meisten Projekte, die du mit einem Arduino baust; der Rest sind meist zusätzliche Funktionen aus Bibliotheken. Wenn du jeden Befehl einmal in einer eigenen kleinen Schaltung ausprobierst und das Ergebnis im seriellen Monitor siehst, bleibt das Gelernte viel besser hängen als durch Auswendiglernen. In der BlueGrays-App findest du Projekte, die diese Befehle nutzen, etwa LED einschalten, LED per Taster steuern, Licht mit einem LDR messen, Frequenz mit einem Summer einstellen, Abstand mit dem HC-SR04 messen und ein Würfelprojekt, Schritt für Schritt mit Schaltplänen und kommentiertem Code.

Häufige Fragen

Welche Arduino-Befehle werden am häufigsten verwendet?

Am häufigsten sind pinMode(), digitalWrite(), digitalRead(), analogRead(), analogWrite(), delay(), millis(), Serial.begin() und Serial.println(). Nimmst du noch map() zum Umrechnen, tone() für Töne, pulseIn() für Abstandssensoren und attachInterrupt() für Interrupts dazu, kannst du fast alle Einsteigerprojekte schreiben.

In welcher Sprache werden Arduino-Befehle geschrieben?

Arduino-Code basiert auf C und C++; der Arduino-Core ergänzt die Sprache um fertige Funktionen wie pinMode() und digitalWrite(). Die Befehle sind englisch, unterscheiden Groß- und Kleinschreibung, und jede Anweisung endet mit einem Semikolon. ESP32 und Raspberry Pi Pico lassen sich auf Wunsch auch mit MicroPython programmieren.

Was ist der Unterschied zwischen digitalWrite und analogWrite?

digitalWrite() setzt einen Pin auf einen von nur zwei Zuständen: HIGH (5 V beim Uno) oder LOW (0 V). analogWrite() schaltet den Pin sehr schnell ein und aus und erzeugt so ein PWM-Signal von 0 bis 255, mit dem du die Helligkeit einer LED oder die Drehzahl eines Motors einstellst. Beim Uno funktioniert analogWrite() nur an den mit ~ markierten Pins.

Was bedeuten void setup und void loop?

setup() ist die Funktion, die einmal läuft, wenn das Board eingeschaltet oder zurückgesetzt wird; hier stehen Vorbereitungen wie pinMode() und Serial.begin(). loop() ist die Funktion, die sich nach dem Ende von setup() endlos wiederholt. Das void davor bedeutet, dass diese Funktionen keinen Wert zurückgeben.

Was ist der Unterschied zwischen Serial.print und Serial.println?

Serial.print() gibt die Daten aus und lässt den Cursor in derselben Zeile, sodass die nächsten Daten direkt daneben erscheinen. Serial.println() sendet nach der Ausgabe die Zeilenende-Zeichen (\r\n), sodass die nächsten Daten in einer neuen Zeile beginnen. Um mehrere Werte nebeneinander in einer Zeile zu zeigen, nimmst du zuerst print() und am Ende println().

Was macht die map-Funktion beim Arduino?

map() rechnet eine Zahl proportional von einem Bereich in einen anderen um; zum Beispiel macht sie aus dem Wert 0–1023 von analogRead() den Bereich 0–255 für analogWrite() oder 0–180 Grad für einen Servo. Sie rechnet nur mit Ganzzahlen und begrenzt das Ergebnis nicht, daher solltest du sie gegen Werte außerhalb des Bereichs mit constrain() kombinieren.

Alle Projekte ansehen
LED Blinken
#1Anfänger

LED Blinken

Einfaches Eingabeprojekt, das eine einzelne LED in bestimmten Intervallen mit Arduino ein- und ausschaltet. Lehrt die Verwendung von digitalWrite und Verzögerungsfunktionen.

4.6(171)
903
LED mit Taster schalten (Push)
#9Anfänger

LED mit Taster schalten (Push)

Sofortiges (Druck-)Steuerprojekt, bei dem die LED aufleuchtet, wenn die Taste gedrückt wird, und erlischt, wenn sie losgelassen wird. Lehrt die Verwendung von Tastenlesung und bedingtem Ausdruck mit d

4.9(112)
190
Lichtstärke messen mit LDR
#11Anfänger

Lichtstärke messen mit LDR

Projekt, das die Umgebungslichtintensität mit einem LDR-Sensor misst und sie auf einem seriellen Monitor anzeigt. Lehrt die Grundlagen der analogen Sensorablesung und der seriellen Kommunikation.

4.6(78)
124
Frequenzeinstellung mit Buzzer
#14Mittel

Frequenzeinstellung mit Buzzer

Interaktives Projekt mit 4 Tasten zum Erhöhen und Verringern der Frequenz des Summers und zum Ein- und Ausschalten. Lehrt das Lesen mehrerer Tasten und die variable Steuerung.

4.6(68)
112
HC-SR04 Abstandsmessung (serielle Anzeige)
#27Anfänger

HC-SR04 Abstandsmessung (serielle Anzeige)

HC-SR04 Ultraschallsensor zur Abstandsmessung und Anzeige des Ergebnisses in cm auf dem seriellen Monitor. Er lehrt das Prinzip der Abstandsberechnung mit Schallwellen.

4.6(44)
66
Knight-Rider-Lauflicht mit einstellbarer Geschwindigkeit
#8Mittel

Knight-Rider-Lauflicht mit einstellbarer Geschwindigkeit

Projekt mit Potentiometer, das die Geschwindigkeit der Knight-Rider-LED-Animation in Echtzeit einstellen kann. Es kombiniert Analogeingang und bidirektionale Schleifensteuerung.

4.5(59)
115
Servomotorbetrieb mit Potentiometer
#36Anfänger
Premium

Servomotorbetrieb mit Potentiometer

Projekt, das den Servomotor in Echtzeit steuert, indem es den Potentiometerwert in einen Bereich von 0-180° umwandelt. Lernt die Funktion map() und die Analog-Servo-Integration.

4.6(37)
51
Würfel-Projekt
#79Mittel
Premium

Würfel-Projekt

Würfelprojekt, das bei jedem Tastendruck eine Zufallszahl zwischen 1 und 6 erzeugt und diese auf einer 7-Segment-Anzeige anzeigt. Dank des Entprellungsmechanismus wird ein einziges Ergebnis bei einem

5.0(48)
67