Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A printf function for serial communication from Arduino boards
/*
This code should be pasted within the files where this function is needed.
This function will not create any code conflicts.
The function call is similar to printf: ardprintf("Test %d %s", 25, "string");
To print the '%' character, use '%%'
This code was first posted on http://arduino.stackexchange.com/a/201
*/
#ifndef ARDPRINTF
#define ARDPRINTF
#define ARDBUFFER 16 //Buffer for storing intermediate strings. Performance may vary depending on size.
#include <stdarg.h>
#include <Arduino.h> //To allow function to run from any file in a project
int ardprintf(char *str, ...) //Variadic Function
{
int i, count=0, j=0, flag=0;
char temp[ARDBUFFER+1];
for(i=0; str[i]!='\0';i++) if(str[i]=='%') count++; //Evaluate number of arguments required to be printed
va_list argv;
va_start(argv, count);
for(i=0,j=0; str[i]!='\0';i++) //Iterate over formatting string
{
if(str[i]=='%')
{
//Clear buffer
temp[j] = '\0';
Serial.print(temp);
j=0;
temp[0] = '\0';
//Process argument
switch(str[++i])
{
case 'd': Serial.print(va_arg(argv, int));
break;
case 'l': Serial.print(va_arg(argv, long));
break;
case 'f': Serial.print(va_arg(argv, double));
break;
case 'c': Serial.print((char)va_arg(argv, int));
break;
case 's': Serial.print(va_arg(argv, char *));
break;
default: ;
};
}
else
{
//Add to buffer
temp[j] = str[i];
j = (j+1)%ARDBUFFER;
if(j==0) //If buffer is full, empty buffer.
{
temp[ARDBUFFER] = '\0';
Serial.print(temp);
temp[0]='\0';
}
}
};
Serial.println(); //Print trailing newline
return count + 1; //Return number of arguments detected
}
#undef ARDBUFFER
#endif
@hemalchevli

This comment has been minimized.

Copy link

hemalchevli commented Aug 5, 2015

Hi, this really a handy function, I need to print float with 4 decimal points, this does two, any way how it can be achieved?

@nkolban

This comment has been minimized.

Copy link

nkolban commented Aug 15, 2015

Howdy ... some problems with this code as it is today (2015-08-15)....

  1. The temp buffer is not flushed at the end so there may be lost data
  2. The va_start should be: va_start(argv, count)
@angelorz

This comment has been minimized.

Copy link

angelorz commented Mar 1, 2016

Hi,

I've some troubles implementing this function on my sketch.

I get this problem:

'va_start' used in function with fixed args

I just paste this code on my sketch and adapted the prototype to my needs:

    int ardprintf(char *str, int sensorValue, unsigned long time) //Variadic Function

Then, on the loop I do:

     ardprintf("%d %l", sensorValue,time);

Being:

     unsigned long time;
     int sensorValue = analogRead(A10);

What can be happening?

Thanks!

@Lucianovici

This comment has been minimized.

Copy link

Lucianovici commented Sep 18, 2018

Why not using something like this?

void _log(const char *format, ...)
{
#if DEBUG_MODE
    char buffer[256];
    va_list args;
    va_start(args, format);
    vsprintf(buffer, format, args);
    va_end(args);
    Serial.print(buffer);
#endif
}
@dale3h

This comment has been minimized.

Copy link

dale3h commented Jan 30, 2019

@Lucianovici Your solution works perfectly for me and actually makes a lot more sense to my brain.

@dale3h

This comment has been minimized.

Copy link

dale3h commented Jan 30, 2019

@angelorz It's been many years since your post, but I believe the problem that you were experiencing was that the function should have worked as-is without change. The , ... tells the compiler that you are willing to accept a variable/infinite amount of arguments, no matter the type, as long as char *str is the first argument.

@platima

This comment has been minimized.

Copy link

platima commented Feb 16, 2020

Just a note that the 'clear buffer' on line 57 does not work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.