Transfert de valeurs numériques vers arduino uno par bluetooth

Bonjour,
Je dispose du montage et du programme suivants que j'ai obtenu lors d'un sujet précédent qui permettent de faire tourner à l'aide d'un module bluetooth hc-05, un moteur pas à pas tant que l'on reste appuyé sur le bouton virtuel d'une application crée sur MIT app inventor:
image

#include "AccelStepper.h"

char Incoming_value = 0;
const char boutonNemaIng1 = 3;
boolean mpap1Running = false;
const bool boutonPinEtatOn = LOW;

const char mpapDirPin = 4;     // Pour driver MPAP pin pas
const char mpapStepPin = 5;     // Pour driver MPAP pin direction

AccelStepper MPAP1(1, mpapStepPin, mpapDirPin); 

int mpapNombreDePasAtourner = 200;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
  MPAP1.setMaxSpeed(400);
  MPAP1.setAcceleration(500);

  pinMode(boutonNemaIng1, INPUT_PULLUP);

  MPAP1.setPinsInverted(false, false, true);
  MPAP1.enableOutputs();     // Activer les signaux du MPAP
}

void loop()
{
  if (Serial.available() > 0)
  {
    Incoming_value = Serial.read();
    Serial.print(Incoming_value);
    Serial.print("\n");

    if (Incoming_value == '0')
    {
      MPAP1.stop();
      MPAP1.setCurrentPosition(0);
      mpap1Running = false;
    }

    if (Incoming_value == '1')
    {
      mpap1Running = true;
    }
  }
  

  if (mpap1Running)
  {
    MPAP1.run();
    MPAP1.move(mpapNombreDePasAtourner);
  }
}

image

J'aspire à faire évoluer ce système en ajoutant dans l'application un slider qui varie entre 0 et 100, puis faire en sorte que lorsque l'on appuie sur le bouton, le moteur tourne automatiquement du même nombre que celui sur lequel le slider est arrêter.



Le slider à bien été ajouté avec à coté de lui sa valeur entre 0 et 100 affichée lorsqu'il varie mais ma difficulté consiste à transférer cette valeur à l'arduino au travers de l'hc-05. Quelqu'un aurait-il une idée de comment faire ?

Cordialement

Vous avez deux communications possibles maintenant, la valeur du slider et celle du bouton

Il faudrait par exemple émettre une lettre juste avant la valeur et décoder cela côté arduino pour savoir quoi en faire

Envoyez s23 suivi d’un passage à la ligne pour dire que le slider prend la valeur 23

Envoyez b1 suivi d’un passage à la ligne pour dire que le bouton est appuyé et b0 suivi d’un passage à la ligne quand il est relâché

Si vous voulez comprendre comment bien écouter le port série (ou gérer un flux asynchrone genre keypad) vous pouvez jeter un oeil à mon petit tuto sur le sujet

Bonjour

Il te faut un block comme ceci:
image
qui t'envoie T22 pour 22 tours.

Cordialement
jpbbricole

1 Like

Bonsoir
Je présume que je vais devoir utiliser une condition du genre:

int nombreTotalDePas = mpapNombreDePasAtourner * thumbPosition;
if (mpap1Running)
  {
    MPAP1.run();
    MPAP1.move(nombreTotalDePas);
  }

j'ai bien parcouru tout le tuto mais je n'ai toujours pas compris comment remplacer la variable "thumbPosition" par sa valeur dans l'arduino afin que lorsque ce dernier lise "1", il mémorise ensuite la lettre suivi de la valeur et d'un passage à la ligne puis met le moteur en route. Y aurait-il une instruction spéciale pour ce faire ?

Cordialement

Bonjour enash

Il faut, d'abord, "étoffer" ce que tu envoies depuis App Inventor, soit:
B0 et B1 pour les boutons.
image

Le slider envoie T15 (par exemple 15 tours)
image
Ainsi on sait qui envoie une valeur Bouton ou Tours.
Tu sépares le B de 1 ou 0 et tu sait si c'est un ordre start ou stop.
Tu sépares T de 15 et tu mets 15 dans une variable mpapNombreDeToursAtourner et tu lances le moteur par un MPAP1.move(mpapNombreDePasAtourner * mpapNombreDeToursAtourner);

Si tu veux un exemple, c'est volontiers.

Cordialement
jpbbricole

1 Like

Autre option c’est envoyer un seul caractère pour le bouton, par exemple A (appui) et R (relâche) et envoyer un nombre avec \n pour les tours.

Ça permet de déterminer facilement dans quel mode on doit être et réagir rapidement au bouton (on teste un seul caractère qui arrive et on sait)

La solution b0 b1 et Txxx est plus générique cependant et extensible simplement

Dans tous les cas comme il faut appeler la fonction run() souvent il ne faut pas que l’attente de la commande soit bloquante d’où l’importance de traiter le port série vraiment de façon asynchrone

un exemple:

enum : byte {EN_PAUSE, EN_ROUTE} etat = EN_PAUSE;

void gestionCommande() {
  static long nbTours = 0;
  static bool negatif = false;
  int c = Serial.read();
  if (c != -1) {  // y-a-t'il un caractère en attente ? (-1 si aucun)
    switch (c) {
      case 'A':
        negatif = false;
        if (nbTours == 0) {
          etat = EN_ROUTE;
          Serial.println(F("EN_ROUTE"));
        }
        break;

      case 'R':
        negatif = false;
        if (nbTours == 0) {
          etat = EN_PAUSE;
          Serial.println(F("EN_PAUSE"));
        }
        break;

      case '-':
        if (nbTours == 0) negatif = true; // on ignore sinon en cours de nombre
        break;

      case '0' ... '9':
        nbTours = (nbTours * 10) + (c - '0');
        break;

      case '\n':
        // faire quelque chose avec le nombre de tours
        Serial.print(F("action nbTours = "));  Serial.println(negatif ? -nbTours : nbTours);
        nbTours = 0; // on remet à 0 pour la prochaine fois
        negatif = false;
        break;
    }
  }
}

void setup() {
  Serial.begin(115200); Serial.println();
}

void loop() {
  gestionCommande();
  if (etat == EN_ROUTE) {
    // appeler run pour faire tourner le moteur
  }
}

si on envoie "123\n" alors ça règle le nombre de tours dès qu'on a reçu le '\n', on peut taper un nombre négatif si on veut (par exemple -234 va être reconnu, le booléen négatif sera vrai)
si on envoie 'A' ou 'R' c'est pris en compte immédiatement
si on envoie un truc un peu incohérent genre A-R123\n ça va faire comme AR123\n mais si on envoie un début de nombre alors les A et R et - sont ignorés A12R34\n va faire A1234\n

la lecture d'un message complet avec marqueur de fin serait alors plus adapté

dans l'absolu si on maitrise le code qui envoie les commandes, il n'y aura pas de cas louche

Bonjour J-M-L

Cette solution est beaucoup souple quand a un ou des ajouts de valeurs à traiter. Personnellement, je pousserai un peu plus loin en utilisant une syntaxe à 2 lettres avec x chiffres suivants.
Ainsi s'il y a 2 boutons, j'utiliserai
B01 Pour Bouton 0 à 1
B20 Pour Bouton 2 à 0

Ou 2 sliders, j'utiliserai
S132 Pour Slider 1 à 32
S0-25 Pour Slider à -25
Etc...

Une application comme MIT App Inventor donne vite envie d'en ajouter toujours plus, c'est si facile, alors il vaut mieux prévoir assez large.

Cordialement
jpbbricole

Et s’il y a 21 boutons :slight_smile:

Peut être pour les boutons avoir B>xxx et B<xxx le < et le > indiquants le relâchement et l’appui et comme ça on n’a pas de confusion entre le Nº du bouton et l’action

Bonjour J-M-L

Mais à ce moment là autant faire ce que j'ai toujours fait, donner un nom explicite à l'objet cliqué ou sélectionné, système qui permet de faciliter le traitement des commandes reçues.
BOUTON_G=0
BOUTON_D=1
TOURS=15
C'est plus simple à faire évoluer, plus explicite et, surtout, plus simple à traiter.

Cordialement
jpbbricole

Bonsoir,
@J-M-L je me suis demander en parcourant le tuto que signifie le "F" dans "Serial.println(F("YYYYYYY"));". A quoi sert-il de l'ajouter ?

Voici le code par rapport aux explications fournies mais il semblerait qu'il exige des blocs bien particuliers dans MIT app inventor ou que quelque chose m'es échappée:

#include "AccelStepper.h"
const char boutonNemaIng1 = 3;
const char mpapDirPin = 4;     // Pour driver MPAP pin pas
const char mpapStepPin = 5;     // Pour driver MPAP pin direction

AccelStepper MPAP1(1, mpapStepPin, mpapDirPin); 
int mpapNombreDePasAtourner = 200;

enum : byte {EN_PAUSE, EN_ROUTE} etat = EN_PAUSE;

void gestionCommande() {
  static long nbTours = 0;
  static bool negatif = false;
  int c = Serial.read();
  if (c != -1) {  // y-a-t'il un caractère en attente ? (-1 si aucun)
    switch (c) {
      case 'A':
        negatif = false;
        if (nbTours == 0) {
          etat = EN_ROUTE;
          Serial.println(F("EN_ROUTE"));
        }
        break;

      case 'R':
        negatif = false;
        if (nbTours == 0) {
          etat = EN_PAUSE;
          Serial.println(F("EN_PAUSE"));
        }
        break;

      case '-':
        if (nbTours == 0) negatif = true; // on ignore sinon en cours de nombre
        break;

      case '0' ... '9':
        nbTours = (nbTours * 10) + (c - '0');
        break;

      case '\n':
        // faire quelque chose avec le nombre de tours
        Serial.print(F("action nbTours = "));  Serial.println(negatif ? -nbTours : nbTours);
        nbTours = 0; // on remet à 0 pour la prochaine fois
        negatif = false;
        break;
    }
  }
}

void setup() {
  Serial.begin(115200); Serial.println();
  MPAP1.setMaxSpeed(400);
  MPAP1.setAcceleration(500);

  pinMode(boutonNemaIng1, INPUT_PULLUP);

  MPAP1.setPinsInverted(false, false, true);
  MPAP1.enableOutputs();     // Activer les signaux du MPAP
}

void loop() {
  gestionCommande();
  if (etat == EN_ROUTE) {
    // appeler run pour faire tourner le moteur
    MPAP1.move(mpapNombreDePasAtourner);
  }
  MPAP1.run();
}

@jpbbricole Si je comprend bien le principe, il faut que le programme attende en permanence si un B (pour bouton) arrive tout en lisant T (pour tours à tourner) sans discontinuer, et faire que si B arrive alors lancer un nombre de tours pareil à celui qui est indiqué après T. Puis-je voir un exemple ?

Cordialement

Bonsoir enash

Tu est dans le juste :wink:
Je te fais l'exemple demain.

Cordialement
jpbbricole

1 Like

ça coûte plus cher en mémoire et complique le décodage. ce n'est pas toujours souhaitable mais pourquoi pas, oui

ça met le texte à imprimer en mémoire programme (F pour mémoire Flash) au lieu de la SRAM qui est très limitée. Puisque ce texte ne change pas, ce n'est pas la peine d'occuper de la RAM pour cela (qui fait double emploi puisqu'en plus il est toujours stocké en mémoire flash de toutes façons avec le code)

sinon essayez en modifiant:

pour mettre à la place

  if (etat == EN_ROUTE) {
    // appeler run pour faire tourner le moteur
    MPAP1.move(mpapNombreDePasAtourner);
    MPAP1.run();
  }

comme cela si on n'est pas en route, on n'appelle pas run et aucun pas n'est effectué

Bonjour
Voici le nouveau programme avec toujours les mêmes blocks:

#include "AccelStepper.h"
const char boutonNemaIng1 = 3;
const char mpapDirPin = 4;     // Pour driver MPAP pin pas
const char mpapStepPin = 5;     // Pour driver MPAP pin direction

AccelStepper MPAP1(1, mpapStepPin, mpapDirPin); 
int mpapNombreDePasAtourner = 200;

enum : byte {EN_PAUSE, EN_ROUTE} etat = EN_PAUSE;

void gestionCommande() {
  static long nbTours = 0;
  static bool negatif = false;
  int c = Serial.read();
  if (c != -1) {  // y-a-t'il un caractère en attente ? (-1 si aucun)
    switch (c) {
      case 'A':
        negatif = false;
        if (nbTours == 0) {
          etat = EN_ROUTE;
          Serial.println(F("EN_ROUTE"));
        }
        break;

      case 'R':
        negatif = false;
        if (nbTours == 0) {
          etat = EN_PAUSE;
          Serial.println(F("EN_PAUSE"));
        }
        break;

      case '-':
        if (nbTours == 0) negatif = true; // on ignore sinon en cours de nombre
        break;

      case '0' ... '9':
        nbTours = (nbTours * 10) + (c - '0');
        break;

      case '\n':
        // faire quelque chose avec le nombre de tours
        Serial.print(F("action nbTours = "));  Serial.println(negatif ? -nbTours : nbTours);
        nbTours = 0; // on remet à 0 pour la prochaine fois
        negatif = false;
        break;
    }
  }
}

void setup() {
  Serial.begin(115200); Serial.println();
  MPAP1.setMaxSpeed(400);
  MPAP1.setAcceleration(500);

  pinMode(boutonNemaIng1, INPUT_PULLUP);

  MPAP1.setPinsInverted(false, false, true);
  MPAP1.enableOutputs();     // Activer les signaux du MPAP
}

void loop() {
  gestionCommande();
  if (etat == EN_ROUTE) {
    // appeler run pour faire tourner le moteur
    MPAP1.move(mpapNombreDePasAtourner);
    MPAP1.run();
  }
}

image

Il n'y a eu malheureusement aucune réaction du moteur. J'ai vérifié que tout est bien branché et que l'arduino fonctionne bien avec un programme précédent et c'est le cas.

Cordialement

Bonjour enash

J'ai fait évoluer les commandes envoyées depuis App Inventor, ça a l'avantage d'être plus facile à décoder et interpréter et, surtout permet d'ajouter de nouvelles commandes facilement.
Les commandes sont:
BSTART=0 ou BSTART=1 pour boutonStart
STOURS=2 ou STOURS=-4 poursliderTour
ça donne ça


Un click sur boutonStart fait faire le nombre de tours sélectionnés avec sliderTours.
Un click sur boutonStop arrête immédiatement le moteur.

Il y a encore des améliorations à apporter, mais dans l'ensemble, ça fonctionne très bien.
Je te prépare les fichiers et les mets en ligne.

Atention, comme je n'ai pas les mêmes pin que toi, méfiance... :wink:

A+
Cordialement
jpbbricole

1 Like

Bonsoir enash

Voilà ma « vision de la chose », le programme associé à celui de MIT App Inventor (MAI) fonctionne avec des commandes :
BSTART=1 (depuis boutonStart) pour démarrer

BSTART =0 (depuis boutonStop) pour arrêter
image

STOURS=12 (depuis sliderTours) pour nombre des tours (Défaut entre -20 et +20)

Tu peux tester ces commandes sans passer par MAI, simplement en les introduisant depuis la ligne de commande du moniteur de l’IDE Arduino, à 9600 et \n comme terminaison.
image

BSTART=1 démarre le nombre de tours sélectionnés (défaut 2)
BSTSART=0 Arrête, immédiatement, le moteur si le nombre de tours n’est pas terminé.
STOURS=-4 Modifie le nombre de tours, c’est actif au prochain click de boutonStart vu que l’ordre est **envoyé en même temps.

Le programme :

/*
    Name:       APPinv_enashMpapBluetooth.ino
    Created:	30.07.2022
    Author:     jpbbricole
*/
#include "AccelStepper.h"

char Incoming_value = 0;
const char boutonNemaIng1 = 3;
boolean mpap1Running = false;
const bool boutonPinEtatOn = LOW;

const char mpapDirPin = 4;  //5; (jpbbricole)     // Pour driver MPAP pin pas
const char mpapStepPin = 5;  //6; (jpbbricole)     // Pour driver MPAP pin direction

AccelStepper MPAP1(1, mpapStepPin, mpapDirPin);

long mpapNombreDeToursAtourner = 2;
long mpapNombreDePasAtourner = 200;

//------------------------------------- Ligne de commandes
bool cmdNouvelleRecue = false;      // Si une nouvelle commande a été reçue
String cmdTexte = "";               // Texte de la commande

void setup() 
{
	Serial.begin(9600);

	MPAP1.setMaxSpeed(400);
	MPAP1.setAcceleration(500);

	pinMode(boutonNemaIng1, INPUT_PULLUP);

	MPAP1.setPinsInverted(false, false, true);
	MPAP1.enableOutputs();     // Activer les signaux du MPAP
}

void loop()
{
	//--------------------------------- Ecoute du port serie
	serialReception();           // Ecouter le port série
 	
	if (cmdNouvelleRecue)      // Si une nouvelle commande depuis le moniteur
	{
		cmdExecute(cmdTexte);
	  
		cmdTexte = "";
		cmdNouvelleRecue = false;
	}
	
	if (MPAP1.distanceToGo() == 0)     // Si moteur à destination
	{
		mpapStop();
	}
	
	MPAP1.run();
}

//------------------------------------- Arrêter le moteur
void mpapStop()
{
		MPAP1.stop();
		MPAP1.setCurrentPosition(0);
		mpap1Running = false;
}

/*  -------------------------------------------------------------------------------
    Ligne de commandes, le format est Commande=Paramètre
    Ce système n'est pas sensible à la casse.
	Le paramètre peut être entier, flottant ou String

    Commandes reconnues

	BSTART=0  ou BSTART=1     Pour boutonStart
	STOURS=12		Pour sliderTours
   '*----------------------------------------------------------------------------
*/
void cmdExecute(String commande)
{
	commande.toUpperCase();     // Tout en majuscules
	commande.replace(" ", "");     // Supprimer les espaces
	Serial.println("Execution de : " + commande);

	int sepPos = commande.indexOf("=");     // Recherche du séparateur
	String cmd = commande.substring(0, sepPos);     // Extraction de la commande
	String cmdParam = commande.substring(sepPos + 1);     // Extraction du paramètre

	int cmdParamInt = cmdParam.toInt();     // Conversion du paramètre en int
	cmdParam.replace(",", ".");     // Remplacer une éventuelle virgule par un point
	float cmdParamFloat = cmdParam.toFloat();     // Conversion du paramètre en float

	if (cmd == "BSTART")     // boutonStart
	{
		Serial.print("Bouton Start ");
		Serial.println((cmdParamInt == 1) ? "ON" : "OFF");
		if (cmdParamInt == 1)     // Si start
		{
			MPAP1.move(mpapNombreDeToursAtourner * mpapNombreDePasAtourner);
			mpap1Running = true;
		} 
		else
		{
			mpapStop();
		}
	}
	else if (cmd == "STOURS")     // sliderTours
	{
		Serial.println("Nombre de tours " + String(cmdParamInt));
		mpapNombreDeToursAtourner = (long)cmdParamInt;
	}
	else if (cmd == "TEST")     // sliderTours
	{
		Serial.println("Test " + cmd);
	}
	else
	{
		Serial.print(F("Commande inconnue!!! ")); Serial.println(commande);
	}
}

/*-----------------------------------------------------------------------
  Réception de commandes depuis le moniteur
'*------------------------------------------------------------------------
*/
void serialReception()                                       
{
  if (Serial.available())
  {
	  cmdTexte = Serial.readStringUntil('\n');

	  // Nettoyage des caractères indésirables, CR, LF, TAB... et les espace de début et de fin
	  cmdTexte.trim();

	  cmdNouvelleRecue  = true;
  }
}

Je te mets, en PJ, le programme MIT.
ARDFRMPAPbuttonSlider.aia.zip (67.1 KB)

Attention, comme je n’ai pas le même brochage que toi, méfiance, des fois que j’aurai oublié… :wink:

** Cet envoi sucessif STOURS=nnn et BSTART=1 est à sécuriser, ça risque d’être trop rapide (je n’ai jamais eu de problème), j’envisage une temporisation entre ces 2 commandes et comme un délais dans MAI n’est pas si simple…

A+
Cordialement
Jpbbricole

1 Like

ce n'est peut être pas très important mais au risque de gêner la lisibilité vous devriez mettre des commandes plus courtes car Serial.readStringUntil() est bloquante et à 9600 on n'a environ un caractère que toutes les millisecondes à peine.

ça veut dire que si vous êtes en réception de commande vous irez moins souvent dans la loop() exécuter le MPAP1.run(); et donc la vitesse pourra être impactée un peu.

De plus s'il y a un souci au niveau du BT et qu'un \n n'est pas transmis, le code bloquera une seconde (modifiable avec le set timeout)

Une réception au fil de l'eau non bloquante comme discuté précédemment, évite ce souci.

Bonsoir
@jpbbricole J'ai tenté de recommencer à utiliser l'application avec le même code un peu modifié pour l'adapter à une méga, et le même montage mais avec une méga à la place d'une uno avec les broches TX et RX de l'HC-05 reliées aux broches 18 et 19 de l'arduino:

/*
    Name:       APPinv_enashMpapBluetooth.ino
    Created:  30.07.2022
    Author:     jpbbricole
*/
#include "AccelStepper.h"
#define btSerial Serial1     // Port du bluetooth

char Incoming_value = 0;
const char boutonNemaIng1 = 3;
boolean mpap1Running = false;
const bool boutonPinEtatOn = LOW;

const char mpapDirPin = 4;  //5; (jpbbricole)     // Pour driver MPAP pin pas
const char mpapStepPin = 5;  //6; (jpbbricole)     // Pour driver MPAP pin direction

AccelStepper MPAP1(1, mpapStepPin, mpapDirPin);

long mpapNombreDeToursAtourner = 2;
long mpapNombreDePasAtourner = 200;

//------------------------------------- Ligne de commandes
bool cmdNouvelleRecue = false;      // Si une nouvelle commande a été reçue
String cmdTexte = "";               // Texte de la commande

void setup() 
{
  Serial.begin(115200);
  btSerial.begin(9600);

  MPAP1.setMaxSpeed(400);
  MPAP1.setAcceleration(500);
  MPAP1.setPinsInverted(false, false, true);
  MPAP1.enableOutputs();     // Activer les signaux du MPAP
}

void loop()
{
  //--------------------------------- Ecoute du port serie
  serialReception();           // Ecouter le port série
  
  if (cmdNouvelleRecue)      // Si une nouvelle commande depuis le moniteur
  {
    cmdExecute(cmdTexte);
    
    cmdTexte = "";
    cmdNouvelleRecue = false;
  }
  
  if (MPAP1.distanceToGo() == 0)     // Si moteur à destination
  {
    mpapStop();
  }
  
  MPAP1.run();
}

//------------------------------------- Arrêter le moteur
void mpapStop()
{
    MPAP1.stop();
    MPAP1.setCurrentPosition(0);
    mpap1Running = false;
}

/*  -------------------------------------------------------------------------------
    Ligne de commandes, le format est Commande=Paramètre
    Ce système n'est pas sensible à la casse.
  Le paramètre peut être entier, flottant ou String

    Commandes reconnues

  BSTART=0  ou BSTART=1     Pour boutonStart
  STOURS=12   Pour sliderTours
   '*----------------------------------------------------------------------------
*/
void cmdExecute(String commande)
{
  commande.toUpperCase();     // Tout en majuscules
  commande.replace(" ", "");     // Supprimer les espaces
  Serial.println("Execution de : " + commande);

  int sepPos = commande.indexOf("=");     // Recherche du séparateur
  String cmd = commande.substring(0, sepPos);     // Extraction de la commande
  String cmdParam = commande.substring(sepPos + 1);     // Extraction du paramètre

  int cmdParamInt = cmdParam.toInt();     // Conversion du paramètre en int
  cmdParam.replace(",", ".");     // Remplacer une éventuelle virgule par un point
  float cmdParamFloat = cmdParam.toFloat();     // Conversion du paramètre en float

  if (cmd == "BSTART")     // boutonStart
  {
    Serial.print("Bouton Start ");
    Serial.println((cmdParamInt == 1) ? "ON" : "OFF");
    if (cmdParamInt == 1)     // Si start
    {
      MPAP1.move(mpapNombreDeToursAtourner * mpapNombreDePasAtourner);
      mpap1Running = true;
    } 
    else
    {
      mpapStop();
    }
  }
  else if (cmd == "STOURS")     // sliderTours
  {
    Serial.println("Nombre de tours " + String(cmdParamInt));
    mpapNombreDeToursAtourner = (long)cmdParamInt;
  }
  else if (cmd == "TEST")     // sliderTours
  {
    Serial.println("Test " + cmd);
  }
  else
  {
    Serial.print(F("Commande inconnue!!! ")); Serial.println(commande);
  }
}

/*-----------------------------------------------------------------------
  Réception de commandes depuis le moniteur
'*------------------------------------------------------------------------
*/
void serialReception()                                       
{
  if (btSerial.available())
  {
    cmdTexte = Serial.readStringUntil('\n');

    // Nettoyage des caractères indésirables, CR, LF, TAB... et les espace de début et de fin
    cmdTexte.trim();

    cmdNouvelleRecue  = true;
  }
}

Le programme n'a, au final, pas fonctionner. Il semble qu'il me manque quelques éléments. Quels éléments me manque-t-il dans le programme pour qu'il fonctionne comme le précédent avec la uno ?

Cordialement

Regardez de ce côté

1 Like

@J-M-L Effectivement le problème venait d'ici, merci. J'ai simplement remplacer "cmdTexte = Serial.readStringUntil('\n');" par "cmdTexte = btSerial.readStringUntil('\n');". Comment avez-vous fait pour repérer d'ou venait le coincement ?

Cordialement