IUT GEII Toulon
Philippe Arlotto

Accueil > Arduino > Arduino printf ?

Arduino printf ?

vendredi 22 mai 2015, par philippe Arlotto

La plupart des classes qui ont des données à afficher propose une méthode print héritée de la classe Print [1].
Par exemple avec la classe Serial, on dispose de Serial.print() et Serial.println().
Ces méthodes permettent d’afficher facilement la plupart des types courants (float, int, String,...) Cependant leur utilisation s’avère rapidement fastidieuse et les possibilités de formatage se révèlent quelque peu limités par rapport à un bon vieux printf.
Par exemple pour afficher simplement "La température est 24 °C" [2], il faut taper trois lignes :

  1. int temp = 24;
  2. Serial.print("La température est ");
  3. Serial.print(temp);
  4. Serial.println("° C");

Télécharger

On peut faire autrement en utilisant les possibilités de la classe String mais si on connaît les formateurs de printf, on souhaiterait écrire simplement :
printf(""La température est %d °C\n",temp);
On peut intégrer un printf de plusieurs manières comme expliqué ici : http://playground.arduino.cc/Main/Printf.

Mais il y a aussi une autre méthode très simple qui consiste à utiliser la fonction c snprintf  :
snprintf génère une chaîne de caractère c (terminée par un ’\0’) dans un tableau (buffer) de char. Il suffit d’imprimer ensuite la chaîne générée avec la méthode print.

On déclare un buffer global :

#define BUF_LEN 128
char buffer[BUF_LEN];

La taille du buffer est à estimer en fonction de la longueur maximale de ce vous souhaitez imprimer.
On peut alors utiliser snprintf comme un printf pour générer le buffer et l’afficher :

  1. snprintf(buffer,sizeof(buffer),"La température est %d °C\n\r",temp );
  2. Serial.print(buffer);

Télécharger

Le deuxième paramètre garanti de ne pas dépasser la taille du buffer même si la chaîne spécifiée par le format a une longueur supérieure.
La plupart des formateurs de printf sont disponibles et on peut enfin ajuster très finement la chaîne produite.... sauf pour les float.
En effet le format %f n’est pas utilisable avec les options de compilation par défaut.
Là encore il y a plusieurs méthodes possibles. En voici une très simple [3] qui utilise la fonction dtostrf() de la libc de l’avr.

  1. Function dtostrf()
  2.  
  3. char * dtostrf(
  4. double __val,
  5. signed char __width,
  6. unsigned char __prec,
  7. char * __s)
  8.  
  9. /*The dtostrf() function converts the double value passed in val into an ASCII representationthat will be stored under s. The caller is responsible for providing sufficient storage in s.
  10.  
  11. Conversion is done in the format "[-]d.ddd". The minimum field width of the output string (including the '.' and the possible sign for negative values) is given in width, and prec determines the number of digits after the decimal sign. width is signed value, negative for left adjustment.
  12.  
  13. The dtostrf() function returns the pointer to the converted string s. */

Télécharger

Exemple :

  1. #define BUF_LEN 128
  2. char buffer[BUF_LEN];
  3. char fBuffer[16];
  4. ....
  5.  
  6. float fTemp = 25.45 ;
  7. dtostrf(fTemp,4,2,fBuffer); // largeur mimimale 4 , 2 chiffres après la virgule
  8. snprintf(buffer,sizeof(buffer),"La température est %s °C\n\r",fBuffer );
  9. Serial.print(buffer);

Télécharger

Attention à la taille du buffer il faut prévoir un espace suffisant et il n’y pas de garde fou comme avec snprintf.

Notes

[2l’affichage correct des caractères non ascii dépend de la configuration de votre terminal

[3Comme cette fonction n’est pas une fonction c standard mais une fonction de la librairie avr, il n’est pas garanti qu’elle soit utilisable avec des arduino non avr.

SPIP | Se connecter | Plan du site | Suivre la vie du site RSS 2.0
Habillage visuel © Andreas Viklund sous Licence free for any purpose