Pages: [1]   Go Down
Author Topic: Tip: Easier debug log toggling  (Read 1531 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I'm new on this forum and don't really know where this message belongs, but this folder seemed most appropriate.

Many of us use Serial.print() to debug our code and when everything is running fine we want to disable it. People have come up with various #ifdef DEBUG approaches as some mentioned here : http://arduino.cc/forum/index.php?topic=46900.0.
But these all seem tedious and some even go to the extend of creating a library for this which adds more memory constraints. And they don't toggle the Serial.begin() you have in your setup().

I've come up with a much easier way of working. Add the following at the top of your sketch:
Code:
#include "Arduino.h"   // replace this by "WProgram.h" when your IDE is older then 1.0
 
#define DEBUG true // flag to turn on/off debugging
#define Serial if(DEBUG)Serial

Advantages over the #ifdef DEBUG approaches:
  • Now you can keep using Serial.print() statements. So no code changes needed.
  • It also turns on/off the Serial.begin() statement.
  • Because Serial.begin() is also avoided this means that finally no Serial code will be referenced and compiled any more. This is a big benefit for SRAM tight sketches. Avoiding a Serial.begin() as well saves 922 bytes in sketch size and 179 bytes SRAM usage!!  smiley-eek
(measurements done on Arduino0022 with the Blink sketch with default rx_buffer size (http://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduino-hacks) and SRAM measured as described at http://www.designer2k2.at/home/arduino/49-arduino-ram-overflow.html.

Note that the include line on top is needed before the defines otherwise you get a compilation error.
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 451
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice approach!

In Cosa, an object-oriented platform for programming the Arduino, I use a traditional Linux, syslog, approach with macros that are redefined depending on the symbol NDEBUG (not debug).

https://github.com/mikaelpatel/Cosa/blob/master/Cosa/Trace.hh

There is a special trace output stream which is used for debugging. As you mention reducing the amount of SRAM consumed by output strings is important. All string in the above Cosa trace are in program memory, i.e., use PSTR() and the _P version of functions.

There is also support for maskable trace levels. The syslog style trace log message are always with the function name, file line number and level as prefix. This helps quickly locate the statement that generated the output.

Most fun is the macro TRACE(expr) which will print the expression and the result.

These are all common tricks you can play with the C/C++ preprocessor and macro symbols.

Cheers!
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Off topic:
I'm still quite new to Arduino but are people really using (object oriented) layers on top of the Arduino lingo?
I find that once you're working on a serious project you quickly need to optimize and tweak very low level core and library things (like the rx_buffer) to make sure your project fits in the atmega, both memory wise and io wise. Adding layers on top of Arduino would have as purpose to abstract Arduino technicalities. So this would thus complicate lowe level tweaking.
Yet, it's the serious projects that would benefit most from those more programmer-friendly layers...
So nice paradox you've got there  smiley-roll

I'm for instance working on a project involving 12 tlc5940's, a max7219, interrupt based IR, an RTC, 1-wire temperature sensor and some buttons.... Any tweak you can do then on interrupts, timers and memory used by yourself, by core arduino and by the libraries you use is then not only nice but vital.

Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 451
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cosa totally replaces the Arduino/Wiring function library with a smaller, more compact and many times faster pure C++ implementation. Cosa uses a lot of techniques that allows the compiler do more optimizations than possible in a C-function library.

I would argue that done correctly you can reduce the memory footprint of a program more with C++ than C. This is due to virtual methods and reuse of code in a somewhat different approach. Take for instance the Arduino/Wiring function digitalRead(). Cosa uses an object-oriented approach and the function is reduces to only a few inlined instructions. Actually not much larger than the call to digitalRead(). The performance gain is X4-X10 not just a few procent. Where Arduino can do a software SPI write at less than 60 Kbps. Cosa can achieve approx. 250 kbps without assembly code.
http://cosa-arduino.blogspot.com/2013/03/benchmarking-pin-classes.html

But all this is somewhat of an Occams razor as going to far with object-orientation will end up with more code and more run-time memory requirements. This is the major experience from large scale usage of C++ in the late 90-ies.

Most important is maybe using name spaces and strong data typing if we are to build larger systems by integrating work from many sources. Arduino code has a long way here. It is cluttered with #defines and variables in global space. 

Anyway you are welcome to test Cosa and see what you think. https://github.com/mikaelpatel/Cosa

Cheers!

BW: Cosa is a very rich set of classes and not just a replacement for Wiring/Arduino. Also AVR GCC-lib, Aduino and Cosa can co-exist. This allows stepwise migration and more libraries to select from.
Logged

Pages: [1]   Go Up
Jump to: