Table des matières

Le BLE sur ESP32

Cet article est écrit fin avril 2020, et l'actualité est à la sortie du confinement dû à l'épidémie de SARS-Cov2. Beaucoup d'états, mais aussi les fabricants de smartphone directement, mettent en avant la possibilité de suivre nos contacts sociaux via une application installée sur nos téléphones. L'idée est de détecter un contact prolongé et rapproché avec une personne qui déclarerait la maladie. Si ces applications ne sont encore pas disponibles partout (quel temps serait gagné si elles étaient open source !), elles s'appuient sur la technologie BLE, Bluetooth Low Energy. Il est possible d'expérimenter cette manière de faire communiquer deux appareils électroniques grâce aux ESP 32 que nous utilisons au fablab.

Cet article détaille de manière très claire, et sans termes techniques cette fois, les fonctionnements, les limites et les avantages de tels systèmes: https://april.org/comment-fonctionne-une-application-de-tracking-du-coronavirus-matti-schneider

Objectif

L'objectif ici sera de détecter la proximité d'un dispositif émettant des informations en BLE, en estimant sa distance à l'aide de l'atténuation du signal. Grâce à l'utilitaire nRF Connect, disponible sur Android, on peut visualiser ci-dessous les variations du RSSI (puissance de réception) en fonction de la distance d'un périphérique BLE. À noter, la ligne bleue est un périphérique… du voisinage ! Probablement de mon voisin du dessous, le signal traversant le plancher. Un sacré défi pour les applications, qui devront faire la différence entre un contact à travers une cloison, et un contact de visu.

On voit que la puissance du signal oscille entre - 40 dBm (proche à 20 cm) et -70 dBm (éloigné de 4 m).

BLE

Mais d'abord, le BLE, qu'est ce que c'est ? Le mieux est d'aller voir ce lien, qui a servi de base à tout ce petit projet: https://randomnerdtutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/ . Autre ressource utile: http://tvaira.free.fr/bts-sn/activites/activite-ble/activite-ble-esp32.html

Pour résumer, le BLE est une variante économe en énergie du Bluetooth, qui permet à des périphériques de s'échanger de petites quantités d'informations sur de courtes distances. Le BLE a une fonction de mise en veille performante qui rend son usage jusqu'à 100 fois moins consommateur que le Bluetooth classique. Le BLE peut se connecter de point à point, mais aussi broadcaster ou communiquer via des réseaux maillés.

La connexion point à point fonctionne avec un serveur, qui fournit des informations et un client qui les reçoit. Ces informations sont organisées de telle façon qu'un service contient des characteristic qui elle-mêmes possèdent des descriptor. Par exemple, un service peut être la lecture des battements du cœur, ou la vitesse de pédalage d'un vélo. La characteristic de chaque service sera, entre autre, sa valeur envoyée.

Chaque characteristic, service et descriptor est identifié par un UUID, c'est à dire un identifiant unique, qui ressemble à 55072829-bc9e-4c53-938a-74a6d4c78776 . Ce sont ces UUID qui nous aideront à différencier nos périphériques de test.

Les périphériques de test

Nous allons travailler avec 4 objets différents:

  1. Un ESP32 sous forme de carte de développement, tel que nous en possédons au fablab. Nous lui connectons 3 Leds pour vérifier que nous discriminons correctement les 3 autres périphériques.
  2. Un M5 Stack, qui est aussi un ESP32 inclus dans un boîtier avec écran, batterie et capteur. Très pratique pour prototyper, nous en utilisons également un au fablab. Plus d'infos: https://m5stack.com/
  3. un M5 Stick, la version portable du modèle précédent
  4. un smartphone sous Android. Le modèle utilisé n'implémente pas la norme BLE nativement, nous utiliserons l'appli BLE Peripheral Simulator pour l'expérience.

Le code des serveurs

Le code que nous allons utiliser s'appuie sur les exemples qui sont disponibles dès lors que nous avons installé la carte ESP32 dans l'éditeur Arduino. Si l'ESP32 n'apparaît pas dans le gestionnaire de cartes, allez dans Préférences>URL de gestionnaire de cartes supplémentaires, et collez cette ligne: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json . Allez ensuite dans Outils > Type de cartes > Gestionnaire de cartes, et installez le support des ESP32. Les cartes du fablab sont des DOIT ESP32 DEVKIT V1 (c'est marqué dessus).

Le code des serveurs BLE va se trouver dans les Exemples>ESP32 BLE Arduino. On choisira le code BLE_server. C'est ce même code que nous chargerons dans les M5, en changeant à chaque fois l'UUID du service. On peut analyser, dans la fonction setup, les différentes étapes pour initialiser notre périphérique, puis notre service, et ses caractéristiques.

  BLEDevice::init("M5 STICK");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setValue("abc");
  pService->start();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

Dès que `startAdvertising` est appelé, le périphérique deviendra visible au client. Pour le smartphone, nous utiliserons donc l'application BLE Peripheral Simulator qui fait peu ou prou le même travail.

Le code du client

Ici, nous allons charger le programme Exemples>ESP32 BLE Arduino>BLE_scan dans l'ESP32 auquel nous aurons connecté 3 Leds. Si nous lançons le programme tel quel, voici ce que la console va afficher à intervalles réguliers:

Advertised Device: Name: M5 STICK, Address: 3c:71:bf:47:5a:56, serviceUUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, txPower: 3 
Advertised Device: Name: M5 STACK, Address: a4:cf:12:44:0d:c6, serviceUUID: 869133b4-9c57-4416-86e9-776a95ecfcd1, txPower: 3 
Advertised Device: Name: PHONE, Address: 50:71:59:c6:c3:81, serviceUUID: 0000180f-0000-1000-8000-00805f9b34fb, txPower: -7 
Devices found: 3
Scan done!

On voit que chaque périphérique BLE des environs a été détecté (nous avons trouvé un emplacement pour éviter celui du voisin), et que chaque UUID de service est correctement lu.

Nous allons récupérer la puissance du signal en ajoutant ces quelques lignes juste après la ligne qui affiche les caractéristiques de chaque appareil détecté (dans la fonction de rappel onResult de la classe MyAdvertisedCallbacks , qui est appelée chaque fois qu'un appareil est détecté):

if (advertisedDevice.haveRSSI())
{
   Serial.printf("Rssi: %d \n", (int)advertisedDevice.getRSSI());
}

Voici ce qui apparaît dans la console après cet ajout:

Advertised Device: Name: M5 STICK, Address: 3c:71:bf:47:5a:56, serviceUUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, txPower: 3 
Rssi: -83 
Advertised Device: Name: M5 STACK, Address: a4:cf:12:44:0d:c6, serviceUUID: 869133b4-9c57-4416-86e9-776a95ecfcd1, txPower: 3 
Rssi: -75 
Advertised Device: Name: PHONE, Address: 50:71:59:c6:c3:81, serviceUUID: 0000180f-0000-1000-8000-00805f9b34fb, txPower: -7 
Rssi: -62 
Devices found: 3
Scan done!

Nous récupérons maintenant à la fois l'UUID du signal et sa puissance, plus qu'à tester et allumer les leds en conséquence.

Nous aurons besoin de déclarer un UUID:

BLEUUID M5STICK_UUID;
M5STICK_UUID = BLEUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");

Pour le comparer, dans la fonction de rappel, avec `RRSI_MIN` qui définit le seuil de détection :

        if (advertisedDevice.isAdvertisingService(M5STICK_UUID) && RSSI_MIN>abs(advertisedDevice.getRSSI()))
        {
           digitalWrite(RED_LED, HIGH);
        }

Et voici le test avec le code complet, disponible en zip tout en bas de la page:


Et si on met le code serveur dans un autre M5 Stick, il devient possible de détecter la proximité d'un congénère qui briserait la distanciation sociale ! L'application StopCovid fonctionnera sensiblement de la même façon, mais en multipliant et stockant les UUID rencontrés.

CODE SOURCE:

À noter, chaque périphérique contient quelques lignes destinées à l'affichage des infos sur les écrans. Elles ne sont pas détaillées ici pour des raisons de clarté.

codesource_esp32_ble.zip