Einfacher Arduino-Debugger

Zum Testen und Auffinden von Fehlern in Sketche ist es oft erforderlich, Haltepunkte zu setzen und Zwischenergebnisse und/oder Laufzeiten anzuzeigen, was als "debuggen" bezeichnet wird. Da solche Funktionen von der Arduino-IDE nicht zur Verfügung gestellt werden, habe ich zur Fehlersuche entsprechende Funktionen, vor allem also Ausgaben am Seriellen Monitor in den jeweiligen Sketch eingebaut, die dann, wenn der Sketch funktionierte, entweder wieder gelöscht oder auskommentiert werden mussten.

Angeregt durch ein Youtube-Video ("Debugging in der Arduino IDE" von "Der Hobbyelektroniker" https://www.youtube.com/watch?v=MOJGBwsPD7I) habe ich mir nun eine Bibliothek mit Makros zusammengestellt, die mir das Debuggen erleichtern sollen. Durch Auskommentieren einer einzigen Textzeile zu Beginn eines Sketches können alle eingebauten Debug-Makros wieder unwirksam gemacht werden und der zum Debuggen benötigte Speicherplatz wird wieder freigegeben.


Makro-Library MyDebug für Arduino:

Folgende Makros stehen derzeit zur Verfügung:

  • Ausgabe von Text und Zahlen (Integer und Float-Zahlen mit 2 Kommastellen) am Seriellen Monitor
  • Ausgabe von Text und Float-Zahlen mit Angabe der Anzahl der Kommastellen am Seriellen Monitor
  • Ausgabe von bis zu drei Zahlen (Integer und Float-Zahlen mit 2 Kommastellen) mit definierten Trennzeichen
  • Anhalten des Sketches bis Taste gedrückt wird
  • Setzen von Delays
  • Setzen von Zeitstempel in Milli- oder Mikrosekunden
  • Ausgabe der Programmlaufzeit in Milli- oder Mikrosekunden seit dem Setzen des letzten Zeitstempels


Die Makro-Library kann hier heruntergeladen werden:

Sollte den Debugger jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!

Version 1.0

MyDebug.h.txt

keywords.txt

Leider kann ich hier kein "h"-Files hochladen, daher zum Verwenden der Makro-Library das Suffix ".txt" aus dem Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyDebug" im Sketchbook-Ordner im Ordner "libraries" speichern.


Makros der Library MyDebug

Hinweise:

Fast alle Makros zur Ausgabe am Seriellen Monitor gibt es in den Versionen mit (...PRINTLN...) oder ohne (...PRINT...) nachfolgendem Zeilenvorschub!

Nachfolgend werden folgende Abkürzungen für die Übergabeparameter der Makros verwendet:

  • rate: Baudrate zum Seriellen Monitor
  • txt: Text
  • val: Interger- oder Float-Zahl
  • dec: Anzahl Dezimalstellen bei Float-Zahlen
  • dT: delay-Zeit
  • cond: Bedingung


Initialisierung:

Im Deklarationsteil:

/*
#define DEBUG_ON .... Debugger ist aktiviert
//#define DEBUG_ON ... Debugger ist deaktiviert
*/

#define DEBUG_ON //Debugger ist aktiviert (Definition muss vor der include-Anweisung stehen!)
#include <MyDebug.h>

Im setup:

DEBUG_BEGIN(rate)

Bemerkung: Kann entfallen, wenn die Funktion Serial.begin(xxxx) im Sketch verwendet wird.


Ausgabe von Zahlen und Zeichen am Seriellen Monitor:

Zeilenvorschub:

DEBUG_PRINTLN


Ausgabe von Text:

DEBUG_PRINT_TXT(txt)

DEBUG_PRINTLN_TXT(txt)


Ausgabe einer Zahl (Interger- oder Float-Zahl mit 2 Kommastellen):

DEBUG_PRINT_VAL(val)

DEBUG_PRINTLN_VAL(val)


Ausgabe von bis zu 3 Zahlen (Interger- oder Float-Zahlen mit 2 Kommastellen):

DEBUG_PRINT_PARAM(val1, val2, val3)

DEBUG_PRINTLN_PARAM(val1, val2, val3)

Beispiel:

x1 = 5;

x2 = 6;

DEBUG_PRINT_PARAM(x1, x2, 0);

  Ausgabe am Seriellen Monitor.:     5 6 0

  Bemerkung: Nicht definierte Parameter müssen mit 0 deklariert werden


Ausgabe von bis zu 3 Zahlen (Interger- oder Float-Zahlen mit 2 Kommastellen) mit definierten Trennzeichen:

DEBUG_PRINT_PARAM_DEL(val1, val2, val3, txt)

DEBUG_PRINTLN_PARAM_DEL(val1, val2, val3, txt)

Beispiel:

x1 = 5;

x2 = 6;

X3 = 7;

x4 = 8;

DEBUG_PRINT_PARAM_DEL(x1, x2, x3, " | ");

DEBUG_PRINT_PARAM_DEL(x4, 0 , 0, " | ");

  Ausgabe am Seriellen Monitor.:     5 | 6 | 7 | 8 | 0 | 0 |

  Bemerkung: Nicht definierte Parameter müssen mit 0 deklariert werden


Ausgabe einer Float-Zahl mit Angabe der Anzahl der Kommastellen:

DEBUG_PRINT_FLOAT(val, dec)

DEBUG_PRINTLN_FLOAT(val, dec)


Ausgabe von Text und einer Zahl (Interger- oder Float-Zahlen mit 2 Kommastellen):

DEBUG_PRINT_TXT_VAL(txt, val)

DEBUG_PRINTLN_TXT_VAL(txt, val)


Ausgabe von Text, einer Zahl (Interger- oder Float-Zahlen mit 2 Kommastellen) und einem Text:

DEBUG_PRINT_TXT_VAL_TXT(txt1, val, txt2)

DEBUG_PRINTLN_TXT_VAL_TXT(txt1, val, txt2)

Beispiel:

tempWert = getTemp(); //Einlesen eines Temperaturmesswertes eines Sensors

DEBUG_PRINTLN_TXT_VAL_TXT("Messwert1 = ", tempWert, "  °C");

  Ausgabe am Seriellen Monitor, z.B.:   Messwert1 = 15.21 °C


Ausgabe von Text und einer Float-Zahl mit Angabe der Anzahl der Kommastellen:

DEBUG_PRINT_TXT_FLOAT(txt, val, dec)

DEBUG_PRINTLN_TXT_FLOAT(txt, val, dec)


Ausgabe von Text, einer Float-Zahl und einem Text mit Angabe der Anzahl der Kommastellen:

DEBUG_PRINT_TXT_FLOAT_TXT(txt1, val, dec, txt2)

DEBUG_PRINTLN_TXT_FLOAT_TXT(txt1, val, dec, txt2)

Beispiel:

luftDruck = BME.readPress(); //Einlesen des Luftdrucks eines Sensors

DEBUG_PRINTLN_TXT_FLOAT_TXT("Luftdruck = ", luftDruck, 1, "mBar");

  Ausgabe am Seriellen Monitor:   Luftdruck = 980.3 mBar


Ausgabe der Programmlaufzeit seit dem letzten gesetzten Zeit-Punkt in Millisekunden

DEBUG_PRINTLN_RUNTIME

Beispiel:

DEBUG_SET_TIMEPOINT;

for (byte i = 0; i < 127; i++) Serial.println(i);

DEBUG_PRINTLN_RUNTIME;

  Ausgabe am Seriellen Monitor:   Runtime = 8 ms


Ausgabe der Programmlaufzeit seit dem letzten gesetzten Zeit-Punkt in Mikrosekunden

DEBUG_PRINTLN_MICRO_RUNTIME

Beispiel:

DEBUG_SET_MICRO_TIMEPOINT;

strcpy(txt1, txt2);

DEBUG_PRINTLN_MICRO_RUNTIME;

  Ausgabe am Seriellen Monitor:   Runtime = 12 us


Sonstige Befehle:

Anhalten des Sketches und warten auf Tasteneingabe 'c' :

DEBUG_WAIT(txt, cond)

Beispiel:

DEBUG_WAIT("Haltepunkt 1", true);

  Ausgabe am Seriellen Monitor:

  Haltepunkt 1

  Druecke 'c' fuer Weiter ...


Ausführen einer Delay-Funktion:

DEBUG_DELAY(dT)


Setzen eines Zeitstempels in Millisekunden

DEBUG_SET_TIMEPOINT

Bemerkung: siehe dazu Makro DEBUG_PRINTLN_RUNTIME


Setzen eines Zeitstempels in Mikrosekunden

DEBUG_SET_MICRO_TIMEPOINT

Bemerkung: siehe dazu Makro DEBUG_PRINTLN_MICRO_RUNTIME


Programmbeispiel mit Einsatz des Debuggers:

Nach Betätigung der Taste 'c' wird die for-Schleife durchlaufen, wobei die Zwischenergebnisse der Schleife und die Gesamtlaufzeit angezeigt werden:

//Debugger Beispiel 1
//Code fuer Arduino
//Author Retian
//Version 1.0


/*

Die Anregung zum Debugger erhielt ich durch das Youtube-Video

"Debugging in der Arduino IDE" von "Der Hobbyelektroniker" 

https://www.youtube.com/watch?v=MOJGBwsPD7I

*/


/*
#define DEBUG_ON .... Debugger ist aktiviert
//define DEBUG_ON ... Debugger ist deaktiviert
*/


#define DEBUG_ON //Debugger ist aktiviert (Definition muss vor der include-Anweisung stehen!)
#include <MyDebug.h>


int sum;


void setup() {
  DEBUG_BEGIN(115200);
  DEBUG_PRINTLN_TXT("*** Debugger-Test ***");
}


void loop() {
  DEBUG_WAIT("Wartepunkt 1!", true);
  DEBUG_SET_TIMEPOINT;
  for (byte i = 1; i <= 9; i++)
  {
    sum += i;
    DEBUG_PRINT_TXT_VAL_TXT("Durchgang ", i, ": ");
    DEBUG_PRINTLN_TXT_VAL("Summe = ", sum);
  }
  DEBUG_PRINTLN_RUNTIME;
  DEBUG_PRINTLN;
}


Programmspeicherbedarf:

Mit aktiviertem Debugger:  2240 Bytes

Mit deaktiviertem Debugger: 462 Bytes


Ausgabe am Seriellen Monitor mit eingeschaltetem Debugger:

Abbildung 1: Debugger-Ausgabe am Seriellen Monitor