Shouldn't this work?

I'm creating a sketch in which I want diagnostic output (to the Serial Monitor) to be generated ONLY when I'm developing the code and have the Arduino connected to my computer via the USB cable.

When I've disconnected the cable and am running the Arduino from battery I don't want it to even TRY to access the Serial Monitor, but I sure don't want to have to manually go through the sketch and either delete or comment-out each and every Serial instruction.

I'm OK with doing an additional compile to prepare it for battery operation, so that it will NOT generate the Serial instructions.

What I've done is use a #define statement like this:

//#define IF_SERIAL_ENABLED
// Replace the above with #define IF_SERIAL_ENABLED //
#define IF_SERIAL_ENABLED //
// if you want all Serial.print calls to be ignored (not even compiled).

And then, throughout the code, I do it like this:

// Prepare for serial text output
IF_SERIAL_ENABLED Serial.begin(115200);
// Wait for Serial to become active
IF_SERIAL_ENABLED while (!Serial)
IF_SERIAL_ENABLED delay(10);

IF_SERIAL_ENABLED Serial.println("MY PROGRAM");

The idea is that if IF_SERIAL_ENABLE is defined as being just blank text then the related Serial command is recognized as being an actual instruction and is compiled by the compiler. For example:

IF_SERIAL_ENABLED Serial.begin(115200);

actually becomes just

Serial.begin(115200);

since the IF_SERIAL_ENABLE gets turned into just a space character during preprocessing for the compiler.

ON THE OTHER HAND, if I have . . .

#define IF_SERIAL_ENABLED //

then every instance of IF_SERIAL_ENABLED should get replaced with just the "//" and basically turn the entire line into a comment statement and be ignored by the compiler.

Something like:

IF_SERIAL_ENABLED Serial.begin(115200);

becomes . . .

// Serial.begin(115200);

That's my theory of how it ought to operate. But that's not what actually happens.

Whether I use . . .

#define IF_SERIAL_ENABLED //

or

#define IF_SERIAL_ENABLED

all of the Serial instructions, like . . .

IF_SERIAL_ENABLED Serial.begin(115200);

do indeed get compiled and become part of the sketch.

While trying to figure out why it wasn't working as I expected, I tried . . .

#define IF_SERIAL_ENABLED crap

and sure enough the compiler reported it as an error, that it didn't recognize the word "crap".

I tried . . .

#define IF_SERIAL_ENABLED /

i.e. just a ingle slash, and that resulted in an error . . .

expected primary-expression before '/' token

So, why isn't this working as I'm expecting (hoping) it to work?

Is there some other way to basically have Serial instructions in the code that will get executed when the USB cable is connected (and therefore has access to the Serial Monitor) but have those Serial instructions NOT executed when running by battery and no USB cable connected (so there's no access to the Serial Monitor)?

Many people use a compilation option like defining a symbol, then testing whether the symbol is defined. Example code:

#define DEBUG_PRINT   //comment out this line to eliminate all code for debug printing
...

void setup() {

#ifdef DEBUG_PRINT
   Serial.begin(9600);
   Serial.println("debug printing enabled");
#endif

Is there some other way to basically have Serial instructions in the code that will get executed when the USB cable is connected

Not without hardware modifications, to my knowledge. Why does it matter if you print to a non-existent serial monitor, other than consuming CPU cycles?

what about

#if 0
# define DBG_PRINT(x)    Serial.print(x)
# define DBG_PRINTLN(x)  Serial.println(x)
#else
# define DBG_PRINT(x)    
# define DBG_PRINTLN(x)  
#endif

void
loop (void)
{
    DBG_PRINTLN("running");
    delay (2000);
}

void
setup (void)
{
    Serial.begin (9600);
    Serial.println ("ready");
}

The precompiler is too clever for you. It takes any single-line comments in the definition of a macro and replaces them with a /* */ comment. For example, your macro definition:
#define IF_SERIAL_ENABLED //
becomes:
#define IF_SERIAL_ENABLED /**/
and your line:
IF_SERIAL_ENABLED Serial.begin(115200);
becomes:
/**/ Serial.begin(115200);

I usually add a menu option to enable and disable debugging. This also works for libraries and across tabs in the IDE, not just in the main .ino file:

DEBUG("This is the result of `DEBUG`");
DEBUGREF("This is the result of `DEBUGREF`");
DEBUGFN("This is the result of `DEBUGFN`");
int a = 1, b = 2, c = 3;
DEBUGVAL(a, b, c);
This is the result of `DEBUG`
[Arduino/Debug/Debug.ino:50]:	This is the result of `DEBUGREF`
[void loop() @ line 51]:	This is the result of `DEBUGFN`
a = 1, b = 2, c = 3

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.