Communiquer entre Android et Arduino en Bluetooth Low Energy grâce à une application en Python-Kivy.
L’ensemble du projet :
Voici l’ensemble du projet. Vous trouverez dans ce zip :
- Le fichier .ino à transférer dans l’Arduino (Uno) ;
- Le fichier .java permettant de surcharger la classe BluetoothGattCallback ;
- Le fichier main.py contenant le code de l’application à compiler avec buildozer ;
- Le fichier buildozer.spec contenant les informations de l’application Android, les droits BLUETOOTH et BLUETOOTH_ADMIN ainsi que le lien vers le fichier .java ;
Je vous conseille de lire les remarques suivantes et l’ensemble des explications afin de comprendre un peu mieux le fonctionnement et les éventuelles modifications que vous pourriez avoir à faire.
Voici l’apk. C’est un zip donc il faut l’extraire et autoriser les sources inconnues sur votre Android.
Une vidéo de démonstration :
Remarques importantes :
- Il existe deux types de Bluetooth (pour faire simple). Le Bluetooth classique (mode EDR) et le Low Energy (mode BLE) ;
- Cette application n’est valable que sous Android (à partir de 4.4.... peut-être 4.3 ?). Pas besoin de rooter la tablette.
- Nous avons acheté un Grove BLE v1 qui n’est pas dual-mode (il ne fait que BLE). Le service qui nous intéresse est le FFE0 qui contient la caractéristique FFE1 (Voir les UUID dans l’application Kivy) ;
- Il faut ouvrir les connexions Bluetooth et appairer le Grove BLE avant de lancer l’application (Mot de passe : "000000") ;
- Si vous partez en mode EDR, vous pouvez regarder ici : https://gist.github.com ;
- Le fait que le mode EDR ne soit pas supporté par ce périphérique provoque des gels des applications qui tentent de se connecter dans ce mode (Applications AppInventor par exemple) ;
- Je n’ai trouvé qu’une seule discussion concernant Kivy et le BLE : groups.google
- Un site qui décrit bien les possibilités : http://developer.android.com ;
- J’ai rencontré deux difficultés : implémenter une classe java abstraite et comprendre les valeurs que recevait le Arduino. (Un grand merci à Pierre et Yo !)
Commençons....
Adapter la class java BluetoothGattCallback pour pouvoir l’implémenter ensuite :
Créez un fichier que vous pouvez appelez BluetoothGattImplem.java :
Application Python-Kivy :
Pour communiquer avec le Grove BLE il faut suivre un processus très précis :
- Il faut ajouter le fichier java dans le dossier du projet (le même que celui où vous allez mettre le main.py suivant ;
- Ajouter certains paramètres dans le fichier buildozer.spec à savoir, les autorisations Bluetooth et la prise en compte du fichier java pour pyjnius. Voici le fichier buildozer.spec :
- Se connecter avec un ConnectGatt et attendre la connexion ;
- Découvrir les services du BLE et attendre la fin de cette recherche ;
- Attraper la Charactéristic qui permet d’envoyer des données au BLE ;
- Mettre une valeur dans cette Charactéristic. La méthode utilisée est setValue(nombre, format, offset). Le format est à 17 ici pour Uint8.
- Envoyer cette valeur au BLE ("writeCharacteristic").
Cette application comprend une interface utilisateur minimum :
- Un bouton de connexion (qui recherche aussi la Charactéristic) ;
- Un TextInput qui ne prend que des nombres (On envoye des chiffres !) ;
- Un bouton Send pour envoyer le contenu du TextInput s’il est valable.
N’oubliez pas deux choses dans cette application :
- Le Grove BLE doit être appairé et se nommer "HMSoft".
- Il n’y a pas de LEscan dans cette application.... à faire...
- Le nom du BLE doit être HMSoft. Changez ce nom dans l’application avant de compliler si vous n’avez pas le même nom.
Le code :
Côté Arduino :
- Branchez le BLE sur les broches 2 et 3 (D2 sur le GroveShield) ;
- Branchez le Grove_RGB_LCD sur un port I2C ;
- Envoyez le code suivant ;
- N’hésitez pas à débrancher puis rebrancher le ArduinoUno ;
Remarques :
- La recherche du bon BaudRate fut difficile (nous sommes ici en 38400 pour le BLE) ;
- Un problème de bit de poids fort qui nous a imposé d’enlever 80 (en hexa) à la valeur lue. (En effet, l’aspect signé ou non signé du nombre n’a rien changé... Si vous avez une idée ?)
- L’application Kivy envoie un par un les chiffres qui composent le nombre. La raison étant qui la lecture sur le Arduino s’arrête à 63. On obtient 0 pour 64 puis 1 pour 65. De même, 0 pour 640 puis 1 pour 641... Si quelqu’un a une idée ?
- Ce code affiche chaque chiffre envoyé seconde par seconde.