/* Le programme Configurer_le_module.ino est un outil logiciel qui permet de configurer à notre guise un
   module Bluetooth de type HC-05 et de consulter ses données internes.

 REMARQUE : Pour faciliter les manipulations les caractères alphabétiques minuscules sont transformés
            automatiquement en leur équivalent majuscule. Ce n'est pas possible de transposer ',' en
            '?' car on a besoin de la virgule dans certaines commandes AT.
 
 NOTE : Les deux tableaux TEXTE_USB[Lgr_TEXTE+1] et TEXTE_HC_05[Lgr_TEXTE+1] servent exactement à la
        même chose, c'est à dire mémoriser les messages échangés sur les deux lignes série. Comme ils
        ne sont jamais utilisés simultanément, il serait possible de n'utiliser qu'un seul tableau
        commun. C'est pour des raisons de lisibilité du programme que j'ai opté pour ce "gaspillage",
        car avec ce démonstrateur on peut se le permettre, on dispose de place à revendre.
        Idem pour les deux variables CAR_Moniteur et CAR_module_HC05.

Comportement du programme :   (Voir le didacticiel)
---------------------------
 • On frappe des commandes AT et on observe le retour du module.
 
 BRANCHEMENTS à effectuer :
--------------------------
  • Le +5V va sur VCC du HC-05.
  • GND va sur GND  du HC-05.
  • 3,3V va sur EN  du HC-05. (Ou +5V avec 1kohm et 2kohm
  • D2 d'Arduino va sur TX du HC-05.
  • D3 d'Arduino va sur RX (1k,2k) du HC-05.
  
                                   PGM            RAM dynamique 
Compilateur v1.7.9 :        5068 Octets (15%)  379 Octets (18%)  */

//------------------------ Constantes du programme --------------------------
#define Version "04/07/2025" // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define Lgr_TEXTE 32 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define CR 13 // Code du Retour Chariot qui vaut 13 codé en ASCII sous forme décimale.
#define LF 10 // Code du passage à la ligne qui vaut 10 codé en ASCII sous forme décimale.
//------------------- Définition des broches binaires -----------------------
#define RX 2 // Va sur TX du module Bluetooth.
#define TX 3 // Va sur RX du module Bluetooth avec pont de résistances.
//---------------------- Déclarations pour le matériel ----------------------
#include <SoftwareSerial.h>
SoftwareSerial Module_HC05(RX,TX);

//------------------------- Variables du programme --------------------------
boolean Mode_question;
char CAR_Moniteur, CAR_module_HC05;
byte Index;
char TEXTE_USB[Lgr_TEXTE+1];
char TEXTE_HC_05[Lgr_TEXTE+1];

//========================= Procédures de servitude ============================
void Vider_le_tampon_USB() {while (Serial.available()) Serial.read();}

void Vider_le_tampon_HC05() {while (Module_HC05.available()) Module_HC05.read();}

void Lecture_sur_le_Moniteur(){
  TEXTE_USB[0] = 'A'; TEXTE_USB[1] = 'T'; TEXTE_USB[2] = '+';
  Index = 3; while (!Serial.available()); // Attente d'une commande sur la ligne USB.
  while (Serial.available()) {CAR_Moniteur = Serial.read();
         //-------------------- Passer les lettre en MAJUSCULES -------------------
         if ((CAR_Moniteur >= 'a') && (CAR_Moniteur < char(123))) CAR_Moniteur = CAR_Moniteur & 223;
         // Bien moins couteux en octets que Chaine_Memorisee.toUpperCase() pour convertir les minuscules.
         //------------------------------------------------------------------------
         if ((Index < Lgr_TEXTE) && (CAR_Moniteur != CR) && (CAR_Moniteur != LF)) 
            {TEXTE_USB[Index] = CAR_Moniteur; Index++;}
         delay(5);} // Délai impératif.
  if (Mode_question) {TEXTE_USB[Index] = '?'; Index++;}
  Vider_le_tampon_USB();} // Vider le tampon série si Nb caractères > Lgr_TEXTE.

void Lecture_sur_le_Module_HC_05() {
  Index = 0; while (!Module_HC05.available()); // Attente du début de l'ACR.
  while (Module_HC05.available()) {CAR_module_HC05 = Module_HC05.read();
         if ((Index < Lgr_TEXTE) && (CAR_module_HC05 != CR) && (CAR_module_HC05 != LF))
            {TEXTE_HC_05[Index] = CAR_module_HC05; Index++;}
  delay(5);}} // Délai impératif.

void Afficher_ACR() {
  Serial.print(F(" ACR = "));
  if ((TEXTE_HC_05[0] == 'E') && (TEXTE_HC_05[1] == 'R') && (TEXTE_HC_05[1] == 'R') && (TEXTE_HC_05[1] == 'O'))
      for (byte I = 0; I < Index; I++) Serial.print(TEXTE_HC_05[I]);
  else {for (byte I = 0; I < Index-2; I++) Serial.print(TEXTE_HC_05[I]);
       Serial.print(' '); Serial.print(TEXTE_HC_05[Index-2]); Serial.print(TEXTE_HC_05[Index-1]);}
  Serial.println();}

//=========================== Corps du programme ===============================

void setup(){
  pinMode(RX,INPUT); pinMode(TX,OUTPUT);  
  Serial.begin(9600); Vider_le_tampon_USB(); // Vider le tampon série.
  Serial.println(); Serial.println(); Serial.print(F(" CONFIGURATEUR : Version du ")); Serial.println(Version);
  Serial.println(); Serial.println(F(" ATTENTION : Dialogue en mode Question."));
  Module_HC05.begin(38400); Mode_question = true;}

void loop(){
  //--------------------- Saisir une commande sur le Moniteur ---------------------
  Serial.println(); Serial.print(F(" Commande ?"));
  // Charger dans TEXTE les caractères disponibles sur le port Série USB du Moniteur :
  Lecture_sur_le_Moniteur();
  //------------------------------ Traiter la commande ----------------------------
  if (TEXTE_USB[3] == '&') {Mode_question = !Mode_question;
     Serial.println(); Serial.print(F(" Mode Question = "));
     if (Mode_question) Serial.print(F("OUI")); else Serial.print(F("NON")); Serial.println();}
  //----------------------------- Afficher la commande ----------------------------
  else {Serial.print(F(" [")); for (byte I = 0; I < Index; I++) Serial.print(TEXTE_USB[I]);
       Serial.print(F("](")); Serial.print(Index); Serial.println(')');
       //------------------- Transmettre le texte vers le module ------------------
       for (byte I = 0; I < Index; I++) Module_HC05.write(TEXTE_USB[I]);
       Module_HC05.write(CR); Module_HC05.write(LF);
       //------------------- Affichage de l'accusé de réception -------------------
       Lecture_sur_le_Module_HC_05(); Afficher_ACR();}}


