Installation du moniteur Bluetooth sur le smartphone
Plusieurs applications Android permettent d’afficher graphiquement des données envoyées en Bluetooth par Arduino. Dans ce projet, j’ai choisi l’application Bluetooth Electronics qui permet non seulement l’affichage de données sous forme graphique depuis une carte Arduino, mais également le paramétrage de cette interface graphique et l’envoi d’instructions à exécuter.
Je vous invite à télécharger cette application sur votre smartphone en utilisant le lien suivant : Bluetooth Electronics.
Bibliothèque de gestion de l’interface Bluetooth
Espressif, le fabriquant du microcontrôleur ESP32, met à disposition une bibliothèque Bluetooth appelée « Bluetooth Serial » qui prend en charge le profil Bluetooth SPP (Serial Port Profile). Cette bibliothèque a déjà été installée dans l’environnement de l’Arduino IDE lors de l’installation de la carte ESP32-DevKitC pour Arduino.
Instructions logicielles
La bibliothèque se déclare par l’instruction :
#include <BluetoothSerial.h>
L’instance de la classe principale:
BluetoothSerial interfaceBluetooth_G;
La méthode begin() permet de démarrer l’interface Bluetooth de la carte ESP32 et de la rendre détectable. La chaîne de caractères passée en paramètre précise le nom à afficher pour les autres équipements :
interfaceBluetooth_G.begin("BMP280 Tropratik");
Dans l’application Bluetooth Electronics un Panneau est une interface graphique comprenant un ensemble de boutons, étiquettes et objet graphiques. 8 panneaux sont installés par défaut :

Aucun des panneaux proposés ne correspond aux besoins de notre projet, aussi nous allons en créer un 9ème.
L’application Bluetooth Electronics propose 3 moyens pour la création d’un panneau :
- Le dessiner directement sur le smartphone en appuyant sur le bouton « Edit » situé en bas à droite.
- Importer la définition d’un panneau depuis un fichier présent dans le smartphone ou grâce à un lien internet en cliquant sur l’icône de disquette localisée en haut à gauche.
- Le définir à l’aide d’instructions transmise par Bluetooth.
Nous choisissons cette dernière solution pour ce tutoriel, c’est-à-dire que c’est notre programme Arduino qui va envoyer des instructions par Bluetooth pour définir notre panneau et l’exécuter.
Je vous invite à lire le guide d’utilisation de ces instructions disponible ici.
Il est à noter que le 9ème paramètre de l’instruction add_text() et le 7ème paramètre de l’instruction add_gauge() précisent l’identifiant qui déclenchera la mise à jour dynamique de la zone de texte et du composant graphique.
Pour faciliter la lecture de notre programme, nous regroupons l’ensemble de ces instructions dans la fonction afficher_panneau():
void afficher_panneau(void)
{
interfaceBluetooth_G.print("*.kwl");
interfaceBluetooth_G.print("select_panel(9);");
interfaceBluetooth_G.print("clear_panel();");
interfaceBluetooth_G.print("set_grid_size(13,8);");
interfaceBluetooth_G.print("add_text(6,0,xlarge,C,Pression et Temperature,20,43,200,);");
interfaceBluetooth_G.print("add_text(3,2,large,C,Pression,0,255,0,);");
interfaceBluetooth_G.print("add_text(9,1,large,C,Temperature,250,250,250,);");
interfaceBluetooth_G.print("add_text(11,3,large,R,??,250,250,250,T);");
interfaceBluetooth_G.print("add_text(12,3,large,L,*C,250,250,250,);");
interfaceBluetooth_G.print("add_text(3,6,large,R,??,0,255,0,P);");
interfaceBluetooth_G.print("add_text(4,6,large,L,hPa,0,255,0);");
interfaceBluetooth_G.print("add_text(12,7,small,R,tropratik.fr,139,25,125,);");
interfaceBluetooth_G.print("add_gauge(2,3,1,500,1500,500,P,500,1500,10,5);");
interfaceBluetooth_G.print("add_gauge(9,2,2,-20,40,-20,T,-20*C,40*C,6,10);");
interfaceBluetooth_G.print("set_panel_notes(Pression et Temperature,lu depuis un capteur BMP280,en utilisant un ESP32-DevKitC,);");
interfaceBluetooth_G.print("run();");
interfaceBluetooth_G.print("*");
}
Les identifiants « T » et « P » sont ensuite utilisés lors de la mise à jours dynamique de la température et de la pression dans la fonction loop() de notre programme :
interfaceBluetooth_G.print("*T"+String(temperature_L)+"*");
interfaceBluetooth_G.print("*P"+String(pression_L)+"*");
Voici le code source Arduino pour l’envoi par Bluetooth de la pression et de la température lors d’une connexion au BMP280 par l’interface I2C :
/* Déclaration des bibliothèques utilisées */
#include <BMP280_DEV.h>
#include <BluetoothSerial.h>
/* Déclaration des fonctions */
void afficher_panneau(void);
/* Déclaration globales */
BMP280_DEV capteur_G;
BluetoothSerial interfaceBluetooth_G;
// Fonction de démarrage, s'exécute une seule fois:
void setup()
{
// Ouverture du port série pour les traces
Serial.begin(115200);
// Ouverture de l'interface Bluetooth
interfaceBluetooth_G.begin("BMP280 Tropratik");
// Configuration du capteur BMP280
capteur_G.begin(0x76); // SDO sur GND ou en l'air
capteur_G.setTimeStandby(TIME_STANDBY_1000MS); // Définie un temps de repos d'1 seconde
capteur_G.startNormalConversion(); // Démarre des acquisitions en continu, espacées par le temps de repos défini précédemment.
}
// Fonction principale du programme, s'exécute en boucle:
void loop()
{
float temperature_L, pression_L, altitude_L;
char tampon_l[60];
if (capteur_G.getMeasurements(temperature_L, pression_L, altitude_L))
{
/* Une mesure a été réalisée */
sprintf(tampon_l, "Temperature: %4.2f°C \t\t Pression: %4.2fhPa", temperature_L, pression_L);
Serial.println(tampon_l);
if(interfaceBluetooth_G.connected())
{
interfaceBluetooth_G.print("*T"+String(temperature_L)+"*");
interfaceBluetooth_G.print("*P"+String(pression_L)+"*");
}
else
{
Serial.println(F("Attente de connexion BlueTooth..."));
while(!interfaceBluetooth_G.connected()); // Attente de connection BlueTooth
afficher_panneau();
}
}
}
void afficher_panneau(void)
{
interfaceBluetooth_G.print("*.kwl");
interfaceBluetooth_G.print("select_panel(9);");
interfaceBluetooth_G.print("clear_panel();");
interfaceBluetooth_G.print("set_grid_size(13,8);");
interfaceBluetooth_G.print("add_text(6,0,xlarge,C,Pression et Temperature,20,43,200,);");
interfaceBluetooth_G.print("add_text(3,2,large,C,Pression,0,255,0,);");
interfaceBluetooth_G.print("add_text(9,1,large,C,Temperature,250,250,250,);");
interfaceBluetooth_G.print("add_text(11,3,large,R,??,250,250,250,T);");
interfaceBluetooth_G.print("add_text(12,3,large,L,*C,250,250,250,);");
interfaceBluetooth_G.print("add_text(3,6,large,R,??,0,255,0,P);");
interfaceBluetooth_G.print("add_text(4,6,large,L,hPa,0,255,0);");
interfaceBluetooth_G.print("add_text(12,7,small,R,tropratik.fr,139,25,125,);");
interfaceBluetooth_G.print("add_gauge(2,3,1,500,1500,500,P,500,1500,10,5);");
interfaceBluetooth_G.print("add_gauge(9,2,2,-20,40,-20,T,-20*C,40*C,6,10);");
interfaceBluetooth_G.print("set_panel_notes(Pression et Temperature,lu depuis un capteur BMP280,en utilisant un ESP32-DevKitC,);");
interfaceBluetooth_G.print("run();");
interfaceBluetooth_G.print("*");
}
Essai du programme
Après avoir compilé et transféré ce programme dans l’ESP32-DevKit, voici les opérations à réaliser sur votre smartphone :
Associer en Bluetooth l’ESP32-DevKit C
Ayant rencontré des difficultés avec la fonction d’association d’un périphérique Bluetooth proposée par l’application Bluetooth Electronics, je vous conseille de réaliser cette opération en utilisant le menu de paramétrage d’Android :


Connecter l’application Bluetooth Electronics à l’ESP32-DevKit C
Le bouton « Connect » donnant accès à l’interface de connexion est situé en haut à droite de l’écran :

On nous demande de choisir le mode de connexion : « Bluetooth Classic » pour ce programme Arduino.

Comme l’association a déjà été réalisée, notre module Arduino apparaît dans la liste des « Paired Devices »:

Il est nécessaire de sélectionner « BMP280 Tropratik » (1) pour pouvoir ensuite demande la connexion à l’aide du bouton « Connect » (2) avant de valider notre demande par le bouton « Done » (3).
Si tout se déroule bien, l’écran suivant s’affiche sur votre smartphone.

J’en ai profité pour vérifier la température du congélateur:
Le tutoriel est fini. N’hésitez pas à poster vos remarques ou vos questions afin d’enrichir cet article !

Tuto, montage et explications, « tropbien ».
Ce petit projet est ma première utilisation de l’ESP32. Je l’ai trouvé très formateur.
Le projet que j’ai en arrière plan est de réaliser des mesures de pression (athmosphérique) de l’air dans un compartiment moteur d’un avion afin d’améliorer le système de ventilation et de refroidissement.
Pour ce faire j’ai besoin de 4 ou 5 points de mesure et d’un transfert en bluetooth vers un téléphone. Le montage tropratik est un super point de départ.
Je suis ensuite passé à 2 capteurs BMP280 en cherchant la liaison SPI. j’ai tout simplement utilisé le code qui est en exemple dans la librairie BMP280 « BMP280_SPI_Normal_Multiple » en utilisant les broche 5 et 17 pour le CSB, mais cela fonctione de façon aléatoire (un capteur, ou l’autre, mais pas les deux…).
Si vous avez des idées ou un peu d’expérience sur le sujet je suis intéréssé par vos avis.
Merci.
Bonjour Thomas,
Merci pour votre retour,
De mon côté j’ai fait l’essai avec deux capteurs et tout a bien fonctionné. Je vous mets ci-dessous le code:
/* Déclaration des bibliothèques utilisées */ #include <BMP280_DEV.h> /* Déclaration globales */ BMP280_DEV capteur1_G(5); BMP280_DEV capteur2_G(17); // Fonction de démarrage, s'exécute une seule fois: void setup() { // Ouverture du port série pour les traces Serial.begin(115200); // Configuration des capteur BMP280 capteur1_G.begin(); capteur1_G.setTimeStandby(TIME_STANDBY_1000MS); // Définie un temps de repos d'1 seconde capteur1_G.startNormalConversion(); // Démarre des acquisitions en continu, espacées par le temps de repos défini précédemment. capteur2_G.begin(); capteur2_G.setTimeStandby(TIME_STANDBY_1000MS); // Définie un temps de repos d'1 seconde capteur2_G.startNormalConversion(); // Démarre des acquisitions en continu, espacées par le temps de repos défini précédemment. } // Fonction principale du programme, s'exécute en boucle: void loop() { float temperature_L, pression_L, altitude_L; char tampon_l[60]; if (capteur1_G.getMeasurements(temperature_L, pression_L, altitude_L)) { /* Une mesure a été réalisée */ sprintf(tampon_l, "Capteur 1 --> Temperature: %4.2f°C \t\t Pression: %4.2fhPa", temperature_L, pression_L); Serial.println(tampon_l); } if (capteur2_G.getMeasurements(temperature_L, pression_L, altitude_L)) { /* Une mesure a été réalisée */ sprintf(tampon_l, "Capteur 2 --> Temperature: %4.2f°C \t\t Pression: %4.2fhPa", temperature_L, pression_L); Serial.println(tampon_l); } }et le schéma de branchement que j’ai utilisés pour mes tests.
N’hésitez surtout pas à partager votre avancée, votre application dans un compartiment moteur d’avion est intéressante et je suis curieux de voir la suite !
Bonsoir Nikko,
Effectivement cela fonctionne bien, j’utilisais une vielle breadboar et j’avais des faux contact…
J’ai ajouté au code une moyenne glissante et un réglage de l’offset des capteurs, ça marche bien.
J’ai besoin de 5 capteurs en tout, si j’ai bien compris, je dois utiliser deux liaisons SPI, VSPI et HSPI?
C’est la que je bloque de nouveau…
J’ai essayé le code suivant pour faire un test avec le HSPI avec le câblage (SCK 14, MOSI 13, MISO 12, SS 5), Si tu vois ce qui clôche???
Merci
Thomas
Code essai HSPI:
/////////////////////////////////////////////////////////////////////////////////////
// BMP280_DEV – ESP32 HSPI Communications, Default Configuration, Normal Conversion
//////////////////////////////////////////////////////////////////////////////////////
#include <BMP280_DEV.h> // Include the BMP280_DEV.h library
float temperature, pressure, altitude; // Create the temperature, pressure and altitude variables
//BMP280_DEV bmp280(5); // Create BMP280_DEV object and set-up for VSPI operation, SCK 18, MOSI 23, MISO 19, SS 5
SPIClass SPI1(HSPI); // Create (instantiate) the SPI1 object for HSPI operation
BMP280_DEV bmp280(5, HSPI, SPI1); // Create BMP280_DEV object and set-up for HSPI operation, SCK 14, MOSI 13, MISO 12, SS 5
void setup()
{
Serial.begin(115200); // Initialise the serial port
bmp280.begin(); // Default initialisation, place the BMP280 into SLEEP_MODE
bmp280.setTimeStandby(TIME_STANDBY_1000MS); // Set the standby time to 1 second (1000ms)
bmp280.startNormalConversion(); // Start NORMAL continuous conversion
xTaskCreatePinnedToCore( // Kick-off « TaskOne » pinned to core 1
taskOne,
« TaskOne »,
10000,
NULL,
1,
NULL,
1);
}
void taskOne(void* parameter)
{
while(true)
{
if (bmp280.getMeasurements(temperature, pressure, altitude)) // Check if the measurement is complete
{
Serial.print(temperature); // Display the results
Serial.print(F(« *C « ));
Serial.print(pressure);
Serial.print(F(« hPa « ));
Serial.print(altitude);
Serial.println(F(« m »));
}
}
}
void loop() { delay(1000); } // Add 1 second delay
.
Bonjour Thomas,
Je t’invite à reprendre le code que je t’ai partagé et à l’adapter pour passer de 2 à 5 capteurs. Une seule liaison SPI suffit pour tous les gérer.
Bonsoir Nikko,
Effectivement je n’ai pas essayé cela. Je te tiens au courant.
Merci.
Bonsoir Nikko,
merci pour ton aide.
Tout fonctionne parfaitement