#define DEBUG true //set to true for debug output, false for no debug output
#define DEBUG_SERIAL if(DEBUG)Serial
Then use debug output like this:
DEBUG_SERIAL.println("Some debug output");
When DEBUG is set to false, the compiler will optimize the calls using DEBUG_SERIAL out of the code because it knows they will never run.
If you want your program to wait for Serial Monitor to be opened before running when using native USB boards (e.g., Leonardo, Micro, MKR, Nano 33 IoT), add this line:
This can easily be extended to allow multiple levels of debug output, still with no overhead when it's disabled:
#define DEBUG_ERROR true
#define DEBUG_ERROR_SERIAL if(DEBUG_ERROR)Serial
#define DEBUG_WARNING true
#define DEBUG_WARNING_SERIAL if(DEBUG_WARNING)Serial
#define DEBUG_INFORMATION true
#define DEBUG_INFORMATION_SERIAL if(DEBUG_INFORMATION)Serial
void setup() {
Serial.begin(9600);
while (!Serial);
DEBUG_ERROR_SERIAL.println("This is an error message");
DEBUG_WARNING_SERIAL.println("This is a warning message");
DEBUG_INFORMATION_SERIAL.print("The state of pin 5 is ");
DEBUG_INFORMATION_SERIAL.println(digitalRead(5) ? "HIGH" : "LOW");
Serial.println("This is standard program output");
}
void loop() {}
You can use the boolean debug macros to switch on and off other parts of your code too.
Using Serial.begin() will cause a bunch of the serial code and memory to get included in your program, even if you never call Serial.print()
So you'll have to figure out how to conditionalize that as well.
I left Serial.begin() unmodified in the final code above because that was a demonstration of using debug output in addition to standard Serial output. If you only were using Serial for debug output, you would use the debug system for the Serial.begin() call as well.