Are my Macros getting too large?

I have been using the following macro to more conveniently format my Serial.print commands, but soon also to change the destination of where the text goes instead of Serial. As I understand it, when compiling, the code in the define replaces spots where I say PRINT(...). With how long these are getting, and each one might get longer, could this be using more processing time/memory than just making a VOID function?

// Debugging switches and macros
#define DEBUG 4    // Switch debug output on and off by 1+ or 0
#define wLine 1    // Set 0 to include printing the line number
#define DEBUGS 0    // Switch Spamming debug output on and off by 1+ or 0
#define TIMELOG 0  // Switch debug output on and off by 1 or 0
#define WIFI 0    //Set to 0 if you want to avoid the wifi check

#if DEBUG  //For all debugs
  #if wLine
    #define PRINTS(s) \
      { \
        Serial.print(F(s)); \
        Serial.print(" @ Line "); \
        Serial.print(__LINE__); \
        Serial.println(); \
      }
    #define PRINT(s, v) \
      { \
        Serial.print(F(s)); \
        Serial.print(": "); \
        Serial.print(v); \
        Serial.print(" @ Line "); \
        Serial.print(__LINE__); \
        Serial.println(); \
      }
    #define PRINTX(s, v) \
      { \
        Serial.print(F(s)); \
        Serial.print(": "); \
        Serial.print(F("0x")); \
        Serial.print(v, HEX); \
        Serial.print(" @ Line "); \
        Serial.print(__LINE__); \
        Serial.println(); \
      }
  #else
  #define PRINTS(s) \
    { \
      Serial.print(F(s)); \
      Serial.println(); \
    }
  #define PRINT(s, v) \
    { \
      Serial.print(F(s)); \
      Serial.print(": "); \
      Serial.print(v); \
      Serial.println(); \
    }
  #define PRINTX(s, v) \
    { \
      Serial.print(F(s)); \
      Serial.print(": "); \
      Serial.print(F("0x")); \
      Serial.print(v, HEX); \
      Serial.println(); \
    }
  #endif
#else
  #define PRINTS(s)
  #define PRINT(s, v)
  #define PRINTX(s, v)
#endif

If you're calling any of them more than once, you'll almost certainly save program space by replacing them by a function.

And if the core platform you're using supports printf, you might want to consider using that instead.

Well right now I call PRINT 65 times and PRINTS 24 times...including a section that prints all of my variables...

PRINTS("<---- START Global Variable Dump ---->");
PRINT("interval", interval);
PRINTS("");

PRINT("previousMicroS", previousMicroS);
PRINT("currentMicroS", currentMicroS);
PRINT("nextEvent", nextEvent);
PRINT("nextEventDrift", nextEventDrift);
PRINTS("");

PRINT("previousMicroSPause", previousMicroSPause);
PRINT("currentMicroSPause", currentMicroSPause);
PRINT("nextEventPause", nextEventPause);
PRINT("pauseMode", pauseMode);

PRINTS("");
PRINT("beat", beat);

PRINTS("");
PRINT("mode", mode);
PRINT("mode name", modeName())
PRINT("lastmode", lastmode);

That is about half of that dump section. I imagine I could make that into into a Macro section since I probably wont need that compiled when finished.

Taking a quick look at your macros only part is getting executed, this is OK. Remember if a part does not get executed it does not use any CPU time.

I believe if it fits in memory it is not to long. The is a subjective decision by the programmer (you).

With UNO, you can easily run out of ram... so keep that in mind...
With esp a bit of text is usually not the problem... things like .png files might get you into trouble though...

Not more time really as in case of a function or duplicated code, you still spend the time doing what needs to be done. The function call will actually add one extra indirection compared to the inlined version so will be (imperceptibly) slower.

The size of the binary will shrink significantly if you use a function which would use the macro but all this is caught and reported by the compiler so you would know if you run out of flash memory.

One challenges going with the function is going to be the text that your macro works on as F(s). You’ll need to have that F() call inside the function’s parameters otherwise you’ll eat up RAM (and of course the F() stuff won’t work in the function anyway), and you’ll have to cast as a flash based address.

Long story short - if the compiler doesn’t say you are running out of flash memory you are fine (for the time being).

Side note:

You could save one call in your macro by removing the last println() and embed that into

Serial.println(__LINE__);

A lot of repetition which can be avoided.

#define PRINT(v) \
    { \
      Serial.print(F(#v)); \
      Serial.print(": "); \
      Serial.println(v); \
    }

PRINT(previousMicroS);
PRINT(currentMicroS);
PRINT(nextEvent);
PRINT(nextEventDrift);

#v turns the macro parameter into a string literal.

instead of macro, why not just a function using sprintf

Output:

msec: 0xD324 @ Line 29
@ line   30 - 0xd324 -11484 msec
    #define PRINTX(s, v) \
      { \
        Serial.print(F(s)); \
        Serial.print(": "); \
        Serial.print(F("0x")); \
        Serial.print(v, HEX); \
        Serial.print(" @ Line "); \
        Serial.print(__LINE__); \
        Serial.println(); \
      }

char s [90];

void printX (
    int   line,
    int   v,
    char *txt )
{
    sprintf (s, "@ line %4d - 0x%04x %6d %s", line, v, v, txt);
    Serial.println (s);
}


// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long msec = millis ();

    PRINTX("msec", msec);
    printX(__LINE__, msec, (char*)"msec");

    delay(1000);
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);
}

You need to modify the function so that the text is in flash memory otherwise with the amount of logs OP has, he might saturate the RAM.

why is s using F() but not `" @ Line " if that is a real concern.

i was going to suggest maybe he should just use a table of var name string and var pointers instead of harcoding so many strings

It can be opTimized indeed but impact is limited because it will likely be stored only once in RAM.

They're not so long, individually. Your longest macro is:

    #define PRINTX(s, v) \
      { \
        Serial.print(F(s)); \
        Serial.print(": "); \
        Serial.print(F("0x")); \
        Serial.print(v, HEX); \
        Serial.print(" @ Line "); \
        Serial.print(__LINE__); \
        Serial.println(); \
      }

Your use of brackets isn't quite right, and there's room for optimization:

#define xstr(s) #s
#define STRINGIFY(n) xstr(n)

#define PRINTX(s, v) \
do {                            \
  Serial.print(F(s ": 0x"));    \
  Serial.print(v, HEX);         \
  Serial.println(F("@ Line " STRINGIFY(__LINE__))); \
} while (0)

(The compiler will automatically concatenate adjacent literal strings, so "foo" " bar" is exactly the same as "foo bar"
The STRINGIFY/xstr stuff is "standard mysterious preprocessor stuff" for turning a compile-time numeric constant into a literal string.)