Comfortable serial debug-output short to write fixed text name AND content of any variable [code example]

some aditional example how it works:

using the #define "statement" to make the compiler "write" code
#define can be used to make the compiler replace text that describes something with (almost) anything else

easy example
let's assume IO-pin number 4 shall be set to work as output
the command for defining an IO-pin to be configured as output is

pinMode(4,OUTPUT);
the number "4" says nothing about the purpose of this IO-pin

let's assume the IO-pin shall switch On/Off a buzzer

you would have to add a comment to explain
pinMode(4,OUTPUT); // IO-pin 4 is buzzer

the compiler needs the number. To make the code easier to read and understand
#define BuzzerPin 4
So the command looks like this
pinMode(BuzzerPin,OUTPUT);

the descriptive word "BuzzerPin" gets replaced through the compiler by a "4"
so what the compiler compiles is still
pinMode(4,OUTPUT);

the #define can do much more than just replace a word by a single number
it can replace multiple words like

#define prHello Serial.println("Hello World!");

identifier-part: prHello

replacement-part: Serial.println("Hello World!");

The mechanism behind it is the compiler acts like if you would

deleting the identifier-part:

and then

typing the replacement-part:

into your *.ino-textfile which is your sourcecode.

This is done right after clicking the compile or the upload-button in the IDE.

macros can do even more.

You can use "MACRO"-variables. If you enter
this means the macros act on a completely different level than the program-code

macros act on the source-code-level

explaining the "variables" myFixedText, variableName, timeInterval

#define dbgi(myFixedText, variableName,timeInterval) \

the macro dbgi has round parenthesis "words" inside the parenthesises are seen as
"MACRO"-variables. MACRO-variables don't need a declaring. Because macros act on the
source-code-level. The MACRO-variable contains text and the MACRO-variable is replaced by the text it contains.

If your program is compiled and uploaded to the microcontroller things are "acting" on the program-level.

an expression like #myFixedText with a leading double-cross "#"
acts like a text-variable

#define dbg(myFixedText, variableName) \

parenthesis open myFixedText = use myFixedText as a macro-variable

a call of the macro looks like this:

dbg("entering case 1", 0);

This means all characters right behind the opening parenthese and the comma get stored into the macro-variable myFixedText

Serial.print( F(#myFixedText does

replace the character-sequence hold by the macro-variable myFixedText
so after this action the source-code looks like this

Serial.print( F("entering case 1"

The macro goes on
Serial.print( F(#myFixedText " " #variableName"=") ); \

which means after finishing the whole line your source-code looks is "transformed from

macro-call:

dbg("entering case 1", 0);

to

Serial.print( F("entering case 1  0=") );

macro-variable "variableName" holds the "0"

this part of the macro-code
Serial.print( F(#myFixedText " " #variableName"=") ); \

is replaced by the "0"
the rest
Serial.print( F(#myFixedText " " #variableName"**=") ); **

are again just characters
so at the end the source-code-line looks like this

Serial.print( F("entering case 1  0=") );

in principle the same thing happends with the rest of the macro

Serial.println(variableName);

With a modified example for the macro-call

dbg("damm! show me the content of variable",myStep);

results in

Serial.print(  F("damm! show me the content of variable myStep=") );
Serial.println(myStep);
dbg("what the heck is value of variable",myCounter);

results in

Serial.print(  F("what the heck is value of variable myCounter=") );
Serial.println(myCounter);

a do - while -loop with a fixed condition "false"

At first view this seems to be nonsense a do-while-loop where the condition always evaluates to "false" means
run down the code only once

curly braces to define a local scope

The purpose of the curly braces {} is it makes the variable intervalStartTime
local to the code inside the curly braces

This has the effect that with mutliples calls of macro dbgi
the always the same named variable intervalStartTime are each local and don't disturb each other.

This means the macro dbgi can be called at thousands places where each call has its own set of variables.