Auteur Sujet: Communication Bluetooth (HC-06) / Arduino : c'est lent !  (Lu 5600 fois)

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Communication Bluetooth (HC-06) / Arduino : c'est lent !
« le: juin 07, 2021, 08:54:18 pm »
Bonsoir,
Pour commander mon réseau, je vais utiliser mon téléphone, et communiquer en BT avec un HC-O6 connecté à un Arduino Mega.
Mon appli envoie une ligne de commande sous forme de chaine de 7 caractères, plus un point-virgule qui indique la fin de la commande.
Les 7 premiers caractères sont (1) un chiffre pour indiquer le module (et envoyer la commande sur un autre Arduino), (2) une lettre pour distinguer le type (Relais, Alimentation via L298, Signal, Moteur d'aiguillage, Eclairage de bâtiment ou de rue), puis un numéro sur 4 chiffre, puis un état (Marche/Arrêt, Gauche/Droite...).
Ça fonctionne... mais c'est lentissime ! De l'ordre de 1 à 2 secondes entre l'appui sur le "bouton" de l'appli et le basculement des relais dans le cadre de mon essai avec 16 relais.
Mon code Arduino :
#define hc06 Serial3            // définition de hc06 comme un objet série sur le port Serial3 (broches Rx3, Tx3)
const byte relais_1 = A7;
const byte relais_2 = A6;
const byte relais_3 = A5;
const byte relais_4 = A4;
const byte relais_5 = A3;
const byte relais_6 = A2;
const byte relais_7 = A1;
const byte relais_8 = A0;
const byte relais_16 = 22;
const byte relais_15 = 24;
const byte relais_14 = 26;
const byte relais_13 = 28;
const byte relais_12 = 30;
const byte relais_11 = 32;
const byte relais_10 = 34;
const byte relais_9 = 36;
String commande_recue="";       // création et initialisation à "" d'une chaine de caractères pour les caractères reçus du HC-06 et former la commande
byte num_relais;                // création d'une variable contenant le numéro de relais reçu du HC-06

void setup()

{
  hc06.begin(9600);             // initialise le port série Bluetooth

// ci-dessous définition des broches
  pinMode(relais_1, OUTPUT);
  pinMode(relais_2, OUTPUT);
  pinMode(relais_3, OUTPUT);
  pinMode(relais_4, OUTPUT);
  pinMode(relais_5, OUTPUT);
  pinMode(relais_6, OUTPUT);
  pinMode(relais_7, OUTPUT);
  pinMode(relais_8, OUTPUT);
  pinMode(relais_9, OUTPUT);
  pinMode(relais_10, OUTPUT);
  pinMode(relais_11, OUTPUT);
  pinMode(relais_12, OUTPUT);
  pinMode(relais_13, OUTPUT);
  pinMode(relais_14, OUTPUT);
  pinMode(relais_15, OUTPUT);
  pinMode(relais_16, OUTPUT);

// ci-dessous mise à l'état HIGH des relais pour les mettre au repos (fonctionnement inversé) :
  digitalWrite(relais_1, HIGH);
  digitalWrite(relais_2, HIGH);
  digitalWrite(relais_3, HIGH);
  digitalWrite(relais_4, HIGH);
  digitalWrite(relais_5, HIGH);
  digitalWrite(relais_6, HIGH);
  digitalWrite(relais_7, HIGH);
  digitalWrite(relais_8, HIGH);
  digitalWrite(relais_9, HIGH);
  digitalWrite(relais_10, HIGH);
  digitalWrite(relais_11, HIGH);
  digitalWrite(relais_12, HIGH);
  digitalWrite(relais_13, HIGH);
  digitalWrite(relais_14, HIGH);
  digitalWrite(relais_15, HIGH);
  digitalWrite(relais_16, HIGH);
}

void loop()
{
_______________________________________________________________
  // Lecture du HC06
  if(hc06.available())
  {
    commande_recue = hc06.readStringUntil(';');
    if ((commande_recue[0]=='4')&&(commande_recue[1]=='R'))     // Si le 1er caractère de la commande est ' (n° de module) et le 2e est 'R' (relais)
    {
      num_relais=((byte)commande_recue[4]-48)*10+((byte)commande_recue[5]-48);  // Reconstitution du n° de relais
      switch (num_relais)                           // On prend le bon numéro de pin relais via la variable
      {
        case 1:
          pin_relais=relais_1;
          break;
        case 2:
          pin_relais=relais_2;
          break;
        case 3:
          pin_relais=relais_3;
          break;
        case 4:
          pin_relais=relais_4;
          break;
        case 5:
          pin_relais=relais_5;
          break;
        case 6:
          pin_relais=relais_6;
          break;
        case 7:
          pin_relais=relais_7;
          break;
        case 8:
          pin_relais=relais_8;
          break;
        case 9:
          pin_relais=relais_9;
          break;
        case 10:
          pin_relais=relais_10;
          break;
        case 11:
          pin_relais=relais_11;
          break;
        case 12:
          pin_relais=relais_12;
          break;
        case 13:
          pin_relais=relais_13;
          break;
        case 14:
          pin_relais=relais_14;
          break;
        case 15:
          pin_relais=relais_15;
          break;
        case 16:
          pin_relais=relais_16;
          break;
        default:
          hc06.println("Mauvaise commande");
          break;
      }
      switch (commande_recue[6])                          // Et l'état de pin relais selon la commande
      {
        case 'R':
          etat_pin_relais=1;
          break;
        case 'T':
          etat_pin_relais=0;
          break;
        default:
          hc06.println("Mauvaise commande");
          break;
      }
      digitalWrite(pin_relais, etat_pin_relais);    // On envoie la commande
    }
  }
}
Auriez-vous une explication et... une solution ?
Merci d'avance !!!

bobyAndCo

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 619
  • HO avec DCC++
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #1 le: juin 07, 2021, 11:47:09 pm »
Il y a plusieurs explications plausibles qui s’additionnent sans doute.

1° Le bluetooth n’est pas réputé pour sa vitesse. De plus ici paramétré à 9600 bauds !

2° Est que le HC6 utilise un Hardware Serial (TX1-RX1, TX2-RX2 ou TX3-RX3 du Mega)  ou SoftwareSerial ? Ca marchera plus vite en hardware serial.

3° Rationnalisez votre code, voir ci-dessous. J’avais fait un petit article sur l’utilisation des tableaux pour les codes répétitifs comme ici : https://www.locoduino.org/spip.php?article227

4° Le switch comportant de nombreux cas est consommateur de ressources. Il doit tester tous les cas jusqu’à celui qui est le bon. Si c’est dans les premières lignes, c’est bon, si par contre c’est vers la fin c’est plus long. Mais c’est toujours mieux que if, elseif qui lui teste tou les cas.

5° Evitez autant que possible les String au profit des char[] ou char*

6° Pourquoi ne pas utiliser un ESP32 qui tourne tout de même 12 x plus vite qu’un Mega et qui a le bluetooth intégré ?

Voilà quelques pistes et du code optimisé. Attention, le premier relais n’est plus le numéro un mais le numéro zéro !!!


const byte relais[] = { A7, A6, A5, A4, A3, A2, A1, A0, 22, 24, 26, 28, 30, 32, 34, 36 };

char commande_recue[7];
byte num_relais;

#define hc06 Serial1

void setup() {

  hc06.begin(9600);  // HC-06 module - Pins 18 (TX1) & 19 (RX1) on MEGA             // initialise le port série RX1 TX1 Bluetooth

  for (byte el : relais) {
    pinMode(el, OUTPUT);
    digitalWrite(el, HIGH);
  }
}

void loop() {

  if (hc06.available()) {
    for (byte i = 0; i < 7; i++)
      commande_recue[i] = hc06.read();

    if ((commande_recue[0] == '4') && (commande_recue[1] == 'R')) {
      num_relais = ((byte)commande_recue[4] - 48) * 10 + ((byte)commande_recue[5] - 48);
      digitalWrite(relais[num_relais], commande_recue[6] == 'R' ? 1 : 0);    // On envoie la commande
    }
  }
}
« Modifié: juin 08, 2021, 08:32:29 am par bobyAndCo »

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #2 le: juin 08, 2021, 09:22:36 am »
Super réponse, merci beaucoup !!!  ;D
Point par point :
1° Oui, c'est vrai... je vais voir si je peux remonter le 9600, mais j'ai peur de la fiabilité de la communication au-dessus. Faut voir.
2° Oui, le HC-06 est branché sur le TX3-RX3 du Mega
3° Je vais regarder. Je n'ai aucune prétention en matière d'optimisation de code
4° Dans la même logique que le 3°
5° Dans la même logique que le 4°... et le 3° !!!
6° Ah, pourquoi pas !? Je ne connaissais pas. Est-ce le même mode de programmation que l'Arduino ? Bon honnêtement, je préfère éviter de changer de solution en cours de route. Il est vrai que je m'intéresse beaucoup à la partie électronique / informatique, mais je veux garder la perspective d'avancer aussi sur le reste du réseau  ;)

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #3 le: juin 08, 2021, 09:27:43 am »
Et oui, bien sûr, j'ai oublié de le dire : je vais essayer ce nouveau code, mais je ne m'inquiète pas : il y a des pros d'Arduino (que je ne suis pas). Mais qu'est-ce qu'il est plus court que le mien !!!
Encore merci !

bobyAndCo

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 619
  • HO avec DCC++
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #4 le: juin 08, 2021, 10:24:12 am »
Bon je n'ai pas testé car je n'ai pas le hard correspondant. Il y a peut-être une ou deux coquilles !

Concernant l'ESP32, le code réalisé avec l'IDE d'Arduino sera totalement compatible
« Modifié: juin 08, 2021, 10:25:47 am par bobyAndCo »

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #5 le: juin 08, 2021, 10:27:05 am »
Pas bien grave, je vais regarder ce soir. Autant je ne suis pas capable du premier coup d'optimiser ainsi mon code, autant je pense arriver à ajuster s'il y a des coquilles. Du moins j'espère ! Sinon, ce sera un petit "au secours" complémentaire  :) Mais peut-être qu'il n'y aura pas besoin, sinon je vais chercher avant !
Encore merci !

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #6 le: juin 08, 2021, 11:02:34 am »
Pas encore vérifié, mais une question à la lecture du code : pourquoi remplacer Serial3 (TX3-RX3) par Serial1 (TX1-RX1) ?

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1935
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #7 le: juin 08, 2021, 12:24:00 pm »
Ca marchera plus vite en hardware serial.
Cordialement

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #8 le: juin 08, 2021, 09:18:01 pm »
Bon, ça y est, j'ai pu essayer.
Il y a un truc qui merdouille ; pour comprendre, j'ai ajouté
    for (byte i = 0; i < 7; i++)
      Serial.print(commande_recue[i]);
    Serial.println();
et j'obtiens
4⸮⸮⸮⸮⸮⸮
R⸮⸮⸮⸮⸮⸮
0⸮⸮⸮⸮⸮⸮
0⸮⸮⸮⸮⸮⸮
0⸮⸮⸮⸮⸮⸮
1⸮⸮⸮⸮⸮⸮
R⸮⸮⸮⸮⸮⸮
Forcément, le
if ((commande_recue[0] == '4') && (commande_recue[1] == 'R')) ne voit pas ce qu'il devrait...
Mais je ne vois pas l'explication...?

bobyAndCo

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 619
  • HO avec DCC++
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #9 le: juin 08, 2021, 09:24:15 pm »
Il faudrait voir ta chaine envoyée par le smartphone. A priori, ta chaine est une suite de 7 bits répétée 7 fois (différentes bien sûr).
1° série de 7 bits on a '4' + 6 ?
2° série de 7 bits on a 'R' + 6 ?
etc...

alors que bien sur, les 7 bits devraient être à suivre. En fait j'ai bien l'impression que tu envoies 49 bits alors que 7 suffisent
« Modifié: juin 08, 2021, 09:28:45 pm par bobyAndCo »

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #10 le: juin 08, 2021, 09:38:48 pm »
Voici ce qu'envoie mon appli (c'est un extrait de la partie Block d'App Inventor.
J'envoie soit en saisissant la ligne de commande dans une case de saisie de texte, et le bouton Button_OK_commande envoie sur le HC-06, soit un bouton envoie 4R0001R ou 4R0001T pour le relais 1 selon l'état précédent (R ou T), et 4R0002R ou 4R0002T pour le relais 2 (2e bouton Button_R4_2 représenté à droite).

bobyAndCo

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 619
  • HO avec DCC++
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #11 le: juin 08, 2021, 09:52:56 pm »
En réalité, je pense que ce n'est pas 4R0001R ou 4R0001T par exemple.

Et d'ailleurs je dis une connerie car ce ne sont pas des bits mais des octets

Quand tu fais Serial.print(commande_recue[i]); et que tu as :

4⸮⸮⸮⸮⸮⸮
R⸮⸮⸮⸮⸮⸮
0⸮⸮⸮⸮⸮⸮
0⸮⸮⸮⸮⸮⸮
0⸮⸮⸮⸮⸮⸮
1⸮⸮⸮⸮⸮⸮
R⸮⸮⸮⸮⸮⸮

On voit que 'R' est le premier octets utile suivi de 6 autres octets. Ce sont probablement des ascii < 33, des caractères invisibles que le Serial.print restitue avec des ?

Ce qui m'étonne c'est que l'on ne retrouve plus ici le ';' qui te servait de séparateur commande_recue = hc06.readStringUntil(';');
Ca vaut le coup de chercher à analyser la chaine d'envoi qui je pense a un problème (trop de caractères) mais sinon, il y a un moyen simple de s'en sortir par programmation (je n'ai pas dit élégant et peu couteux en ressources)
« Modifié: juin 09, 2021, 09:24:07 pm par bobyAndCo »

babskwal

  • Jr. Member
  • **
  • Messages: 67
  • Echelle N, analogique DIY
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #12 le: juin 08, 2021, 10:00:07 pm »
Oui, ça confirme que le sujet n'est pas que côté Arduino...
Je prends ma pelle et ma pioche et je creuse un peu plus.
En tous cas, merci beaucoup !!!
A suivre... mais pas ce soir, j'ai les yeux qui se croisent et les neurones qui décrochent ! (Pas un problème de communication smartphone Arduino, mais plutôt la journée au taf)

bobyAndCo

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 619
  • HO avec DCC++
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #13 le: juin 08, 2021, 10:03:09 pm »
Juste petite suggestion : Essaye d'envoyer des bits (7 donc) au lieu de 7 octes (8 fois plus lourds). D'où aussi mon erreur ci-dessus car ça me paraissait tellement évident que ça devait être de bits.

bobyAndCo

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 619
  • HO avec DCC++
    • Voir le profil
Re : Communication Bluetooth (HC-06) / Arduino : c'est lent !
« Réponse #14 le: juin 09, 2021, 09:11:34 pm »
Ce n’est pas indispensable mais ce serait souhaitable de mettre en place une petite messagerie « binaire ». Ce serait plus élégant et un peu plus efficient.

Du type :

-   codage du module sur 4 bits par exemple (ce qui autorise 16 modules)
-   type (Relais, Alimentation via L298, Signal, Moteur d'aiguillage, Eclairage de bâtiment ou de rue) sur 3 ou 4 bits
-   le numéro doit pouvoir être codé sur 4 bits (possible jusqu’à 7 bits)
-   l’état se code sur 1 bit (0 ou 1)

Au total 13 bits qui pourront être porté à 16 bits (si j’ai vu juste à certains endroits) puisque de toutes les façons il faudra 2 octets de données.

Pour la lecture du message, ce ne sera pas bien différent de ce qui existe actuellement, il faudra juste ajouter une lecture des bits à l’intérieur des 2 octets envoyés.

C’est codé en quel langage côté smartphone ? Ce serait bien d’envoyer ce code aussi !