9

I like having serial communication for debugging and testing purposes but after a while it takes away too much speed from the sketch.

Is it possible to have the Arduino ignore serial.print and serial.println throughout my code, without turning it into a comment or placing every serial printing inside for example "if(debug == true)" statements?

Thanks in advance.

3 Answers 3

15

If you insist on top performance, the best thing would be to use a macro for that:

#define Sprintln(a) (Serial.println(a))

Then instead of

Serial.println(F("Hello world!"));

write

Sprintln(F("Hello world!"));

etc. To deactivate the Serial printing, define the macro empty:

#define Sprintln(a) 

This will have the preprocessor remove all debugging code defined with Sprintln from your code.

(Of course, there's a huge number of variations on this theme.)

2
  • 1
    You can also wrap all exiting prints in #ifdef ENABLE_PRINT and #endif and then define or comment out #define ENABLE_PRINT at the top of ur file
    – benathon
    Apr 5, 2015 at 12:20
  • 1
    You can even set a debug level and define macro's for debugL1();, debugL2(); etc, so you can choose how many details you want to "log". The macro's will though make it unable to change runtime, but at the advantage of not having runtime overhead.
    – aaa
    Oct 4, 2016 at 20:04
7

You could, for example, use the preprocessor to change all Serial in your code.

#ifndef ENABLE_PRINT
// disable Serial output
#define Serial SomeOtherwiseUnusedName
static class {
public:
    void begin(...) {}
    void print(...) {}
    void println(...) {}
} Serial;
#endif
0
2

Yet another solution is to implement a dummy Serial device. That would be a class that as HardwareSerial inherits from Stream and implements the necessary virtual member functions with dummy functions.

class NullSerial : public Stream {
public:
  virtual size_t write(uint8_t) { return (1); }
  virtual int available() { return (0); }
  virtual int read() { return (0); }
  virtual int peek() { return (0); }
  virtual void flush() {}
  ...
  void begin(unsigned long, uint8_t) {}
  void end() {}
  ...
};

NullSerial Serial;

As Serial is not defined as a weak symbol the application would need to use a Steam variable for output. And bind this to the HardwareSerial or the NullSerial.

#if defined(DEBUG)
Stream& trace = Serial;
#else
NullSerial noSerial;
Stream& trace = noSerial;
#else

#endif
...
trace.print(42);

This is not complete as all the HardwareSerial member functions (that the sketch uses) are needed but gives the general idea how to use OOP to solve the problem.

Cheers!

1
  • This worked well for me (great for debugging in PlatformIO!). Instead of declaring NullSerial Serial (which conflicts with the HardwareSerial declaration by the same name), I gave it a unique name (NullSerial nullSerial) and then overrode the original everywhere with #define Serial nullSerial. Lovely thing about this method is that my existing code does not change. Aug 19, 2023 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.