ESP32 where can I find the reference for Serial.printf ( the print with the "f" as a suffix)

Hi everybody,

recently I used a code that uses the function-call
Serial.printf() The print with the "f"

So I looked up the reference of serial

but there it is not listed. Huh? Why not? is this some kind of macro?

I quogled for it
https://www.google.de/search?q=arduino+printf()
but the hits only say "Arduino does not have printf.
Well the code compiles for an ESP32. Does this mean the ESP32-core has it but the Arduino-Uno core does not have it?

Where can I find the documentation about it?

best regards Stefan

The ESP32 is not an Arduino and Espressif, the company that makes it, has nothing to do with Arduino. Espressif is responsible for their implementation of the relevant Arduino core.

Check the ESP32 docs. Edit: googling "esp32 arduino printf" turns up many useful pages.

From Print.cpp in the Arduino ESP32 core:

size_t Print::printf(const char *format, ...)
{
    char loc_buf[64];
    char * temp = loc_buf;
    va_list arg;
    va_list copy;
    va_start(arg, format);
    va_copy(copy, arg);
    int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
    va_end(copy);
    if(len < 0) {
        va_end(arg);
        return 0;
    };
    if(len >= sizeof(loc_buf)){
        temp = (char*) malloc(len+1);
        if(temp == NULL) {
            va_end(arg);
            return 0;
        }
        len = vsnprintf(temp, len+1, format, arg);
    }
    va_end(arg);
    len = write((uint8_t*)temp, len);
    if(temp != loc_buf){
        free(temp);
    }
    return len;
}
2 Likes

Rejected by the way.

The Arduino-Team makes consequent use of encapsulation to their island.
So I will try this additional library

In this way the code stays compatible with the standard arduino core

best regards Stefan

What do you think about the following?

inline void mPrint(Stream&) {}

template <class H, class... Tail>
void mPrint(Stream& stream, H head, Tail... tail) {
  stream.print(head);
  mPrint(stream, tail...);
}

This works with any Stream-like object and allows for reasonably compact print statements. E.g., the following

mPrint(Serial, "x: ", 9, ", y: ", 10, "\r\n");

results in:

x: 9, y: 10

For how to use the printf() method in the ESP32 Print class:
see any documentation for printf() since the implementation in the ESP32 Print class is a robust implementation.
What you see in printf() documentation will work with the ESP32 Print class printf() method.
Information on printf() is widely available using a google search.

Now for some background:
For YEARS (like 10+), the Arduino.cc team has been asked to add a printf() method to the Print class many times.
Time and time again, they have refused to do this.
A few early excuses was that it make the users code get bigger. This is disingenuous since the users linked code would only get bigger if the users actually used it (the printf() method). So users would not be surprised.
On the AVR it was like 1.8k of code size if it got linked in.
Tom Igoe once even said that it should not be added to the Print class because printf() is too scary for Arduino users.
And as recently as just 3 years ago Massimo said:

Honestly I would avoid adding printf to Serial., the syntax is not very friendly.

(Have you ever looked at the syntax for using streaming IO which some people try to push as an alternative? it is much worse and and still can format fixed width fields that are trivial with xxprintf() )

Now there are some issues related to floating point formatting on the arduino.cc AVR platform which is due to the way the AVR gcc developers implemented libC since by default floating point is disabled - but can be re-enabled with linker options which could be handled by the IDE.
No other gcc toolset has this floating point issue in their xxprintf() code so this is unique to the AVR toolset.

YEARS ago, I even updated an Arduino "Printf" playground wiki to show uses a few ways to add printf() support to the arduino.cc Print class.

At this point in time most 3rd party cores have added support to their Print class implementation. i.e., ESP32, esp8286, STM, Chipkik/PIC32, Teensy, Teensy3.
Note: Pauls Teensy platforms, which includes his AVR based core, supports a printf() method whereas the arduino.cc platforms for AVR based boards like UNO, Leonardo, and Mega do not support a printf() method in their Print class.

To this day, the arduino.cc platform cores have still refused to implement it so you won't get a printf() method in the Print class on boards like UNO, Mega, DUE, etc...

I have given up even trying to get arduino.cc to add a printf() method to their Print class since they are dead set on not doing it.

These days I have a Pprintf() function that is just a few lines that I sometimes incorporate into sketches that offers printf() capability for any Print class object.
It is portable so it works on any platform with any Print class object.
i.e. Serial, or any other Print class object like lcd objects, etc...
I use it when I want to have easy printf() type output on AVR based boards that use the Arduino.cc AVR platform core.


About the use of the term "Arduino" this is a muddy subject that goes back more than 10 years all the way to be to founding of "arduino".

That is a bit misleading as it depends on your definition of "Arduino"
i.e. the term "Arduino" has had many different meanings over the years.

The word "Arduino" has and still has several different meanings.
I even had a discussion about this with Massimo years ago (like 10+) about straightening out the terminology.
The problem is, especially in the early days, the word "Arduino" had many meanings.
In many articles being published, blog entries, or on web pages, various Arduino founders & arduino.cc developers were using the term "Arduino" inconsistently and to mean different things. The inconsistency wasn't just limited to different people. i.e. the same person would often use the term inconsistently.
It could mean an actual Arduino board (UNO at the time which was often called just "Arduino"), a Language, the IDE, or even a generic board made by a user or 3rd party that can run can "Arduino" sketches using a 3rd party Arduino platform.

At various times all those items were simply referred to as "Arduino" and it was ridiculously confusing.
I.e users use Arduino to build and upload a sketch written in Arduino to an Arduino board which might actually be an Arduino.
I gave this exact example to Massimo, and he agreed that the term "Arduino" was too broad and overused to the point of sometimes being confusing but didn't want to do anything to attempt to resolve the confusion over the use of the word/term.

And now for quite some time the official IDE from Arduino.cc has supported third party core platform plugins that allow the building for Arduino sketches on 3rd party "Arduino" boards.
And don't forget that in the early days the original founders even encouraged users to build their own "Arduino" boards. Yes they were calling boards that they didn't make "Arduino" boards.
And then there was the huge dust up between Arduino.cc and Arduino.org and several 3rd party board makers over the term "Arduino".
As at the time anybody, given the Arduino founders comments and encouragement, could make a board and call it "Arduino".
And arduino.cc mishandled the USPTO trademark application filing so they didn't really have an actual trademark on the term "Arduino" when they said they did..
But even then it was filed after the term "Arduino" was already in use by others which make things even more difficult for them.
arduino.cc eventually got things worked out with arduino.org.

So in the early days "Arduino" board did not necessarily refer to a board made by arduino.cc or arduino.org - it could be home made board or even a 3rd party board.

Roll the clock forward and now we have a situation where the vernacular of the more common person will use the term "Arduino board" to mean a generic term for a product that can run Arduino sketch code - not necessarily a board made by arduino.cc
It is no different that people that use the terms Kleenex, coke, xerox, freon, Jet Ski, Jacuzzi, etc...

--- bill

3 Likes

All the Arduino core platforms come with xxprintf() support in the their gcc libraries.
My approach is add a new function that works like fprintf() called Pprintf(), but instead of a FILE pointer you pass in a Print class object to indicate where the output is to go.
This allows you to use printf() formatting but can specify the Print class object where to send the output.
It is simple and is portable across all platforms.

It is implemented using a single trivial function to incorporate in your sketch.
It does need a stack buffer for the formatting, but this is not an issue for most projects.

here is a sample sketch that uses the Serial object.
But you can use on any Print class object, i.e. lcd objects, etc...

void setup(void)
{
	Serial.begin(115200);
	Pprintf(Serial, "Pprintf...\n");
}
void loop(void)
{
	Pprintf(Serial, "Seconds up: %04ld\n", millis()/1000);
	delay(1000);
}

#ifndef PPRINTF_BUFSIZE
#define PPRINTF_BUFSIZE 64
#endif
size_t Pprintf(Print &outdev, const char *format, ...)
{
char buf[PPRINTF_BUFSIZE];
	va_list ap;
	va_start(ap, format);
	vsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);
	return(outdev.write(buf));
}

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