J'ai un projet d'allumage d'un ruban leds NéoPixel WS2812B collé derrière ma télé via mon téléphone.
Le ruban est branché à un ESP32 ou le Vcc passe par un relais.
Le sélecteur de couleurs et le bouton d'allumage sont déclenché par un serveur NodeRed dashboard 2 via MQTT et envoyé à mon ESP32.
Lorsque je clique sur le bouton allumage des leds, le relais s'active bien.
Lorsque je sélectionne une couleur, le moniteur série de l'ESP me renvoi une valeur de type String((char*)payload); représentant une valeur hexadécimale de la couleur.
Voici la fonction qui réceptionne la valeur du bon topic :
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
payload[length]='\0';
String cons = String((char*)payload);
consigne = cons;
Serial.println();
// -------------------- Exécution des souscription au topic MQTT ----------------------------------
if(topic[7] == 'a') {
payload[length]='\0';
callbackAllumageLedsTeleviseur = String((char*)payload);
Serial.println();
} else if (topic[7] == 'o') {
payload[length]='\0';
callbackChoixCouleurs = String((char*)payload);
Serial.println();
}
}
Et voici l'intéraction dans la void loop() :
// ------------------------- Lecture des conditions de déclenchement des relais pilotés MQTT + lecture couleurs ----------------------------------
if(callbackAllumageLedsTeleviseur == "true") {
delay(500);
digitalWrite(relaisAllumageLeds, HIGH);
} else {
digitalWrite(relaisAllumageLeds, LOW);
}
callbackChoixCouleurs = couleurLeds; // couleurLeds est édité au début du programme en unsigned long
if(callbackAllumageLedsTeleviseur == "true"){
for( int i=0; i<=LED_COUNT; i++ ){
rubanLedsTele.Color(i, couleurLeds);
rubanLedsTele.show();
Serial.println(couleurLeds);
}
}
J'aimerais pouvoir récupérer la valeur String et la transformer en valeur intégrable dans une variable rubanLedsTele.Color(i, couleurLeds); qui peut changer dès que je sélectionne une autre couleur.
Faut il passer par strcmp() ? Je n'ai encore jamais été confronté à ce genre de problème.
indexOf() pour chercher une sous-chaine charAt() pour chercher un caractère
Et des fonctions de conversion de texte vers des nombres de différents types toDouble() toInt() toFloat()
Par contre, je ne vois pas comment intégrer chaque caractère dans une variable.
J'ai testé avec concat() mais le type int de ma variable n'est pas bon.
En fait, je ne vois pas clairement la finalité.
Tu veux extraire chaque caractère séparément pour en récupérer sa valeur ou bien tu veux un nombre de 2, 3, 4, .. digits ??
Je viens de simplifier le payload de node red qui arrive sur l'ESP32 car la bibliothèque Adafruit ne prend en compte que les valeurs RGBA, donc voici ce que je récupère en payload au final :
Mon objectif est de récupérer la valeur de chaque couleur RGBA pour qu'elles s'intègrent automatiquement dans la fonction rubanLedsTele.Color(r, g, b), a);
Pour le coup, je pense qu'il faut repérer les trois caractères de chaque couleur afin de créer une variable par couleur et intégrer ces variables dans la fonction ci-dessus.
Donc, maintenant, le message reçu n'est plus de cette forme: {"r":180,"g":124,"b":103,"a":1} comme indiqué au post précédent?
Faudrait voir à figer le protocole une bonne fois pour toute.
Donc avec {1, 34, 200} tu devrais faire quelque chose comme ceci:
tu sais que la première valeur commence à l'index 1 donc tu peux faire int valeur1 = message.toInt(1) qui extraira le premier nombre. La méthode toInt() arrête automatiquement la conversion au premier caractère non numérique.
pour la seconde valeur, tu sais qu'elle se trouve après une virgule donc tu fais index = message.indexOf(",") pour trouver la position de la première virgule. int valeur2 = message.toInt(index+1) pour extraire le nombre qui commence après la virgule
pour la troisième valeur, il faut trouver la seconde virgule index = message.indexOf(",", index+1) on utilise index pour commencer la recherche après la première virgule int valeur3 = message.toInt(index+1) pour extraire le dernier nombre
C'est pour cela que je proposais d'utiliser .indexOf() pour faire chercher le séparateur.
Donc, au final c'est cela que tu reçois {"r":180,"g":124,"b":103,"a":1}
Si c'est le cas, il suffit de faire chercher la position des sous-chaines "r":, "g": et "b": en utilisant .indexOf()
Et ensuite d'extraire la valeur avec .toInt(index+4) +4 pour pointer juste derrière les :
Les lignes : int premiereChaineCouleurR = callbackChoixCouleurs.indexOf(":");
int secondeChaineCouleurG = callbackChoixCouleurs.indexOf(":", premiereChaineCouleurR + 1); int troisiemeChaineCouleurB = callbackChoixCouleurs.indexOf(":", secondeChaineCouleurG + 1);
La position des caractères ":" se fait bien car le débug me ramène le bon positionnement.
Merci pour ces exemples, je vais étudier ça et je te redirais, à première vu, le retour des couleurs se passe bien mais je veux décortiquer la méthode !
Encore merci