A devenir fada :(

Bonsoir à tous, je vais devenir fou avec ce bug qui m'échappe depuis trois jours. J'étais tout content d'avoir trouvé le mot magique 'extern' pour certaines globales, mais maintenant j'ai un test sur variable qui ne fonctionne pas et je sèche. J'espère que la fonction avec l'output correspondant vous suffira, je l'ai truffé pour voir d'où ça vient . La fonction prend la bonne variable globale 'tour' (que j'ai initialisée à 4 en débogage pour en être sûr), elle l'incrémente comme demandé (5), mais quand je teste l'égalité à 3 elle dit toujours TRUE.

int BatteryAlarm() {
    Serial.print ("tour IN: "); // XXX
    Serial.println (tour);
    Serial.print ("battery_can_sum IN: ");   
    Serial.println (battery_can_sum);
    int battery_can=0;
    Serial.println("< -------------- TEST BATTERIE ----------");
    Serial.print("Battery_can: ");
    Serial.println(battery_can);    
    battery_can=analogRead(34);
    Serial.print ("CAN ACCU :");
    Serial.println (battery_can);
    // moyenne de mesure sur trois tours:
    battery_can_sum=battery_can_sum+battery_can;
    Serial.print ("battery_can_sum: ");   
    Serial.println (battery_can_sum);
    tour+=1;
    Serial.println("QQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
    Serial.print ("tour: ");
    Serial.println (tour);
    if (tour == 3){ // remise à zéro de la boucle 3 
      Serial.println ("tour == 3");   // XXX
      average_can = battery_can_sum/3;
      Serial.print ("average_can: ");      
      Serial.println (average_can);   
      tour=0;  
      average_can =0;
      battery_can_sum=0;
      Serial.println("QQQQQQQQQQQQQQQQQQQQQQQQQQQQ");  
      return (battery_can); 
      }    

OUTPUT CORRESPONDANT:

tour IN: 4
battery_can_sum IN: 0
< -------------- TEST BATTERIE ----------
Battery_can: 0
CAN ACCU :0
battery_can_sum: 0
QQQQQQQQQQQQQQQQQQQQQQQQQQQQ
tour: 5
tour == 3

Comme vous pouvez le deviner c'est un testeur de tension batterie via un CAN. Ici il n'est pas branché.

Merci beaucoup par avance :slight_smile:

Êtes vous dans ke contexte d’une interruption?
Si oui, les variables globales sont elles volatile?

ne postez pas de snippets (Snippets R Us!), postez tout le code

Bonjour et merci. En fait je suis un petit bidouilleur du dimanche c'est très sale car reprise d'un de mes anciens scripts avec capteurs, et j'ai des grosses lacunes.
C'est pour un ESP32, une mesure de niveau de décharge d'une batterie solaire sur balcon parisien, et je me suis risqué essayer le multithreading, sans doute à tort vu mon niveau. Dans le passage qui me pose problème je veux simplement faire une moyenne sur plusieurs mesures, rien de plus banal, mais ma variable 'tour' ne s'incrémentait pas, j'ai alors compris que le test ==3 répondait toujours TRUE...
Je poste l'ensemble pour ceux qui auraient le courage. Je m'excuse pour le fouillis, j'ai essayé de développer en 'modulaire' mais manifestement cela ne me réussit pas :frowning:


/***********************************************************************************
  ESP32 serveur wifi ethernet et DHT22 pour tester l'humidité et la température
  Surtout un différentiel intérieur/extérieur pour gestion de canicule
================================================================================

22 09 16 REPRISE pour CAN > ici récepteur > 
1 = supprimer ESPNOW
**********************************************************************************/
#include "B_DECLARATIONS.h"
#include "C_SETUP_A.h"   // pinmodes, etc.
#include "D_SETUP_SERVER.h" 
#include "E_SETUP_MULTITHREAD.h"  
#include "functions.h"

int tour=4;     // moyenne de mesure sur n tours:
int battery_can_sum;
int CanAverageGlobal;

int ALARM_LEVEL = 3300;
float approxMapR=0;
float MapR;
// =========== Task1code COEUR 0 : SERVEUR < ============================ <

void Task1code( void * pvParameters ) {
  for (;;) {
    Serial.print("Task1 running on core ");
    Serial.println(xPortGetCoreID());
    WiFiClient client = server.available();   // listen for incoming clients

// SERVEUR

//----------   SERVEUR ECOUTE   ----------------------------

   if (client) {                             // if you get a client,
        Serial.println("New Client.");           // print a message out the serial port
        String currentLine = "";                // make a String to hold incoming data from the client
        while (client.connected()) {            // loop while the client's connected
          if (client.available()) {             // if there's bytes to read from the client,
            char c = client.read();             // read a byte, then
            Serial.write(c);                    // print it out the serial monitor
            if (c == '\n') {                    // if the byte is a newline character
  
              if (currentLine.length() == 0) {
                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                // and a content-type so the client knows what's coming, then a blank line:
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println();
                client.println("<head>");
                client.println("<meta http-equiv=\"refresh\" content=\"20\">");
                           
                client.println("<title>""</title>");
                client.println("<style>");
                client.println("body {");
                client.println("background-color: #ebcc76;");
                client.println("}");
                client.println("</style>");
                client.println("</head>");   
                                        
                // the content of the HTTP response follows the header:
                client.print("<font size=");
                client.print("7");
                client.print("<br>"); 
                
             
                client.print("Carte ");
                client.println(carte);
                client.print("&nbsp;&nbsp;");
                client.print("<a href=\"http://82.64.37.196:1902\">22</a>");            
                client.print("&nbsp;&nbsp;");
                client.println("<a href=\"http://82.64.37.196:1900\">20</a>"); 
                client.print("<br>");                  
                client.print("<br>"); 
               
                client.print(NOW);  // (= bufferA)       
                client.print("<br>");
                client.print("<br>");                                           
                }                     
                
                // =======>                
                client.print("<p style=\"color:black;font-size:28px;\">");
                client.print("Alarm level: ");
                client.println(ALARM_LEVEL);
                client.print("</p>");               
                            
                client.print("CAN battery: ");
                //client.print("&nbsp;&nbsp;");
                //client.println(battery_can);
                client.print(CanAverageGlobal);
                client.print("&nbsp;&nbsp;");
                client.println("  /4095");                
                client.print("<br>"); 
                client.println(approxMapR); // XXXXXXXXXXXXXX
                client.print("<br>"); 
                client.print("MAP : ");
                //client.print("&nbsp;&nbsp;");
                client.println(MapR); // XXXXXXXXXXXXXX                
                client.println("  V");                 
                alarmIf( CanAverageGlobal, ALARM_LEVEL);                
                client.print("<br><br>");                              
                //client.print("&nbsp;&nbsp;");
                client.print("SPIFFS essai - random float: ");
                client.println(myVariable);               
                client.print("<br>");
                          
                client.print("<br>");
                client.print("<a href=\"/H\">5 ON</a>");
                client.print("&nbsp;&nbsp;&nbsp;");
                client.print("<a href=\"/L\">5 OFF</a><br>"); 
                client.print("<br>");
                client.print("<a href=\"/3100\">3100</a>");
                client.print("&nbsp;&nbsp;&nbsp;");
                client.print("<a href=\"/3300\">3300</a><br>");                 
                client.print("<br>");
                //client.print("&nbsp;&nbsp;");
                client.print("RSSI: ");
                rssi = WiFi.RSSI();
                client.println(rssi);    
                // The HTTP response ends with another blank line:
                client.println();
                // break out of the while loop:
                break;
              } else {    // if you got a newline, then clear currentLine:
                currentLine = "";
              }
            } else if (c != '\r') {  // if you got anything else but a carriage return character,
              currentLine += c;      // add it to the end of the currentLine
            }
  
            // Check to see if the client request was "GET /H" or "GET /L":
            if (currentLine.endsWith("GET /H")) {
              digitalWrite(5, HIGH);               // GET /H turns the LED on
            }
            if (currentLine.endsWith("GET /L")) {
              digitalWrite(5, LOW);                // GET /L turns the LED off
            }

            if (currentLine.endsWith("GET /3100")) {
              Serial.println("");
              Serial.println ("3100 demandé");                // setup niveau d'alarme
              ALARM_LEVEL = 3100;
              //delay(2000);
            }

            if (currentLine.endsWith("GET /3300")) {
              Serial.println("");
              Serial.println ("3300 demandé");              
              ALARM_LEVEL = 3300;             
              //delay(2000);
            }
            
          } // client avaible end >
        }
        // close the connection:
        client.stop();
        Serial.println("Client Disconnected.");
      }
    delay(SERVER_SLEEP);
  }
}

//======== task1 - SERVEUR END ==== >

// ======================================   TASK 2   COEUR 1 =========================================== <
void Task2code( void * pvParameters ) {
   // pour moyenne des mesures CAN volts
//  int tour=1;     // moyenne de mesure sur n tours:
//  int battery_can_sum=0;
//  int average_can=0; // made global sister 'int Average' for sum to print

  for (;;) {
    Serial.println("===================================================================== ");
    Serial.print("Task2 running on core ");
    Serial.println(xPortGetCoreID());
    Serial.println("===================================================================== ");
    CanAverageGlobal=BatteryAlarm();
//    approxMapR=approxMap(CanAverageGlobal);
    Serial.println ("MAAAAAAAAAAAAAAAAAAP XXXXXXXXXXXXX   XXXXXXXXXX  XXXXXXXXX");
    // XXXX ESSAI MAP
    MapR=CanMap(CanAverageGlobal);     
    Serial.println(MapR);   
    delay (TASK2_SLEEP);
   
  }
}

void loop () { // NTP TIME ================<
  time_t timestamp = time( NULL );
  char buffer[MAX_SIZE];
  struct tm *pTime = localtime(&timestamp );
  strftime(buffer, MAX_SIZE, "%d/%m/%Y %H:%M:%S", pTime);
  Serial.println(buffer);
  bufferA=buffer; //CH fait n'importe comment
  NOW=bufferA; // je garde bufferA pour me rappeler de voir ce que c'est le 'buffer'
  // supprimer après cette variable sans significationclaire dans le programme
  delay(1000);
  // ========>
  
}

/***********************************************************************************
  ESP32 serveur wifi ethernet et DHT22 pour tester l'humidité et la température
  Surtout un différentiel intérieur/extérieur pour gestion de canicule
================================================================================

**********************************************************************************/
#include "functions.h"
const int BATTERY_MINI = 3000; // voir
const int BATTERY_MINI_20 = 3100;
const int SERVER_SLEEP = 3000;      // sur coeur 0
const int TASK2_SLEEP = 3000;     // sur coeur 1

//============= NTP TIME==============
#define MAX_SIZE 80
const char* ntpServer = "pool.ntp.org";
char* bufferA; //CH fait n'importe comment
char* NOW = "";
//====================================

//  ETALONNAGES /CONVERSIONS selon carte ========================
int carte = 0; //CH repérer quelle carte pour éventuel étalonnage (caduque >> adresse mac)
String mac= "";
float myVariable;  // XXX
//------ 
int  rssi = 0;

// CAN BATTERIE =====
int battery_can=0; // mesure batterie quand alim autonome
//------->

//------------ WIFI & ESPNOW  ----------- <
#include <WiFi.h>
//ESP XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <esp_now.h> 
uint8_t broadcastAddress[] = {0xEC,0x62,0x60,0x84,0xF9,0xA0}; //adresse mac receiver

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {

  float a;
  float b;
  float c;
  float d;
} struct_message;

// Create a struct_message called myData
struct_message myData;
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.println("TEST_String: ###########################  ");
  Serial.print(" #######################################  ");
  Serial.println(myData.a);
  

  Serial.print("FLOAT B FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF: ");
  Serial.println(myData.b);
  Serial.print("Float: ");
  Serial.println(myData.c);
  Serial.print("Bool: ");
  Serial.println(myData.d);
  Serial.println();
}

//multitâche-------------
TaskHandle_t Task1;
TaskHandle_t Task2;
// DHT:------------------
//#include <SimpleDHT.h>
//int pinDHT22 = 4;
//SimpleDHT22 dht22(pinDHT22);



//--------
const char* ssid     = "xxxx";
const char* password = "xxxxxx";
WiFiServer server(80);
void setup() { // ============================================================ SETUP <
  Serial.begin(115200);
  spiffs_setup();
  Serial.println(__FILE__); // get sketch name and print it
//  pinMode(5, OUTPUT); //led rouge (différentiel>+0.5 °C)  
//  pinMode(2, OUTPUT); //led jaune (différentiel>-0.5 °C)
  pinMode(16,OUTPUT);  // buzzer
//  pinMode(17, OUTPUT); //led verte(différentiel>-4 °C)
  pinMode(34, INPUT);//CAN batterie
  digitalWrite(17, HIGH); 
  delay(2000);
  digitalWrite(17, LOW); 

  digitalWrite(2, LOW); 
  digitalWrite(5, LOW); 
  digitalWrite(16, LOW); 

  delay(10);
  Serial.println("");
  buzzA(100);
//======= SERVEUR SETUP
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");


  Serial.print("ESP Board MAC Address:  ");
  mac = WiFi.macAddress();

// ============== NTP TIME ==================
  configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);
// ==========================================

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ESP-NOW XXXXXXXXXXXXXXXXXXXXXXXXX

WiFi.mode(WIFI_MODE_STA);

// Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);


   
         

 
  // Adresse IP:
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  //===================================================================== >

  rssi = WiFi.RSSI();
  Serial.print("RRSI: ");
  Serial.println(rssi);

  server.begin();

  // SERVEUR SETUP end ======== >
  //MULTITHREAD SETUP ========================================================   
  //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
  
  void Task1code (void * pvParameters);
  void Task2code (void * pvParameters);
 
  xTaskCreatePinnedToCore(
    Task1code,   /* Task function. */
    "Task1",     /* name of task. */
    10000,       /* Stack size of task */
    NULL,        /* parameter of the task */
    3,           /* priority of the task */
    &Task1,      /* Task handle to keep track of created task */
    0);          /* pin task to core 0 */
  delay(500);

  //create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
  xTaskCreatePinnedToCore(
    Task2code,   /* Task function. */
    "Task2",     /* name of task. */
    10000,       /* Stack size of task */
    NULL,        /* parameter of the task */
    3,           /* XXXXXXXXXXXXXXX
                    priority of the task */
    &Task2,      /* Task handle to keep track of created task */
    1);          /* pin task to core 1 */
  delay(500);
}// ======= SETUP END >
#include "functions.h"
#include "SPIFFS.h" 

//------ CAN BATTERY -----
extern int tour;
extern int battery_can_sum;
int average_can=0; 
// ---->

void spiffs_setup(){
 // SPIFFS setup : ==================<
 Serial.println();
 if(!SPIFFS.begin()){
  Serial.println("An Error has occurred while mounting SPIFFS");
  return;
//=========>
 }
}

/*-----------------------------------------------------------------------
 *      float spiffs_read_write(float myVariable)
 *     
 * essais Ecriture/lecture dans la mémoire flash de la carte d'une variable changée à 
 * chaque tour
 
-----------------------------------------------------------------------*/

bool spiffs_read_write(float Mydata){
    //--------- Append to file --------------
    File fileToAppend = SPIFFS.open("/testAppend.txt", "a");  
    if(!fileToAppend){
        Serial.println("There was an error opening the file for appending");
        return(1);
    }     
    if(fileToAppend.println(Mydata)){
        Serial.println("File content was appended");
    } else {
        Serial.println("File append failed");
    } 
    fileToAppend.close();
  
    //---------- Read from file fileWrToRead --------------
    File fileWrToReadApp = SPIFFS.open("/testAppend.txt", "r");
  
    if(!fileWrToReadApp){
        Serial.println("Failed to open testWr for reading");
        return(1);
    } 
    Serial.println("TTTTTTTTT  testAppend.txt Content TTTTTTTTTTTTTTTTTTTTTT TTT :");  
    Serial.println("TEMPERATURE EXTERIEURE :");  
    while(fileWrToReadApp.available()){  
        Serial.write(fileWrToReadApp.read());
    }  
    fileWrToReadApp.close();
    return(0);
}
//------------------------->

/*-----------------------------------------------------------------------
 *     bool spiffs_read_writeB(const char* FilePath, float Mydata) 
 *     
écriture/lecture de température extérieur/intérieur (amélioré)
(essais de passage d'objet file à une fonction)  
 ===================================   
 !!!! const char* FilePath : A VOIR 
 ===================================
 
-----------------------------------------------------------------------*/

bool spiffs_read_writeB(const char* FilePath, float Mydata){
    //--------- Append to file --------------
    File fileToAppend = SPIFFS.open(FilePath, "a");  
    if(!fileToAppend){
        Serial.println("There was an error opening the fileB for appending");
        return(1);
    }   

String MydataStr = "    "+String (Mydata); // XXXXXXXXXXXX //concaten pour espace
//Serial.println("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");
//Serial.println(MydataStr);
//Serial.println("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");
//delay(50000);

    if(fileToAppend.println(MydataStr)){
        Serial.println("FileB content was appended");
    } else {
        Serial.println("FileB append failed");
    } 
    fileToAppend.close();
  
    //---------- Read from file fileWrToRead --------------
    File fileWrToReadApp = SPIFFS.open(FilePath, "r"); 
    if(!fileWrToReadApp){
        Serial.println("Failed to open testWrB for reading");
        return(1);
    } 
    Serial.println("UUUUUUUUUUUUUU  testAppend.txt Content UUUUUUUUUUUUUUUUUUUUUUU UUU :");
    Serial.println("TEMPERATURE INTERIEURE :");   
   // Serial.print("   ");
    while(fileWrToReadApp.available()){  
        Serial.write(fileWrToReadApp.read());
    }  
    fileWrToReadApp.close();
    return(0);
}

// XXXXXXXXXXXXX A FAIRE: if 0.00 comme ds serveur html


//-----------> 

/*-----------------------------------------------------------------------
 *      void buzzA()
 *      
 * Petit buz discret à installer sur pin 16
-----------------------------------------------------------------------*/
void buzzA(int aTime){

   Serial.print ("Buzzer >>>>>>>>>>>>>>>>>>");
   {
    digitalWrite(16,HIGH);
    delay(aTime);
    digitalWrite(16,LOW);
    }
}
/*-----------------------------------------------------------------------
 *    void BatteryAlarm(int CanAverageGlobal, int battery_can,bool usbMode,bool justOneTime,char tour)
 *     
 * Tests batterie
-----------------------------------------------------------------------*/
int BatteryAlarm() {
    Serial.print ("tour IN: "); // XXX
    Serial.println (tour);
    Serial.print ("battery_can_sum IN: ");   
    Serial.println (battery_can_sum);
    int battery_can=0;
    Serial.println("< -------------- TEST BATTERIE ----------");
    Serial.print("Battery_can: ");
    Serial.println(battery_can);    
    battery_can=analogRead(34);
    Serial.print ("CAN ACCU :");
    Serial.println (battery_can);
    // moyenne de mesure sur trois tours:
    battery_can_sum=battery_can_sum+battery_can;
    Serial.print ("battery_can_sum: ");   
    Serial.println (battery_can_sum);
    tour+=1;
    Serial.println("QQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
    Serial.print ("tour: ");
    Serial.println (tour);
    if (tour == 3){ // remise à zéro de la boucle 3 
      Serial.println ("tour == 3");   // XXX
      average_can = battery_can_sum/3;
      Serial.print ("average_can: ");      
      Serial.println (average_can);   
      tour=0;  
      average_can =0;
      battery_can_sum=0;
      Serial.println("QQQQQQQQQQQQQQQQQQQQQQQQQQQQ");  
      return (battery_can); 
      }    
//     delay(2000);
    // ========>
      
    
}

void alarmIf(int sample,int level){
      if (sample<level){
        Serial.println("ALAAAAAAAAAAAAAAAARM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");  
        buzzA(200);
        delay(100);
        buzzA(300);
      }
  
}

float CanMap(int can){
  int fromLow=3350;  
  int fromHigh=4095; 
  int toLow=120; 
  int toHigh=140; 
  int result;
  float resultF;
  
  result = map(can, fromLow, fromHigh, toLow, toHigh);
  Serial.println("OOOOOOOOOOO MAP OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
  Serial.println(result);
  resultF = float(result)/10;
  Serial.println("OOOOOOOOOOO MAP FFFF   OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
  Serial.println(resultF);
  
  return (resultF);  
   
}
//#include "B_DECLARATIONS.h" 
bool spiffs_read_write(float);
void buzzA(int aTime);

void spiffs_setup(void);

// (GGG passage d'objet File à une fonction):
bool spiffs_read_writeB(const char* FilePath, float Myadata);

int BatteryAlarm();
void alarmIf(int sample,int level);

float approxMap(int can); // sorte de conversion très approximative du CAN en volts à partir de quelques correspondances

float CanMap(int can);

je ne vois pas le code concernant tour dans ce que vous avez posté

Dans le 6ème code dans lequel il y a un commentaire au début contenant

//------ CAN BATTERY -----

Ah, il a rajouté du contenu après que j’ai lu son post

Est-ce que tour est utilisé dans Les 2 threads?
Si oui il faut le déclarer volatile et mettre un sémaphore pour la lecture/écriture

Merci beaucoup je vais voir ça. Déjà je vais me renseigner sur les deux concepts lol

Lors de mes premiers essais en multithread j'avais l'impression que la gestion des globales ne posait aucun problème entre les deux coeurs, mais finalement...

Il n’y a pas de protection sur les accès concurrents entre les cœurs et le compilateur peut aussi choisir des optimisations incongrues si on ne protège pas les variables partagées

Je lis le code juste sur mon iPhone, donc difficile de dire si c’est le cas, mais c’est une piste à regarder

Merci d'avoir pris du temps. Je crois que je fais trop compliqué pour mon niveau. Mais si on veut un serveur et des fonctions c'est naturel de vouloir séparer les threads. Je crois que je vais devoir reprendre tout ça à zéro. Bon, j'ai l'essentiel: mon alarme est fonctionnelle. Je voulais juste lisser un peu le truc. (et surtout apprendre un peu à développer :wink:

si vous voulez un serveur web asynchrone qui utilise le second core, le plus simple c'est de prendre Async Web Server for ESP8266 and ESP32

ça vous simplifiera grandement la vie

Bonjour bohin92fr,

C'est peut-être dû à un écrasement mémoire.

Avez-vous analysé les warnings de compilation ?

Je vous invite à remplacer

par

dans un premier temps.

ça ne changera rien

Dans l'absolu associer un buffer dont le contenu est constant à un pointeur dont le contenu n'est pas constant est une erreur

il faudrait au moins dire

char* NOW = nullptr;

mais ça oblige à tester NOW plus tard si on veut l'imprimer

donc la "bonne" façon pour que NOW pointe toujours sur quelque chose de correct c'est

char caractereNull = '\0';
char* NOW = & caractereNull;

Merci je note tout ça, mais je doute que mon soucis de variable globale 'tour' dans int BatteryAlarm() ait un rapport avec ma récupération de l'heure via ntp.
C'est normal que vous ne vous repériez pas dans mon foutoir, je suis incompétent. Le pointeur NOW je l'ai écrit après moultes essais au hasard, il faudrait que je fasse une vraie initiation, mais je n'ai pas vraiment le temps. J'ai toujours eu des soucis avec la programmation modulaire. Je suppose que le multithread aggrave les choses...

ce n'est pas si le foutoir que ça, ni mal écrit en général. Juste que je lis depuis mon iPhone et donc pas forcément simple de suivre le code et la séparation en "modules" me parait un peu bizarre.

pourriez vous poster les fichiers de code séparés avec leur nom pour comprendre l'organisation? (le .ino, y-a-t-il des .cpp et .h ou juste des .ino etc)

par exemple le bout de code où il y a le setup() et séparé de celui où il y a la loop() et le setup ne se termine pas par une }

Le comportement que tu décris dans ton premier message est étonnant, car tu n'affecte la variable 'tour' que dans la fonction 'BatteryAlarm'.
Sachant que tu as initialisé ta variable à 4, pour que la valeur passe à 3 normalement, c'est justement de passer dans ton if (tour == 3).

Il reste l'écrasement mémoire, mais là encore c'est assez surprenant, pour vérifier cet possibilité tu peux rajouter une variable genre tableau de char de 10 élément (char test[10];), juste avant int tour=4.

Ah oui, là il y a un soucis. Comme le script tourne en l'état j'ai dû faire une correction erronée pour équilibrer les accolades dans le fichier qui inclue..
Je vais déjà voir ça

Après avoir ajouté l'accolade finale ici j'en ai trouvé une en trop à la fin de E_SETUP_MULTITHREAD.h - bien sûr maintenant j'ai plein d'erreurs en chaîne. Il n'est pas un peu bizarre ce compilateur qui avalait mes fichiers avec de telles erreurs d'accolades? J'ai voulu installer VS Code hier Seven, il ne démarrait pas.
Voici l'output orange actuel:

In file included from I:\0a_2010\DEV_20\ESP32\PROJETS\MULTITACHE_THREADING\RECEPTEUR\B\ESP32-SRV-CAN_C-0151-00\ESP32-SRV-CAN_C-0151-00.ino:11:
D_SETUP_SERVER.h:3:3: error: 'Serial' does not name a type
Serial.println();
^~~~~~
D_SETUP_SERVER.h:4:3: error: 'Serial' does not name a type
Serial.println();
^~~~~~
D_SETUP_SERVER.h:5:3: error: 'Serial' does not name a type
Serial.print("Connecting to ");
^~~~~~
D_SETUP_SERVER.h:6:3: error: 'Serial' does not name a type
Serial.println(ssid);
^~~~~~
D_SETUP_SERVER.h:8:3: error: 'WiFi' does not name a type
WiFi.begin(ssid, password);
^~~~
D_SETUP_SERVER.h:9:3: error: expected unqualified-id before 'while'
while (WiFi.status() != WL_CONNECTED) {
^~~~~
D_SETUP_SERVER.h:13:3: error: 'Serial' does not name a type
Serial.println("");
^~~~~~
D_SETUP_SERVER.h:14:3: error: 'Serial' does not name a type
Serial.println("WiFi connected.");
^~~~~~
D_SETUP_SERVER.h:18:3: error: 'Serial' does not name a type
Serial.println("reconnaissance de carte ...");
^~~~~~
D_SETUP_SERVER.h:19:3: error: 'Serial' does not name a type
Serial.print("ESP Board MAC Address: ");
^~~~~~
D_SETUP_SERVER.h:20:3: error: 'mac' does not name a type
mac = WiFi.macAddress();
^~~
D_SETUP_SERVER.h:23:15: error: expected constructor, destructor, or type conversion before '(' token
configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);
^
D_SETUP_SERVER.h:28:1: error: 'WiFi' does not name a type
WiFi.mode(WIFI_MODE_STA);
^~~~
D_SETUP_SERVER.h:32:3: error: expected unqualified-id before 'if'
if (esp_now_init() != ESP_OK) {
^~
D_SETUP_SERVER.h:39:27: error: expected constructor, destructor, or type conversion before '(' token
esp_now_register_recv_cb(OnDataRecv);
^
D_SETUP_SERVER.h:44:3: error: 'Serial' does not name a type
Serial.println(mac);
^~~~~~
D_SETUP_SERVER.h:45:3: error: expected unqualified-id before 'if'
if(mac == "78:21:84:A0:29:08"){
^~
D_SETUP_SERVER.h:50:3: error: expected unqualified-id before 'else'
else if (mac == "EC:62:60:84:F9:A0"){
^~~~
D_SETUP_SERVER.h:55:3: error: expected unqualified-id before 'else'
else if (mac == "78:21:84:9F:78:50"){
^~~~
D_SETUP_SERVER.h:64:3: error: 'Serial' does not name a type
Serial.println("IP address: ");
^~~~~~
D_SETUP_SERVER.h:65:3: error: 'Serial' does not name a type
Serial.println(WiFi.localIP());
^~~~~~
D_SETUP_SERVER.h:69:3: error: 'rssi' does not name a type
rssi = WiFi.RSSI();
^~~~
D_SETUP_SERVER.h:70:3: error: 'Serial' does not name a type
Serial.print("RRSI: ");
^~~~~~
D_SETUP_SERVER.h:71:3: error: 'Serial' does not name a type
Serial.println(rssi);
^~~~~~
D_SETUP_SERVER.h:73:3: error: 'server' does not name a type
server.begin();
^~~~~~
In file included from I:\0a_2010\DEV_20\ESP32\PROJETS\MULTITACHE_THREADING\RECEPTEUR\B\ESP32-SRV-CAN_C-0151-00\ESP32-SRV-CAN_C-0151-00.ino:12:
E_SETUP_MULTITHREAD.h:7:26: error: expected constructor, destructor, or type conversion before '(' token
xTaskCreatePinnedToCore(
^
E_SETUP_MULTITHREAD.h:15:8: error: expected constructor, destructor, or type conversion before '(' token
delay(500);
^
E_SETUP_MULTITHREAD.h:18:26: error: expected constructor, destructor, or type conversion before '(' token
xTaskCreatePinnedToCore(
^
E_SETUP_MULTITHREAD.h:27:8: error: expected constructor, destructor, or type conversion before '(' token
delay(500);
^
Multiple libraries were found for "WiFi.h"
Used: C:\Users\bohin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\libraries\WiFi
Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
Using library WiFi at version 2.0.0 in folder: C:\Users\bohin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\libraries\WiFi
Using library SPIFFS at version 2.0.0 in folder: C:\Users\bohin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\libraries\SPIFFS
Using library FS at version 2.0.0 in folder: C:\Users\bohin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\libraries\FS
exit status 1
'Serial' does not name a type

voici la partie orange

PFOUUU... Je vous remercie tous mais je crois que c'est vraiment trop le bazar pour faire le ménage, je devrais recommencer avec moins de fichiers, peut-être même sans multithread.

Pardon mais vu mon niveau il faudrait développer un tout petit peu si tu as le temps merci. Tu veux que j'initialise un string en globale et après pas compris