LOCODUINO
Parlons Arduino => Vos projets => Discussion démarrée par: CATPLUS le septembre 11, 2017, 08:11:20 pm
-
Bonsoir
Remplacer 16 interrupteurs (ou plus) par l'affichage de BOUTONS fictifs sur l'écran NEXTION.
Utilisation => commande Switch Motor TORTOISE (j'ai fait le test uniquement avec ces moteurs)
Avant de développer ce montage quelques photos.
-
Joli projet, avec un superbe écran même pas (trop) cher ! Je crois que je regarderais pour ma prochaine centrale DCC...
-
(http://185.14.178.233/locoduino/images/myriam.jpg)
Cette technique qui consiste à en montrer un peu en nous laissant sur notre faim s'appelle le "teasing". On attend avec impatience les développements. Type d'écran ? Tactile (sinon je vois pas) ? Programme pour dessin des boutons et interactivité ?
Demain tu nous montres le derrière (du programme bien sûr :-)
Christophe
-
On trouve des claviers tactiles sur la Baie nettement moins chers qu'un écran graphique :
http://www.ebay.fr/ulk/itm/311568380186 (http://www.ebay.fr/ulk/itm/311568380186)
Mais l'intérêt de l'écran graphique est de pouvoir afficher bien plus que des boutons ! :P
On attend donc d'en savoir plus.
Dominique
-
Et c'est un afficheur qui a tenu ses promesses !
C'est pas toujours le cas sur eBay ...
-
En effet, ça a l'air intéressant :
https://www.youtube.com/watch?v=V99LvyRQqto (https://www.youtube.com/watch?v=V99LvyRQqto)
-
Bonjour
On se calme >:(
J'ai prévu de faire ce qui'il faut.
Je suis en TRAIN de refaire le câblage de ma maison. Donc il y des priorités.
Jusqu’a présent j'ai rendu mon devoir dans les délais..........
Ce petit montage m'a demandé plusieurs jours de délire.
Un peu de patience SVP. Merci
Cordialement
Marcel
-
Remplacer des interrupteurs par des touches TACTILES sur écran NEXTION
Arduino Mega
NEXTION 3,5 pouce
Carte mini SD
Interface CI 7406
Switch Motor TORTOISE
Alimentation 5 & 12 volts (alimentation PC)
Visiter le site de NEXTION
https://nextion.itead.cc/
Logiciel de création:
IL Y A UNE CHOSE IMPERATIVE A RESPECTER NE JAMAIS, JAMAIS OUBLIER D’INSERER LA POLICE DE CARACTER
https://nextion.itead.cc/resource/download/nextion-editor/
Suivant le type d’écran
https://nextion.itead.cc/resource/download/libraries/
J'ai utilisé un Ecran 3,5 pouces (pas besoin d'alimentation extérieur. NB au dessus l'Arduino ne peu pas fournir suffisamment de tension)
1 Charger la bibliothèque => NEXTION
2 Pour charger le fichier (BUTTON_8.tft)
21 Enregistrer le fichier sur la carte SD => BUTTON_8.tft
22 Couper l’alimentation 5volts de l’écran
23 Insérer carte SD (arrière de l’écran => ATTENTION au SENS)
24 Mettre le courant
25 Le chargement doit s’effectuer (progression sur l’affichage en %)
26 Si tout est OK, couper l’alimentation 5volts
27 Retirer la carte SD
28 Mettre le courant
29 L’affichage des Boutons doit apparaître
3 Branchement sur l’ARDUINO
31 ATTENTION au fil TX & RX (fil jaune & fil rouge) bien les brancher sur les pins 10 & 11
32 Charger le fichier => TORTOISE_3_16_OUT_OK.ino
33 Test ouvrir le port série (avec la bonne vitesse) appuyer sur les touches de l’écran
"L' affichage des touches en fonctions (1 => 16) dans la fenêtre port série"
4 Fabrication de l’interface
41 J’utilise des CI 7406 ( l’alimentation du CI est en 5 volts) sur les sorties je branche les Tortoises
NE PAS OUBLIER les résistances de 1,2k entre le 12volts (voir schéma)
AVANT de brancher l’ARDUINO à l’interface faire un essai (un fil du moins à l’Entrée du 7406)
Pin IN 1, 3, 5, 9, 11, 13
Pin OUT 2, 4, 6, 8, 10, 12
-
J'ai jeté un petit coup d’œil à ton fichier ino, il me semble que tu pourrais remplacer les tests
if (message == "65 0 2 0 ffff ffff ffff") {
par
if (message[5] == "2") {
et pour le premier et le dernier, il faut tester les deux caractères différents :
if (message[5] == "1" && message[6] == " ") {
et
if (message[5] == "1" && message[6] == "0") {
Ce type de programmation devrait être plus rapide et moins encombrante en mémoire que de tester la chaîne entière, de toutes façons seulement différentes par un ou deux caractères.
A noter qu'il est étonnant que ça marche un peu, parce que la comparaison de chaîne en C doit se faire avec une fonction comme strcmp(), sinon avec un simple '==' tu compares les adresses, ce qui n'est pas du tout la même chose !
-
Bonsoir Thierry
Je viens de faire le test que tu ma conseillé:
Apparemment il est pas content:
exit status 1
ISO C++ forbids comparison between pointer and integer [-fpermissive]
Marcel
-
Tu peux poster ton nouveau source ?
-
Bonjour Thierry
-
Bonjour Marcel,
Eh déjà, ça peut pas marcher ligne 106 :
if (message[5] == "10"
message[5] ne peut correspondre qu'à un seul caractère. Par ailleurs, prendre soin de mettre un char entre ' ' et une string entre " ". message[5] == '1'
Je pense que tu voulais écrire : if (message[5] == '1' && message[6] =='0')
.
Bien amicalement.
Christophe
-
Marcel,
Je m'autorise par ailleurs une petite suggestion pour rendre le code plus lisible et plus facilement maintenable. Tout comme tu as déclaré et initialisé tes relais dans un tableau :
byte relais[] = {22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52};
Pourquoi ne pas faire de même pour tes pins out : const int Pin23 = 23;
jusqu'à 53 ? Pourquoi ne pas également mettre un type byte comme tu l'as fait pour les relais ?
byte pinOut[] = {23,25,27,29,31,33,...........};
et tant qu'à faire, puisque tu avais déclaré tes pins en constantes, eh bien tu fais la même chose pour les tableaux :
const byte relais[] = {22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52};
const byte pinOut[] = {23,25,27,29,31,33,...........};
L'avantage de passer par des tableaux est que tu pourras plus facilement manipuler tes données et simplifier ton code comme par exemple, au lieu de :
pinMode(Pin23, OUTPUT);//TORTOISE1
pinMode(Pin25, OUTPUT);//TORTOISE2
pinMode(Pin27, OUTPUT);//TORTOISE3
pinMode(Pin29, OUTPUT);//TORTOISE4
pinMode(Pin31, OUTPUT);//TORTOISE5
pinMode(Pin33, OUTPUT);//TORTOISE6
pinMode(Pin35, OUTPUT);//TORTOISE7
pinMode(Pin37, OUTPUT);//TORTOISE8
pinMode(Pin39, OUTPUT);//TORTOISE9
pinMode(Pin41, OUTPUT);//TORTOISE10
pinMode(Pin43, OUTPUT);//TORTOISE11
pinMode(Pin45, OUTPUT);//TORTOISE12
pinMode(Pin47, OUTPUT);//TORTOISE13
pinMode(Pin49, OUTPUT);//TORTOISE14
pinMode(Pin51, OUTPUT);//TORTOISE15
pinMode(Pin53, OUTPUT);//TORTOISE16
tu vas pouvoir écrire :
for( int i = 0; i < sizeof(pinOut); i++) {
pinMode(pinOut[i], OUTPUT);
}
comme tu l'as fait avec tes relais. Mais ici, sizeof(pinOut)
te permet d'ajouter ou retirer des pins et ton code fonctionne toujours. Et tu vois bien que tout le reste de ton code va aussi pouvoir être simplifié de la même manière.
Voilà des petites astuces de codage qui peuvent simplifier la vie.
Bien amicalement.
Christophe
-
Oui, autant pour moi, on parle bien de caractère avec '0', alors que "0" est une chaine de caractères, un tableau... Voir l'article http://www.locoduino.org/spip.php?article131 à ce sujet.
-
En fait, dans le message, les valeurs renvoyées sont en hexadecimal. On voit bien dans la série de messages possible qu'il s'agit d'une suite d'hexa "01", "02"....."0a","0b"....
if (message == "65 0 1 0 ffff ffff ffff") {digitalWrite((relais[0]),button1State); button1State = !(button1State); }
if (message == "65 0 2 0 ffff ffff ffff") {digitalWrite((relais[1]),button2State); button2State = !(button2State); }
if (message == "65 0 3 0 ffff ffff ffff") {digitalWrite((relais[2]),button3State); button3State = !(button3State); }
if (message == "65 0 4 0 ffff ffff ffff") {digitalWrite((relais[3]),button4State); button4State = !(button4State); }
if (message == "65 0 5 0 ffff ffff ffff") {digitalWrite((relais[4]),button5State); button5State = !(button5State); }
if (message == "65 0 6 0 ffff ffff ffff") {digitalWrite((relais[5]),button6State); button6State = !(button6State); }
if (message == "65 0 7 0 ffff ffff ffff") {digitalWrite((relais[6]),button7State); button7State = !(button7State); }
if (message == "65 0 8 0 ffff ffff ffff") {digitalWrite((relais[7]),button8State); button8State = !(button8State); }
if (message == "65 0 9 0 ffff ffff ffff") {digitalWrite((relais[8]),button9State); button9State = !(button9State); }
if (message == "65 0 a 0 ffff ffff ffff") {digitalWrite((relais[9]),button10State); button10State = !(button10State); }
if (message == "65 0 b 0 ffff ffff ffff") {digitalWrite((relais[10]),button11State); button11State = !(button11State); }
if (message == "65 0 c 0 ffff ffff ffff") {digitalWrite((relais[11]),button12State); button12State = !(button12State); }
if (message == "65 0 d 0 ffff ffff ffff") {digitalWrite((relais[12]),button13State); button13State = !(button13State); }
if (message == "65 0 e 0 ffff ffff ffff") {digitalWrite((relais[13]),button14State); button14State = !(button14State); }
if (message == "65 0 f 0 ffff ffff ffff") {digitalWrite((relais[14]),button15State); button15State = !(button15State); }
if (message == "65 0 10 0 ffff ffff ffff") {digitalWrite((relais[15]),button16State); button16State = !(button16State); }
avec probablement une erreur à la dernière ligne "65 0 10 ...." qui est en réalité "65 10", "10" étant la valeur suivant directement "0f" en hexa.
Il ne faut pas faire une lecture en ASCII (lecture de string message). A mon avis, dès le départ, ce n'est pas une string (message) qui doit enregistrer la réponse de l'écran mais un int. Ou alors faire une conversion de la string en int : int val = atoi(message);
-
J'ai essayé d'optimiser le code mais je n'ai pas ce qu'il faut pour le tester. Il est certainement encore améliorable, mais je pense que déjà les bugs de lecture des messages devraient trouver ici une solution. Ligne 48, il faut retraiter la valeur retournée pour retrouver une valeur de bouton sélectionné dans une plage de
En fin de programme, il est mieux de passer par la fonction millis() qui est "non bloquante" que delay(). Mais ça ne conditionne pas le fonctionnement du programme, on pourra le faire plus tard.
#include <SoftwareSerial.h>
#include <Nextion.h>
#define YES !1
#define NO !0
#define NBRE_MOTEURS 16
#define DUREE_IMPULS_MOTEUR 100
SoftwareSerial nextion(10, 11);
Nextion myNextion(nextion, 9600);
const byte relais[] = {22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52};
const byte pinOut[] = {23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53};
bool buttonState[NBRE_MOTEURS];
// int recv, trxv; -> mis en commentaire car ne semble pas être utilisé !!!
String message;
void setup()
{
Serial.begin(9600);
myNextion.init();
for ( int i = 0; i < NBRE_MOTEURS; i++) {
buttonState[i] = 0;
pinMode(pinOut[i], OUTPUT);
digitalWrite(pinOut[i], LOW); // Toutes les pins sont mises à LOW
pinMode((relais[i]), OUTPUT);
digitalWrite((relais[i]), NO);
}
while (!Serial) {};
Serial.println("Serial On");
int brightness = 255;
int bright = map(brightness, 0, 1024, 0, 100);
String dim = "dim=" + String(bright);
myNextion.sendCommand(dim.c_str());
} // Fin Setup
void loop()
{
String message = myNextion.listen(); //check for message
if (message != "") {
Serial.println(message, HEX);
int val = atoi(message);
// val = val..... (retraiter ici la vraie valeur retournée)
buttonState[val] = !buttonState[val];
digitalWrite(relais[val], buttonState[val]);
digitalWrite(pinOut[val], HIGH);
// mais ne faut-il pas remettre pinOut[val] à LOW après quelques secondes
// je crois que ce type de moteur ne nécessite qu'une très courte impulsion de courant
// aussi faudrait-il écrire...
delay(DUREE_IMPULS_MOTEUR); // mettre ici le temps désiré
digitalWrite(pinOut[val], LOW);
// Il serait cependant mieux de passer par une fonction millis()
}
} // Fin Loop
-
Proposition : Le même code mais en remplaçant delay() par millis().
Bien amicalement.
Christophe
#include <SoftwareSerial.h>
#include <Nextion.h>
#define YES !1
#define NO !0
#define NBRE_MOTEURS 16
#define DUREE_IMPULS_MOTEUR 100
SoftwareSerial nextion(10, 11);
Nextion myNextion(nextion, 9600);
const byte relais[] = {22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52};
const byte pinOut[] = {23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53};
bool buttonState[NBRE_MOTEURS];
unsigned long previous[NBRE_MOTEURS];
// int recv, trxv; -> mis en commentaire car ne semble pas être utilisé !!!
String message;
void setup()
{
Serial.begin(9600);
myNextion.init();
for ( int i = 0; i < NBRE_MOTEURS; i++) {
buttonState[i] = 0;
pinMode(pinOut[i], OUTPUT);
digitalWrite(pinOut[i], LOW); // Toutes les pins sont mises à LOW
pinMode((relais[i]), OUTPUT);
digitalWrite((relais[i]), NO);
previous[i] = 0;
}
while (!Serial) {};
Serial.println("Serial On");
int brightness = 255;
int bright = map(brightness, 0, 1024, 0, 100);
String dim = "dim=" + String(bright);
myNextion.sendCommand(dim.c_str());
} // Fin Setup
void loop()
{
String message = myNextion.listen(); //check for message
if (message != "") {
Serial.println(message, HEX);
int val = atoi(message);
// val = val..... (retraiter ici la vraie valeur retournée)
buttonState[val] = !buttonState[val];
digitalWrite(relais[val], buttonState[val]);
digitalWrite(pinOut[val], HIGH);
previous[val] = millis(); // On enregistre l'heure qu'il est
} // End of -> if (message != "")
for(int i = 0; i < NBRE_MOTEURS; i++) {
if(pinOut[i] == HIGH) { // Pour les seules pin en etat haut
if(millis() - previous[i] > DUREE_IMPULS_MOTEUR) { // l'interval est dépassé
digitalWrite(pinOut[i], LOW); // On met la pin à LOW
}
}
}
} // Fin Loop
-
Au fait Marcel, il y a quoi relié à tes pins impaires : 23 à 53 ???
-
Le Tortoise fonctionne avec du courant en continu par le biais des résistance de 1,2k entre le (+) 12volts
On ne mélange pas le 5 volts et la puissance 12 volts (de toute façon ces moteurs ne fonctionnent pas en dessous de 9volts)
Regarde le schéma
Les pins 22 et 23 sortent de l'Arduino, attaquent 2 entrées du 7406 et après l'impulsion sur le NEXTION, celui-ci change de sens
Il faut 2 états HIGH pour inversé.
Je retourne me coucher
Amicalement
Marcel
-
Ok, je comprends mieux. Sinon, je ne voyais pas l'intérêt de conserver l'état du bouton dans la variable buttonState
En fait, dans le loop, l'appui sur un bouton permet de changer l'état d'un relais (et donc de l'aiguille) en mettant simultanément les deux pins paires et impaires (exemple 22 et 23) à l'état HIGH. Ce n'est pas une pin à HIGH et l'autre à LOW on est bien d'accord ? Puis il faut une nouvelle impulsion sur le même bouton pour mettre ces mêmes deux pins à LOW et du coup faire revenir l'aiguille dans sa position initiale.
Il n'y a donc pas besoin de faire revenir les pins automatiquement à leur état LOW après un petits laps de temps comme je le faisais avec la fonction delay() ou millis(). Ce qui simplifirait encore le code.
Par ailleurs, au démarrage du MEGA, tel que c'est actuellement, toutes tes pins sont commutées sur LOW, donc toutes tes aiguilles sont dans la même position. Tu ne cherches pas à enregistrer en EEPROM la position que tu souhaiterais au démarrage pour chacune des aiguilles, tournée ou non tournée ?
Merci de me confirmer ces points et je te proposerai un code modifié.
PS : Tu vas encore me trouver un peu ch**nt, mais si les deux pins paires et impaires envoient en même temps le même signal électrique (5V ou 0V), pourquoi ne pas utiliser une seule pin et faire le dédoublement (distribution) au niveau du relais ??? Si encore, une envoyait un HIGH sur une pin et sur l'autre un LOW, mon petit cerveau comprendrait sans doute mieux. Mais, tu me diras peut-être, avec 53 pins sur un MEGA, au diable l'avarice !!! De plus, ça ne change rien fondamentalement au code.
Bien amicalement.
Christophe
-
Bon, j'ai récupéré un MEGA et mon IDE Arduino. Mais ça commence mal. J'ai une erreur à la compilation :
sketch_sep15a:46: error: 'class Nextion' has no member named 'listen'
String message = myNextion.listen(); //check for message
La bibliothèque est installée et reconnue. J'ai passé les premières étapes de compilation comme myNextion.init();
Il se dit sur les forum qu'il y aurait peut-être une incompatibilité avec la biblio : SoftwareSerial.h ??? Peux-tu me confirmer Marcel que tu arrives à lire : String message = myNextion.listen(); ? Moi je suis en Mac avec l'IDE en 1.8.3.
Je me demande dans quelle mesure ce code dont tu as recopié les bases sur des forum est fiable.
Quelqu'un a t'il des infos en particulier sur l'utilisation de SoftwareSerial.h ?
Est-il possible que quelques uns puisse aussi tester ce code ?
#include <SoftwareSerial.h>
#include <Nextion.h>
//#include "Nextion.h"
#define YES !1
#define NO !0
#define NBRE_MOTEURS 16
#define DUREE_IMPULS_MOTEUR 100
SoftwareSerial nextion(10, 11);
Nextion myNextion(nextion, 9600);
const byte relais[] = {22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52};
const byte pinOut[] = {23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53};
bool buttonState[NBRE_MOTEURS];
unsigned long previous[NBRE_MOTEURS];
// int recv, trxv; -> mis en commentaire car ne semble pas être utilisé !!!
String message;
void setup()
{
Serial.begin(9600);
myNextion.init();
for ( int i = 0; i < NBRE_MOTEURS; i++) {
buttonState[i] = 0;
pinMode(pinOut[i], OUTPUT);
digitalWrite(pinOut[i], LOW); // Toutes les pins sont mises à LOW
pinMode((relais[i]), OUTPUT);
digitalWrite((relais[i]), NO);
previous[i] = 0;
}
while (!Serial) {};
Serial.println("Serial On");
int brightness = 255;
int bright = map(brightness, 0, 1024, 0, 100);
String dim = "dim=" + String(bright);
myNextion.sendCommand(dim.c_str());
} // Fin Setup
void loop()
{
String message = myNextion.listen(); //check for message
if (message != "") {
//Serial.println(message, HEX); // En l'etat, ne retourne sans doute rien de signifiant
int val;
switch (message[6]) {
case '1':
if (message[7] == '0')
val = 16;
else
val = 1;
break;
default:
val = strtoul(message[6], 0, 16);
}
buttonState[val] = !buttonState[val];
digitalWrite(relais[val], buttonState[val]);
digitalWrite(pinOut[val], HIGH);
previous[val] = millis(); // On enregistre l'heure qu'il est
} // End of -> if (message != "")
for(int i = 0; i < NBRE_MOTEURS; i++) {
if(pinOut[i] == HIGH) { // Pour les seules pin en etat haut
if(millis() - previous[i] > DUREE_IMPULS_MOTEUR) { // l'interval est dépassé
digitalWrite(pinOut[i], LOW); // On met la pin à LOW
}
}
}
} // Fin Loop
-
Hello,
J'ai testé aussi avec la bibliothèque NeoNextion accessible depuis l'IDE avec le menu "gerer les bibliothèques" et j'ai eu le même problème.
Le problème est décrit sur internet et j'ai chargé la bibliothèque Nextion modifiée ici : https://github.com/bborncr/nextion (https://github.com/bborncr/nextion). Je l'ai installée à partir du menu "ajouter la bibliothèque.zip", sans enlever l'autre bibliothèque NeoNextion.
Ca compile sans erreur .
Je m'inquiète quand même du fait qu'il y a 2 fichiers nextion.h dans les bibliothèques, l'un dans "NeoNextion" et l'autre dans "Nextion-Master". Comment l'IDE résoud le conflit ?
Je n'ai pas le matériel pour tester plus mais c'est un projet très interessant qui évite de se farcir du graphique à gogo ;)
Amicalement
Dominique
-
Bon, j'ai aussi fait la même manip (charger la biblio de "bborncr/nextion") mais par le terminal. Et ça ne marche pas chez moi. Oui c'est assez inquiétant que deux biblio portent le même nom mais ne sont absolument pas substituables.
Seul Marcel à l'équipement pour tester totalement mais il rencontre un bug sur la ligne 59 : val = strtoul(message[6], 0, 16);
Je lui ai envoyé un nouveau code de test... A suivre !
Bien amicalement.
Christophe
-
Pour moi le soucis est que le firmware des écrans nextion n'est pas en opensource (sans parler de logiciel libre)
-
Le problème est décrit sur internet et j'ai chargé la bibliothèque Nextion modifiée ici : https://github.com/bborncr/nextion (https://github.com/bborncr/nextion). Je l'ai installée à partir du menu "ajouter la bibliothèque.zip", sans enlever l'autre bibliothèque NeoNextion
Ouuuuuh là, c'est inquiétant. Avec le téléchargement et l'installation du zip, ça marche maintenant chez moi. Alors que je rappelle qu'avec le terminal, ça n'avait pas fonctionné.
-
Bonjour :)
Suite & Fin
L'aide très très précieuse de Christophe pour la partie Soft a donné une autre dimension à ce projet (Merci)
Ci-joint le nouveau fichier "TORTOISE_8"
NB: Je vous rappelle que les tests sont fait UNIQUEMENT avec des Switchs Motor TORTOISE
A ceux qui vont l'utiliser merci de nous faire part de leurs réflexions et suggestions.
Cordialement
Marcel
-
Quelques réflexions à la suite du projet de Marcel maintenant opérationnel.
L'exemple de lecture des messages envoyés par le NEXTION à l'Arduino :
if (message !="") {
if (message == "65 0 1 0 ffff ffff ffff") {
......
}
}
Cet exemple est très présent sur internet sans doute parce qu'il a le grand avantage de la simplicité. Après 65, le chiffre est le n° de la page dans laquelle est implanté le bouton, le deuxième chiffre nous l'avons vu est le n° du bouton sur lequel on a appuyé, le troisième chiffre, l'état du bouton; 0 (zéro) bouton appuyé, 1 bouton relaché. Attention donc, quand on appuie sur un bouton et qu'on le relache, le NEXTION envoie 2 messages : "65 0 1 0 ffff ffff ffff" position DOWN, "65 0 1 1 ffff ffff ffff" position UP.
Ce type de message est donc facile à interpréter dans un programme Arduino comme on le voit dans le scketch de Marcel. A mon avis, une meilleure solution aurait même été d’utiliser la fonction sscanf qui permet d’extraire rapidement et facilement les valeurs du message qui sont séparées par un espace :
// String message == "65 0 1 0 ffff ffff ffff"
int ns; // Non signifiant
int page; // numéro de la page
char bouton[3]; // numéro du bouton (hexadecimal)
int etat // Etat du bouton
sscanf(message, "%d %d %s %d", &ns, &page, bouton, &etat);
La fonction sscanf permet de récupérer les valeurs significatives et en décimal (ou alpha pour le n° du bouton) dans des variables déclarées juste avant. Pratique et puissant !
Mais ce type de sketch fonctionne avec une bibliothèque <Nextion.h> disponible ici : https://github.com/bborncr/nextion (https://github.com/bborncr/nextion) qui porte le même nom que la bibliothèque "officielle" <Nextion.h> disponible ici : https://github.com/itead/ITEADLIB_Arduino_Nextion (https://github.com/itead/ITEADLIB_Arduino_Nextion) bibliothèque par ailleurs autrement plus complète que la première. Elle permet entre autres choses l'échange d'informations entre l'écran et l'Arduino et entre l'Arduino et l'écran ce que ne permet pas la première.
Il y a donc conflit qui pourrait se résoudre en changeant le nom du fichier pour la première bibliothèque puis en modifiant le début du code également pour ce nouveau fichier ".h". Compliqué donc, d'autant qu'il est à peu prés certain que les deux bibliothèques chargées dans le même sketch entreront en conflit.
Voilà, il n'y a probablement pas de solution miracle. Soit, à mon avis, votre Nextion ne vous sert que d'écran tactile avec des boutons pour déclancher des actions au travers de l'Arduino; alors la première bibliothèque, utilisée comme Marcel l'a fait, à laquelle vous pouvez ajouter la fonction sscanf que je vous ai proposée, cette bibliothèque donc peut vous suffire.
Soit vous voulez réaliser des projets plus élaborés et il vous faudra recourir à la bibliothèque officielle et "oublier" la première.
Christophe