algorithm Arduino software

Simple Debugging for Arduino Sketches

Bug_TrackingDespite the advent of source level debuggers for Arduino code, one of the most accessible ways to debug Arduino projects is still the Serial.print() statement. It is how most beginners will start when trying to debug their code.

But what do you do with all the print() statements sprinkled through the code once your application is working?

You certainly don’t want to delete the debug after all the hard work putting it in – after all, you may need this again – and commenting it out everywhere can be a real pain.

A very simple technique is to use the C++ preprocessor to do the work for you. This is an obvious method for experienced programmers, but not always so for beginners.

Debug Macros

Somewhere in the headers for most of my Arduino sketches and libraries is this macro block:

// Debugging switches and macros
#define DEBUG 0 // Switch debug output on and off by 1 or 0

#define PRINTS(s)   { Serial.print(F(s)); }
#define PRINT(s,v)  { Serial.print(F(s)); Serial.print(v); }
#define PRINTX(s,v) { Serial.print(F(s)); Serial.print(F("0x")); Serial.print(v, HEX); }
#define PRINTS(s)
#define PRINT(s,v)
#define PRINTX(s,v)

If the serial port is not used in the application, setup() needs to open the port specifically for debugging, otherwise no output will be visible on the serial monitor:

void setup(void)

Debugging output is enabled or disabled by setting DEBUG to 1 or 0.

If debugging is turned on, each statement is expanded into a block of code invoking a sequence of Serial.print() statements.

With debug turned off, the PRINT statements are expanded to ‘nothing’.  This frees the final code of all debugging statements, whilst still retaining all the debug source code in place.

The PRINT statements are built for convenience and can be expanded to suit your debugging style. They also automatically put the constant string in PROGMEM by applying the F() macro to these strings, minimizing the amount of RAM that is used to support debugging.


  • There is no need for PRINTLN – simply put in the “\n” as part of the string.
  • PRINTS prints a string, as in
 PRINTS("\nError check");
  • PRINT prints a string and a value. This is a very common requirement and greatly simplifies this operation.
PRINT("\nCurrent state:", state);
  • PRINTX is a variation on PRINT that outputs the value parameter in hexadecimal.
  • Specialized PRINT statements can also be created. For example, I often have specific ones for Finite State Machine tracing:
#define PRINT_STATE(f) { Serial.print(F("\n")); Serial.print(F(f)); Serial.print(F(" fsm "));


As with anything there are some limitations I have found when using this technique:

  1. You cannot use it in interrupt routines. Serial.print() needs interrupts to work so is not compatible with use in an ISR.
  2. The string parameters to the PRINT statements need to be constants for the F() macro to work. This is not usually a problem, but it does cause compiler errors. A different PRINT statement can be created if required, but I have never found the need.
  3. Conditional statements can cause errors under certain circumstances. For example
if (condition)
  PRINT("Value: ", variable);

will be expanded to have a ‘;’ before the else. The PRINT statement needs to be inside braces to make it a block of code. This error can be very confusing the first time you see it happen!

3 replies on “Simple Debugging for Arduino Sketches”

if you write #define DEBUG 0 or 1 then DEBUG is in both cases defined.
runs both times. If you comment out #define DEBUG then it is not defined and will not run at all ..


#if tests the boolean value (in the C language sense of zero or non-zero), #ifdef test whether the symbol is defined. So #if is the correct syntax if you are defining as 1 or 0.

Liked by 1 person

The third limitation should be fixable.
I have not tested these, but:

#define PRINTS(s) Serial.print(F(s))
#define PRINT(s,v) do { Serial.print(F(s)); Serial.print(v); } while(0);
#define PRINTX(s,v) do { Serial.print(F(s)); Serial.print(F(“0x”)); Serial.print(v, HEX); } while(0);

This is a very common pattern in C programming. It’s a bit ugly, but it groups the statements together such that it “just works”.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s