Skip to content

Instantly share code, notes, and snippets.

@asheeshr
Last active January 11, 2024 16:37
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save asheeshr/9004783 to your computer and use it in GitHub Desktop.
Save asheeshr/9004783 to your computer and use it in GitHub Desktop.
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
Copy link

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
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
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
Copy link

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
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
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
Copy link

platima commented Feb 16, 2020

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

@mponiedzialek
Copy link

mponiedzialek commented Oct 11, 2020

Hi, It is very useful function!
I have one remark. When I invoked it like this:
ardprintf("Test %d %s other text", 25, "string");
"other text" was not shown"
Adding this code in line 65 resolve it:

  temp[j] = '\0';
  Serial.print(temp);  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment