You can try "extending" the Print class to include a printf() function. It requires modification of the Arduino core to add it, and it's something I have been meaning to suggest to the Arduino guys as a permanent modification, but I often manually add a function such as this:
void Print::printf(const char *fmt, ...) {
va_list va;
va_start(va, fmt);
char temp[1];
uint32_t slen = vsnprintf(temp, 1, fmt, va);
va_end(va);
char out[slen + 2];
va_start(va, fmt);
vsnprintf(out, slen+1, fmt, va);
va_end(va);
print(out);
}
to my core.
It's not wonderfully efficient from a processing point of view - it first runs a vsnprintf()
to a single byte target. This allows it to work out how long the formatted string will need to be:
If the output was truncated due to this limit, then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available.
So it then knows how much memory is needed to store the formatted string. It then goes ahead and allocates that much memory on the stack and re-formats the string again into that newly allocated memory. It can then go ahead and send that data to the serial port.
It's a "quick and dirty" hack, but it works. A better solution would be to re-write the printf()
parser in the function and instead of formatting to memory then printing, to format the data stream directly to the Serial
device, thus saving the double-processing and memory allocation.
You can then quite happily do things like:
Serial.printf("The temperature is %d degrees C\n", temperature);