DIY Projects

C++ functions print•println•printf•sprintf for Arduino ESP32 ESP8266. Combine•format → serial port

cpluplus arduino esp32 esp8266 print sprintf println write functions 1

We use the serial monitor to debug the Arduino code, but there are many other things you can do. We will discover in this article the main methods to print(send) character strings on the serial port. print and println to send plain text. The printf function to convert, format and combine several variables in the same character string. sprintf and snprintf to store the results in a variable.


Quick access to functions

print or println  printf   options printf   sprintf    write  Macro F

How to open the serial port in the Arduino code?

Before being able to send messages on the serial port, it is necessary to initialize the communication with the command Serial.begin(speed). This method takes the baud rate of the serial port as a parameter.

By default, it is set at 9600 baud .

You can choose one of these speeds 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200.

Most current development boards support the speed of 115200 baud without any problem.


Print text on the serial port with print or println

The print() function is the base function. It allows to send(print) a character or a character string without any particular formatting.

Characters are sent to the serial port one after the other.

Example Result on serial monitor

To return the cursor to the line (as on a word processor), there are several solutions:

Example Result obtained on the serial monitor
Serial.print("A demo"); 
Serial.println("a carriage return");
A demo with 
a new line
Serial.print("A half with \ n"); 
Serial.print("a carriage return");
A demo with 
a new line

How to combine multiple variables with print or println

As in most other languages ​​(Javascript, PHP ..), C ++ allows combining strings using the + operator . The data must first be converted into a string using the String() function.

Here is an example which combines in the same character string an integer variable, a float variable (decimal number) and a boolean.

int INT_VAR = 32;
float FLOAT_VAR = 32.23;
bool BOOL_VAR = true;
Serial.println("A string that combines an integer " + String(INT_VAR) + ", un decimal " + String(FLOAT_VAR) + " and a boolean" + String(BOOL_VAR));

Combine and format multiple variables into a string with printf

The printf method is a standard C++ output format. Espressif has implemented the printf method in the Serial class of the Arduino-ESP32 and ESP8266 framework. This is not the case with the Arduino framework.

How to use printf on Arduino with PrintEx

If you try to compile code developed for ESP32 or ESP8266 on an Arduino, you will get a compilation error if you write Serial.printf(). This is simply because the method was not developed for the Arduino framework.

There are examples of code all over the internet to do this, but the easiest way is to use Christopher Andrews’ PrintEx library. Its operation is almost as complete as the implementation made by Espressif for the ESP32 and ESP8266.

On PlatformIO, add the following option to your platformio.ini file. On the Arduino IDE, add the library from the manager as usual

lib_deps = 
    chris--a/PrintEx @ ^1.2.0

Then, declare PrintEx at the start of your program

#include <PrintEx.h>

Finally, just extend (add the functions) to the Print class of the Arduino framework

  PrintEx serial = Serial;

And now we can use the function like this

serial.printf("atmospheric pressure is %u hPa", pressure);

How to use printf() from ESP32, ESP8266 or PrintEx framework

Note. For PrintEx, add serial before calling printf ().

The printf() method allows both to format one or more data and then combine them into a single string before sending it to the serial port. To do this, all you have to do is specify the position in the string using the % character.

Serial.printf("atmospheric pressure is %u hPa", pressure);

The % specifier  argument will then be replaced with the corresponding formatted value.

To format the output string as desired, it is possible to add additional options. The options are detailed in the following paragraphs.


Here is an example that formats a decimal number with a single significant digit. The rounding is automatic.


You can combine as many variables as you want. You just have to pass the variables in the same order as in the output string.

Specifier available

To be able to combine variables of different natures in the output string, you must indicate to the printf command the type of each data

Warning, choose the specifier which corresponds to the type of variable declared in the Arduino code.

In bold the specifiers not supported by PrintEx

Specifier Arduino data type Description Example
d or  i Int



Long (better to use unsigned Int)

Signed decimal integer 392
u Unsigned decimal integer 7235
o Unsigned octal 610
x unsigned long

unsigned int

Unsigned hexadecimal integer (lowercase) 7fa
X Unsigned hexadecimal integer (uppercase) 7FA
f or F float


Lowercase decimal floating point 392.65
e Lowercase exponent scientific notation 3.9265e + 2
E Scientific notation exponent in uppercase 3.9265E + 2
g Use the shorter representation: % e  or  % f 392.65
G Use the shorter representation: % E  or  % F 392.65
c char Character a
s char [] String of characters example
n Nothing is printed
% %  followed by another % character   will write a single  % %

Flag option

The flag allows you to add characters before the value:

flag Description
- Left-justify within the given field width. By default, the justification is to the right of the value (see the width option )
+ Forces the result to precede the result with a plus or minus sign (  +  or  -  ) even for positive numbers. By default, only negative numbers are preceded by the sign  -
(space) If no sign must be written, a space is inserted before the value
# Used with the ox  or  X specifiers ,  the value is preceded by  0  ,  0x  or  0X  respectively for nonzero values.
Used with  aAeEfF , g  or  G, the output string must contain a decimal point even if no number follows. By default, if no number follows, no decimal point is written
0 Left-padded number with zeros ( 0 ) instead of spaces when padding is specified (see width option )

Option width

Specifies (or not) the number of characters to print

with Description
(number) Minimum number of characters to print. If the value to be printed is less than this number, the result is completed by empty spaces. The value is not truncated even if the result is larger
* The  width  is not specified in the formatting string  , but as an additional integer value argument preceding the argument to be formatted

Precision option

Allows you to define the precision of the decimal numbers (the number of significant digits to print) or the maximum number of characters if it is a string.

.precision Description
  • For d, i, o, u, x, X, the precision specifies the minimum number of digits to write. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0
  • For a, A, E, E, f and F, this is the number of digits to print after the decimal point (by default, this is 6)
  • For g and G, this is the maximum number of significant digits to print
  • For s, this is the maximum number of characters to print. By default, all characters are printed until the trailing null character is encountered
.* The  precision  is not specified in the format string   , but as an additional integer value argument preceding the argument to be formatted.

Conversion options taken from this article.

Macro F

The macro F() which allows to move the string in the Flash memory in order to prevent the RAM of the microcontroller from being full if many messages are sent on the serial port for example.

Store the result of a string formatted with sprintf or snprintf in a variable (only for ESP32 or ESP8266)

The sprintf() method allows you to store the result of the conversion in a variable of type char[] .

Only restriction, it is not possible to convert several variables with a single command.

The sprintf() command requires initializing the output variable with a size at least equal to the length of the string. It is simply the number of characters in the output string.

char output_sprintf[6];
sprintf(output_sprintf, "%.1f°C", temp);
Serial.printf("Formatted value saved in the variable output %s \n", output_sprintf);

To combine several variables in the same string, you will need to use the snprintf() function which is written in a similar way

char output_snprintf[60];
snprintf(output_snprintf, sizeof(output_snprintf), "Température is %.1f°C, humidity is %.1f%% \n", temp, hum);
Serial.printf("output_snprintf = %s \n", output_snprintf);

Print the content of a byte buffer with write()

You may need to use an array of bytes. This array could for example contain the numeric code of each character of a String(character string).

To print an array of bytes to the serial port, the print(), println() functions do not work because they expect a variable of type char, char[] or String.

To print the contents of a buffer with the write() function , all you have to do is iterate through the latter using a for loop().

String stringtocopy = "Arduino"; 

// Measure string length
int buffer_size = stringtocopy.length();
Serial.printf("Buffer size: %u\n", buffer_size);

// Create a buffer having the same size as the string
byte buffer[buffer_size]; 

// Copy the contents of the string using the getBytes function 
// Attention, you must add 1 to the size of the string so as not to have a NULL character
stringtocopy.getBytes(buffer, buffer_size + 1); 
Serial.println("Print buffer with write function"); 

// Each cell of the buffer is printed one by one using a for loop
for (int i = 0; i < buffer_size; i++) { 

Warning, you must add 1 to the length of the string at the level of the len parameter of the getBytes function , otherwise the last character will be null, for example: Arduin␀

Upload the Arduino code of the examples

Create a new sketch on the Arduino or PlatformIO IDE and upload the code to test all the examples presented previously.

  • main.ino
  • platformio.ini
#include "Arduino.h"
#include <PrintEx.h>

#define SERIAL_SPEED 115200

void setup() {

  PrintEx serial = Serial; //Wrap the Serial object in a PrintEx interface.

  Serial.println("\n=== print et println ====");


  Serial.println("A demo with ");
  Serial.print("A line break ");
  Serial.println("\n---- Or -----");

  Serial.print("A demo with \n");
  Serial.print("a line break");

  Serial.println("\n=== Concatenate with println ====");
  int INT_VAR = 32;
  float FLOAT_VAR = 32.23;
  bool BOOL_VAR = true;
  Serial.println("<code>A string that combine integer " + String(INT_VAR) + ", decimal " + String(FLOAT_VAR) + " and boolean " + String(BOOL_VAR)); Serial.println("\n=== printf ===="); unsigned int x = 0x999b989; byte b = 120; word w = 63450; signed long l = 2147483646; // signed long -2,147,483,648 to 2,147,483,647 char c = 65; // A char s[] = "une chaîne de caractères"; float f = 99.57; double fdbl = 99.5769; #ifdef __AVR__ serial.printf("Hexa %x %X \n", x, x); serial.printf("Byte %u \n", b); serial.printf("Word %u \n", w); serial.printf("Long %lu \n", l); serial.printf("Caractère %c \n", c); serial.printf("%s \n", s); serial.printf("Variable float %f | %.2f \n", f, f); serial.printf("Variable double %f | %.2f \n", fdbl, fdbl); #else printf("Hexa %x %X \n", x, x); printf("Byte %u \n", b); printf("Word %u \n", w); printf("Long %u \n", l); printf("Caractère %c \n", c); printf("%s \n", s); printf("Variable float %f | %.2f \n", f, f); printf("Variable double %f | %.2f \n", fdbl, fdbl); #endif Serial.println("\n=== FAKE BME280 ===="); double temp = 18.68; double hum = 67.98; #ifdef __AVR__ serial.printf("Temperature is %.2f°C, humidity is %.1f%% \n", temp, hum); #else printf("Temperature is %.1f°C, humidity is %.1f%% \n", temp, hum); #endif #ifdef __AVR__ //printf("output_sprintf = %s \n", output_sprintf); serial.printf("Temperature %.1f°C, humidity is %.1f%% \n", temp, hum); #else char output_sprintf[6]; sprintf(output_sprintf, "%.1f°C", temp); printf("output_sprintf = %s \n", output_sprintf); #endif #ifdef __AVR__ #else char output_snprintf[60]; snprintf(output_snprintf, sizeof(output_snprintf), "Température is %.1f°C, humidity is %.1f%% \n", temp, hum); printf("output_snprintf = %s \n", output_snprintf); #endif Serial.println("\n=== write() buffer to Serial ===="); String stringtocopy = "Arduino"; int buffer_size = stringtocopy.length(); #ifdef __AVR__ serial.printf("Buffer size: %u\n", buffer_size); #else printf("Buffer size: %u\n", buffer_size); #endif byte buffer[buffer_size]; stringtocopy.getBytes(buffer, buffer_size + 1); Serial.println("Print buffer with write() function"); for (int i = 0; i < buffer_size; i++) { Serial.write(buffer[i]); } } void loop() { }

platform = atmelavr
board = uno
framework = arduino
monitor_speed = 115200
lib_deps = 
    chris--a/PrintEx @ ^1.2.0

platform = espressif32
board = lolin_d32
framework = arduino
monitor_speed = 115200

Open the serial monitor to view the operation of the functions. Execution log retrieved from an ESP32.

=== print and println ====
A demo with 
a line break 
---- Ou -----
A demo with 
a line break
=== Concatenate with println ====
A string that combine integer 32, decimal 32.23 and a boolean 1

=== printf ====
Hexa 999b989 999B989 
Byte 120 
World 63450 
Long <code>2147483646 Char A a string Variable float 99.570000 | 99.57 Variable double 99.576900 | 99.58 === FAKE BME280 ==== Temperature is 18.7°C, humidity is 68.0% === Write buffer to Serial ==== Buffer size: 7 Print buffer with write function Arduino 


2020/12/11 Add PrintEx library for Arduino (AVR Platform)

2020/10/22 Publication of the article

Version française

Click to rate this post!
[Total: 0 Average: 0]
Exit mobile version