/* Ce programme sert à établir le dialogue avec un module ESCLAVE associé piloté par un autre Arduino.
   Le programme associé sur l'Esclave est nommé P07_Esclave_C.
   Ce démonstrateur est directement dérivé de P06 et se contente d'ajouter un écran OLED pour
   afficher sous forme graphique analogique et numérique la valeur de la consigne.

   >>>>>>>> Avant d'utiliser de démonstrateur, il faut brancher le potentiomètre de 10kOhm sur A0,
            téléverser P00_Outil_de_mesure_U.ino et noter les valeurs de MIN et de MAX. Puis avant de
            téléverser P06_Maitre_C remplacer par les valeurs mesurées celles des déclarations de
            #define MINI 17 et de #define MAXI 1010 en ligne 41 et 42.

 Préalable à l'utilisation de ce démonstrateur :
 -----------------------------------------------
  • L'adresse du module esclave a été lue et initialisée dans le programme Maitre avec AT+BIND.
  • Les deux machines ont PSWD = 1905 comme Mot de passe.
  • Les deux machines ont UART = 9600,0,0 comme format de transfert série sur TX et RX.

Comportement du programme :   
---------------------------
 • On tourne le potentiomètre. La valeur affichée sur le Moniteur doit varier entre 0 et 8 pour la plage
   angulaire totale. Ces valeurs comprises entre 0 et 8 sont envoyées en permanence à l'ESCLAVE qui retourne
   l'ACR et surtout illumine la rampe de LEDs en fonction de la consigne. Le chiffre reçu précise le nombre
   de LEDs illuminées. La rapidité de lecture du potentiomètre est directement influencée par la durée de la
   chaîne de communication entre les deux unités. Il faut donc minimiser cette dernière. En particulier
   l'affichage sur l'écran OLED ralentit le processus. C'est la raison pour laquelle il n'est effectué que
   si la valeur de la consigne a changé.
 
 BRANCHEMENTS à effectuer :
--------------------------
  • Le +5V va sur VCC du HC-05.
  • GND va sur GND  du HC-05.
  • GND va sur EN  du HC-05.
  • D2 d'Arduino va sur TX du HC-05.
  • D3 d'Arduino va sur RX (1k,2k) du HC-05.
  • A0 est reliée à un potentiomètre de 10kOhm de type linéaire.
                       ----------------------------------------- 
  
                                   PGM            RAM dynamique 
Compilateur v1.7.9 :        12918 Octets (40%)  591 Octets (28%)  */

//------------------------ Constantes du programme --------------------------
#define Version "10/07/2025" // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define Lgr_TEXTE 32 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define MINI 17 // Valeur minimale mesurée par la CAN @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define MAXI 1010 // Valeur maximale mesurée par la CAN @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#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 d'entrées analogiques ----------------
#define Potentiometre 14 // A0 pour lire la tension fournie par le potentiomètre. 
#define Ligne_deux_touches 15  // A1 pour lire le clavier à 2 BP.
//------------------- 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.
#define LED_Arduino 13
//---------------------- Déclarations pour le matériel ----------------------
#include <SoftwareSerial.h>
SoftwareSerial Module_HC05(RX,TX);

#include "U8glib.h"
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // Usage de la ligne I2C (Two Wire Interface)

//------------------------- Variables du programme --------------------------
char CAR_module_HC05;
byte Chiffre, Index, SAV_Chiffre;
int CAN_sur_A0;
long int Total;

char TEXTE_HC_05[Lgr_TEXTE+1];

//========================= Procédures de servitude ============================

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

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(10);}} // Délai impératif.

void Mesurer_la_tension() {
  //-------------------- 100 mesures dont on fait la moyenne --------------------
  Total = 0; 
  for (byte N = 0; N < 100; N++) {Total = Total + analogRead(Potentiometre);}
  CAN_sur_A0 = int(Total / 101);}
  // NOTE : On divise par 101 au lieu de 100 pour minorer la moyenne, car l'arrondi par int
  //        conduit à des valeurs moyennes > 1013 si on divise par 100.

void CADRES() {u8g.drawFrame(0,0,128,64); u8g.drawHLine(1,12,126);} // Cadre TITRE et cadre rampe.

void Barre_lumineuse() {u8g.drawBox(4,1,Chiffre * 15,11);}

void AFF_Curseur() {
  u8g.drawCircle(97,38,22); u8g.drawDisc(97,38,11);
  switch(Chiffre) {
    case 0 : {u8g.drawLine(97,38,80,48); break;}
    case 1 : {u8g.drawLine(97,38,77,38); break;}
    case 2 : {u8g.drawLine(97,38,80,28); break;}
    case 3 : {u8g.drawLine(97,38,87,21); break;}
    case 4 : {u8g.drawLine(97,38,97,18); break;}
    case 5 : {u8g.drawLine(97,38,107,21); break;}
    case 6 : {u8g.drawLine(97,38,114,28); break;}
    case 7 : {u8g.drawLine(97,38,117,38); break;}
    case 8 : {u8g.drawLine(97,38,114,48);}}}

void Aff_Ecran_OLED() {
  u8g.firstPage(); do {// Début de la boucle d'affichage de la page écran.
  //================ Définition des éléments à afficher ================
    u8g.setScale2x2();
    // ATTENTION : Ci-dessus les coordonnées sont doublées par le logiciel de la bibliothèque.
    u8g.setPrintPos(5,20); u8g.print("L = "); u8g.print(Chiffre);
    u8g.undoScale(); CADRES(); Barre_lumineuse(); AFF_Curseur();}
  //====================================================================
  while(u8g.nextPage());} // Fin de la boucle d'affichage de la page écran.

void Envoyer_la_consigne() {
  Chiffre = map(CAN_sur_A0,MINI,MAXI-112,0,8); Module_HC05.write(Chiffre);
  // NOTE Pour avoir un angle égal aux autres pour la valeur 8 il faut enlever au MAXI le neuvième de
  //      la CAN la plus grande possible. Dans notre cas c'est MAXI = 1010 / 9 = 112.
  if (Chiffre != SAV_Chiffre) {Aff_Ecran_OLED(); SAV_Chiffre = Chiffre;}}

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

void setup(){
  pinMode(RX,INPUT); pinMode(TX,OUTPUT);
  pinMode(LED_Arduino, OUTPUT); Module_HC05.begin(9600);
  Serial.begin(38400); Serial.println(); Serial.println();
  Serial.print(F(" MAITRE-C : Version du ")); Serial.println(Version);
  Serial.println(); Serial.println(F(" Programme aveugle."));
  u8g.setFont(u8g_font_6x10);} // Police de matrices de 6x10 pixels lettres MJA/min comprises.

void loop() {
  digitalWrite(LED_Arduino, HIGH);
  Mesurer_la_tension();
  Envoyer_la_consigne(); digitalWrite(LED_Arduino, LOW);
  Lecture_sur_le_Module_HC_05();} // L'ACR n'est pas analysé.

