-
-
Save asheeshr/9004783 to your computer and use it in GitHub Desktop.
/* | |
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 |
Howdy ... some problems with this code as it is today (2015-08-15)....
- The
temp
buffer is not flushed at the end so there may be lost data - The
va_start
should be:va_start(argv, count)
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!
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
}
@Lucianovici Your solution works perfectly for me and actually makes a lot more sense to my brain.
@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.
Just a note that the 'clear buffer' on line 57 does not work!
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);
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?