Arduino-IDE: Was ist Debugging und wie nutze ich es

Jeder, der schon einmal eigenen Code geschrieben hat, kennt diesen Moment: Man lädt das Programm auf den Mikrocontroller hoch, aber statt zu blinken, zu messen oder zu steuern, passiert… nichts. Oder noch schlimmer: Es passiert etwas völlig Unerwartetes. Bisher haben wir uns in solchen Fällen oft mit unzähligen Serial.print()-Befehlen beholfen, um zu erraten, was im Code gerade schiefläuft.

Heute zeige ich euch eine viel elegantere Methode: Das Debugging. Wir schauen uns an, was das genau ist und wie ihr es mit einem modernen ESP32-C6 und der aktuellen IDE (Integrierte Entwicklungsumgebung) von Arduino kinderleicht selbst nutzen könnt.

Was ist Debugging eigentlich?

Stellt euch vor, euer Programm-Code ist ein rasanter Actionfilm, der in Millisekunden abläuft. Wenn ein Fehler (ein „Bug“) auftritt, ist er meist so schnell vorbei, dass ihr ihn gar nicht bemerkt.

Beim Debugging (also dem „Entwanzen“ oder Fehlerfinden) bekommt ihr eine Fernbedienung für diesen Film.

Ihr könnt:

  • den Debugger steuern mit:
    Step Into (Hineinspringen): Betritt eine Funktion und debugge sie Zeile für Zeile.
    Step Over (Ausführen, aber nicht hinein): Führt die gesamte Funktion aus, ohne hineinzuspringen.
    Step Out (Funktion zu Ende laufen lassen): Beendet die aktuelle Funktion und kehrt zum Aufrufer zurück.
    Continue (Weiterlaufen lassen): Setzt die Ausführung bis zum nächsten Breakpoint fort.
  • Den Code an einer beliebigen Zeile komplett anhalten (das nennt man einen Breakpoint oder Haltepunkt setzen).
  • Bedingte Breakpoints erstellen (z.B. nur stoppen, wenn zaehler == 5)
  • Funktionen (hineinspringen, Funktion ausführen, aber nicht hinein, Funktion zu Ende laufen lassen)
  • Den Code Zeile für Zeile in Zeitlupe weiterlaufen lassen.
  • Live in den Speicher schauen und sehen, welche Werte eure Variablen in genau diesem Moment haben.
  • Beachte: Achtung bei Echtzeit-Anwendungen: Der Debugger unterbricht die Ausführung – das kann zu unvorhersehbarem Verhalten führen, wenn dein Code auf exakte Timing-Abläufe angewiesen ist (z. B. bei:
    PWM-Signalen (z. B. für Motoren)
    Interrupts (z. B. Timer-Interrupts)
    Echtzeit-Sensoren (z. B. Encoder-Ablesung) Tipp: In solchen Fällen Serial.print() oder Logs nutzen, statt den Debugger.

Warum der ESP32-C6 dafür perfekt ist

Früher brauchte man für echtes Debugging teure Zusatzgeräte und einen Kabelsalat auf dem Steckbrett. Der ESP32-C6 hat hier aber ein echtes Ass im Ärmel: Er hat die Hardware für die Fehlersuche direkt eingebaut!

Die Technik dahinter nennt sich JTAG (Joint Test Action Group)
JTAG ist ein IEEE-Standard (1149.1), der ursprünglich für das Testen von Leiterplatten (PCBs) entwickelt wurde. Bei Mikrocontrollern wie dem ESP32-C6 oder dem Renesas RA4M1 ermöglicht JTAG den Zugriff auf den Debug-Port des Prozessors. Also das Lesen/Schreiben von Registern und das Setzen von Breakpoints.
Beim ESP32-C6 läuft dieses JTAG-Signal direkt über das ganz normale USB-Kabel (Universal Serial Bus). Ihr steckt das Board also einfach an euren PC an und habt sofort einen vollwertigen Fehlersucher zur Verfügung.

Die Vorbereitung in der Arduino IDE

Damit das klappt, benötigen wir die Arduino IDE in der Version 2.x (idealerweise die aktuelle Version 2.3.10 oder neuer). So bereitet ihr alles vor:

  1. Board anschließen: Verbindet euren ESP32-C6 per USB-Kabel mit dem Rechner.
  2. Board auswählen: Wählt in der Arduino IDE oben in der Leiste euer ESP32-C6 Board aus.
  3. USB-Modus umstellen: Geht im Menü auf Werkzeuge -> USB CDC On Boot und stellt diesen Wert auf Enabled.
  4. JTAG aktivieren: Geht auf Werkzeuge -> JTAG Adapter und wählt dort Integrated USB JTAG aus.

Unser Test-Code (mit absichtlichem Fehler!)

Kopiert nun den folgenden Code in eure IDE. Wir haben hier einen ganz klassischen Logikfehler eingebaut. Das Ziel des Codes ist eigentlich: Ein Zähler soll hochzählen und eine angeschlossene LED (hier fiktiv an Pin 8) soll blinken, solange der Zähler kleiner als 5 ist.

static int zaehler = 0;  // "static" behält den Wert zwischen loop()-Aufrufen
const int ledPin = 8; // Hier könnte eine LED angeschlossen sein

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  zaehler = zaehler + 1;

  // ABSICHTLICHER FEHLER: Wir haben versehentlich ein ">" statt "<" getippt!
  if (zaehler > 5) {
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    
    // Zähler nach dem Blinken wieder zurücksetzen
    zaehler = 0; 
  }
  
  delay(1000); // Eine Sekunde warten
}

Wenn ihr diesen Code normal hochladet, wird die LED die ersten 5 Sekunden dunkel bleiben und erst dann anfangen zu blinken. Genau falsch herum!

Den Fehler live aufspüren

Jetzt nutzen wir den Debugger, um herauszufinden, warum das passiert:

  1. Haltepunkt (Breakpoint) setzen: Klickt in der Arduino IDE links neben der Zeilennummer von
    if (zaehler > 5) {
    Es erscheint ein roter Punkt. Hier wird der Code gleich anhalten.
  2. Debugger starten: Klickt oben in der Leiste nicht auf den normalen „Hochladen“-Pfeil, sondern auf das Symbol mit dem kleinen Käfer (Play-Button mit Bug).
  3. Der Code hält an: Die IDE lädt den Code hoch und startet. Plötzlich stoppt die Ausführung genau bei eurem roten Punkt. Die Zeile ist nun farbig markiert.
  4. Variablen prüfen: Schaut euch die linke Seitenleiste in der IDE an. Dort gibt es einen Bereich namens „Lokale Variablen“. Ihr seht dort nun den Wert der Variablen zaehler (zunächst ist es eine 1).
  5. Schritt für Schritt: Klickt oben in der kleinen Debugger-Leiste auf „Schritt überspringen“ (Step Over).
    Ihr werdet sehen, dass die Ausführung nicht in die if-Bedingung springt, sondern direkt zum delay(1000) am Ende geht.

Die Erkenntnis: Da ihr den Wert von zaehler (der ist 1) direkt live im Speicher seht, wird sofort klar:

Die Bedingung 1 > 5 ist falsch.

Der Fehler ist entlarvt, ohne dass wir auch nur ein einziges Mal Serial.print() bemühen mussten!

Ihr könnt nun den Code korrigieren (aus dem > ein < machen), neu hochladen und alles funktioniert wie geplant.

Probiert es an euren eigenen Projekten aus. Sobald man sich an diese Arbeitsweise gewöhnt hat, spart sie beim Tüfteln enorm viel Zeit und Nerven.


Geht auch mit Arduino Zero, Arduino R4 Wifi oder ESP32-S3

1. ESP32-S3: Ja, exakt wie der ESP32-C6

Das funktioniert genau wie in dem Beispiel für deinen Blogbeitrag. Der ESP32-S3 hat ebenfalls die nötige Hardware für JTAG (Joint Test Action Group – der Standard zur Fehlersuche) direkt für den USB-Anschluss (Universal Serial Bus) eingebaut. Man nennt das „JTAG over USB“.

  • Wichtiger Praxis-Tipp: Die meisten ESP32-S3-Boards (z. B. ESP32-S3-DevKitC) haben zwei USB-Ports:
    „USB-C“ (Native/OTG): Für Debugging und Programmieren (nutzt JTAG over USB).
    „UART“ (CP210x/CH340): Nur zum Hochladen von Code (kein Debugging möglich).
    Wichtig: Nutze immer den Native-USB-Port für Debugging

2. Arduino Zero: Ja, direkt auf der Platine

Der Zero ist der Klassiker für dieses Thema. Er hat einen echten EDBG-Chip (Embedded Debugger) fest auf der Platine verlötet. Du steckst das USB-Kabel einfach in den Anschluss, der als „Programming Port“ beschriftet ist. Die Arduino IDE erkennt den Debugger sofort und du kannst ohne weitere Einstellungen loslegen.

3. Arduino UNO R4 WiFi: Debugging direkt über den Hauptprozessor

Hier hat Arduino eine sehr saubere, direkte Lösung umgesetzt. Der UNO R4 WiFi nutzt einen Renesas RA4M1-Chip als Hauptprozessor. Das Praktische daran: Dieser Chip hat seinen eigenen Debug-Port für SWD (Serial Wire Debug) und JTAG (Joint Test Action Group) bereits fest integriert.
Das Debugging läuft hier also direkt über den USB-C-Anschluss, der mit dem Hauptprozessor verbunden ist. Der ebenfalls auf dem Board verbaute ESP32-Chip dient rein als Co-Prozessor für das WLAN (Wireless Local Area Network) und Bluetooth – er fungiert hier nicht als Debugger.
Die Arduino-Entwicklungsumgebung nutzt im Hintergrund eine Software namens OpenOCD (Open On-Chip Debugger), um mit dem Hauptprozessor zu kommunizieren.
Für dich bedeutet das: Du kannst einfach das USB-Kabel einstecken, auf das Käfer-Symbol klicken und direkt auf Fehlersuche gehen.

Viel Spaß beim Ausprobieren und bis zum nächsten Projekt!

, , ,
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzerkomfort bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst und hilft uns zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.