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.