📱 Diffuseur de messages prĂ©-enregistrĂ©s

pour ceux que cela intéresse, je crée mes annonces en mp3 sur ce générateur TTS :
Free Text-To-Speech for 28+ languages & MP3 Download | ttsMP3.com

2 « J'aime »

voici un programme avec plus de fonctionnalités :

  • vĂ©rification pĂ©riodique de la connexion Wifi avec tentative de reconnexion automatique.
  • WifiManager
  • Led verte si connexion OK
  • Led rouge si dĂ©connectĂ©
  • gestion de la broche BUSY

#include <WiFi.h>
#include <AsyncTCP.h> // dépendance pour ESPAsyncWebServer
#include <WiFiManager.h> // à déclarer avant ESPAsyncWebServer pour éviter les conflits
#include <ESPAsyncWebServer.h> // serveur web asynchrone
#include <DYPlayerArduino.h> // lib pour DY-HV20T like
#include <HardwareSerial.h> // port série
#include <ArduinoJson.h>

// Définition des broches RX/TX
HardwareSerial SerialPort1(1);

// Broche BUSY du DY-HV20T
#define BUSY_PIN 27

// Broches des LEDs
#define LED_VERTE 25
#define LED_ROUGE 32

// Initialisation du DYPlayer
DY::Player player(&SerialPort1);

// Initialisation du serveur
AsyncWebServer server(80);

// Initialisation du WiFiManager
WiFiManager wifiManager;

// Variable pour stocker l'état de la connexion Wi-Fi
bool isConnected = false;

// Variables pour la vérification périodique non bloquante
unsigned long previousMillis = 0; // Stocke le dernier moment oĂč la vĂ©rification a Ă©tĂ© effectuĂ©e
const long interval = 1000;       // Intervalle de vérification (1 seconde)

void setup() {
  // Configuration des broches série pour le module DY HV20T
  SerialPort1.begin(9600, SERIAL_8N1, 1, 3);

  // Configuration de la broche BUSY en entrée
  pinMode(BUSY_PIN, INPUT);

  // Configuration des broches des LEDs en sortie
  pinMode(LED_VERTE, OUTPUT);
  pinMode(LED_ROUGE, OUTPUT);

  // Éteindre les LEDs au dĂ©marrage
  digitalWrite(LED_VERTE, LOW);
  digitalWrite(LED_ROUGE, LOW);

  // Configurer le point d'accÚs avec un mot de passe par défaut
  wifiManager.autoConnect("ESP32-AudioPlayer", "motdepasse"); // SSID : "ESP32-AudioPlayer", Mot de passe : "motdepasse"

  // Optimiser les paramĂštres Wi-Fi
 // WiFi.setTxPower(WIFI_POWER_19_5dBm); // Augmente la puissance du signal Wi-Fi
  WiFi.setSleep(false); // Désactive le mode veille Wi-Fi

  // Vérifier si la connexion Wi-Fi est réussie
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("Connecté au Wi-Fi");
    Serial.println(WiFi.localIP());
    digitalWrite(LED_VERTE, HIGH); // Allumer la LED verte
    digitalWrite(LED_ROUGE, LOW);  // Éteindre la LED rouge
    isConnected = true; // Mettre à jour l'état de la connexion
    player.playSpecified(1); // Jouer le fichier 1 si la connexion est réussie
  } else {
    Serial.println("Échec de la connexion au Wi-Fi");
    digitalWrite(LED_VERTE, LOW);  // Éteindre la LED verte
    digitalWrite(LED_ROUGE, HIGH); // Allumer la LED rouge
    isConnected = false; // Mettre à jour l'état de la connexion
    player.playSpecified(2); // Jouer le fichier 2 en cas d'échec
  }

  // Route pour jouer un fichier avec volume
  server.on("/play", HTTP_GET, [](AsyncWebServerRequest *request) {
    if (request->hasParam("volume") && request->hasParam("file")) {
      int volume = request->getParam("volume")->value().toInt();
      int fileNumber = request->getParam("file")->value().toInt();

      // Créer un objet JSON pour la réponse
      DynamicJsonDocument jsonResponse(200);
      jsonResponse["status"] = 1; // SuccĂšs
      jsonResponse["file"] = fileNumber;
      jsonResponse["volume"] = volume;

      // Régler le volume
      player.setVolume(volume);
      delay(50); // Pause pour permettre au module de traiter

      // Attendre que le module soit prĂȘt (broche BUSY LOW) avec un timeout
      unsigned long startTime = millis();
      while (digitalRead(BUSY_PIN) == LOW && millis() - startTime < 1000) {
        delay(10); // Attendre que le module soit libre, avec un timeout de 1 seconde
      }
      if (digitalRead(BUSY_PIN) == LOW) {
        Serial.println("Timeout : le module n'est pas prĂȘt");
        jsonResponse["status"] = 0; // Échec
        jsonResponse["message"] = "Le module n'est pas prĂȘt";
      } else {
        // Jouer le fichier
        player.playSpecified(fileNumber);
      }

      // Convertir l'objet JSON en chaĂźne de caractĂšres
      String response;
      serializeJson(jsonResponse, response);

      // Envoyer la réponse JSON
      request->send(200, "application/json", response);
    } else {
      // Réponse JSON en cas de paramÚtres manquants
      DynamicJsonDocument jsonError(100);
      jsonError["status"] = 0; // Échec
      jsonError["message"] = "ParamĂštres manquants : volume et/ou file";

      String errorResponse;
      serializeJson(jsonError, errorResponse);

      request->send(400, "application/json", errorResponse);
    }
  });

  // Démarrer le serveur
  server.begin();
}

void loop() {
  // Vérification périodique non bloquante de la connexion Wi-Fi
  unsigned long currentMillis = millis(); // Temps actuel

  if (currentMillis - previousMillis >= interval) {
    // Sauvegarder le dernier moment oĂč la vĂ©rification a Ă©tĂ© effectuĂ©e
    previousMillis = currentMillis;

    // Vérifier l'état de la connexion Wi-Fi
    if (WiFi.status() != WL_CONNECTED && isConnected) {
      // Déconnexion détectée
      Serial.println("Déconnecté du Wi-Fi");
      digitalWrite(LED_VERTE, LOW);  // Éteindre la LED verte
      digitalWrite(LED_ROUGE, HIGH); // Allumer la LED rouge
      isConnected = false; // Mettre à jour l'état de la connexion
      reconnectWiFi(); // Tenter de se reconnecter
    } else if (WiFi.status() == WL_CONNECTED && !isConnected) {
      // Reconnexion réussie
      Serial.println("Reconnecté au Wi-Fi");
      digitalWrite(LED_VERTE, HIGH); // Allumer la LED verte
      digitalWrite(LED_ROUGE, LOW);  // Éteindre la LED rouge
      isConnected = true; // Mettre à jour l'état de la connexion
    }
  }

  // Le serveur web asynchrone continue de fonctionner sans ĂȘtre bloquĂ©
}

// Fonction pour tenter de se reconnecter au Wi-Fi
void reconnectWiFi() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Tentative de reconnexion au Wi-Fi...");
    WiFi.disconnect();
    WiFi.reconnect();
    delay(1000); // Attendre 1 seconde avant de vérifier à nouveau
  }
}

mp3.zip (19,1 Ko)

Il ne me reste plus qu’à mettre en boüte :slight_smile:

Je vous laisse adapter et améliorer le code selon vos besoins. Merci de nous faire un retour.

T’es survoltĂ©, j’ampĂšre mes moyens et ne puis opposer rĂ©sistance Ă  tes arguments, c’est au delĂ  de mes capacitĂ©s ! :rofl::rofl::rofl:

9 « J'aime »

Intégration terminée dans un petit haut parleur de PC de 13 cm de haut.

Le montage est alimenté en USB, il est en standalone sur un meuble du salon.

La tension en entrĂ©e du module Ă©lĂ©vateur de tension Ă©tant prĂ©levĂ©e sur l’USB, est donc de 5.08V. J’ai rĂ©glĂ© la sortie Ă  11.5V. Faites attention, la sortie peut facilement atteindre 30V si vous rĂ©glez mal le potentiomĂštre. MĂȘme si le module audio le supporterait ce n’est pas la peine de dĂ©passer 12V.

Le connecteur micro-USB Ă  l’arriĂšre du HP permet la connexion au PC pour le tĂ©lĂ©versement des fichiers audio sur la carte SD du module.
Pour le tĂ©lĂ©versement, dĂ©branchez l’alimentation du montage, ne branchez que le port micro USB du module audio Ă  votre PC.
J’ai remplacĂ© les 2 leds par une Led bicolore (bleu/rouge) Ă  cathode commune. J’ai donc utilisĂ© une seule rĂ©sistance entre la cathode et le Gnd du montage.

Le bouton de volume est factice, j’ai rĂ©glĂ© le volume du module assez fort via le mini potentiomĂštre prĂ©sent sur le module. Je prĂ©fĂšre rĂ©gler le volume via la valeur « volume Â» insĂ©rĂ©e dans les push. De plus, cela Ă©vite que le volume du Haut-parleur soit baissĂ© par inadvertance et rendent les messages inaudibles.

2 « J'aime »

Salut François

t’as pas mis une zener 12v ?

Sinon :+1: l’intĂ©gration dans l’enceinte :star_struck:

bonjour Claude,
non pas de zener, la tension est rĂ©glĂ©e par le potar de l’élĂ©vateur. La tension 5V Ă©tant rĂ©gulĂ©e par une alim de bonne marque (Anker) et le module supportant jusqu’à 35V, je n’ai pas trouvĂ© utile de limiter la tension.

J’avais Ă©galement mis une rĂ©sistance d’1 k sur le haut-parleur. Je l’ai retirĂ©e car je n’ai pas de bruit parasite.

Schéma ajusté avec la Led bicolore à cathode commune

Matériel utilisé :

bonne journée

4 « J'aime »

Bonsoir fgtoul, pour téléverser le code. Tu utilise quoi ?
Le logiciel Arduino ?

bonjour Arnaud,

oui, j’utilise Arduino IDE.

Bonne journée

Merci pour ta réponse.
Tu mets quoi comme référence de carte dans le logiciel ?
Je suppose que tu as aussi télécharger toutes les bibliothÚques avant.

Bonsoir Ă  tous,

Une implĂ©mentation Ă  tester, si vous pouvez faire des retours ( j’ai pas encore le matos et pas le temps en ce moment) ! :+1:

Cela devrait ajouter des fonctionnalités supplementaires autant HTTP mais surtout MQTT
telles que :

  1. Jouer un son :
    • HTTP GET : /play?track=<numĂ©ro_piste>
    • MQTT : Publier <numĂ©ro_piste> sur le topic « son/play Â»
  2. ArrĂȘter la lecture :
    • HTTP GET : /stop
    • MQTT : Publier « stop Â» sur le topic « son/control Â»
  3. Mettre en pause :
    - HTTP GET : /pause
    - MQTT : Publier « pause Â» sur le topic « son/control Â»
  4. Reprendre la lecture :
    - HTTP GET : /resume
    - MQTT : Publier « resume Â» sur le topic « son/control Â»
  5. ContrĂŽle du volume :
    - HTTP GET : /volume?value=<0-30>
    - MQTT : Publier <0-30> sur le topic « son/volume Â»
  6. Obtenir l’état courant :
    - HTTP GET : /status
    - MQTT : Publier « status Â» sur le topic « son/control Â» (la rĂ©ponse arrive sur « son/status Â»)
  7. Mode streaming distant :
    - HTTP GET : /stream?url=<url_audio>
  8. Liste des pistes disponibles :
    - HTTP GET : /tracks

:scream:

Code V2
//  
 // Commandes disponibles pour contrĂŽler le DY-HV20T :
 //  
 // 1. Jouer un son :
 //   - HTTP GET : /play?track=<numéro_piste>
 //   - MQTT    : Publier <numéro_piste> sur le topic "son/play"
 //  
 // 2. ArrĂȘter la lecture :
 //   - HTTP GET : /stop
 //   - MQTT    : Publier "stop" sur le topic "son/control"
 //  
 // 3. Mettre en pause :
 //   - HTTP GET : /pause
 //   - MQTT    : Publier "pause" sur le topic "son/control"
 //  
 // 4. Reprendre la lecture :
 //   - HTTP GET : /resume
 //   - MQTT    : Publier "resume" sur le topic "son/control"
 //  
 // 5. ContrĂŽle du volume :
 //   - HTTP GET : /volume?value=<0-30>
 //   - MQTT    : Publier <0-30> sur le topic "son/volume"
 //  
 // 6. Obtenir l'état courant :
 //   - HTTP GET : /status
 //   - MQTT    : Publier "status" sur le topic "son/control" (la réponse arrive sur "son/status")
 //  
 // 7. Mode streaming distant :
 //   - HTTP GET : /stream?url=<url_audio>
 //  
 // 8. Liste des pistes disponibles :
 //   - HTTP GET : /tracks
 // 
 
#include <WiFi.h>
#include <AsyncTCP.h>
#include <WiFiManager.h>
#include <ESPAsyncWebServer.h>
#include <DYPlayerArduino.h>
#include <HardwareSerial.h>
#include <ArduinoJson.h>
#include <PubSubClient.h> // Ajout V2  : MQTT + Fonctionnalités V2

// Définition des broches RX/TX
HardwareSerial SerialPort1(1);

// Broche BUSY du DY-HV20T
#define BUSY_PIN 27

// Broches des LEDs
#define LED_VERTE 25
#define LED_ROUGE 32

// Configuration MQTT
const char* mqtt_server = "IP broker mqtt"; // À adapter // Ajout V2  : MQTT + FonctionnalitĂ©s V2
WiFiClient espClient;                                    // Ajout V2  : MQTT + Fonctionnalités V2
PubSubClient mqttClient(espClient);                      // Ajout V2  : MQTT + Fonctionnalités V2

// Initialisation du DYPlayer
DY::Player player(&SerialPort1);

// Initialisation du serveur
AsyncWebServer server(80);

// Initialisation du WiFiManager
WiFiManager wifiManager;

// Variable pour stocker l'état de la connexion Wi-Fi
bool isConnected = false;

// Variables pour la vérification périodique non bloquante
unsigned long previousMillis = 0; // Stocke le dernier moment oĂč la vĂ©rification a Ă©tĂ© effectuĂ©e
const long interval = 1000;       // Intervalle de vérification (1 seconde)

// Variables globales
int currentVolume = 30;  // Ajout V2  : MQTT + Fonctionnalités V2
int currentTrack = 0;    // Ajout V2  : MQTT + Fonctionnalités V2 
bool isPlaying = false;  // Ajout V2  : MQTT + Fonctionnalités V2
bool isPaused = false;   // Ajout V2  : MQTT + Fonctionnalités V2

void setup() {
	
  // Configuration des broches série pour le module DY HV20T
  Serial.begin(115200);
  SerialPort1.begin(9600, SERIAL_8N1, 1, 3);

  // Configuration de la broche BUSY en entrée
  pinMode(BUSY_PIN, INPUT);
		
  // Configuration des broches des LEDs en sortie
  pinMode(LED_VERTE, OUTPUT);
  pinMode(LED_ROUGE, OUTPUT);
	
	// Éteindre les LEDs au dĂ©marrage
  digitalWrite(LED_VERTE, LOW);
  digitalWrite(LED_ROUGE, LOW);
	
	// Configurer le point d'accÚs avec un mot de passe par défaut
  wifiManager.autoConnect("ESP32-AudioPlayer", "motdepasse"); // SSID : "ESP32-AudioPlayer", Mot de passe : "motdepasse"
  
  // Optimiser les paramĂštres Wi-Fi
  // WiFi.setTxPower(WIFI_POWER_19_5dBm); // Augmente la puissance du signal Wi-Fi
  WiFi.setSleep(false); // Désactive le mode veille Wi-Fi
	
  // Vérifier si la connexion Wi-Fi est réussie
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("Connecté au Wi-Fi");
    Serial.println(WiFi.localIP());
    digitalWrite(LED_VERTE, HIGH); // Allumer la LED verte
    digitalWrite(LED_ROUGE, LOW);  // Éteindre la LED rouge
    isConnected = true; // Mettre à jour l'état de la connexion
    player.playSpecified(1); // Jouer le fichier 1 si la connexion est réussie
    currentTrack = 1;  // Ajout V2  : MQTT + Fonctionnalités V2
    isPlaying = true;  // Ajout V2  : MQTT + Fonctionnalités V2
  } else {
    Serial.println("Échec de la connexion au Wi-Fi");
    digitalWrite(LED_VERTE, LOW);  // Éteindre la LED verte
    digitalWrite(LED_ROUGE, HIGH); // Allumer la LED rouge
    isConnected = false; // Mettre à jour l'état de la connexion
    player.playSpecified(2); // Jouer le fichier 2 en cas d'échec
  }

  // Initialisation MQTT
  mqttClient.setServer(mqtt_server, 1883); // Ajout V2  : MQTT + Fonctionnalités V2
  mqttClient.setCallback(mqttCallback); // Ajout V2  : MQTT + Fonctionnalités V2

  // Route pour jouer un fichier avec volume
  server.on("/play", HTTP_GET, [](AsyncWebServerRequest *request) {
    if (request->hasParam("volume") && request->hasParam("file")) {
      int volume = request->getParam("volume")->value().toInt();
      int fileNumber = request->getParam("file")->value().toInt();

     // Créer un objet JSON pour la réponse
      DynamicJsonDocument jsonResponse(200);
      jsonResponse["status"] = 1; // SuccĂšs
      jsonResponse["file"] = fileNumber;
      jsonResponse["volume"] = volume;
			
			// Régler le volume
      player.setVolume(volume);
      currentVolume = volume;  // Ajout V2  : MQTT + Fonctionnalités V2
      delay(50); // Pause pour permettre au module de traiter

      // Attendre que le module soit prĂȘt (broche BUSY LOW) avec un timeout
      unsigned long startTime = millis();
      while (digitalRead(BUSY_PIN) == LOW && millis() - startTime < 1000) {
        delay(10); // Attendre que le module soit libre, avec un timeout de 1 seconde
      }
      if (digitalRead(BUSY_PIN) == LOW) {
        Serial.println("Timeout : le module n'est pas prĂȘt");  // Ajout V2  : MQTT + FonctionnalitĂ©s V2
        jsonResponse["status"] = 0; // Échec
        jsonResponse["message"] = "Le module n'est pas prĂȘt";
      } else {
        // Jouer le fichier
        player.playSpecified(fileNumber);
        currentTrack = fileNumber; // Ajout V2  : MQTT + Fonctionnalités V2
        isPlaying = true; // Ajout V2  : MQTT + Fonctionnalités V2
        isPaused = false; // Ajout V2  : MQTT + Fonctionnalités V2
      }

      // Convertir l'objet JSON en chaĂźne de caractĂšres
      String response;
      serializeJson(jsonResponse, response);

      // Envoyer la réponse JSON
      request->send(200, "application/json", response);
    } else {
      // Réponse JSON en cas de paramÚtres manquants
      DynamicJsonDocument jsonError(100);
      jsonError["status"] = 0; // Échec
      jsonError["message"] = "ParamĂštres manquants : volume et/ou file";

      String errorResponse;
      serializeJson(jsonError, errorResponse);

      request->send(400, "application/json", errorResponse);			
    }
		
	
  });

  // Nouvelles routes HTTP // Ajout V2  : MQTT + Fonctionnalités V2
  server.on("/stop", HTTP_GET, [](AsyncWebServerRequest *request) { // Ajout V2  : MQTT + Fonctionnalités V2
    player.stop(); // Ajout V2  : MQTT + Fonctionnalités V2
    isPlaying = false; // Ajout V2  : MQTT + Fonctionnalités V2
    request->send(200, "text/plain", "Playback stopped"); // Ajout V2  : MQTT + Fonctionnalités V2
  }); // Ajout V2  : MQTT + Fonctionnalités V2

  server.on("/pause", HTTP_GET, [](AsyncWebServerRequest *request) { // Ajout V2  : MQTT + Fonctionnalités V2
    player.pause(); // Ajout V2  : MQTT + Fonctionnalités V2
    isPaused = true; // Ajout V2  : MQTT + Fonctionnalités V2
    request->send(200, "text/plain", "Playback paused"); // Ajout V2  : MQTT + Fonctionnalités V2
  }); // Ajout V2  : MQTT + Fonctionnalités V2

  server.on("/resume", HTTP_GET, [](AsyncWebServerRequest *request) { // Ajout V2  : MQTT + Fonctionnalités V2
    player.play(); // Ajout V2  : MQTT + Fonctionnalités V2
    isPaused = false; // Ajout V2  : MQTT + Fonctionnalités V2
    request->send(200, "text/plain", "Playback resumed"); // Ajout V2  : MQTT + Fonctionnalités V2
  }); // Ajout V2  : MQTT + Fonctionnalités V2

  server.on("/volume", HTTP_GET, [](AsyncWebServerRequest *request) { // Ajout V2  : MQTT + Fonctionnalités V2
    if (request->hasParam("value")) { // Ajout V2  : MQTT + Fonctionnalités V2
      int vol = request->getParam("value")->value().toInt(); // Ajout V2  : MQTT + Fonctionnalités V2
      if (vol >= 0 && vol <= 30) { // Ajout V2  : MQTT + Fonctionnalités V2
        player.setVolume(vol); // Ajout V2  : MQTT + Fonctionnalités V2
        currentVolume = vol; // Ajout V2  : MQTT + Fonctionnalités V2
        request->send(200, "text/plain", "Volume set to " + String(vol)); // Ajout V2  : MQTT + Fonctionnalités V2
      } else { // Ajout V2  : MQTT + Fonctionnalités V2
        request->send(400, "text/plain", "Volume must be 0-30"); // Ajout V2  : MQTT + Fonctionnalités V2
      } // Ajout V2  : MQTT + Fonctionnalités V2
    } else { // Ajout V2  : MQTT + Fonctionnalités V2
      request->send(400, "text/plain", "Missing value parameter"); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2
  }); // Ajout V2  : MQTT + Fonctionnalités V2

  server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request) { // Ajout V2  : MQTT + Fonctionnalités V2
    DynamicJsonDocument doc(200); // Ajout V2  : MQTT + Fonctionnalités V2
    doc["track"] = currentTrack; // Ajout V2  : MQTT + Fonctionnalités V2
    doc["volume"] = currentVolume; // Ajout V2  : MQTT + Fonctionnalités V2
    doc["status"] = isPlaying ? (isPaused ? "paused" : "playing") : "stopped"; // Ajout V2  : MQTT + Fonctionnalités V2
    String response; // Ajout V2  : MQTT + Fonctionnalités V2
    serializeJson(doc, response); // Ajout V2  : MQTT + Fonctionnalités V2
    request->send(200, "application/json", response); // Ajout V2  : MQTT + Fonctionnalités V2
  }); // Ajout V2  : MQTT + Fonctionnalités V2
	
  // Démarrer le serveur
  server.begin();

}

void loop() {
	
  // Vérification périodique non bloquante de la connexion Wi-Fi
  unsigned long currentMillis = millis(); // Temps actuel
	
	if (currentMillis - previousMillis >= interval) {
    // Sauvegarder le dernier moment oĂč la vĂ©rification a Ă©tĂ© effectuĂ©e
    previousMillis = currentMillis;
    checkWiFiConnection();  // Ajout V2  : MQTT + Fonctionnalités V2
  }

  // Gestion MQTT
  if (!mqttClient.connected()) { // Ajout V2  : MQTT + Fonctionnalités V2
    reconnectMQTT(); // Ajout V2  : MQTT + Fonctionnalités V2
  }
  mqttClient.loop(); // Ajout V2  : MQTT + Fonctionnalités V2
	
}

// Callback MQTT // Ajout V2  : MQTT + Fonctionnalités V2
void mqttCallback(char* topic, byte* payload, unsigned int length) { // Ajout V2  : MQTT + Fonctionnalités V2
 
 String message; // Ajout V2  : MQTT + Fonctionnalités V2
  for (unsigned int i = 0; i < length; i++) { // Ajout V2  : MQTT + Fonctionnalités V2
    message += (char)payload[i]; // Ajout V2  : MQTT + Fonctionnalités V2
  } // Ajout V2  : MQTT + Fonctionnalités V2

  String topicStr(topic); // Ajout V2  : MQTT + Fonctionnalités V2

  if (topicStr == "son/play") { // Ajout V2  : MQTT + Fonctionnalités V2
    int track = message.toInt(); // Ajout V2  : MQTT + Fonctionnalités V2
    if(track > 0) { // Ajout V2  : MQTT + Fonctionnalités V2
      player.playSpecified(track); // Ajout V2  : MQTT + Fonctionnalités V2
      currentTrack = track; // Ajout V2  : MQTT + Fonctionnalités V2
      isPlaying = true; // Ajout V2  : MQTT + Fonctionnalités V2
      isPaused = false; // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2
  }  // Ajout V2  : MQTT + Fonctionnalités V2
  else if (topicStr == "son/control") { // Ajout V2  : MQTT + Fonctionnalités V2
    if(message == "stop") { // Ajout V2  : MQTT + Fonctionnalités V2
      player.stop(); // Ajout V2  : MQTT + Fonctionnalités V2
      isPlaying = false; // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2 
    else if(message == "pause") { // Ajout V2  : MQTT + Fonctionnalités V2
      player.pause(); // Ajout V2  : MQTT + Fonctionnalités V2
      isPaused = true; // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2  
    else if(message == "resume") { // Ajout V2  : MQTT + Fonctionnalités V2
      player.play(); // Ajout V2  : MQTT + Fonctionnalités V2
      isPaused = false; // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2 
    else if(message == "status") { // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2
  } // Ajout V2  : MQTT + Fonctionnalités V2
  else if (topicStr == "son/volume") { // Ajout V2  : MQTT + Fonctionnalités V2
    int vol = message.toInt(); // Ajout V2  : MQTT + Fonctionnalités V2
    if(vol >= 0 && vol <= 30) { // Ajout V2  : MQTT + Fonctionnalités V2
      player.setVolume(vol); // Ajout V2  : MQTT + Fonctionnalités V2
      currentVolume = vol; // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2
  } // Ajout V2  : MQTT + Fonctionnalités V2
} // Ajout V2  : MQTT + Fonctionnalités V2

// Fonction pour envoyer le status via MQTT Ajout V2  : MQTT + Fonctionnalités V2 
void sendStatusUpdate() { // Ajout V2  : MQTT + Fonctionnalités V2
  DynamicJsonDocument doc(200); // Ajout V2  : MQTT + Fonctionnalités V2
  doc["track"] = currentTrack; // Ajout V2  : MQTT + Fonctionnalités V2
  doc["volume"] = currentVolume; // Ajout V2  : MQTT + Fonctionnalités V2
  doc["status"] = isPlaying ? (isPaused ? "paused" : "playing") : "stopped"; // Ajout V2  : MQTT + Fonctionnalités V2
  String json; // Ajout V2  : MQTT + Fonctionnalités V2
  serializeJson(doc, json); // Ajout V2  : MQTT + Fonctionnalités V2
  mqttClient.publish("son/status", json.c_str()); // Ajout V2  : MQTT + Fonctionnalités V2
}

void reconnectMQTT() { // Ajout V2  : MQTT + Fonctionnalités V2
  while (!mqttClient.connected()) { // Ajout V2  : MQTT + Fonctionnalités V2
    Serial.println("Connecting to MQTT..."); // Ajout V2  : MQTT + Fonctionnalités V2
    if (mqttClient.connect("ESP32AudioPlayer")) { // Ajout V2  : MQTT + Fonctionnalités V2
      mqttClient.subscribe("son/play"); // Ajout V2  : MQTT + Fonctionnalités V2
      mqttClient.subscribe("son/control"); // Ajout V2  : MQTT + Fonctionnalités V2
      mqttClient.subscribe("son/volume"); // Ajout V2  : MQTT + Fonctionnalités V2
      Serial.println("MQTT connected"); // Ajout V2  : MQTT + Fonctionnalités V2
      sendStatusUpdate(); // Envoyer l'état actuel aprÚs connexion // Ajout V2  : MQTT + Fonctionnalités V2
    } else { // Ajout V2  : MQTT + Fonctionnalités V2
      delay(2000); // Ajout V2  : MQTT + Fonctionnalités V2
    } // Ajout V2  : MQTT + Fonctionnalités V2
  } // Ajout V2  : MQTT + Fonctionnalités V2
} // Ajout V2  : MQTT + Fonctionnalités V2

// Fonction pour vérifier la connexion au Wi-Fi est ok ou pas // Ajout V2  : MQTT + Fonctionnalités V2  
void checkWiFiConnection() { // Ajout V2  : MQTT + Fonctionnalités V2 
	
  // Vérifier l'état de la connexion Wi-Fi
  if (WiFi.status() != WL_CONNECTED && isConnected) {
    // Déconnexion détectée
		Serial.println("Déconnecté du Wi-Fi");
		digitalWrite(LED_VERTE, LOW);  // Éteindre la LED verte
		digitalWrite(LED_ROUGE, HIGH); // Allumer la LED rouge
		isConnected = false; // Mettre à jour l'état de la connexion
		reconnectWiFi(); // Tenter de se reconnecter
	} else if (WiFi.status() == WL_CONNECTED && !isConnected) {
		// Reconnexion réussie
		Serial.println("Reconnecté au Wi-Fi");
		digitalWrite(LED_VERTE, HIGH); // Allumer la LED verte
		digitalWrite(LED_ROUGE, LOW);  // Éteindre la LED rouge
		isConnected = true; // Mettre à jour l'état de la connexion
	}
		
} // Ajout V2  : MQTT + Fonctionnalités V2

// Fonction pour tenter de se reconnecter au Wi-Fi
void reconnectWiFi() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Tentative de reconnexion au Wi-Fi...");
    WiFi.disconnect();
    WiFi.reconnect();
    delay(1000); // Attendre 1 seconde avant de vérifier à nouveau
  }
}

A vos claviers ! :grinning:

Bonjour Ă  tous,
pour ceux qui prĂ©fĂšrent du filaire et qui ont la chance d’avoir une IPX800 V5, sachez qu’il existe Ă©galement des modules de lecture MP3 en Modbus RTU pour moins de 30€ (modĂšle FN-BC07)
Ce module peut par exemple ĂȘtre utilisĂ© sur un systĂšme d’alarme et diffuser des messages dissuasifs en cas d’intrusion, un chien de garde Ă©lectronique, un simulateur de prĂ©sence, activation d’un relai avec accessoire (exemple : diffuseur de fumĂ©e) via la sortie « Warning light Â», etc.

Bon WE

2 « J'aime »

Une question sur l’esp32. Je suis pas trĂšs calĂ© sur ce type de code.
Il y a moyen de le modifier pour qu’il se connecte Ă  un rĂ©seau wifi plutĂŽt que d’émettre

Bonjour Arnaud,
C’est ce que fait mon code :slight_smile:
L’ESP32 se connecte au wifi et attend une requĂȘte HTTP pour jouer une piste prĂ©-enregistrĂ©e sur son haut-parleur.

Bonjour Arnaud44,
vous pensez à un lecteur réseau audio pour recevoir le flux des radios web?

Bonne journée

le montage ne permet pas d’avoir une qualitĂ© stĂ©rĂ©o, il n’y a qu"un haut parleur.
SincĂšrement le montage a Ă©tĂ© conçu pour Ă©mettre des notifications, ce n’est pas un player musical ou cast :wink:
On peut lui ajouter toutes les commandes play/pause/ ou autre, ça ne restera qu’un lecteur mp3 en son mono et ce ne sera jamais une chaine hifi :slight_smile:
De plus, seuls les fichiers sur carte SD peuvent ĂȘtre lus.

Pour un player online, il faudra des modules type I2S.