Création de librairie

Actuellement j'ai des problèmes à faire ma première librairie pour un affichage OLED 4x20 via une communication spi.
Je me suis inspiré du tutoriel pour la création d'une librairie du code du code morse pour faire un croquis d'un SOS. À la compilation j'ai ce message d'erreur.

C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI\OLED_4X20_SPI.ino: In function 'void setup()':
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI\OLED_4X20_SPI.ino:20:16: error: expected unqualified-id before '.' token
OLED_4X20_SPI.init1();
^

exit status 1

Compilation error: expected unqualified-id before '.' token

Pouvez-vous m'aider à résoudre ce problème?
voici mes trois fichiers:

1- OLED_4X20_SPI.ino

#include <OLED_4X20_SPI.h>

//OLED_4X20_SPI.ino  pour pilote SPI de l'affichage OLED NHD-0420DZW-AB5

/****************************************************
*                   PINOUT: CPU                     *
****************************************************/

#define DT 1

#define VERSION "1.53"
OLED_4X20_SPI oled = OLED_4X20_SPI(18, 17, 16, 240);

/*****************************************************
*           Setup Function, to run once              *
*****************************************************/

void setup() {

  OLED_4X20_SPI.init1();
  Serial.begin(115200);
 // oled.clear_screen();
  //                  12345678901234567890
  oled.oled_puts("    Ver:" VERSION);
  
}

/*****************************************************
*           Loop Function = Main                           *
*****************************************************/

void loop()
{
  float T1=35.6;
  float f=-23.66;
  int k=-5;
  char buffer[6];
  String test = dtostrf(T1,3,1,buffer); // écrit les caractères de T1 dans le tableau buffer (3 chiffres et 1 decimale 35.6)
                                       //   écrit la chaine de caractère 35.6 dans variable test 
  
  oled.goto_xy(1,2);
  oled.oled_puts("temperature:12.3");  // test d'affichage d'une chaine de caratère
  oled.goto_xy(17,2);
  oled.data(0xD2);                 // test d'affichage du caratère ° du °C
  oled.oled_putc('C');             // Affichage du C de °C
  char buffer2[15];    
  sprintf(buffer2,"f:%3.1f k:%d T1:%s", f, k, buffer);  // création tableau buffer2 
  oled.goto_xy(1,3);
  oled.oled_puts(buffer2);   //affichage du tableau buffer2
  oled.goto_xy(1,4);
  //                       12345678901234567890
  oled.oled_puts("BUG avec les accents");
  oled.delai_ms(5000);
}

2- OLED_4X20_SPI.h

/*
OLED_4X20_SPI.h  pour pilote SPI de l'affichage OLED NHD-0420DZW-AB5
ver:1.0
*/

#ifndef OLED_4X20_SPI_h
#define OLED_4X20_SPI_h

#include "Arduino.h"

#define DT 1
#define CLS 1
#define HOME 2
class OLED_4X20_SPI
{
  public:
    OLED_4X20_SPI(int CS, int SDO, int SCL, int speed);
	  void command(char i);
    void start_data_transmission();
    void data(char i);
    void end_data_transmission();
    //void clear_screen();
   // void ret_home();
    void goto_xy(short x, short y);
    char accent(char a);
    void oled_putc(char i );
    void oled_puts(char *doc );
    void init1();
    void delai_ms(int nb_ms);
	
  private:
    int _CS, _SDO, _SCL, _speed;
};

#endif

3- OLED_4X20_SPI.CCP

/*
OLED_4X20_SPI.CCP  pour pilote SPI de l'affichage OLED NHD-0420DZW-AB5
ver:1.0
*/

#include "Arduino.h"
#include OLED_4X20_SPI.h

// ce qui suit est le CONSTRUCTEUR

OLED_4X20_SPI::OLED_4X20_SPI(int CS, int SDO, int SCL, int speed)
{
  pinMode(SCL, OUTPUT);
  pinMode(SDO, OUTPUT);
  pinMode(CS, OUTPUT);
  _SCL = SCL;
  _SDO = SDO;
  _CS = CS;
  _speed = speed; 
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  10-bit Instruction Transmission
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::command(char i) {
  unsigned int m;
  digitalWrite(_CS, LOW);   // CS = 0;
  digitalWrite(_SDO, LOW);  // RS = 0;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RS Pin in
  digitalWrite(_SCL, LOW);
  delay(1);
  digitalWrite(_SDO, LOW);  // RW = 0;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RW Pin in
  digitalWrite(_SCL, LOW);
  for (m = 0; m < 8; m++) {  // Clock in DB0 - DB7
    if ((i & 0x80) == 0x80)
      digitalWrite(_SDO, HIGH);
    else
      digitalWrite(_SDO, LOW);
    while (0)  ;
    i = (i << 1);
    digitalWrite(_SCL, LOW);
    while (0)
      ;
    digitalWrite(_SCL, HIGH);
    while (0)
      ;
    digitalWrite(_SCL, LOW);
  }
  digitalWrite(_CS, HIGH);  // CS = 1;
}

/-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Start_Data_Transmission Function:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Set CS pin LOW to begin transmission; Set RS & RW bits
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::start_data_transmission() {
  digitalWrite(_CS, LOW);  // CS = 0;
  delay(1);
  digitalWrite(_SDO, HIGH);  // RS = 1;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RS Pin in
  digitalWrite(_SCL, LOW);
  delay(1);
  digitalWrite(_SDO, LOW);  // RW = 0;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RW Pin in
  digitalWrite(_SCL, LOW);
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Data Function:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Send 8-bit Transmission; Can be continuous transmission
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::data(char i) {
  unsigned int m;
   start_data_transmission();
   for (m = 0; m < 8; m++) {  // Clock in DB0 - DB7
    if ((i & 0x80) == 0x80)
      digitalWrite(_SDO, HIGH);
    else
      digitalWrite(_SDO, LOW);
    while (0)
      ;
    i = (i << 1);
    digitalWrite(_SCL, LOW);
    while (0)
      ;
    digitalWrite(_SCL, HIGH);
    while (0)
      ;
    digitalWrite(_SCL, LOW);
  }
  end_data_transmission(); 
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  End_Data_Transmission Function:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Set _CS pin HIGH to end transmission.
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::end_data_transmission() {
  digitalWrite(_CS, HIGH);  // CS = 1;
  delay(1);
}

/****************************************************
*         Function qui efface tout l'écran          *
****************************************************/

void OLED_4X20_SPI::clear_screen() {  // clear display
  command(0x01);
}

/****************************************************
*         Function de retour du curseur à 1,1      *
****************************************************/ 

void OLED_4X20_SPI::ret_home() {  // Return to home position
  command(0x02);
}

/*****************************************************************************/
/*                                  OledLigne()                              
/* Entrées : x : colonne du curseur                                         
/*           y : ligne du curseur (0 ou 1)                                   
/*               position initiale en haut à gauche, (0,0)              
/* Sortie  : nil
/*****************************************************************************/

void OLED_4X20_SPI::goto_xy(short x, short y) 
{ 
    unsigned char adresse;

    switch (y)
    {
        case 1  :  
			adresse = 0x80;  // 1 000 0000
			Gligne = 1;      //    0   0    0x00
        break;

        case 2  :   
			adresse = 0xC0;  // 1 100 0000
			Gligne = 2;      //     4  0    0X40
        break;

        case 3  :  
			adresse = 0x94;   // 1 001 0100
			Gligne = 3;       //    1   4   0X14
        break;

        case 4  :  
			adresse = 0xD4;   // 1 101 0100
			Gligne = 4;       //    5   4   0X54
        break;

        default :   
			adresse = 0x80;
			Gligne = 1;
        break;
    }
   adresse += (x-1);  //deplacement en X
   command(adresse);
 }

 /***************************************************************
  Déclaration de la fonction de conversion des lettres accentuées               
  ***************************************************************/	

char OLED_4X20_SPI::accent(char a) {
   switch(a)
	 {
		case 'Û'   :   data(0x80);  
					         delay(DT);
		               break; 
		case 'Ù'   :   data(0x81);  
		               break;                           
		case 'Ü'   :   data(0x83);  
		               break; 
		case 'û'   :   data(0x84);  
					         delay(DT);
		               break; 
		case 'ù'   :   data(0x85);  
					         delay(DT);
		               break;           
		case 'ô'   :   data(0x87);  
					         delay(DT);
		               break;  
		case 'ò'   :   data(0x88);  
					         delay(DT);
		               break; 
		case 'ö'   :   data(0x8E);  
					         delay(DT);
		               break; 
		case 'Ê'   :   data(0x90);  
					         delay(DT);
		               break;
		case 'È'   :   data(0x91);  
					         delay(DT);
		               break;                                                          
		case 'É'   :   data(0x92);  
					         delay(DT);
		               break;                    
		case 'Ë'   :   data(0x93);  
					         delay(DT);
		               break;                    
		case 'ê'   :   data(0x94);  
					         delay(DT);
		               break;
		case 'è'   :   data(0x95);  
					         delay(DT);
		               break;
		case 'é'   :   data(0x96);  
					         delay(DT);
		               break;                    
		case 'ë'   :   data(0x97);  
					         delay(DT);
		               break;
		case 'Ä'   :   data(0x99);  
					         delay(DT);
		               break;
		case 'â'   :   data(0x9A);  
					         delay(DT);
		               break;               
		case 'à'   :   data(0x9C);  
					         delay(DT);
		               break;                    
		case 'ä'   :   data(0x9E);  
					         delay(DT);
		               break;
		case 'î'   :   data(0xA1);  
					         delay(DT);
		               break;
		case 'ì'   :   data(0xA2);  
					         delay(DT);
		               break;                                                            
		case 'ï'   :   data(0xA4);  
					         delay(DT);
		               break;                    
		case 'ç'   :   data(0xC4); 
					         delay(DT);
			 		         break;     
		case 'µ'  :    data(0xC8);  
					         delay(DT);
		               break;                                  
		case '¶'   :   data(0xBC);  
					         delay(DT);
		               break; 
		case '@'   :   data(0x40);  
					         delay(DT);
		               break;  

		case '\f':     clear_screen();
                   delay(5);
                   goto_xy(1,1);
                   Gligne = 1;
                   break;
		               
		case '\n':     Gligne++;
		               if (Gligne > 4){
		                Gligne=1;
		               }
					         goto_xy(1, Gligne);
		               break;
                       
    case '\r':     goto_xy(1,Gligne);
                   delay(1);
                   break;               
                       
		               
		default     :  data(a);
                   delay(DT);
		               break;
   }
 } 

/****************************************************
*             Affichage d'un seul caratère          *
****************************************************/

 void OLED_4X20_SPI::oled_putc(char i ) {  // affiche un carratère
   accent(i);
  }

/****************************************************
*       Affichage d'une chaine de caractères         *
****************************************************/

 void OLED_4X20_SPI::oled_puts(char *doc ) {  // affiche chaine de carratères
   while (*doc){
   oled_putc(*doc++);
  }
 }

/****************************************************
*              Initialization Routine               *
****************************************************/

void OLED_4X20_SPI::init1() {
  delay(300);
  command(0x28);  //Function set
  delay(2);
  command(0x08);  //Display OFF
  delay(2);
  command(0x01);  //Clear Display
  delay(2);
  command(0x06);  //Entry Mode set
  delay(2);
  command(0x02);  //Return Home
  delay(2);
  command(0x0C);  //Display ON
  delay(2);
  command(0x39);  //Table de caractère Europe de ouest #1 
  delay(2);
 }
 
  /***************************************************************
            Déclaration de la fonction de delai ms()                 
  ***************************************************************/		
 
  void OLED_4X20_SPI::delai_ms(int nb_ms){
	
    float z= 99999999.99999;
    float s = 0.00;
    unsigned long i;
    int t;

	if (_speed = 240){
		t=2247;
    }
	else{
		t = 225;   // donnera des 100us pour claque mb_ms
	}	
	  while(nb_ms--){	
		 for (i=0; i<t; i++){
       s = z/3.141698765;
       z=s;
      } 	 
    }
    Serial.println(s);
 }

Merci d’éditer votre post pour rajouter les balises de de code, c’est illisible tel quel:

  • sélectionner la partie du texte qui correspond à chaque code
  • appuyez sur l’icône code dans la barre d’outils pour indiquer que c’est du code

(Assurez vous aussi d’indenter le code correctement dans l’IDE avant de le copier pour le coller ici. Cela se fait en pressant ctrlT sur PC ou cmdT sur un Mac)


A mon Avis il manque le #include pour votre écran avant la définition qui utilise

OLED_4X20_SPI

Lire un tuto de C/Cpp de programmation en fichier séparés apportera plus de 95% des réponses.

Ce code comporte quelques erreurs.
OLED_4X20_SPI::goto_xy, OLED_4X20_SPI::accent : variable GLigne non déclarée
OLED_4X20_SPI::delai_ms : variable t non déclarée

On appelle une méthode d'instance en utilisant une instance, et pas la classe elle-même.

Ce commentaire commence par /-

Dans le .ino il manque :
#include "OLED_4X20_SPI.h"

En général une librairie contient des fichiers .cpp et .h, pas de .ino.

1- J'ai ajouté #include <OLED_4X20_SPI.h> dans le fichier OLED_4X20_SPI.ino.

2- J'ai inséré les trois codes entre pour simplifier la lecture.

Je vous remercie pour ces remarques constructives.

Daniel Caron

Vous avez de nouvelles erreurs ?

1- Dans la fonction goto_xy je déclare les variable x et y comme du type short,
Arduino comprend-il cela ou je devrais utilisé le type byte?

2- Gligne est une variable du type Global je la déclare avant Setup est-ce le bon endroit, car je sais qu'elle doit être avant SETUP et LOOP?

void OLED_4X20_SPI::goto_xy(short x, short y) 
{ 
    unsigned char adresse;

    switch (y)
    {
        case 1  :  
			adresse = 0x80;  // 1 000 0000
			Gligne = 1;      //    0   0    0x00
        break;

J'ai encore ce message d'erreur que je ne comprend pas.

C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI\OLED_4X20_SPI.ino: In function 'void setup()':
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI\OLED_4X20_SPI.ino:20:16: error: expected unqualified-id before '.' token
OLED_4X20_SPI.init1();
^

exit status 1

Compilation error: expected unqualified-id before '.' token

J'ai fait une fonction delai_ms car la fonction delay est influencé par les interruptions et je fait appel souvent aux interruptions lorsque je fais de la programmation.
J'ai ajouté la déclaration de la variable t qui était pas déclaré comme vous me l'avez spécifié. :wink:

void OLED_4X20_SPI::delai_ms(int nb_ms){
	
    float z= 99999999.99999;
    float s = 0.00;
    unsigned long i;
	int t;
	if (_speed = 240){
		t=2247;
    }
	else{
		t = 225;  // donnera des 100us pour claque mb_ms
	}	
	  while(nb_ms--){	
		 for (i=0; i<t; i++){
       s = z/3.141698765;
       z=s;
      } 	 
    }
    Serial.println(s);
 }

Je ne comprend pas pourquoi vous me dite qu'il y a variable non déclarée dans OLED_4X20_SPI::accent(char a) car il me semble que (char a) est la déclaration de la variable a du type char.

char OLED_4X20_SPI::accent(char a) {
   switch(a)
	 {...

Je ne comprend pas ce que je doit faire!
Qu'est-ce qu'une instance?

OLED_4X20_SPI est la classe, oled est l'instance.

Plutôt :
oled.init1();

Non elle doit être déclarée dans le fichier où elle est utilisée, pas dans le sketch.

delai_ms() sera aussi impactée par les interruptions puisque pendant le traitement des interruptions la boucle while ne s'exécutera pas.

si dans la procédure d'interruption j'utiliserais mon delai_ms il ne va pas fonctionner?

Pour qu'une variable soit GLOBAL ne doit-elle pas être déclaré avant SETUP et LOOP?

Il suffit qu'elle soit déclarée en dehors d'une fonction.

Si, je pensais que ce délai ce déroulait dans le corps du programme.
C'est une mauvaise pratique de placer des délais dans une routine de traitement d'interruption. Car cela perturbe justement le bon déroulement du reste du programme.

Voici les nouveaux messages d'erreurs!

C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal._Z5setupv+0x18): undefined reference to `OLED_4X20_SPI::init1()'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal._Z5setupv+0x1c): undefined reference to `OLED_4X20_SPI::oled_puts(char*)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal._Z4loopv+0x20): undefined reference to `OLED_4X20_SPI::goto_xy(short, short)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal._Z4loopv+0x24): undefined reference to `OLED_4X20_SPI::data(char)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal._Z4loopv+0x28): undefined reference to `OLED_4X20_SPI::oled_putc(char)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal._Z4loopv+0x2c): undefined reference to `OLED_4X20_SPI::delai_ms(int)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o:(.literal.startup._GLOBAL__sub_I_oled+0x4): undefined reference to `OLED_4X20_SPI::OLED_4X20_SPI(int, int, int, int)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o: In function `setup()':
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:20: undefined reference to `OLED_4X20_SPI::init1()'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:24: undefined reference to `OLED_4X20_SPI::oled_puts(char*)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o: In function `loop()':
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:41: undefined reference to `OLED_4X20_SPI::goto_xy(short, short)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:42: undefined reference to `OLED_4X20_SPI::oled_puts(char*)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:43: undefined reference to `OLED_4X20_SPI::goto_xy(short, short)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:44: undefined reference to `OLED_4X20_SPI::data(char)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:45: undefined reference to `OLED_4X20_SPI::oled_putc(char)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:48: undefined reference to `OLED_4X20_SPI::goto_xy(short, short)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:49: undefined reference to `OLED_4X20_SPI::oled_puts(char*)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:50: undefined reference to `OLED_4X20_SPI::goto_xy(short, short)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:52: undefined reference to `OLED_4X20_SPI::oled_puts(char*)'
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:53: undefined reference to `OLED_4X20_SPI::delai_ms(int)'
C:\Users\Daniel\AppData\Local\Temp\arduino\sketches\13D1530914E64503B4E1A5E84C45715A\sketch\OLED_4X20_SPI.ino.cpp.o: In function `_GLOBAL__sub_I_oled':
C:\Users\Daniel\AppData\Local\Arduino15\libraries\OLED_4X20_SPI/OLED_4X20_SPI.ino:12: undefined reference to `OLED_4X20_SPI::OLED_4X20_SPI(int, int, int, int)'
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

voici les fichiers à jour:

                                            1- OLED_4X20_SPI.ino
#include <OLED_4X20_SPI.h>

//Pilote pour affichage OLED NHD-0420DZW 

/****************************************************
*                   PINOUT: CPU                     *
****************************************************/

#define DT 1

#define VERSION "1.54"
OLED_4X20_SPI oled = OLED_4X20_SPI(18, 17, 16, 240);

/*****************************************************
*           Setup Function, to run once              *
*****************************************************/

void setup() {

  oled.init1();
  Serial.begin(115200);
 // oled.clear_screen();
  //                  12345678901234567890
  oled.oled_puts("    Ver:" VERSION);
  
}

/*****************************************************
*           Loop Function = Main                           *
*****************************************************/

void loop()
{
  float T1=35.6;
  float f=-23.66;
  int k=-5;
  char buffer[6];
  String test = dtostrf(T1,3,1,buffer); // écrit les caractères de T1 dans le tableau buffer (3 chiffres et 1 decimale 35.6)
                                       //   écrit la chaine de caractère 35.6 dans variable test 
  
  oled.goto_xy(1,2);
  oled.oled_puts("temperature:12.3");  // test d'affichage d'une chaine de caratère
  oled.goto_xy(17,2);
  oled.data(0xD2);                 // test d'affichage du caratère ° du °C
  oled.oled_putc('C');             // Affichage du C de °C
  char buffer2[15];    
  sprintf(buffer2,"f:%3.1f k:%d T1:%s", f, k, buffer);  // création tableau buffer2 
  oled.goto_xy(1,3);
  oled.oled_puts(buffer2);   //affichage du tableau buffer2
  oled.goto_xy(1,4);
  //                       12345678901234567890
  oled.oled_puts("BUG avec les accents");
  oled.delai_ms(5000);
}
                                   2-  OLED_4X20_SPI.h
*
OLED_4X20_SPI.h  pour pilote SPI de l'affichage OLED NHD-0420DZW-AB5
ver:1.2
*/

#ifndef OLED_4X20_SPI_h
#define OLED_4X20_SPI_h

#include "Arduino.h"

#define DT 1
#define CLS 1
#define HOME 2
class OLED_4X20_SPI
{
  public:
    OLED_4X20_SPI(int CS, int SDO, int SCL, int speed);
	  void command(char i);
    void start_data_transmission();
    void data(char i);
    void end_data_transmission();
    void goto_xy(short x, short y);
    char accent(char a);
    void oled_putc(char i );
    void oled_puts(char *doc );
    void init1();
    void delai_ms(int nb_ms);
	
  private:
    int _CS, _SDO, _SCL, _speed;
};

#endif
                             3-OLED_4X20_SPI.ccp
*
OLED_4X20_SPI.CCP  pour pilote SPI de l'affichage OLED NHD-0420DZW-AB5
ver:1.2
*/

#include "Arduino.h"
#include OLED_4X20_SPI.h

// ce qui suit est le CONSTRUCTEUR

OLED_4X20_SPI::OLED_4X20_SPI(int CS, int SDO, int SCL, int speed)
{
  pinMode(SCL, OUTPUT);
  pinMode(SDO, OUTPUT);
  pinMode(CS, OUTPUT);
  _SCL = SCL;
  _SDO = SDO;
  _CS = CS;
  _speed = speed; 
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  10-bit Instruction Transmission
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::command(char i) {
  unsigned int m;
  digitalWrite(_CS, LOW);   // CS = 0;
  digitalWrite(_SDO, LOW);  // RS = 0;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RS Pin in
  digitalWrite(_SCL, LOW);
  delay(1);
  digitalWrite(_SDO, LOW);  // RW = 0;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RW Pin in
  digitalWrite(_SCL, LOW);
  for (m = 0; m < 8; m++) {  // Clock in DB0 - DB7
    if ((i & 0x80) == 0x80)
      digitalWrite(_SDO, HIGH);
    else
      digitalWrite(_SDO, LOW);
    while (0)  ;
    i = (i << 1);
    digitalWrite(_SCL, LOW);
    while (0)
      ;
    digitalWrite(_SCL, HIGH);
    while (0)
      ;
    digitalWrite(_SCL, LOW);
  }
  digitalWrite(_CS, HIGH);  // CS = 1;
}

/-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Start_Data_Transmission Function:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Set CS pin LOW to begin transmission; Set RS & RW bits
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::start_data_transmission() {
  digitalWrite(_CS, LOW);  // CS = 0;
  delay(1);
  digitalWrite(_SDO, HIGH);  // RS = 1;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RS Pin in
  digitalWrite(_SCL, LOW);
  delay(1);
  digitalWrite(_SDO, LOW);  // RW = 0;
  digitalWrite(_SCL, LOW);
  digitalWrite(_SCL, HIGH);  // Clock RW Pin in
  digitalWrite(_SCL, LOW);
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Data Function:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Send 8-bit Transmission; Can be continuous transmission
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::data(char i) {
  unsigned int m;
   start_data_transmission();
   for (m = 0; m < 8; m++) {  // Clock in DB0 - DB7
    if ((i & 0x80) == 0x80)
      digitalWrite(_SDO, HIGH);
    else
      digitalWrite(_SDO, LOW);
    while (0)
      ;
    i = (i << 1);
    digitalWrite(_SCL, LOW);
    while (0)
      ;
    digitalWrite(_SCL, HIGH);
    while (0)
      ;
    digitalWrite(_SCL, LOW);
  }
  end_data_transmission(); 
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  End_Data_Transmission Function:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//  Set _CS pin HIGH to end transmission.
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void OLED_4X20_SPI::end_data_transmission() {
  digitalWrite(_CS, HIGH);  // CS = 1;
  delay(1);
}

/*****************************************************************************/
/*                                  OledLigne()                              
/* Entrées : x : colonne du curseur                                         
/*           y : ligne du curseur (0 ou 1)                                   
/*               position initiale en haut à gauche, (0,0)              
/* Sortie  : nil
/*****************************************************************************/

void OLED_4X20_SPI::goto_xy(short x, short y) 
{ 
    unsigned char adresse;

    switch (y)
    {
        case 1  :  
			adresse = 0x80;  // 1 000 0000
			Gligne = 1;      //    0   0    0x00
        break;

        case 2  :   
			adresse = 0xC0;  // 1 100 0000
			Gligne = 2;      //     4  0    0X40
        break;

        case 3  :  
			adresse = 0x94;   // 1 001 0100
			Gligne = 3;       //    1   4   0X14
        break;

        case 4  :  
			adresse = 0xD4;   // 1 101 0100
			Gligne = 4;       //    5   4   0X54
        break;

        default :   
			adresse = 0x80;
			Gligne = 1;
        break;
    }
   adresse += (x-1);  //deplacement en X
   command(adresse);
 }

 /***************************************************************
  Déclaration de la fonction de conversion des lettres accentuées               
  ***************************************************************/	

char OLED_4X20_SPI::accent(char a) {
   switch(a)
	 {
		case 'Û'   :   data(0x80);  
					   delay(DT);
		               break; 
		case 'Ù'   :   data(0x81);  
		               break;                           
		case 'Ü'   :   data(0x83);  
		               break; 
		case 'û'   :   data(0x84);  
					   delay(DT);
		               break; 
		case 'ù'   :   data(0x85);  
					         delay(DT);
		               break;           
		case 'ô'   :   data(0x87);  
					         delay(DT);
		               break;  
		case 'ò'   :   data(0x88);  
					         delay(DT);
		               break; 
		case 'ö'   :   data(0x8E);  
					         delay(DT);
		               break; 
		case 'Ê'   :   data(0x90);  
					         delay(DT);
		               break;
		case 'È'   :   data(0x91);  
					         delay(DT);
		               break;                                                          
		case 'É'   :   data(0x92);  
					         delay(DT);
		               break;                    
		case 'Ë'   :   data(0x93);  
					         delay(DT);
		               break;                    
		case 'ê'   :   data(0x94);  
					         delay(DT);
		               break;
		case 'è'   :   data(0x95);  
					         delay(DT);
		               break;
		case 'é'   :   data(0x96);  
					         delay(DT);
		               break;                    
		case 'ë'   :   data(0x97);  
					         delay(DT);
		               break;
		case 'Ä'   :   data(0x99);  
					         delay(DT);
		               break;
		case 'â'   :   data(0x9A);  
					         delay(DT);
		               break;               
		case 'à'   :   data(0x9C);  
					         delay(DT);
		               break;                    
		case 'ä'   :   data(0x9E);  
					         delay(DT);
		               break;
		case 'î'   :   data(0xA1);  
					         delay(DT);
		               break;
		case 'ì'   :   data(0xA2);  
					         delay(DT);
		               break;                                                            
		case 'ï'   :   data(0xA4);  
					         delay(DT);
		               break;                    
		case 'ç'   :   data(0xC4); 
					         delay(DT);
			 		         break;     
		case 'µ'  :    data(0xC8);  
					         delay(DT);
		               break;                                  
		case '¶'   :   data(0xBC);  
					         delay(DT);
		               break; 
		case '@'   :   data(0x40);  
					         delay(DT);
		               break;  

		case '\f':     clear_screen();
                   delay(5);
                   goto_xy(1,1);
                   Gligne = 1;
                   break;
		               
		case '\n':     Gligne++;
		               if (Gligne > 4){
		                Gligne=1;
		               }
					         goto_xy(1, Gligne);
		               break;
                       
    case '\r':     goto_xy(1,Gligne);
                   delay(1);
                   break;               
                       
		               
		default     :  data(a);
                   delay(DT);
		               break;
   }
 } 

/****************************************************
*             Affichage d'un seul caratère          *
****************************************************/

 void OLED_4X20_SPI::oled_putc(char i ) {  // affiche un carratère
   accent(i);
  }

/****************************************************
*       Affichage d'une chaine decaratères         *
****************************************************/

 void OLED_4X20_SPI::oled_puts(char *doc ) {  // affiche chaine de carratères
   while (*doc){
   oled_putc(*doc++);
  }
 }

/****************************************************
*              Initialization Routine               *
****************************************************/

void OLED_4X20_SPI::init1() {
  delay(300);
  command(0x28);  //Function set
  delay(2);
  command(0x08);  //Display OFF
  delay(2);
  command(0x01);  //Clear Display
  delay(2);
  command(0x06);  //Entry Mode set
  delay(2);
  command(0x02);  //Return Home
  delay(2);
  command(0x0C);  //Display ON
  delay(2);
  command(0x39);  //Table de caractère Europe de ouest #1 
  delay(2);
 }
 
  /***************************************************************
            Déclaration de la fonction de delai ms()                 
  ***************************************************************/		
 
  void OLED_4X20_SPI::delai_ms(int nb_ms){
	
    float z= 99999999.99999;
    float s = 0.00;
    unsigned long i;
	int t;
	if (_speed = 240){
		t=2247;
    }
	else{
		t = 225;  // donnera des 100us pour claque mb_ms
	}	
	  while(nb_ms--){	
		 for (i=0; i<t; i++){
       s = z/3.141698765;
       z=s;
      } 	 
    }
    Serial.println(s);
 }

Il est préférable que le code appelé par une interruption soit le plus court possible, pour ne pas gêner les autres actions

1- Donc Gligne doit être déclaré dans LOOP car c'est là où la fonction goto_xy va utilisé Gline et dans le LOOP.

2- Dans setup on doit mettre le préfixe oled. avant la fonction init1()?

void setup() {

oled.init1();
Serial.begin(115200);