Due, disconnecting prog port in production... Serial.print...

I've just about got my new Due-based USB game controller project finished, touch screen and all. But I've just had a nasty sinking feeling about something. I ported a lot of the code from the Leonardo version and it's sprinkled with Serial.print commands for debugging; and of course I've thoughtlessly sprinkled still more throughout the new code. But the simple little Leonardo only had one USB port which served as both Serial and HID/USB. The Due has two-ay: programming port and HID port. Separate.

Looking ahead: when it's installed for real I only want one USB cable (HID) connected, the Prog port unplugged, no IDE running, no Serial Monitor... and then the very first Serial.print command will hang, right? I have to start the Serial Monitor now to get through setup (hangs without it), so that seems conclusive.

I think I've shot self in foot by not writing some kind of logmsg function that wrapped all the Serial.prints (hundreds of 'em), so that the run mode (production or debug) could have been ifdef'd at the start, detected in the logmsg function, etc. Oops.

I kinda doubt there's any way out of this other than a lot of very tedious editing, but being a lazy person I wondered if there might be any sneaky expert way to... make the Arduino pretend its Serial is live? or make all its Serial.prints non-blocking? or similar trickery? ... it would save me an awful lot of (well deserved, ouch) pain. Meanwhile, there will be 2 usb cables and the IDE will stay open (which is OK for now 'cos I'm still debugging).

You can easily switch on and off debug serial prints with very minimal changes to your code. Add these lines to your sketch somewhere before the first use of Serial:

#define DEBUG false  //set to true for debug output, false for no debug ouput
#define Serial if(DEBUG)Serial

That will work with most uses of Serial without any changes needed. There are certain cases it won't cover. The most common is this sort of thing:

while (!Serial);  // wait for a serial connection to be made before continuing

You will need to change that to this:

while (DEBUG && !Serial);

@pert wow. You mean that if I put

#define DEBUG false  //set to true for debug output, false for no debug ouput
#define Serial if(DEBUG)Serial

in the early definitions before setup is called, then a line of code like

Serial.println(F("Whatever I meant to say, it wasn't really that interesting"));

will become effectively a NOP? I really don't quite understand the magic of #define. It looks almost like pre-compile string substitution? Or maybe what I don't understand is the magic of methods (like println)? but whichever, if this works I'm home free -- this lazy person thanks you very much indeed!

UPDATE: doesn't seem to work for me on the Due so far. I add

// setting up for production mode, no serial output so we can unplug prog port
#define DEBUG true
#define Serial if(DEBUG)Serial

at the very beginning of the source (top of first tab) and I get a weird compile error part way through Setup:

exit status 1
expected primary-expression before 'if'

if I take out the define Serial if(DEBUG) Serial statement then everything compiles. WTH?

Tazling:
will become effectively a NOP?

No, it will just be optimized out by the compiler completely. The reason is it sees that the if statement will never be true.

Tazling:
I really don't quite understand the magic of #define.

It just does a text replace. If you have a line of code like this:

Serial.println("hello");

Then after preprocessing, it will be this:

if(false)Serial.println("hello");

Tazling:
at the very beginning of the source (top of first tab) and I get a weird compile error part way through Setup:

exit status 1

expected primary-expression before 'if'

Hmm. It looks like my replacement code for while(!Serial); is bad. I remember figuring this out a while ago, but now I don't know how I did it. Here's a solution:
The debug switching code is now this:

#define DEBUG false //set to true for debug output, false for no debug ouput
#if DEBUG == false
#define Serial if(DEBUG)Serial
#endif

The replacement for while(!Serial); is now this:

#if DEBUG == true
  while (!Serial);
#endif

@pert ... magic! the more elaborate version works. I never used while(!Serial) so can't speak to that syntax but the 2nd version of the define compiles properly, great! I have no idea why, but I'm content not to understand some things :slight_smile:

UPDATE: darnit, no it still doesn't work. I put this code at the top of my first tab

#define DEBUG false //set to true for debug output, false for no debug ouput

#if DEBUG == false
#define Serial if(DEBUG)Serial
#endif

As long as I define DEBUG true, everything is fine. But if I define DEBUG false as you see here, thus invoking the 2nd #define, then I get a compile error at some random later place in the code. If I define it true again, everything compiles just fine.

Too bad. I have a timing issue now which I think might be related to the thousands of Serial.prints my debug statements are barfing out, and was hoping to turn them off all at once to see if the timing issue improved. But I guess I'll just have to comment out the chattiest ones and see what happens.