Completement perdu .. help (pointeur sur c-string)

Mon but ... stocker sur une carte SD le SSID et le mot de passe de ma connexion WIFI
Par exemple : toto et 70

La récuperation par :
P10 = strtok(buf,";"); // SSID
P11 = strtok(NULL,";"); // mot de passe
se fait correctement et le moniteur affiche bien : toto et 70

Les declarations sont : char *P10; et char *P11;

Probleme:
si je lance Wifi.begin( "toto","70"); la connexion fonctionne
Mais si je lance Wifi.begin(P10,P11); la connexion ne se fait pas
Les guillemets semble importants dirait-on?

J'ai essayé de placer les guillemets dans mon fichier excel "toto" et "70" mais après récupération, mon moniteur m'indique P10 = """toto""" et P11 = """70""" et ma connexion ne se fait donc pas

Je ne sais pas comment faire pour ajouter une seule paire de guillemets à mon P10 et P11 récupérés

ils le sont à la compilation, pour dire une c'est une c-string. Donc pas nécessaire (ils disparaissent à la compilation, c'est un pointeur qui est passé à la fonction vers une zone mémoire qui contient le texte sans guillemets)

quand vous faites

P10 et P11 sont des pointeurs qui pointent vers buf
si buf n'est plus en mémoire quand vous faites Wifi.begin(P10,P11); alors c'est normal que ça ne fonctionne pas.

donc ici il ne faut pas faire ça, mais si vous voulez mettre des guillemets dans une chaine, il faut faire un échappement avec \

const char toto[]  ="un guillemet ici => \" et celui là c'est la fin de chaîne. =>";

Ils sont importants si tu en as dans ton SSID ou dans ton mot de passe.

C'est peut-être ça le problème mais comme tu ne donnes qu'un petit bout de programme sorti de son contexte on ne peut pas t'aider plus.

Hello,
:thinking::innocent:peut être mettre un titre plus explicite :joy:

donc ici il ne faut pas faire ça, mais si vous voulez mettre des guillemets dans une chaine, il faut faire un échappement avec \

const char toto[]  ="un guillemet ici => \" et celui là c'est la fin de chaîne. =>";

Je n'ai pas compris ...

Dans ma table excel toto et 70 sont sans guillemets
Lorsque je les extraits, ils sont sans guillemets P10= toto et P11=70

Mais dans arduino Wifi.begin ne fonctionne que si toto et 70 sont entre guillemets c-a-d Wifi.begin ("toto","70");

Par conséquent, il faut que je rajoute des guillements aux P10 et P11 extraits du CSV pour que Wifi.begin fonctionne

Je ne comprends pas ce que tu veux que j'écrives?

Non il ne faut aucun guillemet dans la représentation en mémoire (s’ils ne font pas partie du texte bien sûr)

Postez tout le code

Si buf n’est plus dans le scope les pointeurs ne veulent plus rien dire

Non, on peut passer en argument:

  • soit une constante "ceci est une chaine"
  • soit une variable contenant une chaine de caractères.
    Si tu initialises ta variable avec une constante
    char maChaine[5] = "toto";
    La représentation de la chaîne en mémoire sera
    toto0
    0 indiquant la fin de la chaîne.
    Si tu remplis ta variable par programme (en l'extrayant d'un fichier par exemple). Tu vas écrire dans la variable toto. Suivant comment tu gères le remplissage de la variable soit tu ajouteras le 0 final soit ce sera fait automatiquement (par des instruction de manipulation de chaîne de caractères)

Ici il utilise strtok() pour le parsing

donc le caractère nul de fin de chaîne est bien mis par la fonction.

A mon avis, Soit le parsing est faux soit buf n’est plus dans le scope au moment de l’utilisation des pointeurs..

Sans le code difficile d’aider …

Il pourrait imprimer P10 et P11 (noms de variables inadaptés) pour voir réellement ce qui est passé en paramètres

Voici le code à l'état brut ...

// VERSION 11 octobre AVEC ANNIVERSAIRES

// --------------- besoins pour affichage anniversaires
#include <SD.h>
#include <SPI.h>

File fichierAniv;
File fichierSSID;

static char buf[50];
int i;
int c;
int ligne = 0;

char *p1;  // prenom
char *p2;  // nom
char *p3;  // jour
char *p4;  // mois
char *p5;  // année

char *p10;  // SSISD
char *p11;  // mot de passe

char *SSID;
char *MP;

// --------------- besoins pour affichage horloge
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

int ledWIFI = 0;
int ledSD = 2;

#define SCREEN_WIDTH 128   // OLED display width, in pixels
#define SCREEN_HEIGHT 64   // OLED display height, in pixels
#define OLED_RESET -1      // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define Oled_ADDRESS 0x3C  // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)

Adafruit_SSD1306 ecranOLED(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);  // initialisation de l'écran avec le nom ecranOLED (à choisir)

//---------------- choix des polices
// Fonts est le nom du dossier dans lequel se trouvent tous les fonts de la bibliotheque Adafruit_GFX
#include <Fonts/FreeSans6pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSansBold12pt7b.h>

//---------------- besoins pour WIFI
#include <ESP8266WiFi.h>
const char *ssid = p10;
const char *password = p11;
int y;
String BUFFER_H;

//----------------- besoins pour internet
#include <EasyNTPClient.h>
#include <WiFiUdp.h>
#include <Timezone.h>

//------------------ besoins pour extraction données hors du WiFi
WiFiUDP Udp_G;                                                                    // Objet UDP permettant d'envoyer et recevoir des trames Wi-Fi selon le protocole UDP
EasyNTPClient ClientNtp_G(Udp_G, "pool.ntp.org");                                 // Objet NTP synchronisé avec "pool.ntp.org"
TimeChangeRule RegleHeureEteFrance_G = { "RHEE", Last, Sun, Mar, 2, 120 };        // Règle de passage à l'heure d'été pour la France
TimeChangeRule RegleHeureHiverFrance_G = { "RHHE", Last, Sun, Oct, 3, 60 };       // Règle de passage à l'heure d'hiver la France
Timezone ConvertirHeureFrance_G(RegleHeureEteFrance_G, RegleHeureHiverFrance_G);  // Objet de conversion d'heure avec les caractéristique de la métropole française


//------------------- matrice du logo Wifi
const unsigned char logoWIFI[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00,
  0x3f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf8,
  0x00, 0x7f, 0xc0, 0x1f, 0xc0, 0x00, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x03, 0xf0, 0x7e, 0x03, 0xff,
  0x01, 0xf8, 0x78, 0x1f, 0xff, 0xe0, 0x78, 0x70, 0x7f, 0xff, 0xf8, 0x38, 0x00, 0xff, 0xff, 0xfc,
  0x00, 0x01, 0xfc, 0x00, 0xfe, 0x00, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x03, 0xc0, 0x00, 0x0f, 0x00,
  0x03, 0x80, 0x38, 0x07, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00,
  0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0x87, 0xe0, 0x00, 0x00, 0x1e, 0x01, 0xe0, 0x00, 0x00, 0x08,
  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc,
  0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };


  void setup() {  // exécuté 1 fois

    // =========== PARTIE NECESSAIRE POUR HORLOGE ==============

    pinMode(ledWIFI, OUTPUT);
    pinMode(ledSD, OUTPUT);
    digitalWrite(ledWIFI, LOW);
    digitalWrite(ledSD, LOW);

   Serial.begin(115200);
   Wire.begin(4, 5);
   sprintf(SSID, """,P10,""");
   sprintf(MP, """,P11,""");
   WiFi.begin(SSID, MP);

   // --- initialisation oled
   ecranOLED.begin(SSD1306_SWITCHCAPVCC, Oled_ADDRESS);  // initialize with the  I2C addr 0x3C
   ecranOLED.clearDisplay();                             // Vidange du buffer de   l'écran OLED


    // ========== PARTIE NECESSAIRE POUR ANNIVERSAIRES ===========

    SPI.pins(14, 12, 13, 15);  // SCK, MISO, MOSI, CS

    // Ouverture du port série
   Serial.begin(115200);
    while (!Serial) {};

    // Initialisation de la carte SD------------------------------
   Serial.print("Initialisation de la carte SD ...");

    if (!SD.begin(15)) {
    Serial.println("initialisation echouee !");
    digitalWrite(ledSD, LOW);
    return;
    }
    Serial.println("initialisation reussie.");
    digitalWrite(ledSD, HIGH);


    //Ouverture du fichier csv anniversaires -----------------------------------
    fichierAniv = SD.open("anniv.csv", FILE_READ);

    //Lecture du fichier csv anniversaires -------------------------------------
    while (fichierAniv.available()) {
    for (i = 0; fichierAniv.available() && i < sizeof buf - 1; i++) {
      buf[i] = fichierAniv.read();
      if (buf[i] == '*')
        break;  // fin de ligne
    }
    buf[i] = 0;  // fin de la chaine

    //-séparation des données d'une ligne (ici 5 données max)-------------
    p1 = strtok(buf, ";") ;  // prenom
    p2 = strtok(NULL, ";");  // nom
    p3 = strtok(NULL, ";");  // jour
    p4 = strtok(NULL, ";");  // mois
    p5 = strtok(NULL, ";");  // années

    //passage à la ligne suivante ----------------------------------
    ligne++;

    //--Verification de la lecture et du découpage anniversairees --------------

    Serial.print(p1);
    Serial.print(" ");
    Serial.print(p2);
    Serial.print(" ");
    Serial.print(p3);
    Serial.print(" ");
    Serial.print(p4);
    Serial.print(" ");
    Serial.print(p5);
    Serial.println("");
  
    }
    //Ouverture du fichier csv SSID -----------------------------------
    fichierSSID = SD.open("SSID.csv", FILE_READ);

    //Lecture du fichier csv SSID ------------------------------------
    while (fichierSSID.available()) {
      for (i = 0; fichierSSID.available() && i < sizeof buf - 1; i++) {
        buf[i] = fichierSSID.read();
        if (buf[i] == '*')
          break;  // fin de ligne
      }
      buf[i] = 0;  // fin de la chaine

      //-séparation des données d'une ligne (ici 5 données max)-------------
      p10 = strtok(buf, ";");   // SSID
      p11 = strtok(NULL, ";");  // mot de passe

      //--Verification de la lecture et du découpage SSID --------------


      Serial.print(p10);
      Serial.print(" ");
      Serial.print(p11);
      Serial.println("");

       //---- attente signal WiFi
   unsigned long chrono = millis();  // remplace la fonction delai
    while (millis() - chrono < 3000) yield();
    while (WiFi.status() != WL_CONNECTED) {
    affichagelogoWifi();  // appel sous-programme affichage logowifi clignotant
    }
    digitalWrite(ledWIFI, HIGH);


      /*
      // ---- detection si date d'anniversaire
      f (AbreviationJour_L[weekday(Heure_P) - 1] = P3) &(AbreviationMois_L[month(Heure_P) - 1] = p4) {
        Serial.println("anniversaire de Joseph");
      }
      */
    }
  }
  


  void loop() {  // executé à l'infini

    time_t HeureLocale_L;
    HeureLocale_L = ConvertirHeureFrance_G.toLocal(ClientNtp_G.getUnixTime());
    AfficherHeureLocale(HeureLocale_L);
  }

  //================ SOUS-PROGRAMME affichage logoWiFi
  void affichagelogoWifi(void) {

    //------------------ affichage logo WIFI
    //drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
    ecranOLED.drawBitmap(50, 20, logoWIFI, 38, 32, WHITE);  // dessin et position du logo placés dans le buffer
    ecranOLED.display();                                    // affichage sur l'écran du contenu du buffer
    unsigned long chrono = millis();
    //  chrono = millis();  // remplace la fonction delai
    while (millis() - chrono < 600) yield();  // durée logo visible

    //------------------ Extinction logo WIFI
    ecranOLED.clearDisplay();                 // dessin et position du logo placés dans le buffer
    ecranOLED.display();                      // affichage sur l'écran du contenu du buffer
    chrono = millis();                        // remplace la fonction delai
    while (millis() - chrono < 300) yield();  //durée logo éteint
  }

  //=================== SOUS PROGRAMME centrage textes
  void oledDisplayCenter(String text, int Y) {
    int16_t x1;
    int16_t y1;
    uint16_t width;
    uint16_t height;

    ecranOLED.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);  // extraction de la longueur width du texte
    ecranOLED.setCursor((SCREEN_WIDTH - width) / 2, Y);              // (largeur écran - longueur du texte) / 2 donne le point de départ du texte
  }

  //===================SOUS PROGRAMME positionnementà droite des textes
  void oledDisplayDroit(String text, int Y) {
    int16_t x1;
    int16_t y1;
    uint16_t longueur;
    uint16_t height;

    ecranOLED.getTextBounds(text, 0, 0, &x1, &y1, &longueur, &height);

    ecranOLED.setCursor((102 - longueur), Y);
    ecranOLED.print(text);  // text to display
  }


  // =============== SOUS PROGRAMME AFFICHAGE SUR ECRAN
  void AfficherHeureLocale(time_t Heure_P) {
    char BUFFER_H[50];
    char BUFFER_H1[50];
    char BUFFER_H2[50];
    char BUFFER_J[50];
    char BUFFER_D[50];
    char AbreviationMois_L[12][10] = { "Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre" };
    char AbreviationJour_L[7][10] = { "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" };

    //----- effacement buffer écran
    ecranOLED.clearDisplay();

    //------création buufer Date = texte affiché
    sprintf(BUFFER_D, "%s - %d", AbreviationMois_L[month(Heure_P) - 1], year(Heure_P));
    ecranOLED.setFont(&FreeSans6pt7b);  //mois, année = petits caractères
    ecranOLED.setTextColor(WHITE);
    oledDisplayCenter(BUFFER_D, 10);
    ecranOLED.print(BUFFER_D);

    //----- création buffer Jour = texte affiché
    sprintf(BUFFER_J, "%s %.2d", AbreviationJour_L[weekday(Heure_P) - 1], day(Heure_P));  // %.2d affiche (01) et %.d affiche ( 1)
    ecranOLED.setFont(&FreeSansBold9pt7b);                                                //jour et date = moyens caractères
    ecranOLED.setTextColor(WHITE);
    oledDisplayCenter(BUFFER_J, 30);
    ecranOLED.print(BUFFER_J);

    //----- création buffer heure-minutes = texte affiché
    sprintf(BUFFER_H1, "%d:%.2d", hour(Heure_P), minute(Heure_P));  // creation et remplissage de la variable "BUFFER_H"... %d
    ecranOLED.setFont(&FreeSansBold12pt7b);                         //heure et minutes = gros caracteres
    ecranOLED.setTextColor(WHITE);
    oledDisplayCenter(BUFFER_H1, 62);
    ecranOLED.print(BUFFER_H1);

    //----- création buffer seconde
    sprintf(BUFFER_H2, "%2d", second(Heure_P));  // creation et remplissage de la variable "BUFFER_H"
    ecranOLED.setFont(&FreeSans6pt7b);
    ecranOLED.setTextColor(WHITE);
    ecranOLED.setCursor(108, 62);
    ecranOLED.print(BUFFER_H2);

    //-------affichage buffer sur écran
    ecranOLED.display();
  }

de nombreuses choses à dire rien que sur

on utilise généralement sprintf quand on a besoin d'un format particulier avec des paramètres. pour copier une chaine on utilise strcpy() ou mieux strncpy() mais il faut pour cela bien sûr avoir de la place réservée à l'endroit où on écrit hors ici vous avez défini

char *SSID;
char *MP;

ce sont juste des pointeurs, il n'y a donc aucune mémoire allouée pour du contenu... vous allez écraser de la mémoire.


sur le contenu, le compilateur voit """,P10,""" sous. la forme suivante ➜ """,P10,""". c'est une notation autorisée pour concatèner de manière statique du texte et donc on a

une chaine vide ""
une chaine avec ",P10,"
une chaine vide ""

➜ il fabrique donc juste le texte ,P10,

si vous vouliez injecter les guillemets dans le texte (comme on l'a dit ce n'est pas nécessaire sauf si c'est vraiment dans le nom de votre SSID et mot de passe, il faudrait mettre un échappement avant le guillemet

la chaîne serait alors écrite sous cette forme "\"\",P10,\"\"" et conduirait au texte en mémoire "",P10,""


oupss .. mauvais code envoyé

Voici mon dernier code
Mais des précisions :
Mon SSID et mon MP familial n'ont pas de guillemets
Si dans Wifi.begin je ne mets pas de guillemets ça ne marche pas
La récupération de SSID et de MP de mon CSV n'a pas de guillemets

// VERSION 11 octobre AVEC ANNIVERSAIRES

// --------------- besoins pour affichage anniversaires
#include <SD.h>
#include <SPI.h>

File fichierAniv;
File fichierSSID;

static char buf[50];
int i;
int c;
int ligne = 0;

char *p1;  // prenom
char *p2;  // nom
char *p3;  // jour
char *p4;  // mois
char *p5;  // année

//String p10;  // SSISD
//String p11;  // mot de passe

char *SSID;
char *MP;

// --------------- besoins pour affichage horloge
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

int ledWIFI = 0;
int ledSD = 2;

#define SCREEN_WIDTH 128   // OLED display width, in pixels
#define SCREEN_HEIGHT 64   // OLED display height, in pixels
#define OLED_RESET -1      // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define Oled_ADDRESS 0x3C  // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)

Adafruit_SSD1306 ecranOLED(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);  // initialisation de l'écran avec le nom ecranOLED (à choisir)

//---------------- choix des polices
// Fonts est le nom du dossier dans lequel se trouvent tous les fonts de la bibliotheque Adafruit_GFX
#include <Fonts/FreeSans6pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSansBold12pt7b.h>

//---------------- besoins pour WIFI
#include <ESP8266WiFi.h>
//const char *ssid = p10;
//const char *password = p11;
int y;
String BUFFER_H;

//----------------- besoins pour internet
#include <EasyNTPClient.h>
#include <WiFiUdp.h>
#include <Timezone.h>

//------------------ besoins pour extraction données hors du WiFi
WiFiUDP Udp_G;                                                                    // Objet UDP permettant d'envoyer et recevoir des trames Wi-Fi selon le protocole UDP
EasyNTPClient ClientNtp_G(Udp_G, "pool.ntp.org");                                 // Objet NTP synchronisé avec "pool.ntp.org"
TimeChangeRule RegleHeureEteFrance_G = { "RHEE", Last, Sun, Mar, 2, 120 };        // Règle de passage à l'heure d'été pour la France
TimeChangeRule RegleHeureHiverFrance_G = { "RHHE", Last, Sun, Oct, 3, 60 };       // Règle de passage à l'heure d'hiver la France
Timezone ConvertirHeureFrance_G(RegleHeureEteFrance_G, RegleHeureHiverFrance_G);  // Objet de conversion d'heure avec les caractéristique de la métropole française


//------------------- matrice du logo Wifi
const unsigned char logoWIFI[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00,
  0x3f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf8,
  0x00, 0x7f, 0xc0, 0x1f, 0xc0, 0x00, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x03, 0xf0, 0x7e, 0x03, 0xff,
  0x01, 0xf8, 0x78, 0x1f, 0xff, 0xe0, 0x78, 0x70, 0x7f, 0xff, 0xf8, 0x38, 0x00, 0xff, 0xff, 0xfc,
  0x00, 0x01, 0xfc, 0x00, 0xfe, 0x00, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x03, 0xc0, 0x00, 0x0f, 0x00,
  0x03, 0x80, 0x38, 0x07, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00,
  0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0x87, 0xe0, 0x00, 0x00, 0x1e, 0x01, 0xe0, 0x00, 0x00, 0x08,
  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc,
  0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };


  void setup() {  // exécuté 1 fois

    // =========== PARTIE NECESSAIRE POUR HORLOGE ==============

    pinMode(ledWIFI, OUTPUT);
    pinMode(ledSD, OUTPUT);
    digitalWrite(ledWIFI, LOW);
    digitalWrite(ledSD, LOW);

   Serial.begin(115200);
   Wire.begin(4, 5);
   WiFi.begin(SSID, MP);

   // --- initialisation oled
   ecranOLED.begin(SSD1306_SWITCHCAPVCC, Oled_ADDRESS);  // initialize with the  I2C addr 0x3C
   ecranOLED.clearDisplay();                             // Vidange du buffer de   l'écran OLED


    // ========== PARTIE NECESSAIRE POUR ANNIVERSAIRES ===========

    SPI.pins(14, 12, 13, 15);  // SCK, MISO, MOSI, CS

    // Ouverture du port série
   Serial.begin(115200);
    while (!Serial) {};

    // Initialisation de la carte SD------------------------------
   Serial.print("Initialisation de la carte SD ...");

    if (!SD.begin(15)) {
    Serial.println("initialisation echouee !");
    digitalWrite(ledSD, LOW);
    return;
    }
    Serial.println("initialisation reussie.");
    digitalWrite(ledSD, HIGH);


    //Ouverture du fichier csv anniversaires -----------------------------------
    fichierAniv = SD.open("anniv.csv", FILE_READ);

    //Lecture du fichier csv anniversaires -------------------------------------
    while (fichierAniv.available()) {
    for (i = 0; fichierAniv.available() && i < sizeof buf - 1; i++) {
      buf[i] = fichierAniv.read();
      if (buf[i] == '*')
        break;  // fin de ligne
    }
    buf[i] = 0;  // fin de la chaine

    //-séparation des données d'une ligne (ici 5 données max)-------------
    p1 = strtok(buf, ";") ;  // prenom
    p2 = strtok(NULL, ";");  // nom
    p3 = strtok(NULL, ";");  // jour
    p4 = strtok(NULL, ";");  // mois
    p5 = strtok(NULL, ";");  // années

    //passage à la ligne suivante ----------------------------------
    ligne++;

    //--Verification de la lecture et du découpage anniversairees --------------

    Serial.print(p1);
    Serial.print(" ");
    Serial.print(p2);
    Serial.print(" ");
    Serial.print(p3);
    Serial.print(" ");
    Serial.print(p4);
    Serial.print(" ");
    Serial.print(p5);
    Serial.println("");
  
    }
    //Ouverture du fichier csv SSID -----------------------------------
    fichierSSID = SD.open("SSID.csv", FILE_READ);

    //Lecture du fichier csv SSID ------------------------------------
    while (fichierSSID.available()) {
      for (i = 0; fichierSSID.available() && i < sizeof buf - 1; i++) {
        buf[i] = fichierSSID.read();
        if (buf[i] == '*')
          break;  // fin de ligne
      }
      buf[i] = 0;  // fin de la chaine

      //-séparation des données d'une ligne (ici 5 données max)-------------
      SSID = strtok(buf, ";");   // SSID
      MP = strtok(NULL, ";");  // mot de passe

      //--Verification de la lecture et du découpage SSID --------------


      Serial.print(SSID);
      Serial.print(" ");
      Serial.print(MP);
      Serial.println("");

       //---- attente signal WiFi
   unsigned long chrono = millis();  // remplace la fonction delai
    while (millis() - chrono < 3000) yield();
    while (WiFi.status() != WL_CONNECTED) {
    affichagelogoWifi();  // appel sous-programme affichage logowifi clignotant
    }
    digitalWrite(ledWIFI, HIGH);


      /*
      // ---- detection si date d'anniversaire
      f (AbreviationJour_L[weekday(Heure_P) - 1] = P3) &(AbreviationMois_L[month(Heure_P) - 1] = p4) {
        Serial.println("anniversaire de Joseph");
      }
      */
    }
  }
  


  void loop() {  // executé à l'infini

    time_t HeureLocale_L;
    HeureLocale_L = ConvertirHeureFrance_G.toLocal(ClientNtp_G.getUnixTime());
    AfficherHeureLocale(HeureLocale_L);
  }

  //================ SOUS-PROGRAMME affichage logoWiFi
  void affichagelogoWifi(void) {

    //------------------ affichage logo WIFI
    //drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
    ecranOLED.drawBitmap(50, 20, logoWIFI, 38, 32, WHITE);  // dessin et position du logo placés dans le buffer
    ecranOLED.display();                                    // affichage sur l'écran du contenu du buffer
    unsigned long chrono = millis();
    //  chrono = millis();  // remplace la fonction delai
    while (millis() - chrono < 600) yield();  // durée logo visible

    //------------------ Extinction logo WIFI
    ecranOLED.clearDisplay();                 // dessin et position du logo placés dans le buffer
    ecranOLED.display();                      // affichage sur l'écran du contenu du buffer
    chrono = millis();                        // remplace la fonction delai
    while (millis() - chrono < 300) yield();  //durée logo éteint
  }

  //=================== SOUS PROGRAMME centrage textes
  void oledDisplayCenter(String text, int Y) {
    int16_t x1;
    int16_t y1;
    uint16_t width;
    uint16_t height;

    ecranOLED.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);  // extraction de la longueur width du texte
    ecranOLED.setCursor((SCREEN_WIDTH - width) / 2, Y);              // (largeur écran - longueur du texte) / 2 donne le point de départ du texte
  }

  //===================SOUS PROGRAMME positionnementà droite des textes
  void oledDisplayDroit(String text, int Y) {
    int16_t x1;
    int16_t y1;
    uint16_t longueur;
    uint16_t height;

    ecranOLED.getTextBounds(text, 0, 0, &x1, &y1, &longueur, &height);

    ecranOLED.setCursor((102 - longueur), Y);
    ecranOLED.print(text);  // text to display
  }


  // =============== SOUS PROGRAMME AFFICHAGE SUR ECRAN
  void AfficherHeureLocale(time_t Heure_P) {
    char BUFFER_H[50];
    char BUFFER_H1[50];
    char BUFFER_H2[50];
    char BUFFER_J[50];
    char BUFFER_D[50];
    char AbreviationMois_L[12][10] = { "Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre" };
    char AbreviationJour_L[7][10] = { "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" };

    //----- effacement buffer écran
    ecranOLED.clearDisplay();

    //------création buufer Date = texte affiché
    sprintf(BUFFER_D, "%s - %d", AbreviationMois_L[month(Heure_P) - 1], year(Heure_P));
    ecranOLED.setFont(&FreeSans6pt7b);  //mois, année = petits caractères
    ecranOLED.setTextColor(WHITE);
    oledDisplayCenter(BUFFER_D, 10);
    ecranOLED.print(BUFFER_D);

    //----- création buffer Jour = texte affiché
    sprintf(BUFFER_J, "%s %.2d", AbreviationJour_L[weekday(Heure_P) - 1], day(Heure_P));  // %.2d affiche (01) et %.d affiche ( 1)
    ecranOLED.setFont(&FreeSansBold9pt7b);                                                //jour et date = moyens caractères
    ecranOLED.setTextColor(WHITE);
    oledDisplayCenter(BUFFER_J, 30);
    ecranOLED.print(BUFFER_J);

    //----- création buffer heure-minutes = texte affiché
    sprintf(BUFFER_H1, "%d:%.2d", hour(Heure_P), minute(Heure_P));  // creation et remplissage de la variable "BUFFER_H"... %d
    ecranOLED.setFont(&FreeSansBold12pt7b);                         //heure et minutes = gros caracteres
    ecranOLED.setTextColor(WHITE);
    oledDisplayCenter(BUFFER_H1, 62);
    ecranOLED.print(BUFFER_H1);

    //----- création buffer seconde
    sprintf(BUFFER_H2, "%2d", second(Heure_P));  // creation et remplissage de la variable "BUFFER_H"
    ecranOLED.setFont(&FreeSans6pt7b);
    ecranOLED.setTextColor(WHITE);
    ecranOLED.setCursor(108, 62);
    ecranOLED.print(BUFFER_H2);

    //-------affichage buffer sur écran
    ecranOLED.display();
  }

Problème résolu ...

J'avais placé le Wifi.begin(SSID,MP); avant l'extraction des valeurs de SSID et MP
Replacée derrière cela fonctionne

vous allez avoir le problème de la mémoire écrasée car pas d'allocation mémoire pour les pointeurs

voici un exemple wokwi de comment faire avec une allocation "propre" de la mémoire et la lecture dans des structures et tableau des données du fichier (sans traiter les erreurs de format)

le code
#include <SD.h>
#define CS_PIN 10

const char * nomFichierConfigWifi = "SSID.csv";
const char * nomFichierConfigAnniversaires = "anniv.csv";

const size_t nbMaxAnniversaires = 10;
const size_t tailleMaxChaine = 20;

struct Anniversaire {
  bool actif;
  char nom[tailleMaxChaine + 1];
  char prenom[tailleMaxChaine + 1];
  uint8_t jour;
  uint8_t mois;
  uint16_t annee;
};

// tableau de toutes les dates
Anniversaire lesAnniversaires[nbMaxAnniversaires];

struct ConfigWifi {
  char SSID[33];
  char PWD[tailleMaxChaine];
};

// on en a besoin que d'une seule
ConfigWifi configuration;

// un buffer général pour la lecture de lignes
const size_t tailleBufferTemporaire = 80;
char tmpBuf[tailleBufferTemporaire + 1]; // +1 pour le caractère nul de fin

void setup() {
  Serial.begin(115200);

  if (!SD.begin(CS_PIN)) {
    Serial.println("Impossible de trouver la carte SD!");
    while (true);
  }
  Serial.println("carte SD OK.");


  // lecture du fichier de confifg WIFI:
  File fichier = SD.open(nomFichierConfigWifi, FILE_READ);
  if (fichier) {
    size_t posLigne = 0;
    while (fichier.available()) {
      char r = fichier.read();
      if ((r != '\r') && (r != '\n'))  {  // on ignore la fin de ligne car c'est l'étoile qui compte
        if (r == '*') break;            // c'est le caractère de fin, on termine ici
        else if (posLigne < tailleBufferTemporaire) tmpBuf[posLigne++] = r;
      }
    }
    fichier.close();
    tmpBuf[posLigne] = '\0'; // on marque la fin de chaîne
    Serial.print(F("ligne lue : ["));
    Serial.print(tmpBuf);
    Serial.println(F("]"));

    // parsing sans gestion des erreurs
    char * ptr = strtok(tmpBuf, ";");
    snprintf(configuration.SSID, sizeof configuration.SSID, "%s", ptr); // https://cplusplus.com/reference/cstdio/snprintf/
    ptr = strtok(nullptr, ";");
    snprintf(configuration.PWD, sizeof configuration.PWD, "%s", ptr);
    Serial.println(F("l'analyse de la ligne donne :"));
    Serial.print(F("\tSSID : [")); Serial.print(configuration.SSID); Serial.println(F("]"));
    Serial.print(F("\tPWD : [")); Serial.print(configuration.PWD); Serial.println(F("]"));

  } else {
    Serial.print(F("Erreur : Impossible de lire "));
    Serial.println(nomFichierConfigWifi);
  }


  Serial.println(F("-------------------------------------"));


  // gestion du fichier des anniversaires

  // on commence par initialiser le tableau
  for (size_t i = 0; i < nbMaxAnniversaires; i++) {
    lesAnniversaires[i].actif = false; // on pourrait se contenter de cette ligne mais je préfère tout nettoyer
    lesAnniversaires[i].nom[0]    = '\0';
    lesAnniversaires[i].prenom[0] = '\0';
    lesAnniversaires[i].jour      = 0;
    lesAnniversaires[i].mois      = 0;
    lesAnniversaires[i].annee     = 0;
  }

  // on lit le fichier ligne par ligne et on remplit le tableau
  fichier = SD.open(nomFichierConfigAnniversaires, FILE_READ);
  if (fichier) {
    size_t nbAnniversaires = 0;

    while (nbAnniversaires < nbMaxAnniversaires) {
      size_t posLigne = 0;
      while (fichier.available()) {
        char r = fichier.read();
        if ((r != '\r') && (r != '\n'))  {  // on ignore la fin de ligne car c'est l'étoile qui compte
          if (r == '*') break;            // c'est le caractère de fin, on termine ici
          else if (posLigne < tailleBufferTemporaire) tmpBuf[posLigne++] = r;
        }
      }
      tmpBuf[posLigne] = '\0'; // on marque la fin de chaîne


      if (posLigne != 0) {
        // on a lu quelque chose
        Serial.print(F("ligne lue : ["));
        Serial.print(tmpBuf);
        Serial.println(F("]"));

        // parsing sans gestion des erreurs
        lesAnniversaires[nbAnniversaires].actif = true;
        char * ptr = strtok(tmpBuf, ";");
        snprintf(lesAnniversaires[nbAnniversaires].nom, sizeof lesAnniversaires[nbAnniversaires].nom, "%s", ptr); // https://cplusplus.com/reference/cstdio/snprintf/
        ptr = strtok(nullptr, ";");
        snprintf(lesAnniversaires[nbAnniversaires].prenom, sizeof lesAnniversaires[nbAnniversaires].prenom, "%s", ptr); // https://cplusplus.com/reference/cstdio/snprintf/
        ptr = strtok(nullptr, ";");
        lesAnniversaires[nbAnniversaires].jour = strtol(ptr, nullptr, 10); // https://cplusplus.com/reference/cstdlib/strtol/
        ptr = strtok(nullptr, ";");
        lesAnniversaires[nbAnniversaires].mois = strtol(ptr, nullptr, 10); // https://cplusplus.com/reference/cstdlib/strtol/
        ptr = strtok(nullptr, ";");
        lesAnniversaires[nbAnniversaires].annee = strtol(ptr, nullptr, 10); // https://cplusplus.com/reference/cstdlib/strtol/
        Serial.println(F("l'analyse de la ligne donne :"));
        Serial.print(F("\tNom : [")); Serial.print(lesAnniversaires[nbAnniversaires].nom); Serial.println(F("]"));
        Serial.print(F("\tPrenom : [")); Serial.print(lesAnniversaires[nbAnniversaires].prenom); Serial.println(F("]"));
        Serial.print(F("\tJour : [")); Serial.print(lesAnniversaires[nbAnniversaires].jour); Serial.println(F("]"));
        Serial.print(F("\tMois : [")); Serial.print(lesAnniversaires[nbAnniversaires].mois); Serial.println(F("]"));
        Serial.print(F("\tAnnée : [")); Serial.print(lesAnniversaires[nbAnniversaires].annee); Serial.println(F("]"));
      }

      // si le fichier est entièrement lu
      if (fichier.available() == 0) break;

      // on passe à la ligne suivante
      nbAnniversaires++;
    }
    fichier.close();
    Serial.print(F("On a trouvé ")); Serial.print(nbAnniversaires); Serial.println(F(" personnes"));

  } else {
    Serial.print(F("Erreur : Impossible de lire "));
    Serial.println(nomFichierConfigWifi);
  }
}

void loop() {}

avec SSID.csv qui contient

ceci est mon SSID;mot de passe secret;*

et anniv.csv qui contient

Joseph1;Bozzer1;3;10;1952;*
joseph2;bozzer2;7;6;1987;*
joseph3;Bozzer3;4;8;1963;*
joseph4;bozzer4;8;7;1977;*
joseph5;Bozzer5;4;8;1948;*
1 Like

Merci JML pour ton gros effort mais c'est trop complexe pour moi avec mes faibles connaissances

J'ai persévéré dans mon code et j'y suis arrivé!
J'ai maintenant :

  • liste complète d'anniversaires, fêtes nationales etc .. dressée sur Excel
  • SSID et mp sur excel egalement (pour permettre à quiconque de se connecter sans avoir Arduino)
  • lancement de la recherche d'anniversaire uniquement 1 fois par jour à 00h001 minutes
  • détection de l'anniversaire du jour (il faudra que je réfléchisse au cas où il y aurait deux anniversaires au même jour

Il me reste à afficher le résultat :
Je voudrais qu'il reste affiché toute la journée de l'anniversaire tout en continuant à afficher l'heure mais j'ai besoin d'une idée :

  • si je mets une tempo de 24h, l'horloge se figera pendant 24h pour reprendre avec la bonne heure uniquement après ce temps => pas bon
  • je pense à un 2eme afficheur dédié aux messages d'anniversaires mais est-ce que je risque d'avoir le même gel de l'heure?

A moins d'une autre idée?

Mon code actuel :

// VERSION 12 octobre AVEC ANNIVERSAIRES

// --------------- besoins pour affichage anniversaires
#include <SD.h>
#include <SPI.h>

File fichierAniv;
File fichierSSID;

static char buf[50];
int i;
int c;
int ligne = 0;

char *p1;  // prenom
char *p2;  // nom
char *p3;  // jour
char *p4;  // mois
char *p5;  // année

//String p10;  // SSISD
//String p11;  // mot de passe

char *SSID;
char *MP;

int MinuteActuelle;
int HeureActuelle;
int JourActuel;
int MoisActuel;
int JourAniv;
int MoisAniv;

// --------------- besoins pour affichage horloge
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

int ledWIFI = 0;
int ledSD = 2;

#define SCREEN_WIDTH 128   // OLED display width, in pixels
#define SCREEN_HEIGHT 64   // OLED display height, in pixels
#define OLED_RESET -1      // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define Oled_ADDRESS 0x3C  // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)

Adafruit_SSD1306 ecranOLED(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);  // initialisation de l'écran avec le nom ecranOLED (à choisir)

//---------------- choix des polices
// Fonts est le nom du dossier dans lequel se trouvent tous les fonts de la bibliotheque Adafruit_GFX
#include <Fonts/FreeSans6pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSansBold12pt7b.h>

//---------------- besoins pour WIFI
#include <ESP8266WiFi.h>
//const char *ssid = p10;
//const char *password = p11;
int y;
String BUFFER_H;

//----------------- besoins pour internet
#include <EasyNTPClient.h>
#include <WiFiUdp.h>
#include <Timezone.h>

//------------------ besoins pour extraction données hors du WiFi
WiFiUDP Udp_G;                                                                    // Objet UDP permettant d'envoyer et recevoir des trames Wi-Fi selon le protocole UDP
EasyNTPClient ClientNtp_G(Udp_G, "pool.ntp.org");                                 // Objet NTP synchronisé avec "pool.ntp.org"
TimeChangeRule RegleHeureEteFrance_G = { "RHEE", Last, Sun, Mar, 2, 120 };        // Règle de passage à l'heure d'été pour la France
TimeChangeRule RegleHeureHiverFrance_G = { "RHHE", Last, Sun, Oct, 3, 60 };       // Règle de passage à l'heure d'hiver la France
Timezone ConvertirHeureFrance_G(RegleHeureEteFrance_G, RegleHeureHiverFrance_G);  // Objet de conversion d'heure avec les caractéristique de la métropole française


//------------------- matrice du logo Wifi
const unsigned char logoWIFI[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00,
  0x3f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xf8,
  0x00, 0x7f, 0xc0, 0x1f, 0xc0, 0x00, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x03, 0xf0, 0x7e, 0x03, 0xff,
  0x01, 0xf8, 0x78, 0x1f, 0xff, 0xe0, 0x78, 0x70, 0x7f, 0xff, 0xf8, 0x38, 0x00, 0xff, 0xff, 0xfc,
  0x00, 0x01, 0xfc, 0x00, 0xfe, 0x00, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x03, 0xc0, 0x00, 0x0f, 0x00,
  0x03, 0x80, 0x38, 0x07, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00,
  0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0x87, 0xe0, 0x00, 0x00, 0x1e, 0x01, 0xe0, 0x00, 0x00, 0x08,
  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc,
  0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
  0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


void setup() {  // exécuté 1 fois

  // =========== PARTIE NECESSAIRE POUR HORLOGE ==============

  pinMode(ledWIFI, OUTPUT);
  pinMode(ledSD, OUTPUT);
  digitalWrite(ledWIFI, LOW);
  digitalWrite(ledSD, LOW);

  Serial.begin(115200);


  // --- initialisation oled
  ecranOLED.begin(SSD1306_SWITCHCAPVCC, Oled_ADDRESS);  // initialize with the  I2C addr 0x3C
  ecranOLED.clearDisplay();                             // Vidange du buffer de   l'écran OLED


  // ========== PARTIE NECESSAIRE POUR ANNIVERSAIRES ===========

  SPI.pins(14, 12, 13, 15);  // SCK, MISO, MOSI, CS

  // Ouverture du port série
  Serial.begin(115200);
  while (!Serial) {};

  // Initialisation de la carte SD------------------------------
  Serial.print("Initialisation de la carte SD ...");

  if (!SD.begin(15)) {
    Serial.println("initialisation echouee !");
    digitalWrite(ledSD, LOW);
    return;
  }
  Serial.println("initialisation reussie.");
  digitalWrite(ledSD, HIGH);



  //Ouverture du fichier csv SSID -----------------------------------
  fichierSSID = SD.open("SSID.csv", FILE_READ);

  //Lecture du fichier csv SSID ------------------------------------
  while (fichierSSID.available()) {
    for (i = 0; fichierSSID.available() && i < sizeof buf - 1; i++) {
      buf[i] = fichierSSID.read();
      if (buf[i] == '*')
        break;  // fin de ligne
    }
    buf[i] = 0;  // fin de la chaine

    //-séparation des données d'une ligne (ici 5 données max)-------------
    SSID = strtok(buf, ";");  // SSID
    MP = strtok(NULL, ";");   // mot de passe

    //--Verification de la lecture et du découpage SSID --------------
    Serial.println(SSID);
    Serial.println(" ");
    Serial.print(MP);
    Serial.println(" ");

    //---- attente signal WiFi
    Wire.begin(4, 5);
    WiFi.begin(SSID, MP);
    unsigned long chrono = millis();  // remplace la fonction delai
    while (millis() - chrono < 3000) yield();
    while (WiFi.status() != WL_CONNECTED) {
      affichagelogoWifi();  // appel sous-programme 3- affichage logowifi clignotant
    }
    digitalWrite(ledWIFI, HIGH);  // wifi connecté
  }
}



void loop() {  // executé à l'infini

  time_t HeureLocale_L;
  HeureLocale_L = ConvertirHeureFrance_G.toLocal(ClientNtp_G.getUnixTime());

  AfficherHeureLocale(HeureLocale_L);  // saut vers sous programme 3 - affichage sur l'ecran
  TestAniversaire();                   // sous programme 5 de test si minuit et bonne date
}


//=============== 1-SOUS-PROGRAMME affichage logoWiFi
void affichagelogoWifi(void) {

  //------------------ affichage logo WIFI
  //drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
  ecranOLED.drawBitmap(50, 20, logoWIFI, 38, 32, WHITE);  // dessin et position du logo placés dans le buffer
  ecranOLED.display();                                    // affichage sur l'écran du contenu du buffer
  unsigned long chrono = millis();
  //  chrono = millis();  // remplace la fonction delai
  while (millis() - chrono < 600) yield();  // durée logo visible

  //------------------ Extinction logo WIFI
  ecranOLED.clearDisplay();                 // dessin et position du logo placés dans le buffer
  ecranOLED.display();                      // affichage sur l'écran du contenu du buffer
  chrono = millis();                        // remplace la fonction delai
  while (millis() - chrono < 300) yield();  //durée logo éteint
}

//================ 2-SOUS PROGRAMME centrage textes
void oledDisplayCenter(String text, int Y) {
  int16_t x1;
  int16_t y1;
  uint16_t width;
  uint16_t height;

  ecranOLED.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);  // extraction de la longueur width du texte
  ecranOLED.setCursor((SCREEN_WIDTH - width) / 2, Y);              // (largeur écran - longueur du texte) / 2 donne le point de départ du texte
}

// ============== 3-SOUS PROGRAMME AFFICHAGE SUR ECRAN
void AfficherHeureLocale(time_t Heure_P) {
  char BUFFER_H[50];
  char BUFFER_H1[50];
  char BUFFER_H2[50];
  char BUFFER_J[50];
  char BUFFER_D[50];
  char AbreviationMois_L[12][10] = { "Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre" };
  char AbreviationJour_L[7][10] = { "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" };

  //----- effacement buffer écran
  ecranOLED.clearDisplay();

  //------création buufer Date = texte affiché
  HeureActuelle = hour(Heure_P);
  MinuteActuelle = minute(Heure_P);
  JourActuel = day(Heure_P);
  MoisActuel = month(Heure_P);
  //Serial.println(HeureTest);
  //Serial.println(MinuteTest);

  sprintf(BUFFER_D, "%s - %d", AbreviationMois_L[month(Heure_P) - 1], year(Heure_P));
  ecranOLED.setFont(&FreeSans6pt7b);  //mois, année = petits caractères
  ecranOLED.setTextColor(WHITE);
  oledDisplayCenter(BUFFER_D, 10);
  ecranOLED.print(BUFFER_D);

  //----- création buffer Jour = texte affiché
  sprintf(BUFFER_J, "%s %.2d", AbreviationJour_L[weekday(Heure_P) - 1], day(Heure_P));  // %.2d affiche (01) et %.d affiche ( 1)
  ecranOLED.setFont(&FreeSansBold9pt7b);                                                //jour et date = moyens caractères
  ecranOLED.setTextColor(WHITE);
  oledDisplayCenter(BUFFER_J, 30);
  ecranOLED.print(BUFFER_J);

  //----- création buffer heure-minutes = texte affiché
  sprintf(BUFFER_H1, "%d:%.2d", hour(Heure_P), minute(Heure_P));  // creation et remplissage de la variable "BUFFER_H"... %d
  ecranOLED.setFont(&FreeSansBold12pt7b);                         //heure et minutes = gros caracteres
  ecranOLED.setTextColor(WHITE);
  oledDisplayCenter(BUFFER_H1, 62);
  ecranOLED.print(BUFFER_H1);

  //----- création buffer seconde
  sprintf(BUFFER_H2, "%2d", second(Heure_P));  // creation et remplissage de la variable "BUFFER_H"
  ecranOLED.setFont(&FreeSans6pt7b);
  ecranOLED.setTextColor(WHITE);
  ecranOLED.setCursor(108, 62);
  ecranOLED.print(BUFFER_H2);

  //-------affichage buffer sur écran
  ecranOLED.display();
}


// ============== 5-SOUS PROGRAMME TEST ANNIVERSAIRE
void TestAniversaire() {
  //Serial.println(HeureActuelle);
  //Serial.println(MinuteActulelle);

  //if ((HeureActuelle == 23) && (MinuteActuelle == 59)) {
  Serial.println("test lancé");

  //Ouverture du fichier csv anniversaires -----------------------------------
  fichierAniv = SD.open("anniv.csv", FILE_READ);

  //Lecture du fichier csv anniversaires -------------------------------------
  while (fichierAniv.available()) {
    for (i = 0; fichierAniv.available() && i < sizeof buf - 1; i++) {
      buf[i] = fichierAniv.read();
      if (buf[i] == '*')
        break;  // fin de ligne
    }
    buf[i] = 0;  // fin de la chaine

    //-séparation des données d'une ligne (ici 5 données max)-------------
    p1 = strtok(buf, ";");   // prenom
    p2 = strtok(NULL, ";");  // nom
    p3 = strtok(NULL, ";");  // jour
    p4 = strtok(NULL, ";");  // mois
    p5 = strtok(NULL, ";");  // années

    JourAniv = atoi(p3);
    MoisAniv = atoi(p4);

    if ((JourActuel == JourAniv) && (MoisActuel == MoisAniv)) {
      Serial.println("anniversaire de Joseph");
      delay(5000);
    }
    //Serial.println(" ");
    Serial.println("dates aniv");
    Serial.println(JourAniv);
    Serial.println(MoisAniv);
    Serial.println("dates du jour");
    Serial.println(" ");
  }
}

Pas la peine de créer autant de buffer alors que tu n'en utilises qu'un seul à la fois et que tu ne réutilises pas son contenu. Heureusement que l'ESP dispose de suffisamment de mémoire.

En effet je n'ai pas besoin du BUFFER_H et je peux réduire le volume des autres à 5
Testé c'est ok

OK vous pourrez y revenir à tête reposé, ça fait à peu près la même chose que votre code : j'ouvre le fichier, je lis une ligne, je l'analyse avec strtok() et conserve les pointeurs. La seule différence c'est qu'ensuite je copie les données en RAM dans des variables ou un tableau, ce qui fait qu'on n'a plus besoin de relire le fichier à chaque tour de loop comme vous le faites (la carte SD va travailler dur à lire le fichier anniv des dizaines de fois par seconde avec votre approche).


sinon il faut changer cela (à moins que vous ne gériez que des Joseph)

    if ((JourActuel == JourAniv) && (MoisActuel == MoisAniv)) {
      Serial.println("anniversaire de Joseph");
      delay(5000);
    }

puisque vous avez les pointeurs sur le nom et prénom, vous pouvez les utiliser

    if ((JourActuel == JourAniv) && (MoisActuel == MoisAniv)) {
      Serial.print("anniversaire de "); Serial.println(p1); // si on veut juste le prénom
      delay(5000);
    }

Non je ne lis le fichier aniv qu'une fois par jour, au passage de minuit

le print "anniversaire de Joseph" .. n'était qu'un test d'essai ... j'aurai fait comme vous dans la version finale dans laquelle je calculerai aussi l'intervalle entre années de façon à pouvoir écrire "Marcel a 65ans aujourd'hui

je vais envisager 2 ecrans oled
dans le second j'afficherai et je gêlerai ensuite l'écran pendant 24h de façon à pouvoir continuer à afficher l'heure sur le 1er sans la bloquer

ah j'ai lu trop vite alors (ou il manque du code?? parce que TestAniversaire est appelé en boucle)