Hi everybody,
some time ago I wrote a macro for debugging purposes that makes it more efficient to add code that does debugoutput
This is the definition of the macro including a description how it works
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
// usage dbg("fixed Text", variableName)
// example printing name and content of a variable called "myCounter"
// dbg("Demo-Text",myCounter);
// serialoutput will be '"Demo-Text" myCounter=1'
// which means this macro does three things
// 1. print the fixed text
// 2. print the NAME of the variable
// 3. print the CONTENT of the variable
// all in one line
As long as the code repeats the call for dbg(...) only at a low frequency this works well.
Now I'm thinking about an enhancement that allows to use a similar debug-output but with an additional requirement:
even if the call for dbgInterval(....) is done thousansds of times per second
do a print only once per second or a user-definable interval
Here is a democode that shows this through using a timing function
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
// non-blocking timing-function
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
// millis()-timing-variables MUST be of type unsigned long
unsigned long MyTestTimer = 0;
boolean buttonHasBeenPressed = false;
unsigned long myDebugIntervalTimer = 0;
const byte ledPin = 13;
const byte buttonPin = 3;
void setup() {
Serial.begin(115200);
Serial.print( F("\n Setup-Start \n") );
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
buttonHasBeenPressed = false;
}
void loop() {
int buttonState;
buttonState = digitalRead(buttonPin);
// only print once per second even if loop repeats very fast
if (TimePeriodIsOver (myDebugIntervalTimer,1000) ) {
dbg("0:looping",buttonState);
dbg("0:",buttonHasBeenPressed);
}
// if-condition only true once
// because boolean flag is changed to "true"
if ( !buttonHasBeenPressed && (buttonState == LOW) ) {
digitalWrite(ledPin, HIGH);
Serial.print( F("Button pressed! \n") );
dbg("1:Button pressed",buttonState);
buttonHasBeenPressed = true;
// initialise timervariable with actual time
MyTestTimer = millis();
}
// if-condition only true once
// because boolean flag is changed to "false"
if ( buttonHasBeenPressed && TimePeriodIsOver (MyTestTimer,5000) ) {
digitalWrite(ledPin, LOW);
buttonHasBeenPressed = false;
dbg("Time is over",digitalRead(ledPin));
}
}
Now the ideal thing would be to reduce the (macro) code that must be written as short as this
dbgi("fixed text",variablename,printInterval);
this has some implications:
- for each new call of the macro a new timing-variable must be created
- an if-condition must be added that checks if printInterval is over
I guess the timing-variable must be static to enable a local declaring at the place where the macro sits in the code.
I would have to use a MACRO-countervariable that would be incremented by one for each call of
the dbgI-macro to create a new timing-variable like
static unsigned long dbgTimer1
and with the next call of dbgI()
static unsigned long dbgTimer2
...
is there a possability to have a MACRO-variable and to increment the value of this MACRO-variable at "compile"-time?
best regards Stefan