I have this tab in the Arduino IDE with all my debugging statements. I now want to change this. My goal is to write a function which will take all the different values. This means I would call the function within another function to be able to include local variables.
These are the debugging statements I have so far:
void loop_debugSerial() {
static float totalHum = 0;
static unsigned long counterHum = 0;
static float averageHum;
float dayAverageHum = 0; // static???
float nightAverageHum = 0; // may be later only one? static???
/*Debug Interval*/
static long previousDebug = 0;
const long debugInterval = 1000;
if (timeNow - previousDebug > debugInterval) {
previousDebug = timeNow;
/*For Debugging*/
Serial.print(F("Time: ");
Serial.prinln(digitalClock());
Serial.print(F("Date: ");
Serial.println(digitalDate());
/*Serial.print(F("Time / Date: "));
digitalClockDisplay();*/
/*Serial.print(F("Date is: "));
Serial.print(day(), DEC);
Serial.print(F("."));
Serial.print(month(), DEC);
Serial.print(F("."));
Serial.println(year(), DEC);*/
Serial.println(F("---"));
Serial.println(F("---"));//(F("---------------------------"));
Serial.print(F("AMB.valPWM: "));
Serial.println(grLEDControl[AMBIENT].valPWM);
Serial.print(F("HOT.valPWM: "));
Serial.println(grLEDControl[HOT].valPWM);
Serial.print(F("NEON: "));
Serial.println(digitalRead(grLEDControl[NEON].pin));
//Serial.print(F("FAN: "));
//Serial.println(digitalRead(outputPin[FAN]));
Serial.print(F("Lamp State: "));
Serial.println(grLEDControl[AMBIENT].state);
Serial.print(F("Temp State: "));
Serial.println(grTEMPControl[AMBIENT].state);
/*Day Time*/
if ( morning() )
Serial.println(F("Morning"));
if ( noon() )
Serial.println(F("Noon"));
if ( afternoon() )
Serial.println(F("Afternoon"));
if ( night() )
Serial.println(F("Night"));
/*Sun state*/
switch( grLEDControl[HOT].state ) {
case SUNRISEPREP:
Serial.println(F("SR_PREP"));
break;
case SUNRISE:
Serial.println(F("SR"));
break;
case SUNUPLOW_AM:
Serial.println(F("S_UP_AM"));
break;
case SUNUPHIGH:
Serial.println(F("S_UP"));
break;
case SUNUPLOW_PM:
Serial.println(F("S_UP_PM"));
break;
case SUNSETPREP:
Serial.println(F("SS_PREP"));
break;
case SUNSET:
Serial.println(F("SS"));
break;
case SUNDOWN:
Serial.println(F("SD"));
break;
}
/*if ( grLEDControl[HOT].state == SUNRISEPREP )
Serial.println(F("SUNRISEPREP"));
if ( grLEDControl[HOT].state == SUNRISE )
Serial.println(F("SUNRISE"));
if ( grLEDControl[HOT].state == SUNUPLOW_AM )
Serial.println(F("SUNUPLOW_AM"));
if ( grLEDControl[HOT].state == SUNUPHIGH )
Serial.println(F("SUNUPHIGH"));
if ( grLEDControl[HOT].state == SUNUPLOW_PM )
Serial.println(F("SUNUPLOW_PM"));
if ( grLEDControl[HOT].state == SUNSETPREP )
Serial.println(F("SUNSETPREP"));
if ( grLEDControl[HOT].state == SUNSET )
Serial.println(F("SUNSET"));
if ( grLEDControl[HOT].state == SUNDOWN )
Serial.println(F("SUNDOWN"));
*/
/*Temperature Level*/
switch( grTEMPControl[HOT].state )
//if ( evaluateTempState() == AMBIENTLOWBOTH )
{
case AMBIENTLOWBOTH:
// Serial.println(F("123"));
Serial.println(F("AMB_LOWB"));
break;
case AMBIENTLOWINHIGHOUT:
Serial.println(F("AMB_LOWINH_OUT"));
// Serial.println(F("123"));
break;
case TEMPLOWALL:
Serial.println(F("LOWALL"));
break;
case TEMPLOWIN:
Serial.println(F("LOWIN"));
break;
case TEMPHIGHALL:
Serial.println(F("HIGHALL"));
break;
case TEMPHIGHIN:
Serial.println(F("HIGHIN"));
break;
case NORMAL:
Serial.println(F("NORMAL"));
break;
}
/*if ( grTEMPControl[HOT].state == AMBIENTLOWBOTH )
//if ( evaluateTempState() == AMBIENTLOWBOTH )
// Serial.println(F("AMBIENTLOWBOTH")); // one or the other
if ( grTEMPControl[HOT].state == AMBIENTLOWINHIGHOUT )
// Serial.println(F("AMBIENTLOWINHIGHOUT"));
if ( grTEMPControl[HOT].state == TEMPLOWALL )
Serial.println(F("TEMPLOWALL"));
if ( grTEMPControl[HOT].state == TEMPLOWIN )
Serial.println(F("TEMPLOWIN"));
if ( grTEMPControl[HOT].state == TEMPHIGHALL )
Serial.println(F("TEMPHIGHALL"));
if ( grTEMPControl[HOT].state == TEMPHIGHIN )
Serial.println(F("TEMPHIGHIN"));
if ( grTEMPControl[HOT].state == NORMAL )
Serial.println(F("NORMAL"));
*/
/*Temperature*/
Serial.print(F("T amb: "));
Serial.print(grTEMPControl[AMBIENT].value);
Serial.println(F("°C"));
Serial.print(F("T Hot: "));
Serial.print(grTEMPControl[HOT].value);
Serial.println(F("°C"));
Serial.print(F("T aussen: "));
Serial.print(grTEMPControl[OUT].value);
Serial.println(F("°C"));
/*Humidity*/
Serial.print(F("H amb: "));
Serial.print(grHUMControl[AMBIENT].value);
Serial.println(F("%"));
Serial.print(F("H Hot: "));
Serial.print(grHUMControl[HOT].value);
Serial.println(F("%"));
Serial.print(F("H aussen: "));
Serial.print(grHUMControl[OUT].value);
Serial.println(F("%"));
Serial.print(F("Tot H: "));
Serial.println(totalHum);
Serial.print(F("Count H: "));
Serial.println(counterHum);
Serial.print(F("Avg Hum: "));
Serial.print(averageHum);
Serial.println(F("%"));
Serial.print(F("Day Avg H: "));
Serial.print(dayAverageHum);
Serial.println(F("%"));
Serial.print(F("dayNight: "));
Serial.println(dayNight);
Serial.println(F("---"));//(F("-----------------------------------------------"));
}
}
This is the function I came up with upto now. I figured I could take auto as the datatype to be able to accept what ever value:
void debug(const char &debug, const auto &value)
{
/*Debug Interval*/
/*static long previousDebug = 0;
const long debugInterval = 1000;
if (timeNow - previousDebug > debugInterval) {
previousDebug = timeNow;
Serial.print(debug);
Serial.println(value);
}
Could this work so far?
The next question that arrose is: How do I pass the time for example? Up to now I could just call the appropriate function. Would the following be possible? Or how would it have to be changed?
void digitalClock()
{
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
debug("Time: ", digitalClock());
}
void printDigits(int digits)
{
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(F(":"));
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
moserroger:
The next question that arrose is: How do I pass the time for example? Up to now I could just call the appropriate function. Would the following be possible? Or how would it have to be changed?
void digitalClock()
{
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
debug("Time: ", digitalClock());
}
It's not at all clear to me what you want to do.
The code you posted has two problems:
The return type of digitalClock is void. There is no return value to pass to the debug function.
If you call a function recursively like that, it'll go on forever (well, until you hit a stack overflow).
Arrays (which a c-string like "Temp State: " is) are almost always passed by pointer. Some C++ guru can probably post a way to do it by reference. But, I don't see the point since passing by reference really uses pointers behind the scenes with some extra safeguards to stop you from shooting yourself in the foot.
gfvalvo:
I can't see the "other functions" that you use.
Arrays (which a c-string like "Temp State: " is) are almost always passed by pointer. Some C++ guru can probably post a way to do it by reference. But, I don't see the point since passing by reference really uses pointers behind the scenes with some extra safeguards to stop you from shooting yourself in the foot.
I now have the syntax to send Strings and other datatypes to the function using template . Now the next problem appears. Of course the pointer points only to the first element of the Stringarray.:
#define DEBUG_ERROR true
//#define DEBUG_ERROR_SERIAL if(DEBUG_ERROR)Serial
#define DEBUG_WARNING true
//#define DEBUG_WARNING_SERIAL if(DEBUG_WARNING)Serial
#define DEBUG_INFORMATION true
#define DEBUG_INFORMATION_SERIAL if(DEBUG_INFORMATION)Serial
const int sensor = 10;
template<typename T> void debug(const T *debugName)
{
const unsigned int debugOutputInterval = 1000;
unsigned long debugOutputTimestamp;
unsigned long currentMillis = millis();
if (currentMillis - debugOutputTimestamp >= debugOutputInterval) {
debugOutputTimestamp = currentMillis;
static byte previousId;
Serial.println(*debugName);
}
}
void setup()
{
Serial.begin(115200);
while (!Serial);
}
void loop()
{
if ( DEBUG_ERROR )
{
debug("Hello Error");
debug(&sensor);
}
if ( DEBUG_WARNING )
debug("Hello Warning");
debug(&sensor, 2);
}
I added the following to read the whole String and to print it in one line:
Is there a way to check if a variable is of datatype String and read it accrodingly? What do I have to do in order for the first character to be printed as well?
Perhaps, you misunderstood the use of template function. It's only useful(at least to you) if the templated arguments share some commonality.
For your case, it's better to write overloaded functions.
About your earlier question, pass by reference is almost always better than pass by pointer. Keep in mind that pass by reference will guarantee that the argument is non-null.
I thought the following code would give me the result I was looking for (passing a string and sensor data to the same function and printing a title to what data they belong to). But I realized this is not true.
the string is printed after the sensor data even though it should appear before. Does this depend on the time it takes to print the string? How to make sure that the will be printed in the right sequence?
the id which should indicate which title should be printed seems to be blocked in the string line and if I change the id in the sensor line both lines within the same if statement will be under the same title even if the string line contains another id.
arduino_new:
Perhaps, you misunderstood the use of template function. It's only useful(at least to you) if the templated arguments share some commonality.
For your case, it's better to write overloaded functions.
About your earlier question, pass by reference is almost always better than pass by pointer. Keep in mind that pass by reference will guarantee that the argument is non-null.
Now there is something else that is bothering me. I would like do distinguish if the String passed by pointer contains ':' if this is the case only Serial.print instead of Serial.println should be used.
I tried *debugName.substring() and *debugName.indexOf()
Both didn't work and returned this error:
request for member 'substring' in 'debugName', which is of non-class type 'const int*'
make this variable as static so the value can persist between function call.
static unsigned long debugOutputTimestamp;
Your reply is of course correct but the result is strange. The serial output is arbitrary with data printed twice once in a while. Here is the changed code: