Pirater un bracelet de fitness pas cher

Ceci est une traduction. Article publié le 27 mai 2018


Tracker de fitness avant et après démontage

Lorsque je suis arrivée dans l'entreprise actuelle, le premier jour, on m'a gentiment offert un ensemble de cadeaux. Parmi eux se trouvait ce bracelet avec un tracker de fitness. Quel que soit votre amour de l'exercice, c'est un gadget incroyablement cool d'un point de vue purement technique:

  • un très petit facteur de forme (environ 15 Ă— 40 mm);
  • Bluetooth basse Ă©nergie (BLE);
  • Écran OLED (96 Ă— 32 pixels);
  • batterie
  • Charge USB
  • accĂ©lĂ©romètre;
  • moteur de vibration;
  • le prix est d'environ 10 $ (!).

A l'extérieur, le seul identifiant sur le panneau arrière est l'autocollant «FCC ID: 2AHFTID115». Si vous le recherchez sur Google, il semble correspondre à l'appareil ID115 et vous pouvez même trouver plusieurs photos de son intérieur. En regardant l' une de ces photographies , si vous essayez dur, vous pouvez voir le nom du plus grand circuit intégré (IC): N51822. Cela suggère qu'il pourrait y avoir un microcontrôleur nordique (MCU) nRF51822 , un processeur ARM M0 32 bits avec prise en charge BLE intégrée, qui est théoriquement assez facile à programmer pour d'autres choses qu'un bracelet devrait faire.

Avant de démonter le gadget, je suis allé un peu plus sur Google et j'ai découvert que dans certains bracelets similaires, la même puce est installée et que les gens l'ont programmée avec succès.

L'ouverture du boîtier n'a pas été si facile. Le couvercle en plastique noir est collé au fond gris. J'ai essayé un sèche-cheveux pour adoucir la colle et je l'ai patiemment coupé avec un petit couteau, en essayant de ne pas trop endommager le plastique. Après ouverture, je me suis assuré qu'il y avait bien du nRF51822. Plus tard, j'ai acheté un bracelet MCU presque identique à Texas Instrument. Gardez à l'esprit qu'il existe des options.


nRF51822 et stylo à bille pour échelle

Trouver un moyen de communiquer


La documentation indique que la puce peut être programmée / déboguée à l'aide de l'interface à deux broches SWD (ARM Serial Wire Debug ). Si nous voulons établir un canal de communication avec une puce, cela signifie deux choses:

  • Nous avons besoin d'un programmeur SWD (par exemple, Segger J-Link ).
  • Nous aurons besoin d'accĂ©der aux deux broches SWD du microcontrĂ´leur, Ă  savoir SWDIO (donnĂ©es) et SWDCLK (impulsions d'horloge).

Heureusement, plusieurs cartes sont disponibles sur la carte. Bien que leur existence soit clairement expliquée par le besoin de débogage, de test et de vérification, je préfère penser qu'un ingénieur cool les a laissés là comme de petits cadeaux pour des gens comme nous. Tous ne sont pas correctement étiquetés, je suggère donc les codes suivants:




Face avant et arrière de la carte de circuit imprimé. Stylo à bille pour les noms d'échelle et semi-arbitraires pour les pads ouverts

En utilisant le même microscope USB bon marché , j'ai pris plusieurs photos des côtés avant et arrière de la carte et j'ai essayé de suivre les pistes du microcontrôleur aux pads.




Pistes vers les broches SWDIO et SWDCLK à l'avant et à l'arrière de la carte

Veuillez noter qu'il s'agit d'une carte de circuit imprimé multicouche avec des trous traversants, vous devez donc vérifier les pistes des deux côtés de la carte. A partir de ces photos, vous pouvez suivre les traces des contacts SWDIO et SWDCLK sur la puce jusqu'aux pads IO et CLK. Nous allons donc nous assurer que la marque CLK sur la carte correspond à SWDCLK sur le MCU et que le contact sans étiquette est la broche SWDIO. Vous pouvez maintenant préparer notre première table de mappage:

NRF51822 pinAire de jeuxLa description
SWDIOIOSortie de données pour la programmation de SWD
SWDCLKCLKSortie d'horloge pour la programmation SWD

Chirurgie post mortem


Ayant accédé à deux plots SWD, je leur ai soudé des fils très fins et à tous les autres contacts disponibles.



Clignote un peu


La tâche suivante consiste à essayer de programmer le périphérique pour une tâche. Pour exécuter le programme le plus simple, nous devons nous assurer des éléments suivants:

  • Nous avons correctement suivi les contacts de SWDIO / SWDCLK.
  • Le programmeur SWD est en cours d'exĂ©cution et l'ordinateur peut Ă©mettre des commandes.
  • Nous pouvons compiler le programme Arm et utiliser correctement le Nordic SDK .
  • Nous pouvons flasher le programme compilĂ© dans la puce.
  • La puce fonctionne correctement et charge notre programme.

Dans ce cas, «bonjour, monde» peut être un programme qui allume et éteint la LED. Et même cela n'est pas élémentaire, car il n'y a pas de LED intégrée sur la carte, et si vous en ajoutez une externe, vous devez toujours savoir à quoi la connecter. Cela ajoute une autre dimension au modèle spatial du problème. En raison du manque de théorème du fromage gratuit, je viens de connecter deux LED aux broches P1 et P2 dans l'espoir que nous puissions accéder à ces pads avec le MCU.


Mauvaise journée

Les pilotes et les programmes de ligne de commande pour le programmeur SWD J-Link se trouvent sur le site Web de Segger . Si vous utilisez macOS et utilisez Homebrew, recherchez la formule Cask dans caskroom/drivers/segger-jlink . La communication avec le programmeur SWD est établie à partir de l' JLinkExe ligne de commande JLinkExe .

J'ai ensuite téléchargé le Nordic nRF5 SDK (j'utilise la version 12.3.0 ). D'après les exemples du SDK, il est clair que nous avons besoin d'un compilateur capable de compiler des programmes Arm. J'ai donc installé gcc-arm-embedded (également disponible sur Homebrew).

Après avoir examiné la documentation du SDK et les forums de développeurs nordiques, j'ai découvert que leurs SDK sont le plus souvent utilisés avec des cartes de développement comme celle-ci . Le SDK est préconfiguré pour plusieurs variantes de ces cartes. Puisque nous sommes en contact direct avec le contrôleur, vous devrez configurer certains paramètres du SDK.

J'ai passé beaucoup de temps à comprendre l'écosystème nRF5, mais au final j'ai quand même pu exécuter le programme sur une puce! La vidéo montre deux LED clignotantes. À ce stade, j'ai créé un référentiel Github et jeté un programme avec un Makefile fonctionnel Makefile . L'un des principaux secrets était qu'il existe en fait plusieurs options pour le nRF51822, et dans le mien, il n'y a que 16 Ko de mémoire. Je devais donc encore corriger le script de l'éditeur de liens .

Entrée / sortie numérique


Comme je l'ai déjà dit, la tâche avec les LED clignotantes a fourni quelques espoirs et une méthode de poussée, qui des contacts MCU conduisent à P1 et P2 , où les LED sont connectées. La stratégie la plus simple est de connecter toutes les sorties à tour de rôle et d'appliquer tour à tour les hautes et basses tensions. À ma grande surprise, les deux LEDs se sont allumées! J'ai été encore plus surpris lorsque le vibromoteur a commencé à fonctionner!

Ainsi, la méthode poke ajoutée au tableau:

NRF51822 pinAire de jeuxLa description
P0.30P1GPIO numérique
P0.00P2GPIO numérique
P0.01-Moteur de vibration

printf


La possibilité de transférer des données vers un ordinateur est indispensable pour le débogage. Le programmateur J-Link prend en charge la transmission en temps réel (RTT) pour l'envoi et la réception de données à partir de la puce. Pour utiliser RTT, vous devez #include "SEGGER_RTT.h" et appeler SEGGER_RTT_WriteString() . Pour recevoir des données sur un ordinateur, appelez l' jlinkrttlogger ligne de commande jlinkrttlogger , fournie avec J-Link.

OLED


Un autre défi consiste à faire fonctionner l'OLED. L'OLED le plus courant sur le marché exécute le pilote / contrôleur ssd1306 , et généralement la communication avec le MCU se fait via une interface série utilisant SPI ou I²C . Voici un exemple d'Adafruit .

Je n'ai trouvé un tel affichage dans aucun des magasins ordinaires. Et la taille de 96 × 32 n'est pas standard. Une recherche par identifiant QT1316P01A sur l'affichage donne des sites chinois comme Aliexpress , mais il n'y a pas de documentation sauf pour les noms des conclusions:


Nommage des broches OLED avec Aliexpress

Si la liste ne se trouve pas, alors les contacts SCL , SDA et RES# nous indiquent qu'il s'agit d'une option I²C. S'il y a des pistes entre les trois broches du nRF51822 et ces trois broches de l'OLED, alors nous ferons un pas en avant. Revenons au microscope.




Pistes de contact de données OLED

Nous mettons Ă  jour la table de correspondance:

NRF51822 pinAire de jeuxLa description
P0.21-Sortie OLED SDA
P0.22-Broche OLED SCL
P0.24-Sortie OLED RES #

Le protocole I²C est beaucoup plus avancé que n'importe quel protocole série simple comme UART . L'un des avantages est qu'il prend en charge plusieurs périphériques maître et esclave sur le même bus. Cela complique un peu les choses: au moins, vous devez indiquer au MCU pour quelles commandes esclaves sont émises. Ainsi à un niveau élevé, outre les contacts physiques, il existe également une adresse «logique» de l'écran OLED.

Heureusement, un exemple dans le SDK nRF5 est le scanner I²C. Il interroge à partir de toutes les adresses logiques possibles et signale si quelque chose y est installé. Ma version modifiée est ici . Il produit le journal suivant:

$ make
# ...
$ make flash
# ...
$ make log
# ...
TWI scanner.
TWI device detected at 0x3c.


Bonne nouvelle! Nous avons de bonnes raisons de croire que l'affichage est correctement identifié et qu'il s'agit bien d'une variante I²C. Une recherche 0x3c indique que 0x3c est une adresse typique pour ces appareils.

Nous sommes maintenant prêts à envoyer quelques pixels à l'écran. A ce niveau, il n'y a pas d'abstraction via la bibliothèque. Voir la documentation ssd1306 pour un moyen de bas niveau de transférer des données. Le processus consiste en une séquence de commandes de configuration qui définissent l'orientation de l'affichage, le mode d'enregistrement, la taille, etc. Ensuite, une séquence d'octets affichés à l'écran est envoyée à la mémoire d'affichage graphique (GDDRAM).

Pour la configuration correcte, j'ai étudié la bibliothèque ssd1306 d'Adafruit et essayé d'émuler des commandes similaires. C'est ce qu'a pris la part du lion dans ce projet. Découvrir tous les détails s'est avéré être une tâche très longue, et je ne peux toujours pas expliquer certaines choses. Mais ça marche!


Afficher une image bitmap codée en dur

Le code de cet exemple est ici .

Avec ces paramètres, l'affichage est divisé en 4 lignes (pages) et 96 colonnes. Les pages mesurent donc 8 pixels. Le premier octet envoyé sera situé "verticalement" dans la première colonne de la première page. Le deuxième octet occupera la deuxième colonne, puis la troisième et ainsi de suite, jusqu'à la 96e colonne, quand il reviendra et commencera à partir de la première colonne de la deuxième page.

C'est le comportement attendu . Comme le montre la vidéo , le comportement observé est différent: d'abord les colonnes impaires sont remplies, puis les paires, et ensuite seulement, il revient à la deuxième page.

J'ai passé beaucoup de temps à comprendre la raison d'un tel comportement d'affichage stupide, puis un peu plus de temps pour le configurer pour le réparer. Au final, j'ai ravalé ma fierté et j'ai quand même implémenté une logique de rendu aussi étrange dans le programme pour le terminer.

Voyage Ă  Arduino


En fouillant dans la bibliothèque Adafruit ssd1306 pour Arduino, j'ai toujours pensé qu'il serait bien d'avoir un moyen de "simuler" des bits Arduino spécifiques pour les tester sur nRF51822. Il s'avère que des gens beaucoup plus expérimentés ont également pensé à ce sujet - c'est ce que fait l'incroyable projet sandeepmistry / arduino-nRF5 . Il implémente les principales bibliothèques Arduino en utilisant le SDK nRF5.

Avec ce projet, nous pouvons ouvrir l'IDE Arduino, sélectionner la carte nRF5 et utiliser le riche écosystème Arduino. J'ai bifurqué le projet et ajouté le support pour la planche de notre bracelet. Vous pouvez le sélectionner dans le menu déroulant Tools > Board > ID115 Fitness Bracelet (nRF51822) .




Bibliothèque Adafruit ssd1306 dans sa forme originale (ci-dessus) et avec un patch (ci-dessous)

Cela signifie également que nous pouvons désormais utiliser la bibliothèque OLED d'Adafruit . À ma grande surprise et soulagement, le même comportement étrange s'est produit en remplissant d'abord les colonnes OLED impaires et même paires! J'ai heureusement bifurqué la bibliothèque et implémenté le même hack. Par rapport à l'approche de bas niveau, nous avons maintenant accès à une variété d'abstractions intéressantes, telles que la sortie de texte:


Le plus familier "Bonjour, monde!"

Entrée / sortie analogique


En plus des signaux numériques marche / arrêt, le nRF51822 possède 10 broches pour l'entrée analogique. Ceci est utile, par exemple, pour lire la charge actuelle de la batterie. À en juger par la documentation, la lecture des contacts analogiques produit une valeur de 10 bits. Par conséquent, s'il y a 0V à l'entrée, alors nous lirons 0 , et s'il y a VCC , nous lirons 1023 avec des valeurs intermédiaires entre elles.

J'ai lu périodiquement les valeurs des entrées analogiques et tracé les signaux les plus intéressants:




L'effet de secouer la carte et de charger la batterie en fonction des données des entrées analogiques

Je suis convaincu que le contact P0.05 fait référence à la charge de la batterie, car la valeur augmente et diminue à mesure qu'elle se charge et se décharge. Je soupçonne que la broche P0.26 connectée à l'une des sorties de l'accéléromètre, car elle devient folle lorsque vous secouez la carte. Les contacts P0.03 et P0.04 peuvent également être connectés à différentes sorties de l'accéléromètre, mais ici un certain effet de second ordre est très probablement superposé au signal de l'entrée. Par exemple, dans le premier graphique, notez comment le niveau de la batterie (broche 5) change lorsque l'accéléromètre a besoin de plus d'énergie. Ceci est un exemple d'un effet de second ordre.

Le code peut être trouvé dans ce croquis . Les données source et le script graphique sont ici . Nous pouvons maintenant ajouter plusieurs lignes à notre table de correspondance:

NRF51822 pinAire de jeuxLa description
P0.05-Entrée analogique - connectée à la batterie
P0.26-Entrée analogique - Accéléromètre à un axe
P0.03-Entrée analogique - un axe de l'accéléromètre (probable)
P0.04-Entrée analogique - un axe de l'accéléromètre (probable)

Bouton


Dans le firmware d'origine, toucher le bracelet à un certain moment allume l'écran. Tenir ce point démarre le chronomètre, si je me souviens bien. Ce n'est pas un bouton physique, mais une sorte de tactile capacitif qui fonctionne étonnamment bien. En utilisant la même approche que pour la recherche de sorties numériques, j'ai trouvé un endroit pour me connecter au MCU (vidéo) .

Le code est ici .

NRF51822 pinAire de jeuxLa description
P0.10-Entrée numérique - bouton intégré

Bluetooth basse énergie (BLE)


La fonctionnalité BLE sur les puces nRF5 est implémentée via quelque chose appelé SoftDevice . Il s'agit d'un binaire précompilé avec une pile BLE. Il est cousu quelle que soit l'application. Il existe de nombreuses versions de SoftDevice, selon la version du SDK et la version de la puce.

La documentation fournit une certaine matrice de dépendances (malheureusement, vous ne pouvez pas y mettre de lien direct). Il montre avec quel SDK les différentes versions de la puce sont livrées - et de quelle version de SoftDevice il s'agit. Dans notre cas, la puce est marquée QFAAH0, cette puce possède 256 Ko de mémoire flash, 16 Ko de RAM et la compatibilité avec SoftDevice s130 est déclarée.

Mon SDK version 12.3 contient déjà quelques exemples d'utilisation de SoftDevice s130. Par rapport aux programmes précédents qui sont directement câblés dans des puces électroniques à partir de l'adresse 0x0 , vous devez maintenant flasher SoftDevice à partir de l'adresse 0x0 et le programme lui-même à partir de l'adresse 0x1b000 . Après chargement et initialisation, le fichier binaire SoftDevice ira à cette adresse et transférera le contrôle à notre programme. Pour illustrer, j'ai pris le même exemple avec des LED clignotantes, mais je l'ai changé pour le firmware SoftDevice ( code ). Le comportement observé n'a pas changé, sauf que vous devez pré-flasher SoftDevice:

$ make
# ...
$ make flash-softdevice
# ...
$ make flash
# ...
$ make log
# ...
Hello, world!


L'application la plus simple pour Bluetooth est peut-être de transformer l'appareil en balise . L'appareil diffuse uniquement sa présence. Un tel exemple est dans le SDK appelé ble_app_beacon . Il suppose que SoftDevice s130 déjà flashé.

Ici aussi, la communication de bas niveau avec la puce complique tout par rapport à la programmation via le SDK. En plus d'ajuster la taille de la RAM (cette connaissance était difficile pour moi dans l'exemple avec les LED), un autre problème difficile à suivre a été révélé. Il s'est avéré que la pile BLE utilise un générateur d'horloge pour effectuer des tâches urgentes. Dans les exemples du SDK, un oscillateur à cristal externe est supposé. Quand j'ai réalisé cela après des milliers de tentatives de printf , j'ai changé l'indicateur de configuration pour utiliser un générateur d'horloge synthétique, et le problème a été résolu. Le code source de la balise est ici .

BLE + Arduino


Lorsque l'exemple BLE a fonctionné avec le SDK nRF5, connaissant les pièges avec RAM et un générateur, j'ai de nouveau regardé l'environnement Arduino. Et encore une fois, il y avait le glorieux projet sandeepmistry / arduino-BLEPeripheral (du même gars que arduino-nRF5!), Qui fournit d'excellentes abstractions en plus des paramètres BLE internes.

À ma grande surprise, je n'ai même pas eu à bifurquer la bibliothèque. L'auteur du projet arduino-nrf5 a passé du temps et ajouté la configuration de toutes les cartes et paramètres, donc maintenant choisir le bon générateur d'horloge pour SoftDevice se résume à un choix simple dans le menu déroulant Tools > Low Frequency Clock > Synthesized . Génial. J'ai rapidement écrit un exemple avec la LED verte allumée via Bluetooth (avec cette application ). Son travail est montré dans la vidéo .

Plans supplémentaires


Après avoir agité cette planche pendant d'innombrables heures, mes mains me démangent pendant plusieurs semaines pour la coller plus loin dans la machine à laver et l'oublier pendant un certain temps.

Source: https://habr.com/ru/post/fr413895/


All Articles