Whant excatly does Serial.printf

Hi.
I'm very confused about the Serial.printf command in this Sketch:

void setup() {
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
  
  //set the resolution to 12 bits (0-4096)
  analogReadResolution(12);
}

void loop() {
  // read the analog / millivolts value for pin 2:
  int analogValue = analogRead(32);
  int analogVolts = analogReadMilliVolts(32);
  
  // print out the values you read:
  Serial.printf("ADC analog value = %d\n",analogValue);
  Serial.printf("ADC millivolts value = %d\n",analogVolts);
  
  delay(1000);  // delay in between reads for clear read from serial

I dont't know:

  1. Why is used Serial.printf instead of serial.print ?
  2. What means %d\n ?
  3. Finally, what advantages I have using Serial.printf ?

I hope I've been ckear.
Any idea?
Thanks in advance

Most Arduino boards do not support the Serial.printf() function but some, such as the ESP32 do

So what is it ?

It is based on the C printf() function which allows text and format specifiers for variables to be used in a single print statement unlike Serial.print()

  Serial.printf("ADC analog value = %d\n",analogValue);

The %d format specifier here will be replaced at print time by the integer value of the analogValue variable. The \n adds a Newline character to the output

The format specifiers are very powerful and allow the data to be formatted in many ways. Take a look at the examples here to see what I mean https://cplusplus.com/reference/cstdio/printf/

1 Like

Most boards by Arduino may not support it directly. I really really wish they would!

It made sense in AVR days to maybe not support it, to save space. Especially on those platforms, that are using it in their underpinnings.

To get around this, many people resort to sprintf() to a buffer and then using Serial.write of that buffer...

Or they use libraries, like libprintf.

Or on boards like GIGA, Arduino has hack, that if you use the stdio library function printf,
you can define in your sketch like:
REDIRECT_STDOUT_TO(Serial)
any calls like:
printf("ADC analog value = %d\n",analogValue);
Will output to the Serial object.

The Teensy builds it into their Print class, to implement it, it simply uses a form of the stdlib printf (vdprintf), and for the file index passed, in to this function, it passes it pointer to the object derived from Print.

This works as these stdlib functions will call a C function _write to do the actual output,
Which in our case is simply implemented like:

extern "C" {
__attribute__((weak))
int _write(int file, char *ptr, int len)
{
	if (file >= 0 && file <= 2) file = (int)&Serial;
	return ((class Print *)file)->write((uint8_t *)ptr, len);
}
}

Which the MBED GIGA stuff under the cover is doing something similar:

#define REDIRECT_STDOUT_TO(stream)    namespace mbed { \
                                        FileHandle *mbed_override_console(int fd) { \
                                        return static_cast<mbed::FileHandle*>(stream); \
                                       } \
                                        FileHandle *mbed_target_override_console(int fd) { \
                                        return static_cast<mbed::FileHandle*>(stream); \
                                       } \
                                      }
2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.