Communication avec MIT App Inventor pour publier une température et contrôler une LED de la NUCLEO-WB55

Ce exemple montre comment configurer notre carte NUCLEO-WB55 en périphérique pour qu’elle puisse se connecter sur un smartphone sous Android excécutant une application conçue avec l’interface de développement par blocs MIT APP Inventor qui fera office de central. Le cas d’usage que nous allons étudier est résumé par la figure qui suit :


MIT APP Inventor 1 use case


C’est exactement celui déjà expliqué ici, le principal changement étant que l’application ST BLE Sensor sera remplacée par une application construite avec MIT App Inventor.

Matériel requis

  1. La carte NUCLEO-WB55
  2. Un smartphone Android pour y installer l’application que nous avons créée avec MIT App Inventor.

Les codes MicroPython pour le périphérique

Les scripts présentés ci-après sont disponibles dans la zone de téléchargement.

Pour ce tutoriel, l’implémentation BLE repose sur deux scripts :

  1. ble_advertising.py une bibliothèque de fonctions qui seront utilisées pour construire les trames d’avertising du protocole GAP, lancé pour et avant la connexion à un central.
  2. ble_sensor.py, une bibliothèque qui appelle ble_advertising.py pour démarrer le protocole GAP et qui implémente aussi le protocole GATT. C’est ce fichier qui paramétrise les services, les caractéristiques et leurs UUID conformément à Blue-ST. Grâce au fichier ble_sensor.py nous allons pouvoir créer un objet BLE ayant 1 service et 2 caractéristiques.C’est ce fichier qu’il faudra modifier pour changer le profil BLE, si besoin.

    Ces fichiers sont construits avec la classe Microbluetooth documentée ici et adaptés des scripts disponibles ici. Leur structure est assez abstraite et leur analyse complète dépasserait le cadre de l’initiative éducative STM32python.

C’est main.py qui contiendra le code du programme utilisateur et qui importera ble_advertising.py et ble_sensor.py.
Ce script montre deux alternatives pour générer les températures : soit par un appel à un générateur de nombres aléatoires pour les simuler, soit par une mesure à l’aide d’un capteur I2C BME280. Dans ce deuxième cas, il faudra bien sûr disposer aussi de la bibliothèque pilote qui convient : bme280.py.

Comme pour tous les autres tutoriels il faudra inclure tous ces fichiers dans le disque USB PYBFLASH associé à l’espace de stockage de l’USB USER de la NUCLEO-WB55.

Le script ble_sensor.py

On retrouve presque exactement le script déjà présenté par le tutoriel sur ST BLE Sensor, avec des changements uniquement dans cette méthode de la classe “BLESensor” :

	# On écrit la valeur de la température dans la caractéristique "temperature" 
	def set_data_temperature(self, temperature, notify):
		self._ble.gatts_write(self._temperature_handle, pack('<f', temperature))
		if notify:
			for conn_handle in self._connections:
				# Signale au Central que la valeur de la caractéristique vient d'être rafraichie et qu'elle peut donc être lue.
				self._ble.gatts_notify(conn_handle, self._temperature_handle)

Pour simplifier le décodage de la caractéristique de température par MIT App Inventor, nous n’envoyons plus l’information d’horodatage de la mesure et nous codons celle-ci comme un nombre à virgule flottante (‘<f’).

Le programme principal

Éditez le script main.py contenu dans le répertoire du disque USB virtuel associé à la NUCLEO-WB55 : PYBFLASH.

# Cet exemple montre comment programmer un périphérique BLE avec le standard Blue-ST pour envoyer
# des mesures de température et contrôler une LED à l'aide d'un service contenant une caractéristique
# de température.
# Si vous n'avez pas de capteur de température :
#    Les mesures sont simulées avec un générateur de nombres aléatoires 
# Si vous disposez d'un capteur de température I2C BME280 :
#    La température est remontée par celui-ci
# Les mesures (simulées ou pas) sont mises à jour toutes les cinq secondes 
# et notifiées à la même fréquence à un éventuel central BLE qui serait connecté.

import ble_sensor # Implémentation du BLE GATT selon Blue-ST
import bluetooth # Pour la gestion du BLE
from time import sleep_ms # Pour la gestion du temps et des temporisations

# Est-ce qu'un module I2C capteur de température BME280 est connecté ) la NUCLEO-WB55 ?
SENSOR = True

# Si vous ne disposez pas d'un capteur de température
if not SENSOR:
	from random import randint # Pour la génération de valeurs aléatoires
else:
# Si vous disposez d'un capteur de température I2C  BME280

	from machine import I2C # Pilote du contrôleur de bus I2C
	import bme280 # Pilote du capteur

	# On utilise l'I2C n°1 de la carte NUCLEO-WB55 pour communiquer avec le capteur
	i2c = I2C(1)

	# Pause d'une seconde pour laisser à l'I2C le temps de s'initialiser
	sleep_ms(1000)

	# Liste des adresses I2C des périphériques présents
	print("Adresses I2C utilisées : " + str(i2c.scan()))

	# Instanciation du capteur
	bme = bme280.BME280(i2c=i2c)

# Instantiation du BLE
ble = bluetooth.BLE()
ble_device = ble_sensor.BLESensor(ble)

while True:

	if not SENSOR:
		# Valeur aléatoire entre -20 et 90 °C
		temperature = randint(-20, 90)
	else:
		# Lecture des valeurs mesurées par le BME280
		bme280 = bme.values
		temperature = round(bme280[0],1)

	# Envoi en BLE de la température en choisissant de notifier l'application
	ble_device.set_data_temperature(temperature, notify=1) 
	
	# Temporisation de cinq secondes
	sleep_ms(5000)

L’application MIT App Inventor pour notre central

Le code source au format “.aix” est disponible dans la section “Tutoriels avec le BLE” de l’archive BLE.ZIP.

Avertissement

Selon les tests que nous avons pu mener, le comportement des applications réalisées avec MIT App Inventor peut être très différent d’une machine Android à une autre. Aussi, si notre application ne fonctionne pas sur votre smartphone, testez là sur un autre terminal en priorité avant d’y rechercher des erreurs.

1. Initialisation du projet

Dans un premier temps, nous allons créer un nouveau projet depuis l’application MIT APP Inventor et analyser l’interface de développement.

Vous pourrez accéder au site de MIT APP Inventor en cliquant ici.

Pour démarrer un nouveau projet il suffit de cliquer sur Create Apps!.



Vous pourrez, à partir de ce moment là, changer de langue (en haut à droite) et passer à la langue française : notre tutoriel est fait à partir du site en français. Une fois votre compte créé vous pourrez cliquer sur Commencer nouveau projet.... Nous appellerons notre projet “BLE_CENTRAL_BLUEST”.

L’interface de développement de MIT APP Inventor est séparée en 2 parties : la partie design et la partie code.



Vous pourrez passer d’une fenêtre à l’autre en cliquant sur les boutons Designer et Blocs situés en haut à droite de l’écran.

Bien évidemment, plutôt que partir de zéro, vous pouvez aussi importer le programme finalisé, dans le fichier BLE_CENTRAL_BLUEST.aia que vous aurez récupéré dans la section “Téléchargements”. Dans ce cas, il faut aller dans le menu Projets (en haut à gauche de page de MIT APP Inventor, après connexion), puis choisr Importer le projet (.aia) de mon ordinateur..., cliquer sur Choisir un fichier, aller chercher BLE_CENTRAL_BLUEST.aia et validez avec OK.

2. Conception de l’interface graphique de l’application

Dans un premier temps nous allons travailler sur le design de notre application. Nous allons devoir déterminer quels sont éléments (boutons, label, listes …) nécessaires.

Sur le côté gauche, dans le menu Palette, vous disposez de plusieurs boites à outils contenant toutes les fonctionnalités que vous pouvez apporter à votre application.

Pour ajouter un élément à notre application il suffit de le faire glisser sur le dessin de l’écran de téléphone (la fenêtre Interface). Vous pouvez voir ici le contenu de cette fenètre pour notre application terminée ; nous allons expliquer sa construction :



Pour la bonne disposition des éléments sur l’écran, nous allons les placer dans des conteneurs ou arrangements. Ceux-ci sont disponibles dans la boite à outils accessible avec l’onglet Disposition, sur le côté gauche. Sélectionnez un Arrangement horizontal et faites-le glisser sur l’interface.

  • Dans la colonne Propriétés, à droite, sélectionnez Alignement horizontal : Centrer et Alignement vertical : Haut.
  • Dans la colonne Composants, juste à côté, apparait désormais une entrée “Arrangement_horizontal1” ; cliquez sur le bouton Renommer, en bas, et changez son nom en “Arrangement_scan”.



Choisissez à présent la boite à outils Interface utilisateur et faites glisser tour à tour quatre éléments Bouton dans Interface. Suivant la procédure expliquée juste avant, renommez les en “ButtonScan”, “ButtonStopScan”, “ButtonConnect” et “ButtonDisconnect”. Pour chacun de ces boutons, utilisez la colonne Propriétés et modifier le champ texte de sorte que leurs intitulés sur l’interface soient “Rech.”, “Fin rech.”, “Connexion” et “Déconnexion”. Votre interface devrait ressembler à ceci :



Pour la gestion du BLE, nous allons devoir importer l’extension BluetoothLE. Pour ce faire, commencer par vous rendre sur cette page et téléchargez la dernière version du fichier edu.mit.appinventor.ble.aix (à la date de la rédaction de ce tutoriel, il s’agit de la version 20200828).

Allez ensuite dans le menu Palette, choisissez l’entrée Extension puis Import extension. Dans la boite de dialogue qui s’affiche, cliquez sur le bouton Choisir un fichier puis sélectionnez le fichier de l’extension :



Cliquez sur le bouton Import. Une entrée BluetoothLE apparait alors sous Extension dans la palette. Glissez-déposez celle-ci dans l’interface, une indication Composant non-visible : BluetoothLE1 apparait alors dans la fenètre Interface, sous le dessin du smartphone :



Pour finir l’écran d’accueil, nous rajoutons les éléments suivants dans l’interface :

  • Un Label, renommé “LabelStatus”, initialisé avec le texte “Aucun appareil connecté”.
  • Une Vue liste, renommée “ListBLE”
  • Un Arrangement vertical, renommé “Fonctionnalités”
  • Un Switch, renommé LED, agrémenté du texte “Allumez / Éteignez la LED : “ et positionné dans l’arrangement vertical “Fonctionnalités”
  • Un Arrangement horizontal renommé “Temp”, qui contient deux labels : “Texte” et “Température”
  • Le label “Texte” a comme texte “Température (°C) : “ et le label “Température” a comme texte “…”.

La figure ci-dessous fait la synthèse de tous ces éléments :



3. Programmation par blocs de l’application

Passons à présent à la programmation de l’application. Basculez dans la partie Blocs. Le programme complet ressemble à ceci :



Les différents blocs sont regroupés par thèmes dans la boite à outils Blocs. Par exemple, sur l’image qui précède, nous avons sélectionné les outils de la catégorie Listes et nous voyons apparaître tous les blocs correspondants. La manipulation des blocs est conçue pour être intuitive : il suffit de les glisser dans la fenêtre Interfaceet de les imbriquer. Nous ne nous attarderons pas sur ce sujet, la principale difficulté consiste à se familiariser avec le contenu de la boite à outils pour y trouver rapidement les blocs dont on a besoin, ce qui nécessite un peu de partique. Nous allons directement passer en revue les différents blocs qui constituent notre programme - central BLE.

Les variables gobales

Trois blocs permettent de partager avec l’ensemble des autres blocs les identifiants uniques (UUID) des services et des caractéristiques. Ils encodent ce que l’on appelle d’ordinaire des variables globales.



Le bloc “Screen Initialise”

Ce bloc rassemble les instructions qui configurent l’interface utilisateur au moment du lancement du programme. Elles sont exécutées entre le moment où l’utilisateur appuie sur l’icône de l’application sur son smatrphone et le moment où celle-ci s’affiche à l’écran.



Le bloc “ButtonScan Clic”

Ce bloc gère les appuis sur le bouton ButtonScan, il permet de démarrer la recherche d’advertisers BLE à proximité et d’ajuster l’interface graphique en conséquence.



Le bloc “BluetoothLE Device Found”

Les instructions de ce bloc sont appelées pour chaque advertiser BLE découvert lorsque la fonction de recherche (bloc ci-avant) est en cours d’exécution. Concrêtement, il rajoute dans ListBLE une ligne contenant l’adresse de chaque advertiser BLE découvert.



Le bloc “ButtonStopScan Clic”

Ce bloc gère les appuis sur le bouton ButtonStopScan, il permet d’interrompre la recherche d’advertisers BLE et d’ajuster l’interface graphique en conséquence.



Le bloc “ListBLE Après prise”

Les instructions de ce bloc son exécutées lorsque l’utilisateur sélectionne une entrée de ListBLE, c’est à dire une adresse d’advertiser BLE.



Le bloc “ButtonConnect Clic”

Ce bloc gère les appuis sur le bouton ButtonConnect, il provoque la connexion du central au périphérique sélectionné dans ListBLE.



Le bloc “quand BluetoothLE1 Connected”

Les instructions de se bloc sont exécutées dès lors que l’application est parvenue à se connecter à un périphérique BLE. Elle met à jour l’interface graphique en conséquence et elle abonne le smartphone aux notifications de la caractéristique “Température” servie par le smartphone.



Le bloc “quand BluetoothLE1 FloatsReceived”

Les instructions de ce bloc capturent les nouvelles valeurs de la caractéristique “Température” chaque fois que celle-ci notifie une mise à jour de son contenu.



Le bloc “quand LED Changé”

Les instructions de ce bloc sont exécutées lorsque le switch LED change d’état. Il permet à l’application d’écrire dans la caractéristique “SWITCH” servie périphérique afin que celui-ci allume ou éteigne la LED de la NUCLEO-WB55 en conséquence.



Le bloc “quand ButtonDisconnect Clic”

La seule instruction de ce bloc est exécutée lorsque l’utilisateur appuie sur ButtonDisconnect et a pour effet de mettre fin à la connexion entre le central MIT App Inventor et le périphérique NUCLEO-WB55.



Le bloc “quand BluetoothLE1 Disconnected”

Ce dernier bloc prend effet lorsque l’évènement de déconnexion entre le périphérique et le central survient (après un appui sur ButtonDisconnect). Il reconfigure l’interface graphique pour une éventuelle nouvelle connexion.



4. Utilisation de l’application créée

fin de pouvoir utiliser l’application que vous venez de créer et donc de pouvoir communiquer avec la carte, vous devrez tout d’abord télécharger l’application MIT AI2 Companion que vous trouverez sur le Play Store :



Afin de pouvoir utiliser notre application, vous devrez l’exporter sur votre téléphone. Pour cela, vous devrez ouvrir le menu Connect sur le site de MIT App Inventor :



Maintenant, vous devez cliquer sur la section AI Companion dans ce menu :



Cela vous ouvrira la fenêtre suivante :



Sur votre téléphone, ouvrez l’application MIT AI2 Companion. Vous verrez cette fenêtre apparaître :



Vous pouvez donc voir que 2 manières existent pour utiliser votre application :

  • un code à 6 lettres ou
  • un QR code.

Or sur votre ordinateur, un QR code est affiché, et à sa droite un code à 6 lettres.

Vous pouvez donc vous connecter de la manière que vous souhaitez.

Une fois le QR code scanné, ou le code à 6 lettres rentré, vous verrez une barre de chargement s’affichée sur l’écran de votre ordinateur :



Une fois celle-ci remplie, vous pourrez voir votre application sur votre téléphone :



Sélectionnez la ligne contenant le nom du périphérique : “WB55-MPY” dans la liste. On remarque que le début de la ligne correspondante est l’adresse matérielle (adresse MAC) de la carte : “02:02:27:4E:25:16” puis appuyez sur Connexion. Vous pouvez lire la température et contrôler la LED de la NUCLEO-WB55 avec le Switch :