OLED 128x32 et 128x64

Bonjour à tous, cela fait quelques temps déjà que je m'intéresse et utilise le micro-contrôleur Arduino et jusqu'à présent, je m'en sortais pas trop mal, mes problèmes étant en général solutionnés en lisant le forum et/ou en faisant quelques recherches sur internet. Aujourd'hui, j'ai un soucis et je ne trouve pas de solution.
J'ai écris un programme qui pour ma première fois affiches des informations. Pour l'affichage, j'ai choisis un afficheur Oled 128x32 i2c. Mon programme fonctionne bien, MAIS (car il y a un mais) je trouvais que c'était petit, j'ai donc acheté un afficheur 128x64 et lorsque j'adapte mon programme pour qu'il fonctionne avec ce dernier, PLUS RIEN NE VA. Je pleure.
Evidemment, je ne sais pas encore comment faire pour vous montrer mon programme, je vais chercher et vous reviens rapidement.

Merci d'avance de me lire.

/*
 * COMPTE-A-REBOURS 2.0 23/11/2021    pour faire 4 pains, maison, au maximum, consécutivement
 * 
 * L'objectif est d'avoir un minuteur programmable pour pouvoir faire au moins 4 pains en série.
 * 
 * Fonctionnement:
 *                  - à la mise sous tension, le programme demande le nombre de prog qui devront être exécutés,
 *                    avec un minimum de 1 et un maximum de 4. Le réglage se fait à l'aide des bp2 (+1) et bp4 (-1).
 *                  - Affichage du contenu des 4 programmes contenant chacun un temps de pétrissage, un premier
 *                    temps de levée, un second temps de levée et un temps de cuisson. Si le second temps de levée est mis à 0,
 *                    lors du séquencement, le programme passera automatiquement au temps de cuisson lors de l'exécution.
 *                    TOUS les temps sont introduit en minutes
 *                  - Le passage en mode intro se fait en appuyant 5 secondes sur bp5.
 *                  - Lors de la première utilisation, le mode INTRO est activé automatiquement
 *                  - En mode intro, on utilise bp1 à bp4 pour faire +10, +1, -10, -1. On valide avec bp5.
 *                  - Si il y a eu modif, lors de l'appui sur bp5 la valeur en cours est écrasée en EEPROM.
 *                  - Si il n'y a pas eu de modif, on passe à la valeur suivante sans écriture EEPROM.
 *  Les boutons poussoirs:                  
 *                  - bp1 - Démarrage Programme 1
 *                        - Passage séquences programme 1
 *                        - + 10 en mode intro
 *                        
 *                  - bp2 - Démarrage Programme 2
 *                        - Passage séquences programme 2
 *                        - + 1 en mode intro
 *                        - + 1 lors du de la mise sous tension pour le nombre de programme(s)
 *                        
 *                  - bp3 - Démarrage Programme 3
 *                        - Passage séquences programme 3
 *                        - - 10 en mode intro
 *                        
 *                  - bp4 - Démarrage Programme 4
 *                        - Passage séquences programme 4
 *                        - - 1 en mode intro
 *                        - - 1 lors du de la mise sous tension pour le nombre de programme(s)
 *                        
 *                  - bp5 - Validation du nombre de programmes
 *                        - Passage en mode INTRO (modification des temps par étapes et par programmes) en appuyant 5 sec
 *                        - Validation des temps d'étapes
 *                        - Acquittement buzer
 *  Les Led:                        
 *                  L1 - Temps programme 1 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 1
 *                     
 *                  L2 - Temps programme 2 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 2
 *                     
 *                  L3 - Temps programme 3 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 3
 *                     
 *                  L4 - Temps programme 4 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 4
 *                     
 *  Le buzer      - S'enclenche à la fin de chaques étapes de chaques programmes et est acquité par un appui
 *                  sur bp5.
 *                - S'enclenche pendant 5 sec à une fréquence différente pour indiquer la fin d'attente du
 *                  démarrage du programme suivant lorsque nombre de programme est plus grand que 1 mais au
 *                  maximum égal à 4
 *                  Le temps d'attente est égal au temps de cuisson du programme suivant moins 10 minutes.
*/



#include <EEPROM.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...

#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D (0x3C dans mon cas) for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int bppin1 = 3;       // Lancement PROG1 ou +10min
int bppin2 = 4;       // Lancement PROG2 ou -10min
int bppin3 = 5;       // Lancement PROG3 ou +1min
int bppin4 = 6;       // Lancement PROG4 ou -1min
int bppin5 = 7;       // ACQUIT buzer ET passage en mode INTRO (appui xx sec) ET validation valeurs intro
int ledpin1 = 8;
int ledpin2 = 9;
int ledpin3 = 10;
int ledpin4 = 11;
int ledpin = 13;
int buzerpin = 12;
int bp1;          // Bouton Poussoir programme 1
int bp2;          // Bouton Poussoir programme 2
int bp3;          // Bouton Poussoir programme 3
int bp4;          // Bouton Poussoir programme 4
int bp5;          // Bouton poussoir acqui, mode intro, validation valeurs intro

int bp1mem = 0;       // Pour la détection de flancs montants
int bp2mem = 0;       // Pour la détection de flancs montants
int bp3mem = 0;       // Pour la détection de flancs montants
int bp4mem = 0;       // Pour la détection de flancs montants
int bp5mem = 0;       // Pour la détection de flancs montants
int cptbp1 = 0;       // Pour les étapes du PROGramme 1
int cptbp2 = 0;       // Pour les étapes du PROGramme 2
int cptbp3 = 0;       // Pour les étapes du PROGramme 3
int cptbp4 = 0;       // Pour les étapes du PROGramme 4
int cptbp5 = 0;       // Réserve
long start1 = 0;      // Utilisée pour le decompte des temporisations.
long start2 = 0;      // Utilisée pour le decompte des temporisations.
long start3 = 0;      // Utilisée pour le decompte des temporisations.
long start4 = 0;      // Utilisée pour le decompte des temporisations.
long ecoule1 = 0;      // Utilisée pour le decompte des temporisations.
long ecoule2 = 0;      // Utilisée pour le decompte des temporisations.
long ecoule3 = 0;      // Utilisée pour le decompte des temporisations.
long ecoule4 = 0;      // Utilisée pour le decompte des temporisations.

long temps1;          // Pour conversion ms vers min, sec du PROGramme 1
long temps2;          // Pour conversion ms vers min, sec du PROGramme 2
long temps3;          // Pour conversion ms vers min, sec du PROGramme 3
long temps4;          // Pour conversion ms vers min, sec du PROGramme 4

long tempsintro;      // Pour passer en mode INTRO/MODIF valeurs EEPROM
int secondes[4];      // Pour conversion ms vers min, sec du PROGramme 2
int minutes[4];       // Pour conversion ms vers min, sec des PROGrammes

int x = 0;            // Indice mémoires INTRO
int y = 0;            // Compteur pour lecture contenu EEPROM
int cpti = 0;             // Compteur de boucle
int cptj = 0;             // Compteur de boucle
int cptk = 0;             // Compteur de boucle

bool demcr1 = false;    // Pour compte à rebours PROGramme 1
bool demcr2 = false;    // Pour compte à rebours PROGramme 2
bool demcr3 = false;    // Pour compte à rebours PROGramme 3
bool demcr4 = false;    // Pour compte à rebours PROGramme 4
bool buzer = false;     // Pour activation du buzer
bool mode_intro = false;  // Pour passage en mode INTRO/MODIF des valeurs EEPROM
bool maj = false;       // Pour écriture en EEPROM si INTRO/MODIF du contenu EEPROM
bool premier_cycle = true;   // Premier cycle à la mise sous tension pour avoir des valeur cohérentes dans l'EEPROM

int mem[32];          // ARRAY pour lecture EEPROM
                      // Pour les 4 programmes
                      // index 0, 8, 16, 24 (temps de pétrissage)
                      // index 2, 10, 18, 26 (temps de levée 1)
                      // index 4, 12, 20, 28 (temps de levée 2)
                      // index 6, 14, 22, 30 (temps de cuisson)
long attente[3];        // Attente entre programmes
long attentestart = 0;
long attentemaintenant = 0;
long progattente;     // Contiendra le temps d'attente pour le prog suivant
                      // si nombre prog > 1
int nombreprog = 1;   // Nombre de programme(s) à faire (minimum 1)

long temps_ms;        // Durée départ pour compte à rebours
long temps_restant;   // Durée restante pour compte à rebours

String etape[4];      // Etape en cours programmes (pétrir, levée1, levée2, cuisson)
String etapetst;

String prog[4] = {"PROG1: ","PROG2: ","PROG3: ","PROG4: "};         // Programme en cours
String progr;                      // Programme en cours pour ode intro


void setup() {


  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  
  display.display();
  delay(3000);
  display.clearDisplay();


  // Définition des I/O
  pinMode(ledpin,OUTPUT);
  pinMode(bppin1,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(bppin2,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(bppin3,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(bppin4,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(bppin5,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(buzerpin,OUTPUT);
  pinMode(ledpin1,OUTPUT);
  pinMode(ledpin2,OUTPUT);
  pinMode(ledpin3,OUTPUT);
  pinMode(ledpin4,OUTPUT);

  // Initialisation moniteur série
  Serial.begin(9600);
  
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

//    Lecture EEPROM

  for(y = 0; y < 32; y += 2)   //LECTURE contenu EEPROM des 16 premières positions (0->30)un int prend 2 octets en EEPROM
  { 
    EEPROM.get(y,mem[y]);
    Serial.print("Position: ");
    Serial.print(y);
    Serial.print("     ");
    Serial.println(mem[y]);
  }
  if(mem[0] < 0)
  {
    Serial.println("Mémoires vides, mode intro");
    intro();
  }else{
        Serial.println("Lecture terminée");
  }

  tempsattente();
    
}

void loop() {


// Intro nombre de programme(s) à faire (minimum 1)

  if(premier_cycle == true)   // Test premier cycle machine
  {
    while(bp5 == LOW && bp5mem == LOW)   // Flanc montant
    {
      majio();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.clearDisplay();
      display.setCursor(0,0);
      display.print("Nbre prog: ");
      display.setCursor(60,16);
      display.print(nombreprog);
      display.display();
      if(bp2 == HIGH && bp2mem == LOW)   // Flanc montant
      {
        if(nombreprog < 4)
        {
          nombreprog++;
        }
        bp2mem = bp2;
      }
      bp2mem = bp2;
      if(bp4 == HIGH && bp4mem == LOW)   // Flanc montant
      {
        if(nombreprog > 1)
        {
          nombreprog--;
        }
        bp4mem = bp4;
      }
      bp4mem = bp4;
    }
    Serial.print(" Nombre de prog: ");
    Serial.println(nombreprog);
    affich_prog(); // Affichage des 4 programmes
  }
  majio();        // Mise à jour des I/O
  
  /*
   *          LANCEMENT PROGRAMME 1
   */
   
  if (bp1 == HIGH && bp1mem == LOW)                          // Flanc montant
  { 
      Serial.println(" Programme 1  ");
      if (bp1 == HIGH && cptbp1 <= 4 && demcr1 == false)
      {
        demcr1 = true;                                       // Démarrage compte à rebours
        cptbp1 += 1;
        if(cptbp1 == 3 && mem[4] == 0)
        {
          cptbp1 += 1;
        }
        start1 = millis();
        if(cptbp1 == 2 && nombreprog > 1)
        {
          attentestart = millis();
          progattente = attente[0];
        }
      }
  }
  bp1mem = bp1;

  /*
   *          LANCEMENT PROGRAMME 2
   */

  if (bp2 == HIGH && bp2mem == LOW)                           // Flanc montant
  { 
      Serial.println(" Programme 2");
      if (bp2 == HIGH && cptbp2 <= 4 && demcr2 == false)
      {
        demcr2 = true;                                       // Démarrage compte à rebours
        cptbp2 += 1;  
        if(cptbp2 == 3 && mem[12] == 0)
        {
          cptbp2 += 1;
        }
        start2 = millis();  
        if(cptbp2 == 2 && nombreprog > 1)
        {
          attentestart = millis();
          progattente = attente[1];
        }
      }
  }
  bp2mem = bp2;

  /*
   *          LANCEMENT PROGRAMME 3 
  */
 
  if (bp3 == HIGH && bp3mem == LOW)                           // Flanc montant
  { 
      Serial.println(" Programme 3");
      if (bp3 == HIGH && cptbp3 <= 4 && demcr3 == false)
      {
        demcr3 = true;                                       // Démarrage compte à rebours
        cptbp3 += 1;  
        if(cptbp3 == 3 && mem[20] == 0)
        {
          cptbp3 += 1;
        }
        if(cptbp3 == 2 && nombreprog > 1)
        {
          attentestart = millis();
          progattente = attente[2];
        }
        start3 = millis();  
      }
  }
  bp3mem = bp3;

  /*
   *          LANCEMENT PROGRAMME 4 
   */
   
  if (bp4 == HIGH && bp4mem == LOW)                          // Flanc montant
  { 
      Serial.println(" Programme 4");
      if (bp4 == HIGH && cptbp4 <= 4 && demcr4 == false)
      {
        demcr4 = true;                                       // Démarrage compte à rebours
        cptbp4 += 1;  
        if(cptbp4 == 3 && mem[28] == 0)
        {
          cptbp4 += 1;
        }
        start4 = millis();  
      }
  }
  bp4mem = bp4;

  //
  //        Attente pour lancer le programme suivant
  //

  if(attentestart > 0)
  {
    attentemaintenant = millis();
    if((attentemaintenant - attentestart) >= progattente)
    {
      tone(buzerpin, 2000, 5000);
      attentestart = 0;
      attentemaintenant = 0;
    }
  }

  // PROGRAMME 1

  if (demcr1 == true)
  {
    switch (cptbp1)
    {
      case 1:
          etape[0] = "Petr: ";
          temps_ms = mem[0] * 60000;
          compte_a_rebours_1();
          break;
      case 2:
          etape[0] = "Lev1: ";
          temps_ms = mem[2] * 60000;
          compte_a_rebours_1();
          break;
      case 3:
          etape[0] = "Lev2: ";
          temps_ms = mem[4] * 60000;
          compte_a_rebours_1();
          break;
      case 4:
          etape[0] = "Cuis: ";
          temps_ms = mem[6] * 60000;
          compte_a_rebours_1();
          break;
      default:
          break;
                  
    }
  }


  // PROGRAMME 2

  if (demcr2 == true)
  {
    switch (cptbp2)
    {
      case 1:
          etape[1] = "Petr: ";
          temps_ms = mem[8] * 60000;
          compte_a_rebours_2();
          break;
      case 2:
          etape[1] = "Lev1: ";
          temps_ms = mem[10] * 60000;
          compte_a_rebours_2();
          break;
      case 3:
          etape[1] = "Lev2: ";
          temps_ms = mem[12] * 60000;
          compte_a_rebours_2();
          break;
      case 4:
          etape[1] = "Cuis: ";
          temps_ms = mem[14] * 60000;
          compte_a_rebours_2();
          break;
      default:
          break;
                  
    }
  }


  // PROGRAMME 3

  if (demcr3 == true)
  {
    switch (cptbp3)
    {
      case 1:
          etape[2] = "Petr: ";
          temps_ms = mem[16] * 60000;
          compte_a_rebours_3();
          break;
      case 2:
          etape[2] = "Lev1: ";
          temps_ms = mem[18] * 60000;
          compte_a_rebours_3();
          break;
      case 3:
          etape[2] = "Lev2: ";
          temps_ms = mem[20] * 60000;
          compte_a_rebours_3();
          break;
      case 4:
          etape[2] = "Cuis: ";
          temps_ms = mem[22] * 60000;
          compte_a_rebours_3();
          break;
      default:
          break;
                  
    }
  }
  

  // PROGRAMME 4

  if (demcr4 == true)
  {
    switch (cptbp4)
    {
      case 1:
          etape[3] = "Petr: ";
          temps_ms = mem[24] * 60000;
          compte_a_rebours_4();
          break;
      case 2:
          etape[3] = "Lev1: ";
          temps_ms = mem[26] * 60000;
          compte_a_rebours_4();
          break;
      case 3:
          etape[3] = "Lev2: ";
          temps_ms = mem[28] * 60000;
          compte_a_rebours_4();
          break;
      case 4:
          etape[3] = "Cuis: ";
          temps_ms = mem[30] * 60000;
          compte_a_rebours_4();
          break;
      default:
          break;
                  
    }
  }


// Acquittement du buzer
  if (bp5 == HIGH && buzer == true)
  {
    noTone(buzerpin);
    buzer = false;
   }
  if(bp5 == HIGH && cptbp1 == 0) digitalWrite(ledpin1, LOW);
  if(bp5 == HIGH && cptbp2 == 0) digitalWrite(ledpin2, LOW);
  if(bp5 == HIGH && cptbp3 == 0) digitalWrite(ledpin3, LOW);
  if(bp5 == HIGH && cptbp4 == 0) digitalWrite(ledpin4, LOW);

   
// Entrée en mode INTRO

    if(bp5 == HIGH && cptbp1 ==0 && cptbp2 == 0 && cptbp3 == 0 && cptbp4 == 0)
    {
      tempsintro ++;
    }else{
          if(bp5 == LOW && tempsintro < 1000)
         {
          tempsintro = 0;
         }
    }
    
    if(bp5 == HIGH && (tempsintro > 50000))
    {
     mode_intro = true;
     tempsintro = 0;
    }
    if(mode_intro == true)
    {
      intro();
    }

//      Affichage des programme et temps restants

  if(demcr1 == true || demcr2 == true || demcr3 == true || demcr4 == true)
  {
  display.setTextSize(1);    
  display.clearDisplay();
  cptj = 0;
  for(cpti = 0; cpti <= 3; cpti++)
  {
  display.setCursor(0,cptj);
  display.print(etape[cpti]);
  display.print(minutes[cpti]);
  display.print(" min ");
  display.print(secondes[cpti]);
  display.print(" sec");
  cptj += 8;    
  }
  display.display();   
  }
  
  premier_cycle = false;    // Fin du premier cycle machine cycle exécuté

}

void majio(void)
{
    // Lecture des entrées


  bp1 = !digitalRead(bppin1);  // En mode PULLUP, les entrées logiques sont inversées:
  bp2 = !digitalRead(bppin2);  //   Si bouton poussoir enfoncé, O (LOW)
  bp3 = !digitalRead(bppin3);  //   Si bouton poussoir relaché, 1 (HIGH)
  bp4 = !digitalRead(bppin4);  // Il faut donc inverser les valeurs lues.
  bp5 = !digitalRead(bppin5);  
}

void conversion_1(void)
{
  minutes[0] =  temps1 / 1000 / 60;
  secondes[0] = (temps1 / 1000) - (minutes[0] * 60);
  if (cptbp1 == 4 && demcr1 == false)
  {
    cptbp1 = 0;
  }
}

void conversion_2(void)
{
  minutes[1] =  temps2 / 1000 / 60;
  secondes[1] = (temps2 / 1000) - (minutes[1] * 60);
  if (cptbp2 == 4 && demcr2 == false)
  {
    cptbp2 = 0;
  }
}
void conversion_3(void)
{
  minutes[2] =  temps3 / 1000 / 60;
  secondes[2] = (temps3 / 1000) - (minutes[2] * 60);
  if (cptbp3 == 4 && demcr3 == false)
  {
    cptbp3 = 0;
  }
}
void conversion_4(void)
{
  minutes[3] =  temps4 / 1000 / 60;
  secondes[3] = (temps4 / 1000) - (minutes[3] * 60);
  if (cptbp4 == 4 && demcr4 == false)
  {
    cptbp4 = 0;
  }
}


void compte_a_rebours_1(void)
{
  digitalWrite(ledpin1, LOW);
  ecoule1 = millis() - start1;
  temps_restant = temps_ms - ecoule1;
  temps1 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr1 == true)
    {
      tone(buzerpin,1500);
      digitalWrite(ledpin1,HIGH);
      buzer = true;
    }
    demcr1 = false;    
  }
  conversion_1();
}

void compte_a_rebours_2(void)
{
  digitalWrite(ledpin2, LOW);
  ecoule2 = millis() - start2;
  temps_restant = temps_ms - ecoule2;
  temps2 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr2 == true)
    {
      tone(buzerpin,1500);
      digitalWrite(ledpin2,HIGH);
      buzer = true;
    }
    demcr2 = false;
  }
  conversion_2();
}
void compte_a_rebours_3(void)
{
  digitalWrite(ledpin3, LOW);
  ecoule3 = millis() - start3;
  temps_restant = temps_ms - ecoule3;
  temps3 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr3 == true)
    {
      tone(buzerpin,1500);
       digitalWrite(ledpin3,HIGH);
      buzer = true;
    }
    demcr3 = false;
  }
  conversion_3();
}
void compte_a_rebours_4(void)
{
  digitalWrite(ledpin4, LOW);
  ecoule4 = millis() - start4;
  temps_restant = temps_ms - ecoule4;
  temps4 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr4 == true)
    {
      tone(buzerpin,1500);
      digitalWrite(ledpin4,HIGH);
      buzer = true;
    }
    demcr4 = false;
  }
  conversion_4();
}


void intro(void)
{
  
  display.setTextSize(2);    
  display.setTextColor(WHITE);
  display.clearDisplay();
  display.setCursor(0,12);
  display.print("Mode INTRO");
  display.display();
  
  delay(2000);
  x = 0;
  
  while(x < 32)
  {
    if(x <= 6)
    {
      digitalWrite(ledpin1, HIGH);
    }
    if(x >= 8 && x <= 14)
    {
      digitalWrite(ledpin1, LOW);
      digitalWrite(ledpin2, HIGH);
    }
    if(x >= 16 && x <= 22)
    {
      digitalWrite(ledpin2, LOW);
      digitalWrite(ledpin3, HIGH);
    }
    if(x >= 24 && x <= 30)
    {
      digitalWrite(ledpin3, LOW);
      digitalWrite(ledpin4, HIGH);
    }    
   test_etape();
   majio();

   affichmodif();

      if(bp1 == HIGH && bp1mem == LOW)   // Flanc montant
      {
          if(mem[x] < 89)
          {
            mem[x] += 10;
            maj = true;
          }
          test_etape();
          affichmodif();

      }
      bp1mem = bp1;
      
      if(bp2 == HIGH && bp2mem == LOW)   // Flanc montant
      {
          if(mem[x] < 99)
          {
            mem[x] += 1;
            maj = true;
          }
          test_etape();
          affichmodif();
      }
      bp2mem = bp2;
      
      if(bp3 == HIGH && bp3mem == LOW)   // Flanc montant
      {
          if(mem[x] >= 11)
          {
            mem[x] -= 10;
            maj = true;
          }
          test_etape();
          affichmodif();
      }
      bp3mem = bp3;

      if(bp4 == HIGH && bp4mem == LOW)   // Flanc montant
      {
          if(mem[x] > 0)
          {
            mem[x] -= 1;
            maj = true;
          }
          test_etape();
          affichmodif();
      }
      bp4mem = bp4;
      
      if(bp5 == HIGH && bp5mem == LOW)   // Flanc montant
      {
          if(maj == true)
          {
          EEPROM.put(x,mem[x]);
          maj = false;
          }
          x += 2;
      }
      bp5mem = bp5;
      
  } 
  digitalWrite(ledpin4, LOW);
  display.setTextSize(2);    
  display.clearDisplay();
  display.setCursor(0,12);
  display.print(" FIN INTRO");
  display.display();
  delay(5000);
  tempsattente();
  affich_prog();

  mode_intro = false;
}


void test_etape(void)
{
  switch (x)
  {
    case 0:
      progr = prog[0];
      etapetst = "Petr: ";
      break;
    case 2:
      progr = prog[0];
      etapetst = "Lev1: ";
      break;
    case 4:
      progr = prog[0];
      etapetst = "Lev2: ";
      break;
    case 6:
      progr = prog[0];
      etapetst = "Cuis: ";
      break;
    case 8:
      progr = prog[1];
      etapetst = "Petr: ";
      break;
    case 10:
      progr = prog[1];
      etapetst = "Lev1: ";
      break;
    case 12:
      progr = prog[1];
      etapetst = "Lev2: ";
      break;
    case 14:
      progr = prog[1];
      etapetst = "Cuis: ";
      break;
    case 16:
      progr = prog[2];
      etapetst = "Petr: ";
      break;
    case 18:
      progr = prog[2];
      etapetst = "Lev1: ";
      break;
    case 20:
      progr = prog[2];
      etapetst = "Lev2: ";
      break;
    case 22:
      progr = prog[2];
      etapetst = "Cuis: ";
      break;
    case 24:
      progr = prog[3];
      etapetst = "Petr: ";
      break;
    case 26:
      progr = prog[3];
      etapetst = "Lev1: ";
      break;
    case 28:
      progr = prog[3];
      etapetst = "Lev2: ";
      break;
    case 30:
      progr = prog[3];
      etapetst = "Cuis: ";
      break;
  }
}

void affich_prog(void)
{
  //////  Affichage des valeurs de temporisation des quatres programmes disponibles.
  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.clearDisplay();
  cpti = 0;
  cptj = 0;
  cptk = 0;
  for(cpti == 0; cpti <= 3; cpti ++)
  {
    display.setCursor(0,cptk);
    display.print(prog[cpti]);
    for(cptj == cptk; cptj <= (cptk + 6); cptj += 2)
    {
      display.print(mem[cptj]);
      display.print(" ");
    }
      if(cptk <= 24)
        {
          cptk +=8;
        }
  }
  display.display();
}

void affichmodif(void)
{
          display.setTextSize(1);    
          display.clearDisplay();
          display.setCursor(0,16);
          display.print(progr);
          display.print(" ");
          display.print(etapetst);
          display.print(" ");
          display.print(mem[x]);
          display.display();
}

void tempsattente(void)
{
            // Chargerment des attentes inter-programmes

  attente[0] = (mem[6] - 10) * 60000;   // Attente lancement prog 2 en ms
  attente[1] = (mem[14] - 10) * 60000;  // Attente lancement prog 3 en ms
  attente[2] = (mem[22] - 10) * 60000;  // Attente lancement prog 4 en ms

}

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

lisez les conseils et postez votre code ici ensuite (avec les balises de code) + un schéma de votre montage / alimentation

Désolé, je vais être plus attentif à l'avenir.

Jean

Voilà, j'ai réussi à mettre le code dans le post d'origine, maintenant, je m'attelle à poster une image du montage.

Jean Antonio.

vous êtes sûr de l'adresse ?

avant de faire un gros code, avez vous essayé avec un code tout simple qui afficherait "Bonjour" ?

Bonjour, oui, je suis sûr de l'adresse, en fait le code ci-dessus est le code que j'ai écris pour le 128x32 et tout fonctionne nickel. Ensuite, j'ai reçu ce lundi les 128x64 dans mon montage, j'ai remplacé le 32 par un 64, corrigé SCREEN_HEIGHT 32 en SCREEN_HEIGHT 64, plus rien ne va.

Dans le moniteur série, je reçois "SSD1306 allocation failed"

Si je re corrige en mettant 32 (sans changer l'afficheur, c'est toujours le 64), cela fonctionne mais c'est pas beau

J'espère avoir été clair, merci de me consacrer du temps, Jean Antonio

Ce code est adapté à un SSD1306 128x32.

C'est que la quantité de mémoire RAM est insuffisante.
Une solution ici :

je parlais de l'adresse

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D (0x3C dans mon cas) for 128x64, 0x3C for 128x32

le commentaire en anglais semble dire que pour un 128x32 il faut prendre 0x3C et pour un 128x64 il faut prendre 0x3D

hors vous êtes resté (?) sur 0x3C

Voici le début de la fonction begin() :

  if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
    return false;

Pour un écran de 128x64 le besoin est de 128*((64+7)/8) = 1136 octets
La compilation donne ceci :

Les variables globales utilisent 1024 octets (50%) de mémoire dynamique, ce qui laisse 1024 octets pour les variables locales. Le maximum est de 2048 octets.

1024 octets disponibles alors que la librairie en réclame 1136
:woozy_face:
-> essayer la librairie Greiman, ce qui implique pas mal de modifs de code, ou adopter une MEGA.

J'avais bien compris que vous parliez de l'adresse, oui, je suis sûr que c'est 0x3c, l'afficheur fonctionne très bien.

hbachetti,

Merci pour toutes ces précisions, suite à votre première réponse (.... RAM insuffisante) j'étais déjà occupé à lire la publication de riton-duino.

A la compilation on a ça:

Les variables globales utilisent 1029 octets (50%) de mémoire dynamique,

Le problème, c'est que la librairie alloue un buffer pour stocker le contenu de l'écran avant de l'afficher. Et le buffer en question fait 1K.
Moralité, il ne reste plus de mémoire libre.
Il faudrait regarder la librairie U8x8 d'olikraus. Elle n'utilise pas de buffer et donc libère pas mal de mémoire.

ou la librairie ss_oled de Larry Bank

Merci à vous tous, je vais investiguer vos différentes propositions de solutions pour adapter celle qui me conviendra le mieux.

Je reviendrai vers vous dès que possible.

Bonjour,

J'ai aussi deux afficheurs oled 1.3".
Ils n'utilisent pas le driver SSD1306 mais un driver SSH1106.
Essaie une librairie qui gère le SSH1106 et configure comme SSH1106.

Bonjour à tous,

Tout d'abord, un grand merci à vous qui m'avez aidé dans la résolution de mon problème. J'ai un peu étudié la librairie Greiman (merci à hbachetti) et je vais dans les prochaines semaines étudier Olikraus et Bitbank2 (merci à fdufnews). En attendant, j'a fais la nouvelles version avec la librairie Greiman et ça fonctionne super, je n'ai plus que la moitié (ou presque 12844 octects de l'espace de stockage de programme et 718 octets de mémoire dynamique utilsée).
Voici le code (que je vais sans doute essayer d'optimiser un peu plus):

Merci encore à tous, Jean Antonio

/*
 * COMPTE-A-REBOURS 2.1 26/11/2021    pour faire 4 pains, maison, au maximum, consécutivement
 * 
 * 
 *              ** 1.1 version fonctionnelle avec un afficheur 128*32
 *              ** 2.0 version fonctionnelle avec un afficheur 128*64 MAIS configuré en 128*32 librairies ADAFRUIT
 *              ** 2.1 Version fonctionnelle avec un afficheur 128*64 correctement configué librairies GREIMAN
 * 
 * L'objectif est d'avoir un minuteur programmable pour pouvoir faire au moins 4 pains en série.
 * 
 * Fonctionnement:
 *                  - à la mise sous tension, le programme demande le nombre de prog qui devront être exécutés,
 *                    avec un minimum de 1 et un maximum de 4. Le réglage se fait à l'aide des bp2 (+1) et bp4 (-1).
 *                  - Affichage du contenu des 4 programmes contenant chacun un temps de pétrissage, un premier
 *                    temps de levée, un second temps de levée et un temps de cuisson. Si le second temps de levée est mis à 0,
 *                    lors du séquencement, le programme passera automatiquement au temps de cuisson lors de l'exécution.
 *                    TOUS les temps sont introduit en minutes
 *                  - Le passage en mode intro se fait en appuyant 5 secondes sur bp5.
 *                  - Lors de la première utilisation, le mode INTRO est activé automatiquement
 *                  - En mode intro, on utilise bp1 à bp4 pour faire +10, +1, -10, -1. On valide avec bp5.
 *                  - Si il y a eu modif, lors de l'appui sur bp5 la valeur en cours est écrasée en EEPROM.
 *                  - Si il n'y a pas eu de modif, on passe à la valeur suivante sans écriture EEPROM.
 *  Les boutons poussoirs:                  
 *                  - bp1 - Démarrage Programme 1
 *                        - Passage séquences programme 1
 *                        - + 10 en mode intro
 *                        
 *                  - bp2 - Démarrage Programme 2
 *                        - Passage séquences programme 2
 *                        - + 1 en mode intro
 *                        - + 1 lors du de la mise sous tension pour le nombre de programme(s)
 *                        
 *                  - bp3 - Démarrage Programme 3
 *                        - Passage séquences programme 3
 *                        - - 10 en mode intro
 *                        
 *                  - bp4 - Démarrage Programme 4
 *                        - Passage séquences programme 4
 *                        - - 1 en mode intro
 *                        - - 1 lors du de la mise sous tension pour le nombre de programme(s)
 *                        
 *                  - bp5 - Validation du nombre de programmes
 *                        - Passage en mode INTRO (modification des temps par étapes et par programmes) en appuyant 5 sec
 *                        - Validation des temps d'étapes
 *                        - Acquittement buzer
 *  Les Led:                        
 *                  L1 - Temps programme 1 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 1
 *                     
 *                  L2 - Temps programme 2 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 2
 *                     
 *                  L3 - Temps programme 3 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 3
 *                     
 *                  L4 - Temps programme 4 étape(x) écoulé (s'éteind au passage étape suivante)
 *                     - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 4
 *                     
 *  Le buzer      - S'enclenche à la fin de chaques étapes de chaques programmes et est acquité par un appui
 *                  sur bp5.
 *                - S'enclenche pendant 5 sec à une fréquence différente pour indiquer la fin d'attente du
 *                  démarrage du programme suivant lorsque nombre de programme est plus grand que 1 mais au
 *                  maximum égal à 4
 *                  Le temps d'attente est égal au temps de cuisson du programme suivant moins 10 minutes.
*/



#include <EEPROM.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"

SSD1306AsciiAvrI2c display;

int ledpin1 = 8;
int ledpin2 = 9;
int ledpin3 = 10;
int ledpin4 = 11;
int ledpin = 13;
int buzerpin = 12;
int bp1;          // Bouton Poussoir programme 1
int bp2;          // Bouton Poussoir programme 2
int bp3;          // Bouton Poussoir programme 3
int bp4;          // Bouton Poussoir programme 4
int bp5;          // Bouton poussoir acqui, mode intro, validation valeurs intro

int bp1mem = 0;       // Pour la détection de flancs montants
int bp2mem = 0;       // Pour la détection de flancs montants
int bp3mem = 0;       // Pour la détection de flancs montants
int bp4mem = 0;       // Pour la détection de flancs montants
int bp5mem = 0;       // Pour la détection de flancs montants
int cptbp1 = 0;       // Pour les étapes du PROGramme 1
int cptbp2 = 0;       // Pour les étapes du PROGramme 2
int cptbp3 = 0;       // Pour les étapes du PROGramme 3
int cptbp4 = 0;       // Pour les étapes du PROGramme 4
int cptbp5 = 0;       // Réserve
long start1 = 0;      // Utilisée pour le decompte des temporisations.
long start2 = 0;      // Utilisée pour le decompte des temporisations.
long start3 = 0;      // Utilisée pour le decompte des temporisations.
long start4 = 0;      // Utilisée pour le decompte des temporisations.

long temps1;          // Pour conversion ms vers min, sec du PROGramme 1
long temps2;          // Pour conversion ms vers min, sec du PROGramme 2
long temps3;          // Pour conversion ms vers min, sec du PROGramme 3
long temps4;          // Pour conversion ms vers min, sec du PROGramme 4

long tempsintro;      // Pour passer en mode INTRO/MODIF valeurs EEPROM
int secondes[4];      // Pour conversion ms vers min, sec du PROGramme 2
int minutes[4];       // Pour conversion ms vers min, sec des PROGrammes

int x = 0;            // Indice mémoires INTRO
int y = 0;            // Compteur pour lecture contenu EEPROM

bool demcr1 = false;    // Pour compte à rebours PROGramme 1
bool demcr2 = false;    // Pour compte à rebours PROGramme 2
bool demcr3 = false;    // Pour compte à rebours PROGramme 3
bool demcr4 = false;    // Pour compte à rebours PROGramme 4
bool buzer = false;     // Pour activation du buzer
bool mode_intro = false;  // Pour passage en mode INTRO/MODIF des valeurs EEPROM
bool premier_cycle = true;   // Premier cycle à la mise sous tension pour avoir des valeur cohérentes dans l'EEPROM

int mem[32];          // ARRAY pour lecture EEPROM
                      // Pour les 4 programmes
                      // index 0, 8, 16, 24 (temps de pétrissage)
                      // index 2, 10, 18, 26 (temps de levée 1)
                      // index 4, 12, 20, 28 (temps de levée 2)
                      // index 6, 14, 22, 30 (temps de cuisson)
long attente[3];        // Attente entre programmes
long attentestart = 0;
long attentemaintenant = 0;
long progattente;     // Contiendra le temps d'attente pour le prog suivant
                      // si nombre prog > 1
int nombreprog = 1;   // Nombre de programme(s) à faire (minimum 1)

long temps_ms;        // Durée départ pour compte à rebours

String etape[4];      // Etape en cours programmes (pétrir, levée1, levée2, cuisson)
String etapetst;

String progr;                      // Programme en cours pour ode intro


void setup() {


  Serial.begin(115200);
  display.begin(&Adafruit128x64, 0x3C);
  display.setFont(System5x7);
//  display.setFont(Callibri10);

  // Définition des I/O
  pinMode(ledpin,OUTPUT);
  pinMode(3,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(4,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(5,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(6,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(7,INPUT_PULLUP);   // PULLUP permet de cabler sans utiliser une résistance. 
  pinMode(buzerpin,OUTPUT);
  pinMode(ledpin1,OUTPUT);
  pinMode(ledpin2,OUTPUT);
  pinMode(ledpin3,OUTPUT);
  pinMode(ledpin4,OUTPUT);

  // Initialisation moniteur série
  Serial.begin(9600);
  
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

//    Lecture EEPROM

  for(y = 0; y < 32; y += 2)   //LECTURE contenu EEPROM des 16 premières positions (0->30)un int prend 2 octets en EEPROM
  { 
    EEPROM.get(y,mem[y]);
    Serial.print("Position: ");
    Serial.print(y);
    Serial.print("     ");
    Serial.println(mem[y]);
  }
  if(mem[0] < 0)
  {
    Serial.println("Mémoires vides, mode intro");
    intro();
  }else{
        Serial.println("Lecture terminée");
  }

  tempsattente();
    
}

void loop() {


// Intro nombre de programme(s) à faire (minimum 1)

  if(premier_cycle == true)   // Test premier cycle machine
  {
    while(bp5 == LOW && bp5mem == LOW)   // Flanc montant
    {
      majio();
      display.set2X();
      display.setCursor(0,2);
      display.print("Nbre prog: ");
      display.setCursor(60,5);
      display.print(nombreprog);
      if(bp2 == HIGH && bp2mem == LOW)   // Flanc montant
      {
        if(nombreprog < 4)
        {
          nombreprog++;
        }
        bp2mem = bp2;
      }
      bp2mem = bp2;
      if(bp4 == HIGH && bp4mem == LOW)   // Flanc montant
      {
        if(nombreprog > 1)
        {
          nombreprog--;
        }
        bp4mem = bp4;
      }
      bp4mem = bp4;
    }
    Serial.print(" Nombre de prog: ");
    Serial.println(nombreprog);
    affich_prog(); // Affichage des 4 programmes
  }
  majio();        // Mise à jour des I/O
  
  /*
   *          LANCEMENT PROGRAMME 1
   */
   
  if (bp1 == HIGH && bp1mem == LOW)                          // Flanc montant
  { 
      Serial.println(" Programme 1  ");
      if (bp1 == HIGH && cptbp1 <= 4 && demcr1 == false)
      {
        demcr1 = true;                                       // Démarrage compte à rebours
        cptbp1 += 1;
        if(cptbp1 == 3 && mem[4] == 0)
        {
          cptbp1 += 1;
        }
        start1 = millis();
        if(cptbp1 == 2 && nombreprog > 1)
        {
          attentestart = millis();
          progattente = attente[0];
        }
      }
  }
  bp1mem = bp1;

  /*
   *          LANCEMENT PROGRAMME 2
   */

  if (bp2 == HIGH && bp2mem == LOW)                           // Flanc montant
  { 
      Serial.println(" Programme 2");
      if (bp2 == HIGH && cptbp2 <= 4 && demcr2 == false)
      {
        demcr2 = true;                                       // Démarrage compte à rebours
        cptbp2 += 1;  
        if(cptbp2 == 3 && mem[12] == 0)
        {
          cptbp2 += 1;
        }
        start2 = millis();  
        if(cptbp2 == 2 && nombreprog > 1)
        {
          attentestart = millis();
          progattente = attente[1];
        }
      }
  }
  bp2mem = bp2;

  /*
   *          LANCEMENT PROGRAMME 3 
  */
 
  if (bp3 == HIGH && bp3mem == LOW)                           // Flanc montant
  { 
      Serial.println(" Programme 3");
      if (bp3 == HIGH && cptbp3 <= 4 && demcr3 == false)
      {
        demcr3 = true;                                       // Démarrage compte à rebours
        cptbp3 += 1;  
        if(cptbp3 == 3 && mem[20] == 0)
        {
          cptbp3 += 1;
        }
        if(cptbp3 == 2 && nombreprog > 1)
        {
          attentestart = millis();
          progattente = attente[2];
        }
        start3 = millis();  
      }
  }
  bp3mem = bp3;

  /*
   *          LANCEMENT PROGRAMME 4 
   */
   
  if (bp4 == HIGH && bp4mem == LOW)                          // Flanc montant
  { 
      Serial.println(" Programme 4");
      if (bp4 == HIGH && cptbp4 <= 4 && demcr4 == false)
      {
        demcr4 = true;                                       // Démarrage compte à rebours
        cptbp4 += 1;  
        if(cptbp4 == 3 && mem[28] == 0)
        {
          cptbp4 += 1;
        }
        start4 = millis();  
      }
  }
  bp4mem = bp4;

  //
  //        Attente pour lancer le programme suivant
  //

  if(attentestart > 0)
  {
    attentemaintenant = millis();
    if((attentemaintenant - attentestart) >= progattente)
    {
      tone(buzerpin, 2000, 5000);
      attentestart = 0;
      attentemaintenant = 0;
    }
  }

  // PROGRAMME 1

  if (demcr1 == true)
  {
    switch (cptbp1)
    {
      case 1:
          etape[0] = "Petr: ";
          temps_ms = mem[0] * 60000;
          compte_a_rebours_1();
          break;
      case 2:
          etape[0] = "Lev1: ";
          temps_ms = mem[2] * 60000;
          compte_a_rebours_1();
          break;
      case 3:
          etape[0] = "Lev2: ";
          temps_ms = mem[4] * 60000;
          compte_a_rebours_1();
          break;
      case 4:
          etape[0] = "Cuis: ";
          temps_ms = mem[6] * 60000;
          compte_a_rebours_1();
          break;
      default:
          break;
                  
    }
  }


  // PROGRAMME 2

  if (demcr2 == true)
  {
    switch (cptbp2)
    {
      case 1:
          etape[1] = "Petr: ";
          temps_ms = mem[8] * 60000;
          compte_a_rebours_2();
          break;
      case 2:
          etape[1] = "Lev1: ";
          temps_ms = mem[10] * 60000;
          compte_a_rebours_2();
          break;
      case 3:
          etape[1] = "Lev2: ";
          temps_ms = mem[12] * 60000;
          compte_a_rebours_2();
          break;
      case 4:
          etape[1] = "Cuis: ";
          temps_ms = mem[14] * 60000;
          compte_a_rebours_2();
          break;
      default:
          break;
                  
    }
  }


  // PROGRAMME 3

  if (demcr3 == true)
  {
    switch (cptbp3)
    {
      case 1:
          etape[2] = "Petr: ";
          temps_ms = mem[16] * 60000;
          compte_a_rebours_3();
          break;
      case 2:
          etape[2] = "Lev1: ";
          temps_ms = mem[18] * 60000;
          compte_a_rebours_3();
          break;
      case 3:
          etape[2] = "Lev2: ";
          temps_ms = mem[20] * 60000;
          compte_a_rebours_3();
          break;
      case 4:
          etape[2] = "Cuis: ";
          temps_ms = mem[22] * 60000;
          compte_a_rebours_3();
          break;
      default:
          break;
                  
    }
  }
  

  // PROGRAMME 4

  if (demcr4 == true)
  {
    switch (cptbp4)
    {
      case 1:
          etape[3] = "Petr: ";
          temps_ms = mem[24] * 60000;
          compte_a_rebours_4();
          break;
      case 2:
          etape[3] = "Lev1: ";
          temps_ms = mem[26] * 60000;
          compte_a_rebours_4();
          break;
      case 3:
          etape[3] = "Lev2: ";
          temps_ms = mem[28] * 60000;
          compte_a_rebours_4();
          break;
      case 4:
          etape[3] = "Cuis: ";
          temps_ms = mem[30] * 60000;
          compte_a_rebours_4();
          break;
      default:
          break;
                  
    }
  }


// Acquittement du buzer
  if (bp5 == HIGH && buzer == true)
  {
    noTone(buzerpin);
    buzer = false;
   }
  if(bp5 == HIGH && cptbp1 == 0) digitalWrite(ledpin1, LOW);
  if(bp5 == HIGH && cptbp2 == 0) digitalWrite(ledpin2, LOW);
  if(bp5 == HIGH && cptbp3 == 0) digitalWrite(ledpin3, LOW);
  if(bp5 == HIGH && cptbp4 == 0) digitalWrite(ledpin4, LOW);

   
// Entrée en mode INTRO

    if(bp5 == HIGH && cptbp1 ==0 && cptbp2 == 0 && cptbp3 == 0 && cptbp4 == 0)
    {
      tempsintro ++;
    }else{
          if(bp5 == LOW && tempsintro < 1000)
         {
          tempsintro = 0;
         }
    }
    
    if(bp5 == HIGH && (tempsintro > 50000))
    {
     mode_intro = true;
     tempsintro = 0;
    }
    if(mode_intro == true)
    {
      intro();
    }

//      Affichage des programme et temps restants

  if(demcr1 == true || demcr2 == true || demcr3 == true || demcr4 == true)
  {
  int cptj = 0;
  for(int cpti = 0; cpti <= 3; cpti++)
  {
  display.setCursor(8,cptj);
  display.print(etape[cpti]);
  display.print(minutes[cpti]);
  display.print(" min ");
  display.print(secondes[cpti]);
  display.print(" sec         ");
  cptj += 2;    
  }
  }
  
  premier_cycle = false;    // Fin du premier cycle machine cycle exécuté

}

void majio(void)
{
    // Lecture des entrées


  bp1 = !digitalRead(3);  // En mode PULLUP, les entrées logiques sont inversées:
  bp2 = !digitalRead(4);  //   Si bouton poussoir enfoncé, O (LOW)
  bp3 = !digitalRead(5);  //   Si bouton poussoir relaché, 1 (HIGH)
  bp4 = !digitalRead(6);  // Il faut donc inverser les valeurs lues.
  bp5 = !digitalRead(7);  
}

void conversion_1(void)
{
  minutes[0] =  temps1 / 1000 / 60;
  secondes[0] = (temps1 / 1000) - (minutes[0] * 60);
  if (cptbp1 == 4 && demcr1 == false)
  {
    cptbp1 = 0;
  }
}

void conversion_2(void)
{
  minutes[1] =  temps2 / 1000 / 60;
  secondes[1] = (temps2 / 1000) - (minutes[1] * 60);
  if (cptbp2 == 4 && demcr2 == false)
  {
    cptbp2 = 0;
  }
}
void conversion_3(void)
{
  minutes[2] =  temps3 / 1000 / 60;
  secondes[2] = (temps3 / 1000) - (minutes[2] * 60);
  if (cptbp3 == 4 && demcr3 == false)
  {
    cptbp3 = 0;
  }
}
void conversion_4(void)
{
  minutes[3] =  temps4 / 1000 / 60;
  secondes[3] = (temps4 / 1000) - (minutes[3] * 60);
  if (cptbp4 == 4 && demcr4 == false)
  {
    cptbp4 = 0;
  }
}


void compte_a_rebours_1(void)
{
  digitalWrite(ledpin1, LOW);
  long temps_restant = temps_ms - (millis() - start1);
  temps1 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr1 == true)
    {
      tone(buzerpin,1500);
      digitalWrite(ledpin1,HIGH);
      buzer = true;
    }
    demcr1 = false;    
  }
  conversion_1();
}

void compte_a_rebours_2(void)
{
  digitalWrite(ledpin2, LOW);
  long temps_restant = temps_ms - (millis() - start2);
  temps2 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr2 == true)
    {
      tone(buzerpin,1500);
      digitalWrite(ledpin2,HIGH);
      buzer = true;
    }
    demcr2 = false;
  }
  conversion_2();
}
void compte_a_rebours_3(void)
{
  digitalWrite(ledpin3, LOW);
  long temps_restant = temps_ms - (millis() - start3);
  temps3 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr3 == true)
    {
      tone(buzerpin,1500);
       digitalWrite(ledpin3,HIGH);
      buzer = true;
    }
    demcr3 = false;
  }
  conversion_3();
}
void compte_a_rebours_4(void)
{
  digitalWrite(ledpin4, LOW);
  long temps_restant = temps_ms - (millis() - start4);
  temps4 = temps_restant;
  if (temps_restant <= 0)
  {
    if (demcr4 == true)
    {
      tone(buzerpin,1500);
      digitalWrite(ledpin4,HIGH);
      buzer = true;
    }
    demcr4 = false;
  }
  conversion_4();
}


void intro(void)
{
  bool maj = false;       // Pour écriture en EEPROM si INTRO/MODIF du contenu EEPROM
  
  display.set2X();    
  display.clear();
  display.setCursor(0,2);
  display.print("Mode INTRO");
  delay(2000);
  display.clear();
  x = 0;
  
  while(x < 32)
  {
    if(x <= 6)
    {
      digitalWrite(ledpin1, HIGH);
    }
    if(x >= 8 && x <= 14)
    {
      digitalWrite(ledpin1, LOW);
      digitalWrite(ledpin2, HIGH);
    }
    if(x >= 16 && x <= 22)
    {
      digitalWrite(ledpin2, LOW);
      digitalWrite(ledpin3, HIGH);
    }
    if(x >= 24 && x <= 30)
    {
      digitalWrite(ledpin3, LOW);
      digitalWrite(ledpin4, HIGH);
    }    
   test_etape();
   affichmodif();
   majio();


      if(bp1 == HIGH && bp1mem == LOW)   // Flanc montant
      {
          if(mem[x] < 89)
          {
            mem[x] += 10;
            maj = true;
          }
          test_etape();
      }
      bp1mem = bp1;
      
      if(bp2 == HIGH && bp2mem == LOW)   // Flanc montant
      {
          if(mem[x] < 99)
          {
            mem[x] += 1;
            maj = true;
          }
          test_etape();
       }
      bp2mem = bp2;
      
      if(bp3 == HIGH && bp3mem == LOW)   // Flanc montant
      {
          if(mem[x] >= 11)
          {
            mem[x] -= 10;
            maj = true;
          }
          test_etape();
      }
      bp3mem = bp3;

      if(bp4 == HIGH && bp4mem == LOW)   // Flanc montant
      {
          if(mem[x] > 0)
          {
            mem[x] -= 1;
            maj = true;
          }
          test_etape();
      }
      bp4mem = bp4;
      
      if(maj)
      {
        affichmodif();
      }
      
      if(bp5 == HIGH && bp5mem == LOW)   // Flanc montant
      {
          if(maj == true)
          {
          EEPROM.put(x,mem[x]);
          maj = false;
          }
          x += 2;
      }
      bp5mem = bp5;
      
  } 
  digitalWrite(ledpin4, LOW);
//  display.setTextSize(2);    
//  display.clearDisplay();
//  display.setCursor(0,12);
//  display.print(" FIN INTRO");
//  display.display();

  display.set2X();    
  display.setCursor(0,0);
  display.clearField(0, display.displayWidth(),3);
  display.setCursor(0,3);
  display.print(" FIN INTRO");

  delay(5000);

  tempsattente();
  affich_prog();

  mode_intro = false;
}


void test_etape(void)
{
  switch (x)
  {
    case 0:
      progr = ("PROG1: ");
      etapetst = "Petr: ";
      break;
    case 2:
      progr = ("PROG1: ");
      etapetst = "Lev1: ";
      break;
    case 4:
      progr = ("PROG1: ");
      etapetst = "Lev2: ";
      break;
    case 6:
      progr = ("PROG1: ");
      etapetst = "Cuis: ";
      break;
    case 8:
      progr = ("PROG2: ");
      etapetst = "Petr: ";
      break;
    case 10:
      progr = ("PROG2: ");
      etapetst = "Lev1: ";
      break;
    case 12:
      progr = ("PROG2: ");
      etapetst = "Lev2: ";
      break;
    case 14:
      progr = ("PROG2: ");
      etapetst = "Cuis: ";
      break;
    case 16:
      progr = ("PROG3: ");
      etapetst = "Petr: ";
      break;
    case 18:
      progr = ("PROG3: ");
      etapetst = "Lev1: ";
      break;
    case 20:
      progr = ("PROG3: ");
      etapetst = "Lev2: ";
      break;
    case 22:
      progr = ("PROG3: ");
      etapetst = "Cuis: ";
      break;
    case 24:
      progr = ("PROG4: ");
      etapetst = "Petr: ";
      break;
    case 26:
      progr = ("PROG4: ");
      etapetst = "Lev1: ";
      break;
    case 28:
      progr = ("PROG4: ");
      etapetst = "Lev2: ";
      break;
    case 30:
      progr = ("PROG4: ");
      etapetst = "Cuis: ";
      break;
  }
}

void affich_prog(void)
{
  //////  Affichage des valeurs de temporisation des quatres programmes disponibles.
  
  display.set1X();
  display.setCursor(0,0);
  display.clear();
  int ligne;
  int cpti = 0;
  int cptj = 0;
  int cptk = 0;

  for(cpti = 1; cpti <= 4; cpti ++)
  {
  switch(cptk)
  {
    case 0:
      ligne = 0;
      break;
    case 8:
      ligne = 2;
      break;
    case 16:
      ligne = 4;
      break;
    case 24:
      ligne = 6;
      break;
    default:
      break;
  }
    display.setCursor(0,ligne);
    display.print("  PROG");
    display.print(cpti);
    display.print(": ");
    for(cptj == ligne; cptj <= (cptk + 6); cptj += 2)
    {
      display.print(mem[cptj]);
      display.print(" ");
    }
      if(cptk <= 30)
        {
          cptk +=8;
        }
  }
}

void affichmodif(void)
{
          display.set1X();
          display.setCursor(16,3);
          display.print(progr);
          display.print(" ");
          display.print(etapetst);
          display.print(" ");
          display.print(mem[x]);
          display.print("  ");
}

void tempsattente(void)
{
            // Chargerment des attentes inter-programmes

  attente[0] = (mem[6] - 10) * 60000;   // Attente lancement prog 2 en ms
  attente[1] = (mem[14] - 10) * 60000;  // Attente lancement prog 3 en ms
  attente[2] = (mem[22] - 10) * 60000;  // Attente lancement prog 4 en ms

}

L'adaptation a été rapide !
L'inconvénient de la librairie Greiman est l'absence de routines graphiques et de positionnement au pixel près en Y.
Je ne connais pas les deux autres.
Bonne découverte @+

Bonsoir,
il est vrai que la librairie est succincte par rapport à ce que j'avais vu et testé de la librairie Adafruit, mais pour ce que je voulais faire, c'était plus que suffisant. D'autant plus que je tenais à l'utilisation du nano car le tout doit tenir dans un petit boitier (ça doit être portable).
Merci, à bientôt.