ESP32S lisaison série

Bonjour, j'utilise deux ESP-32S NODE MCU avec antenne externe. Le premier pour recevoir des tags de Foobar2000 qui les envoi au deuxième via une liaison série. Celui-ci doit décoder les tags et les afficher sur deux bandeaux Led.

Le code du premier fonctionne bien mais j'ai du mal avec celui du deuxième car il y a un problème dans la boucle loop car l'arduino reboot en boucle. Voici le code du premier:

// ESP32S
// Programme pour se connecter au WiFi et au FTP pour lire les tags de Foobar dans un fichier .txt
// et les envoyer par le port série à l'autre arduino qui gère le bandeau

#include <WiFi.h>
#include <ESP32_FTPClient.h>
#include <SoftwareSerial.h>
SoftwareSerial portOne(18, 19);

// WiFi Livebox
#define WIFI_SSID "XXXX"
#define WIFI_PASS "XXXX"

// // Définie les pins du port série Série1
// #define RXD1 16
// #define TXD1 17

// FTP MakomotoryP
char ftp_server[] = "192.168.1.16";
char ftp_user[] = "XXXX";
char ftp_pass[] = "XXXX";
char fileName[] = "Foobar_Now_Playing.txt";
ESP32_FTPClient ftp (ftp_server, 21, ftp_user, ftp_pass, 1000);

// Variables d'envoi vers le port série
unsigned long TempoReadFtp;
int WifiRead, WifiSend, FtpRead, FtpSend, PortSerie;
String FoobarRead, FoobarSend;


// Envoi vers le moniteur série - Juste pour les tests
// A supprimer à la fin
void SendToSerial() {
  Serial.print("WiFi: ");
  Serial.print(WifiSend);
  Serial.print(" - FTP: ");
  Serial.print(FtpSend);
  Serial.print(" - Port série: ");
  Serial.print(PortSerie);
  Serial.print(" - FoobarSend: ");
  Serial.println(FoobarSend);
}


void setup() {
  TempoReadFtp = millis();
  WifiRead,  WifiSend, FtpRead, FtpSend, PortSerie = 0;
  FoobarRead, FoobarSend = "";
  
  // Initialisation moniteur série
  // A supprimer à la fin
  Serial.begin(115200);
  Serial.println();

  portOne.begin(115200);

  // Initialisation du WiFi
  // L'ESP32S s'occupe de la reconnection automatique
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  if(portOne.isListening()) { 
    Serial.println("portOne is listening!");
  }
  else { 
    Serial.println("portOne is not listening!");
  }

  if(portOne.available()){
    Serial.println("portOne is available!");
  }
  else {
    Serial.println("portOne is not available!");
  }

  // Envoi de la première trame pour renseigner le moniteur série
  // A supprimer à la fin
  //delay(1000);
  SendToSerial();
}


void loop() {
  // Etat du port série
  if(portOne.available()) {
    PortSerie = 1;
  }
  else {
    PortSerie = 0;
  }

  // Si WiFi déconnecté
  if(WiFi.status() != WL_CONNECTED){
    WifiRead = 0;
    FtpRead = 0;
    //FoobarRead = "";
  }

  // Si FTP Déconnecté
  if(ftp.isConnected()==0){
     FtpRead = 0;
     //FoobarRead = "";
  }
  
  // Si WiFi connecté
  if (WiFi.status() == WL_CONNECTED){
    WifiRead = 1;

    // Si FTP Déconnecté
    if(ftp.isConnected()==0){
      FtpRead = 0;
      //FoobarRead = "";
      ftp.OpenConnection();
    }

    // Si FTP connecté
    if((ftp.isConnected()==1)&&(millis()-TempoReadFtp)>=300){
      FtpRead = 1;

      // Lire le fichier
      String response = "";
      ftp.InitFile("Type A");
      ftp.DownloadString(fileName, response);
      FoobarRead = response;
      TempoReadFtp = millis();
    }
  }

  // Envoi sur le moniteur série
  // A supprimer à la fin
  if((WifiRead != WifiSend) || (FtpRead != FtpSend) || (FoobarRead != FoobarSend)){
    WifiSend = WifiRead;
    FtpSend = FtpRead;
    FoobarSend = FoobarRead;
    SendToSerial();
  }

  // Envoi sur le port série 'Série1' vers Arduino
  if((WifiRead != WifiSend) || (FtpRead != FtpSend) || (FoobarRead != FoobarSend)){
    while(portOne.available()){
      WifiSend = WifiRead;
      FtpSend = FtpRead;
      FoobarSend = FoobarRead;
      Serial.println("Envoi vers portOne");
      portOne.print("<");
      portOne.print(WifiSend);
      portOne.print("<");
      portOne.print(FtpSend);
      portOne.print("<");
      portOne.print(FoobarSend);
      portOne.println("#");
      //Serial.println("<");
    }
  }
}

...et voici le code du deuxième qui me pose problème. Je ne sais pas si cela vient de la boucle ListenSerial ou de la loop

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <SoftwareSerial.h>

SoftwareSerial portOne(18, 19);

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 16

#define CLK_PINH   27
#define DATA_PINH  25
#define CS_PINH    26

MD_Parola AffichHaut = MD_Parola(HARDWARE_TYPE, DATA_PINH, CLK_PINH, CS_PINH, MAX_DEVICES);

#define CLK_PINB   13
#define DATA_PINB  14
#define CS_PINB    12

MD_Parola AffichBas = MD_Parola(HARDWARE_TYPE, DATA_PINB, CLK_PINB, CS_PINB, 8);

char *EtatFoo = nullptr;
char *Artiste = nullptr;
char *Album = nullptr;
char *Titre = nullptr;
char *Bitrate = nullptr;
char *Codec = nullptr;
char *Duree = nullptr;

const size_t TailleMaxMessage = 100;
const char * separateurs = "<";
const char marqueurDeFin = '#';
char TexteHaut[TailleMaxMessage];
char TexteBas[TailleMaxMessage];

char SerialRead[TailleMaxMessage];
char SerialReadTmp[TailleMaxMessage];
char messageRecu[TailleMaxMessage];
char* SerialUse = nullptr;
char* WifiEtat = nullptr;
char* FtpEtat = nullptr;

//char portOneRead[TailleMaxMessage];   //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//int toto;

void ExtrTags(char * message) {
  WifiEtat = strtok(message, separateurs);
  FtpEtat  = strtok(NULL, separateurs);
  strcpy(EtatFoo, strtok(NULL, separateurs));
  strcpy(Artiste, strtok(NULL, separateurs));
  strcpy(Album, strtok(NULL, separateurs));
  strcpy(Titre, strtok(NULL, separateurs));
  strcpy(Bitrate, strtok(NULL, separateurs));
  strcpy(Codec, strtok(NULL, separateurs));
  strcpy(Duree, strtok(NULL, separateurs));
  Serial.println("Extract tags OK");   // PHASE TEST
}

void MoniSerie(){
  Serial.println("Affichage de l'extration des tags");
  Serial.print("WifiEtat: ");   Serial.println(WifiEtat);
  Serial.print("FtpEtat: ");    Serial.println(FtpEtat);
  Serial.print("EtatFoo: ");    Serial.println(EtatFoo);
  Serial.print("Artiste: ");    Serial.println(Artiste);
  Serial.print("Album: ");      Serial.println(Album);
  Serial.print("Titre: ");      Serial.println(Titre);
  Serial.print("Bitrate: ");    Serial.println(Bitrate);
  Serial.print("Codec: ");      Serial.println(Codec);
  Serial.print("Duree: ");      Serial.println(Duree);
}

void Afficher() {
  Serial.println("**Texte envoyé aux afficheurs**");
  Serial.print("TexteHaut: ");  Serial.println(TexteHaut);
  Serial.print("TexteBas: ");   Serial.println(TexteBas);

  if(AffichHaut.displayAnimate()) {
    AffichHaut.displayText(TexteHaut, AffichHaut.getTextAlignment(), AffichHaut.getSpeed(), AffichHaut.getPause(),PA_MESH ,PA_MESH );
    AffichHaut.displayReset();
  }
 
  if(AffichBas.displayAnimate()) {
    AffichBas.displayText(TexteBas, AffichBas.getTextAlignment(), AffichBas.getSpeed(), AffichBas.getPause(),PA_MESH ,PA_MESH );
    AffichBas.displayReset();
  }
}

void ListenSerial(){
  while (portOne.available()) {
    char c = portOne.read();
    if (c != -1) {
      switch (c) {
        case marqueurDeFin:
          SerialReadTmp[0] = '\0'; // On termine la c-string
          strcpy(SerialRead, SerialReadTmp);
          Serial.print("Lecture Serial1: "); 
          Serial.println(SerialReadTmp);
          break;
        default:
          strncat(SerialReadTmp, &c, 1); // On ajoute le caractère à la c-string
          break;
      }
    }
  }
}


// void ListenSerial(){
//   while (portOne.available()) {
//     Serial.println("Boucle reception Serial1");   // PHASE TEST

//     char toto = portOne.read();

//     strncat(SerialReadTmp, &toto, 1);

//     //SerialReadTmp = portOne.read([TailleMaxMessage]);
//     Serial.print("Lecture Serial1: ");
//     Serial.println(SerialReadTmp);
//   }
//   // return messageEnCours;
// }



void setup() {
  Serial.begin(115200);  // Initialisation moniteur série   // PHASE TEST
  portOne.begin(115200);

  AffichHaut.begin();
  AffichHaut.setIntensity(0);
  AffichHaut.setTextAlignment(PA_LEFT);
  AffichHaut.setSpeed(40);
  AffichHaut.setPause(3000);
  AffichHaut.displayClear();
  AffichBas.begin();
  AffichBas.setIntensity(0);
  AffichBas.setTextAlignment(PA_LEFT);
  AffichBas.setSpeed(40);
  AffichBas.setPause(3000);
  AffichBas.displayClear();

  WifiEtat = "0";
  FtpEtat = "0";
}


//Cette boucle fait juste planter l'arduino "begin: exit"
void loop() {
  ListenSerial();

  if(SerialRead[0] != '\0'){
    ExtrTags(SerialRead);

    snprintf(TexteHaut, sizeof TexteHaut, "%s - %s", Artiste, Album);
    snprintf(TexteBas, sizeof TexteBas, "%s - %s", Titre, Duree);

    Afficher();
    SerialRead[0] = '\0'; // Réinitialiser le buffer
  }
}


//Cette boucle fait rebouter l'arduino en boucle
// void loop() {
//   ListenSerial();
  
//   if(SerialRead != SerialReadTmp){
//     //SerialReadTmp.toCharArray(SerialRead, TailleMaxMessage);
//     strlcpy(SerialRead, SerialReadTmp, TailleMaxMessage);

//     ExtrTags(SerialRead);

//     //Formatage des données pour les Afficheurs
//     snprintf(TexteHaut, sizeof TexteHaut, "%s - %s", Artiste, Album);
//     snprintf(TexteBas, sizeof TexteBas, "%s - %s", Titre, Duree);

//     Afficher();
//   }
// }

Tu es certain que tu ne reçois jamais plus de 99 caractères?

Salut,
Je ne suis pas certains de ne jamais en recevoir mais cela serait un cas très rare. Je contrôle avec le moniteur série et jamais de problème d'affichage venant de l'ESP32S qui émet.

Tu as des impressions sur le moniteur série, peut tu nous les donner, pour ce que tu reçcois et essayer d'identifier dans quelle partie de ton code tu crash l'ESP?

Il faut que je rebranche l'ESP et que je charge son code.
Mais même quand il ne reçoit rien, quand la liaison série est coupée, il plante au démarrage.

Oui mais lui utilise des String qui n'ont pas de problème de débordement puisqu'elles peuvent grandir indéfiniment (pour autant qu'il y ait de la mémoire libre)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.