Comment je peux faire?
Je peux revenir à l'ancienne version du code si besoin.
Une boucle for qui imprime le code hexa de chaque octet de la String
for (size_t i = 0; i < FoobarRead.length(); i++) {
Serial.printf("%02X ", FoobarRead.c_str()[i]);
}
Serial.println();
(Si vous êtes sur un ESP printf() fonctionne)
Bonjour à tous...
Désolé d'avoir mis tout ce temps pour répondre. J'ai intégré le code pour avoir les octets de la string reçue.
Voici le code dans Foobar
$if(%isplaying%,
$if(%ispaused%,
paused<,
playing<
)
%artist%<%album%<%title%<%bitrate%<%codec%<%length%<,
stoped
)
Le code Arduino
//ESP32S
//Programme pour se connecter au WiFi et au FTP pour lire les tags de Foobar dans un fichier .txt
//et les afficher sur un bandeau LED
#include <WiFi.h>
#include <ESP32_FTPClient.h>
#include <SoftwareSerial.h>
//WiFi Livebox
#define WIFI_SSID "XXXX"
#define WIFI_PASS "XXXX"
SoftwareSerial SerialHaut(16, 17);
SoftwareSerial SerialBas(18, 19);
//FTP MakomotoryP
char ftp_server[] = "192.168.1.17";
char ftp_user[] = "Arduino";
char ftp_pass[] = "Arduino";
char fileName[] = "Foobar_Now_Playing.txt";
ESP32_FTPClient ftp (ftp_server, 21, ftp_user, ftp_pass, 1000);
unsigned long TempoReadFtp;
int WifiEtat, FtpEtat, NewMessage = 0;
String FoobarRead = "";
String FoobarSend = "";
String FoobarEtat = "";
String Artiste = "";
String Album = "";
String Titre = "";
String Bitrate = "";
String Codec = "";
String Duree = "";
String TextHaut = "";
String TextBas = "";
String data = "";
void setup() {
TempoReadFtp = millis();
Serial.begin(115200);
SerialHaut.begin(115200);
SerialBas.begin(115200);
//Initialisation du WiFi
//L'ESP32S s'occupe de la reconnection automatique
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("SETUP état Wifi: "); Serial.println(WiFi.status()); // Phase test
ftp.OpenConnection();
Serial.print("SETUP état FTP: "); Serial.println(ftp.isConnected()); // Phase test
Serial.println("Fin de boucle SETUP"); // Phase test
}
void loop() {
// Si WiFi déconnecté
if(WiFi.status() != WL_CONNECTED){
Serial.print("Début boucle Wifi déconnecté: "); Serial.println(WiFi.status()); // Phase test
WifiEtat = 0;
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("Wifi status suite à déconnection: "); Serial.println(WiFi.status()); // Phase test
}
while (WiFi.status() == WL_CONNECTED) {
WifiEtat = 1;
if (ftp.isConnected()==1){
FtpEtat = 1;
if((millis()-TempoReadFtp)>=300){
// Lire le fichier
FoobarRead = "";
ftp.InitFile("Type A");
ftp.DownloadString(fileName, FoobarRead);
TempoReadFtp = millis();
}
}
else {
Serial.print("Déconnection FTP. FtpEtat: "); Serial.println(FtpEtat); // Phase test
FtpEtat = 0;
ftp.OpenConnection();
Serial.print("FTP status suite à déconnection: "); Serial.println(ftp.isConnected()); // Phase test
}
if (FoobarRead != FoobarSend){
// code hexa de chaque octet de la String
Serial.println("***");
Serial.println("***");
Serial.println("***");
Serial.println("*** String reçue");
Serial.println(FoobarRead);
Serial.println("*** Code hexa de chaque octet de la String");
for (size_t i = 0; i < FoobarRead.length(); i++) {
Serial.printf("%02X ", FoobarRead.c_str()[i]);
}
Serial.println();
Serial.println("***");
Serial.println("***");
Serial.println("***");
Serial.print("FoobarSend avant copie Read -> Send: ["); Serial.print(FoobarSend); Serial.print("]\t"); Serial.println(FoobarSend.length()); // PHASE TEST
FoobarSend = FoobarRead;
Serial.print("FoobarSend apres copie Read -> Send: ["); Serial.print(FoobarSend); Serial.print("]\t"); Serial.println(FoobarSend.length()); // PHASE TEST
// Extraction de FoobarRead "FoobarEtat<artiste<album<titre<bitrate<codec<duree<"
int startPos = 0;
int endPos = FoobarSend.indexOf("<");
FoobarEtat = FoobarSend.substring(startPos, endPos); //playing, paused, stoped
startPos = endPos + 1;
endPos = FoobarSend.indexOf("<", startPos);
Artiste = FoobarSend.substring(startPos, endPos);
startPos = endPos + 1;
endPos = FoobarSend.indexOf("<", startPos);
Album = FoobarSend.substring(startPos, endPos);
startPos = endPos + 1;
endPos = FoobarSend.indexOf("<", startPos);
Titre = FoobarSend.substring(startPos, endPos);
startPos = endPos + 1;
endPos = FoobarSend.indexOf("<", startPos);
Bitrate = FoobarSend.substring(startPos, endPos);
startPos = endPos + 1;
endPos = FoobarSend.indexOf("<", startPos);
Codec = FoobarSend.substring(startPos, endPos);
startPos = endPos + 1;
endPos = FoobarSend.indexOf("<", startPos);
Duree = FoobarSend.substring(startPos, endPos);
Serial.print("FoobarEtat: ["); Serial.print(FoobarEtat); Serial.print("]\t"); Serial.println(FoobarEtat.length()); // PHASE TEST
Serial.print("Artiste: ["); Serial.print(Artiste); Serial.print("]\t"); Serial.println(Artiste.length()); // PHASE TEST
Serial.print("Album: ["); Serial.print(Album); Serial.print("]\t"); Serial.println(Album.length()); // PHASE TEST
Serial.print("Titre: ["); Serial.print(Titre); Serial.print("]\t"); Serial.println(Titre.length()); // PHASE TEST
Serial.print("Bitrate: ["); Serial.print(Bitrate); Serial.print("]\t"); Serial.println(Bitrate.length()); // PHASE TEST
Serial.print("Codec: ["); Serial.print(Codec); Serial.print("]\t"); Serial.println(Codec.length()); // PHASE TEST
Serial.print("Duree: ["); Serial.print(Duree); Serial.print("]\t"); Serial.println(Duree.length()); // PHASE TEST
Serial.println("*** Fin ***"); // PHASE TEST
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();
}
} //While
} //Loop
Et la sortie du port série
***
***
***
*** String reçue
stoped
*** Code hexa de chaque octet de la String
EF BB BF 73 74 6F 70 65 64
***
***
***
FoobarSend avant copie Read -> Send: [playing< Mike Oldfield<Tubular Bells<Part One<693<FLAC<25:33<] 64
FoobarSend apres copie Read -> Send: [stoped] 9
FoobarEtat: [stoped] 9
Artiste: [stoped] 9
Album: [stoped] 9
Titre: [stoped] 9
Bitrate: [stoped] 9
Codec: [stoped] 9
Duree: [stoped] 9
*** Fin ***
***
***
***
*** String reçue
playing< Mike Oldfield<Tubular Bells<Part One<693<FLAC<25:33<
*** Code hexa de chaque octet de la String
EF BB BF 70 6C 61 79 69 6E 67 3C 20 4D 69 6B 65 20 4F 6C 64 66 69 65 6C 64 3C 54 75 62 75 6C 61 72 20 42 65 6C 6C 73 3C 50 61 72 74 20 4F 6E 65 3C 36 39 33 3C 46 4C 41 43 3C 32 35 3A 33 33 3C
***
***
***
FoobarSend avant copie Read -> Send: [stoped] 9
FoobarSend apres copie Read -> Send: [playing< Mike Oldfield<Tubular Bells<Part One<693<FLAC<25:33<] 64
FoobarEtat: [playing] 10
Artiste: [ Mike Oldfield] 14
Album: [Tubular Bells] 13
Titre: [Part One] 8
Bitrate: [693] 3
Codec: [FLAC] 4
Duree: [25:33] 5
*** Fin ***
***
***
***
*** String reçue
playing< Mike Oldfield<Tubular Bells<Part Two<652<FLAC<23:22<
*** Code hexa de chaque octet de la String
EF BB BF 70 6C 61 79 69 6E 67 3C 20 4D 69 6B 65 20 4F 6C 64 66 69 65 6C 64 3C 54 75 62 75 6C 61 72 20 42 65 6C 6C 73 3C 50 61 72 74 20 54 77 6F 3C 36 35 32 3C 46 4C 41 43 3C 32 33 3A 32 32 3C
***
***
***
FoobarSend avant copie Read -> Send: [playing< Mike Oldfield<Tubular Bells<Part One<693<FLAC<25:33<] 64
FoobarSend apres copie Read -> Send: [playing< Mike Oldfield<Tubular Bells<Part Two<652<FLAC<23:22<] 64
FoobarEtat: [playing] 10
Artiste: [ Mike Oldfield] 14
Album: [Tubular Bells] 13
Titre: [Part Two] 8
Bitrate: [652] 3
Codec: [FLAC] 4
Duree: [23:22] 5
*** Fin ***
Il y a un espace avant "Mike oldfield" car j'avais oublié un espace après une parenthèse dans le code Foobar mais la taille correspond ^^
Artiste: [ Mike Oldfield] 14
Tout s’explique
Le préfixe EF BB BF correspond à une BOM (Byte Order Mark) UTF-8, indiquant que le texte est encodé en UTF-8.
Le reste, 73 74 6F 70 65 64, correspond en ASCII (et UTF-8 sans BOM) au mot “stoped”.
Comment avez vous créé le fichier ?
C'est un fichier .txt généré par Foobar via l'extension "foo_nowplaying"
et bien il ajoute en début de fichier quelques infos qui disent que le contenu est en UTF8
➜ il faut ignorer la BOM
C'est ce que j'ai fini par faire à ma manière. J'ai rajouté une variable que j'ignore ensuite lors de l'extract. Je pourrais aussi récupérer la string en hexa et ensuite supprimer la BOM pour avoir une string propre mais cette étape demanderait plus de ressource.
Oups.... Je ne m'attendais pas à ça ![]()
Je vérifie ce soir ^^
Vous recevez de toutes façons tout le fichier dans votre buffer donc il suffit de faire le parsing à partir du 4eme caractère du buffer.
Mais c’est encore mieux de ne pas mettre la BOM
C'est bon ça fonctionne en UTF-8 sans header.
cool. bonne continuation
Merci à tous encore une fois pour votre aide ^^
Bonjour ^^
J'ai juste une petite question. Dans mon code je pourrais remplacer la boucle "if" par une boucle "while"?
while (WiFi.status() == WL_CONNECTED) {
WifiEtat = 1;
if (ftp.isConnected()==1){
FtpEtat = 1;
Dans la boucle "while" Wifi.status, si la condition n'est plus réunie on va jusqu'à la fin ou on sort immédiatement de la boucle? Je pense qu'on sort immédiatement de la boucle mais cela ne risque pas d'entrainer des erreurs dans l'exécution du programme?
Si la condition est remplie tu n'entres pas dans la boucle.
Si tu sais que cela risque de poser un problème pas la suite, tu intègres le fait et tu anticipes les problèmes.
if n'est pas une boucle...
La condition du while n'est testée qu'à l'entrée de ce qui doit être répété. Une fois le corps du while() exécuté, la condition est testée à nouveau et soit on repart pour un cycle, soit on sort.
Donc on test la condition
- si elle est fausse on passe à l'instruction après le bloc while
- si elle est vraie on rentre dans le corps du while et on y reste jusqu'à ce que ce bout de code se finisse ou qu'on interrompe le while avec un
break - si on n'est pas sorti avec un break, on retourne tester la condition et ça recommence.
Par exemple ça veut dire que si le WiFi tombe une fois passé le test, vous n'en savez rien et le code continue de s'exécuter (bon ce serait pas de bol qu'il tombe juste quelque micro-secondes plus tard, mais c'est pour cela que si vous dépendez de la connexion il ne faut pas que le while soit trop long non plus.
Merci pour l'explication ^^
