I have written simple code to enable toggling of serial.print
debug data.
#define DEBUG
#ifdef DEBUG
#define DEBUG3(x,y,z) Serial.print(x);Serial.print(" ");Serial.print(y);
Serial.print(" "); Serial.println (z)
#define DEBUG2(y,z) Serial.print(y);Serial.print(" ");Serial.println
(z)
#define DEBUG(z) Serial.println(z)
#define DEBUGln Serial.println("");
#else
#define DEBUG3(x,y,z)
#define DEBUG2(x,y)
#define DEBUG(x)
#define DEBUGln
#endif
Then I can just call DEBUG3("words",value,"words");
anywhere in the sketch and it will automatically print out the text, int, strings, etc with a single space between and automatically go to next line etc etc.
Just define the correct number of fields to print and separate using commas.
If I want to turn off debug then I just comment out #define DEBUG
at the top.
Now the issue is I don't want to copy in this code every time I want to use it, so it makes sense to make it a library so that I can just call something like:
#include <SERIAL_DEBUG.h>
#define DEBUG (or //#define DEBUG) //to enable or disable
The reason being that sometimes I might want to print up to 10 things on a single line (not very often but it could happen).
This is my first library attempt and I'm having a hard time finding any information on how I would go about setting up the .h and .cpp files for this type of #define DEBUG(x) Serial.println(x)
and the #define DEBUG (from sketch)
parts.
2 Answers 2
Anything in a header file that is included with #include
is literally pasted into the file at the point of the #include
.
So anything in your sketch you want to place into a header file you can just place it in a header file and include that file at the same location where the original code was.
So you can have a header file debug.h
:
#ifdef DEBUG
#define DEBUG3(x,y,z) Serial.print(x);Serial.print(" ");Serial.print(y);
Serial.print(" "); Serial.println (z)
#define DEBUG2(y,z) Serial.print(y);Serial.print(" ");Serial.println
(z)
#define DEBUG(z) Serial.println(z)
#define DEBUGln Serial.println("");
#else
#define DEBUG3(x,y,z)
#define DEBUG2(x,y)
#define DEBUG(x)
#define DEBUGln
#endif
And include that in your sketch at the right location:
#define DEBUG
#include "debug.h"
Note that the #define DEBUG
must come before the #include
. Remember: the #include
is replaced by the content of the included file, so after preprocessing you end up with exactly what you had before in your sketch:
#define DEBUG
#ifdef DEBUG
#define DEBUG3(x,y,z) Serial.print(x);Serial.print(" ");Serial.print(y);
Serial.print(" "); Serial.println (z)
#define DEBUG2(y,z) Serial.print(y);Serial.print(" ");Serial.println
(z)
#define DEBUG(z) Serial.println(z)
#define DEBUGln Serial.println("");
#else
#define DEBUG3(x,y,z)
#define DEBUG2(x,y)
#define DEBUG(x)
#define DEBUGln
#endif
The file can be in the same location as the sketch (in which case you should use #include "debug.h"
or in a library folder (Arduino/libraries/debug/debug.h
) in which case you should include it with #include <debug.h>
. In the Arduino IDE it actually makes little or no difference which type of #include
you use, but it does serve as a visual reminder that this is either a header included with the sketch (""
) or an external library or system header (<>
).
-
thank you sir . this worked and solved the issue.. i was thinking it would be more complicated to do from all the content out there about libraries and not realzing what exactly a the #include and .h file actually do cheersR Lloyd– R Lloyd2017年08月11日 12:29:14 +00:00Commented Aug 11, 2017 at 12:29
Not a direct answer to your question, but I would suggest a different
approach based on streaming output, as described in the Arduino
Playground: Adding Streaming (insertion-style) Output. In
a nutshell, you define the <<
operator for Serial
(and any other
object that inherits from Print
) in a way that allows you to write
things like:
Serial << "My name is " << name << " and I am " << age << " years old.";
Now you can define a Debug
object which would be, depending on whether
you want debugging output or not:
- an alias to Serial
- a dummy object that just discards its input.
Example:
#define DEBUG_ON
// From https://playground.arduino.cc/Main/StreamingOutput
template<class T> inline Print& operator<<(Print &obj, T arg)
{ obj.print(arg); return obj; }
#ifdef DEBUG_ON
# define Debug Serial
#else
class DummyStream {
public:
template<class T> DummyStream& operator<<(T arg)
{ (void) arg; return *this; }
} Debug;
#endif
void setup()
{
const unsigned long BAUDRATE = 9600;
Serial.begin(BAUDRATE);
Debug << "Serial port open at " << BAUDRATE << " bps\r\n";
}
-
That's is an overly complicated solution for a OP that is struggling with using
#define
. OP approach does the thing in a simple and easily comprehensible way. I love you, Edgar, but C++ looks like the unwanted child of PHP raping JavaScript.user31481– user314812017年08月11日 10:41:24 +00:00Commented Aug 11, 2017 at 10:41 -
thanks both of you. Alterno i agree haha. i had a look at a few of the other ways to go about toggling serial debug lines @COMPILE TIME. all of which seem really long winded and overly complicated. {{{continue on next}}}R Lloyd– R Lloyd2017年08月11日 11:59:51 +00:00Commented Aug 11, 2017 at 11:59
-
my approach seems to work a lot better than i had expected. being simple to implement a long chain of serial data and with ZERO change in overhead compared to Serial.print when DEBUG enabled(extra spaces aside..), and also ZERO overhead (as if all Serial.print was // commented out..) when disabled. it literally turns it all on or completely eliminates it. i discovered if i put all the #define DEBUG#(X) into an otherwise enpty sketch and #include <DIR\sketch.ino> that works its not a proper library but i guess it'l do if i cant make the library workR Lloyd– R Lloyd2017年08月11日 12:00:03 +00:00Commented Aug 11, 2017 at 12:00
if (something) DEBUG3(x,y,z);
will not give you what you want.