Serial printf impelmentation

Some of you guys may want to have printf function to write to serial port. and I do!

#include <stdarg.h>

#define PRINTF_BUFFER_SIZE 128
void Serial_printf(const char* fmt, ...) {
   char buff[PRINTF_BUFFER_SIZE];
   va_list args;
   va_start(args, fmt);
   vsnprintf(buff, PRINTF_BUFFER_SIZE, fmt, args);
   va_end(args);
   Serial.println(buff);
}   

I hope this will help!

3 Likes

Most useful!

I have a similar function called DebugPrintf, which prints to both serial and a log file.
One warning: beware for buffer-overflows. In an earlier version my buffer was too small for the text printed. The result was a nice red blinking SOS for hard fault, caused by overwriting the heap. Reset would give the same SOS, so all I could do to unbrick my Spark Core was the factory reset. Luckily that worked!

Also note that using these functions will increase your code size, perhaps more than you would expect from a single function call…

Hi maxint,
Thanks.

buffer-overflows

Really great point. My version is not using vsprintf but vsnprintf, so it won't overwite heap or stack.

increase your code size,

That's true. I think 64 byte or 128byte are enough for most cases :slight_smile:

This is a great initiaitve! You can generalize it to any Print instance, such as a TCPClient, UDP, or Serial. And for convenience, also provide a default buffer size, but allow overrides, like this:

#include <stdarg.h>

void pnprintf(Print& p, uint16_t bufsize, const char* fmt, ...) {
   char buff[bufsize];
   va_list args;
   va_start(args, fmt);
   vsnprintf(buff, bufsize, fmt, args);
   va_end(args);
   p.println(buff);
}

#define pprintf(p, fmt, ...) pnprintf(p, 128, fmt, __VA_ARGS__)
#define Serial_printf(fmt, ...) pprintf(Serial, fmt, __VA_ARGS__)

void examples() {
   pnprintf(Serial, 64, "%s", "2123");
   pprintf(Serial, "%d", 123);
   Serial_printf("%d", 123);
}
4 Likes

This is really great!
I didn’t know they have Print class as super class.