Ein billiges Fitness-Armband hacken

Dies ist eine Übersetzung. Artikel veröffentlicht am 27. Mai 2018


Fitness-Tracker vor und nach der Demontage

Als ich zur jetzigen Firma kam, bekam ich am ersten Tag freundlicherweise eine Reihe von Geschenken. Unter ihnen war dieses Armband mit einem Fitness-Tracker. Unabhängig von Ihrer Liebe zur Bewegung ist dies aus rein technischer Sicht ein unglaublich cooles Gerät:

  • ein wirklich kleiner Formfaktor (ungefähr 15 × 40 mm);
  • Bluetooth Low Energy (BLE);
  • OLED-Anzeige (96 × 32 Pixel);
  • Batterie
  • USB-Aufladung
  • Beschleunigungsmesser;
  • Vibrationsmotor;
  • Der Preis beträgt ca. 10 $ (!).

Draußen ist die einzige Kennung auf der Rückseite der Aufkleber „FCC ID: 2AHFTID115“. Wenn Sie es googeln, scheint es dem ID115- Gerät zu entsprechen, und Sie können sogar mehrere Fotos seiner Innenseiten finden. Wenn Sie sich eines dieser Fotos ansehen, können Sie den Namen der größten integrierten Schaltung (IC) sehen: N51822. Dies deutet darauf hin, dass es möglicherweise einen nordischen Mikrocontroller (MCU) nRF51822 gibt , einen 32-Bit-ARM-M0-Prozessor mit integrierter BLE-Unterstützung, der theoretisch recht einfach für andere Aufgaben zu programmieren ist, die ein Armband ausführen sollte.

Bevor ich das Gadget zerlegte, ging ich noch ein wenig auf Google und stellte fest, dass in einigen ähnlichen Armbändern derselbe Chip installiert ist und die Leute ihn erfolgreich programmiert haben.

Das Öffnen des Koffers war nicht so einfach. Die schwarze Plastikhülle ist auf den grauen Hintergrund geklebt. Ich versuchte einen Fön, um den Kleber zu erweichen, und schnitt ihn geduldig mit einem kleinen Messer ab, um den Kunststoff nicht zu stark zu beschädigen. Nach dem Öffnen habe ich sichergestellt, dass es wirklich nRF51822 gibt. Später kaufte ich ein fast identisches MCU-Armband von Texas Instrument. Denken Sie daran, dass es Optionen gibt.


nRF51822 und Kugelschreiber für Waage

Einen Weg finden, um zu kommunizieren


Die Dokumentation besagt, dass der Chip über die zweipolige Schnittstelle ARM Serial Wire Debug (SWD) programmiert / debuggt werden kann. Wenn wir einen Kommunikationskanal mit einem Chip einrichten möchten, bedeutet dies zwei Dinge:

  • Wir brauchen einen SWD-Programmierer (zum Beispiel Segger J-Link ).
  • Wir benötigen Zugriff auf die beiden SWD-Pins des Mikrocontrollers, nämlich SWDIO (Daten) und SWDCLK (Taktimpulse).

Glücklicherweise gibt es mehrere Pads auf dem Board. Obwohl ihre Existenz klar durch die Notwendigkeit des Debuggens, Testens und Verifizierens erklärt wird, denke ich lieber, dass ein cooler Ingenieur sie dort als kleine Geschenke für Leute wie uns zurückgelassen hat. Nicht alle von ihnen sind ordnungsgemäß beschriftet, daher schlage ich die folgenden Codes vor:




Vorder- und Rückseite der Leiterplatte. Kugelschreiber für Skalen und halb beliebige Namen für offene Pads

Mit demselben billigen USB-Mikroskop machte ich mehrere Bilder von der Vorder- und Rückseite der Platine und versuchte, die Spuren vom Mikrocontroller bis zu den Pads zu verfolgen.




Tracks zu SWDIO- und SWDCLK-Pins auf der Vorder- und Rückseite der Platine

Bitte beachten Sie, dass dies eine mehrschichtige Leiterplatte mit Durchgangslöchern ist. Überprüfen Sie daher die Spuren auf beiden Seiten der Leiterplatte. Auf diesen Fotos können Sie die Spuren von den Kontakten SWDIO und SWDCLK auf dem Chip bis zu den Pads IO und CLK verfolgen. Wir werden also sicherstellen, dass die CLK-Markierung auf der Platine der SWDCLK auf der MCU entspricht und der unbeschriftete Kontakt der SWDIO-Pin ist. Jetzt können Sie unsere erste Zuordnungstabelle vorbereiten:

NRF51822 StiftSpielplatzBeschreibung
SWDIOIODatenausgabe zur Programmierung von SWD
SWDCLKCLKTaktausgang für SWD-Programmierung

Obduktion


Nachdem ich Zugang zu zwei SWD-Pads erhalten hatte, löte ich sehr dünne Drähte an diese und an alle anderen verfügbaren Kontakte.



Blink ein wenig


Die nächste Aufgabe besteht darin, zu versuchen, das Gerät für eine bestimmte Aufgabe zu programmieren. Um das einfachste Programm auszuführen, müssen wir Folgendes sicherstellen:

  • Wir haben die Kontakte von SWDIO / SWDCLK korrekt verfolgt.
  • Der SWD-Programmierer wird ausgeführt und der Computer kann Befehle ausgeben.
  • Wir können das Arm-Programm kompilieren und das Nordic SDK korrekt verwenden.
  • Wir können das kompilierte Programm in den Chip flashen.
  • Der Chip funktioniert korrekt und lädt unser Programm.

In diesem Fall kann „Hallo Welt“ ein Programm sein, das die LED ein- und ausschaltet. Und selbst dies ist nicht elementar, da auf der Platine keine eingebaute LED vorhanden ist. Wenn Sie eine externe hinzufügen, müssen Sie noch herausfinden, an was sie angeschlossen werden soll. Dies fügt dem räumlichen Modell des Problems eine weitere Dimension hinzu. Aufgrund des Mangels an freiem Käsesatz habe ich gerade zwei LEDs an die Pins P1 und P2 in der Hoffnung, dass wir mit der MCU zu diesen Pads gelangen können.


Schlechter Tag

Treiber und Befehlszeilenprogramme für den J-Link SWD-Programmierer finden Sie auf der Segger-Website . Wenn Sie unter macOS arbeiten und Homebrew verwenden, suchen Sie unter caskroom/drivers/segger-jlink nach der Cask-Formel. Die Kommunikation mit dem SWD-Programmierer wird über das JLinkExe .

Dann habe ich das Nordic nRF5 SDK heruntergeladen (ich verwende Version 12.3.0 ). Aus den SDK-Beispielen geht hervor, dass wir einen Compiler benötigen, der Arm-Programme kompilieren kann. Also habe ich gcc-arm-embedded installiert (auch bei Homebrew erhältlich).

Nachdem ich die SDK-Dokumentation und die nordischen Entwicklerforen untersucht hatte, stellte ich fest, dass ihre SDKs am häufigsten mit solchen Entwicklungsboards verwendet werden. Das SDK ist für mehrere Varianten solcher Karten vorkonfiguriert. Da wir in direktem Kontakt mit dem Controller stehen, müssen Sie einige SDK-Parameter konfigurieren.

Ich habe viel Zeit damit verbracht, das nRF5-Ökosystem zu verstehen, aber am Ende konnte ich das Programm immer noch auf einem Chip ausführen! Das Video zeigt zwei blinkende LEDs. Zu diesem Zeitpunkt habe ich ein Github-Repository erstellt und dort ein Programm mit einem funktionierenden Makefile gespeichert . Eines der Hauptgeheimnisse war, dass es tatsächlich mehrere Optionen für nRF51822 gibt, und in meinem gibt es nur 16 KB Speicher. Also musste ich noch das Linker-Skript reparieren .

Digitaler Ein- / Ausgang


Wie ich bereits sagte, gab die Aufgabe mit blinkenden LEDs einige Hoffnungen und eine Poke-Methode, welche der MCU-Kontakte zu P1 und P2 , wo die LEDs angeschlossen sind. Die einfachste Strategie besteht darin, alle Ausgänge nacheinander zu verbinden und nacheinander Hoch- und Niederspannung anzulegen. Zu meiner Überraschung leuchteten beide LEDs auf! Ich war noch mehr überrascht, als der Vibromotor anfing zu arbeiten!

Also, die der Tabelle hinzugefügte Poke-Methode:

NRF51822 StiftSpielplatzBeschreibung
P0.30P1Digitales GPIO
P0.00P2Digitales GPIO
P0.01- -Vibrationsmotor

printf


Die Fähigkeit, Daten auf einen Computer zu übertragen, ist für das Debuggen unverzichtbar. Der J-Link-Programmierer unterstützt Echtzeitübertragung (RTT) zum Senden und Empfangen von Daten vom Chip. Um RTT verwenden zu können, müssen Sie #include "SEGGER_RTT.h" und SEGGER_RTT_WriteString() aufrufen. Um Daten auf einem Computer zu empfangen, rufen Sie die jlinkrttlogger , die mit J-Link geliefert wird.

OLED


Eine weitere Herausforderung besteht darin, OLED zum Laufen zu bringen. Auf der am häufigsten verwendeten OLED auf dem Markt wird der Treiber / Controller ssd1306 ausgeführt. Die Kommunikation mit der MCU erfolgt normalerweise über eine serielle Schnittstelle, die entweder SPI oder I²C verwendet . Hier ist ein Beispiel von Adafruit .

Ich habe ein solches Display in keinem der normalen Geschäfte gefunden. Und die Größe von 96 × 32 ist nicht Standard. Eine Suche nach der Kennung QT1316P01A auf dem Display zeigt chinesische Websites wie Aliexpress an , es gibt jedoch keine Dokumentation außer den Namen der Schlussfolgerungen:


OLED-Pin-Benennung mit Aliexpress

Wenn die Liste nicht lügt, teilen uns die Kontakte SCL , SDA und RES# , dass dies eine I²C-Option ist. Wenn zwischen den drei Pins von nRF51822 und diesen drei Pins von OLED Spuren vorhanden sind, werden wir einen Schritt nach vorne machen. Kehren wir zum Mikroskop zurück.




OLED-Datenkontaktspuren

Wir aktualisieren die Korrespondenztabelle:

NRF51822 StiftSpielplatzBeschreibung
P0.21- -OLED SDA-Ausgabe
P0.22- -OLED SCL Pin
P0.24- -OLED RES # ausgeben

Das I²C-Protokoll ist viel weiter fortgeschritten als jedes einfache serielle Protokoll wie UART . Einer der Vorteile besteht darin, dass mehrere Master- und Slave-Geräte am selben Bus unterstützt werden. Dies macht die Sache etwas komplizierter: Zumindest müssen Sie der MCU mitteilen, für welche Slave-Befehle ausgegeben werden. Auf hoher Ebene gibt es also neben physischen Kontakten auch eine „logische“ Adresse des OLED-Displays.

Glücklicherweise ist ein Beispiel im nRF5 SDK der I²C-Scanner. Er fragt nach allen möglichen logischen Adressen und meldet, ob dort etwas installiert ist. Meine modifizierte Version ist hier . Es wird das folgende Protokoll erstellt:

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


Tolle Neuigkeiten! Wir haben guten Grund zu der Annahme, dass das Display korrekt identifiziert wurde und es sich tatsächlich um eine I²C-Variante handelt. Eine 0x3c Suche besagt, dass 0x3c eine typische Adresse für solche Geräte ist.

Jetzt können wir einige Pixel an das Display senden. Auf dieser Ebene gibt es keine Abstraktion durch die Bibliothek. In der Dokumentation zu ssd1306 finden Sie eine einfache Möglichkeit zum Übertragen von Daten. Der Prozess besteht aus einer Folge von Konfigurationsbefehlen, mit denen die Ausrichtung der Anzeige, der Aufnahmemodus, die Größe usw. festgelegt werden. Anschließend wird eine Folge von Bytes, die auf dem Bildschirm angezeigt werden, an den Grafikdisplayspeicher (GDDRAM) gesendet.

Für die richtige Konfiguration habe ich die ssd1306-Bibliothek von Adafruit studiert und versucht, ähnliche Befehle zu emulieren. Das war es, was der Löwe in diesem Projekt zeitlich in Anspruch nahm. Es stellte sich als sehr zeitaufwändig heraus, alle Details herauszufinden, und dennoch kann ich einige Dinge nicht erklären. Es funktioniert jedoch!


Zeigen Sie eine fest codierte Bitmap an

Der Code für dieses Beispiel ist hier .

Mit diesen Einstellungen ist die Anzeige in 4 Zeilen (Seiten) und 96 Spalten unterteilt. Die Seiten sind also 8 Pixel groß. Das erste gesendete Byte befindet sich "vertikal" in der ersten Spalte der ersten Seite. Das zweite Byte belegt die zweite Spalte, dann die dritte usw. bis zur 96. Spalte, wenn es zurückkehrt und von der ersten Spalte auf der zweiten Seite beginnt.

Dies ist das erwartete Verhalten. Wie im Video gezeigt , ist das beobachtete Verhalten anders: Zuerst werden die ungeraden Spalten gefüllt, dann die geraden, und erst dann kehrt es zur zweiten Seite zurück.

Ich habe viel Zeit damit verbracht, den Grund für solch ein dummes Anzeigeverhalten zu verstehen, und dann noch etwas Zeit, um es zu konfigurieren, um es zu beheben. Am Ende schluckte ich meinen Stolz und implementierte immer noch eine so seltsame Renderlogik in das Programm, um es zu beenden.

Reise nach Arduino


Als ich mich in die Adafruit ssd1306-Bibliothek für Arduino vertiefte , dachte ich immer, es wäre schön, eine Möglichkeit zu haben, bestimmte Arduino-Bits zu „simulieren“, um sie auf nRF51822 zu testen. Es stellt sich heraus, dass auch viel erfahrenere Leute über dieses Thema nachgedacht haben - das ist es, was das erstaunliche Sandeepmistry / Arduino-nRF5- Projekt tut . Es implementiert die wichtigsten Arduino-Bibliotheken mithilfe des nRF5-SDK.

Mit diesem Projekt können wir die Arduino IDE öffnen, das nRF5-Board auswählen und das reichhaltige Arduino-Ökosystem nutzen. Ich gabelte das Projekt und fügte Unterstützung für das Brett von unserem Armband hinzu. Sie können es aus dem Dropdown-Menü Tools > Board > ID115 Fitness Bracelet (nRF51822) .




Adafruit ssd1306 Bibliothek in ihrer ursprünglichen Form (oben) und mit einem Patch (unten)

Dies bedeutet auch, dass wir jetzt die Adafruit OLED-Bibliothek verwenden können . Zu meiner Überraschung und Erleichterung passierte dasselbe seltsame Verhalten, als zuerst ungerade und gerade OLED-Spalten ausgefüllt wurden! Ich gabelte gerne die Bibliothek und implementierte den gleichen Hack. Im Vergleich zum Low-Level-Ansatz haben wir jetzt Zugriff auf eine Vielzahl cooler Abstraktionen, wie z. B. die Textausgabe:


Das bekanntere "Hallo Welt!"

Analoge Ein- / Ausgabe


Zusätzlich zu den digitalen Ein / Aus-Signalen verfügt der nRF51822 über 10 Pins für den analogen Eingang. Dies ist beispielsweise zum Ablesen der aktuellen Batterieladung nützlich. Nach der Dokumentation ergibt das Lesen von analogen Kontakten einen 10-Bit-Wert. Wenn also am Eingang 0V anliegen, lesen wir 0 , und wenn VCC , lesen wir 1023 mit Zwischenwerten dazwischen.

Ich habe regelmäßig die Werte der Analogeingänge gelesen und die interessantesten Signale aufgezeichnet:




Der Effekt des Schüttelns der Platine und des Ladens des Akkus gemäß den Daten der Analogeingänge

Ich bin überzeugt, dass sich der Kontakt P0.05 auf die Batterieladung bezieht, da der Wert beim Laden und Entladen zunimmt und abnimmt. Ich vermute, dass Pin P0.26 mit einem der Ausgänge des Beschleunigungsmessers verbunden ist, da er verrückt wird, wenn Sie die Platine schütteln. Die Kontakte P0.03 und P0.04 können auch mit verschiedenen Ausgängen des Beschleunigungsmessers verbunden werden, aber hier wird dem Signal vom Eingang höchstwahrscheinlich ein bestimmter Effekt zweiter Ordnung überlagert. Beachten Sie beispielsweise im ersten Diagramm, wie sich der Batteriestand (Pin 5) ändert, wenn der Beschleunigungsmesser mehr Energie benötigt. Dies ist ein Beispiel für einen Effekt zweiter Ordnung.

Code finden Sie in dieser Skizze . Die Quelldaten und das Grafikskript finden Sie hier . Jetzt können wir unserer Korrespondenztabelle mehrere Zeilen hinzufügen:

NRF51822 StiftSpielplatzBeschreibung
P0.05- -Analogeingang - An Batterie angeschlossen
P0.26- -Analogeingang - Einachsiger Beschleunigungsmesser
P0.03- -Analogeingang - eine Achse des Beschleunigungsmessers (wahrscheinlich)
P0.04- -Analogeingang - eine Achse des Beschleunigungsmessers (wahrscheinlich)

Knopf


Wenn Sie in der Original-Firmware das Armband an einer bestimmten Stelle berühren, wird das Display eingeschaltet. Wenn Sie diesen Punkt halten, wird der Chronometer gestartet, wenn ich mich richtig erinnere. Dies ist keine physische Taste, sondern eine Art kapazitive Berührung, die überraschend gut funktioniert. Mit dem gleichen Ansatz wie bei der Suche nach digitalen Ausgängen habe ich einen Ort gefunden, an dem eine Verbindung zur MCU (Video) hergestellt werden kann .

Der Code ist hier .

NRF51822 StiftSpielplatzBeschreibung
P0.10- -Digitaleingang - Eingebaute Taste

Bluetooth Low Energy (BLE)


Die BLE-Funktionalität auf nRF5-Chips wird über SoftDevice implementiert. Dies ist eine vorkompilierte Binärdatei mit einem BLE-Stapel. Es wird unabhängig von der Anwendung genäht. Abhängig von der SDK-Version und der Chip-Version gibt es viele Versionen von SoftDevice.

Die Dokumentation enthält eine bestimmte Abhängigkeitsmatrix (Sie können leider keinen direkten Link dazu setzen). Es zeigt, mit welchem ​​SDK die verschiedenen Versionen des Chips geliefert werden - und um welche Version von SoftDevice es sich handelt. In unserem Fall ist der Chip mit QFAAH0 gekennzeichnet, dieser Chip verfügt über 256 KB Flash-Speicher, 16 KB RAM und die Kompatibilität mit SoftDevice s130 ist deklariert.

Mein SDK Version 12.3 enthält bereits einige Beispiele für die Verwendung von SoftDevice s130. Im Vergleich zu früheren Programmen, die von Adresse 0x0 direkt mit Mikrochips 0x0 , müssen Sie jetzt SoftDevice von Adresse 0x0 und das Programm selbst von Adresse 0x1b000 . Nach dem Laden und Initialisieren wird die SoftDevice-Binärdatei an diese Adresse gesendet und die Steuerung an unser Programm übertragen. Zur Veranschaulichung habe ich dasselbe Beispiel mit blinkenden LEDs verwendet, es jedoch für die SoftDevice-Firmware ( Code ) geändert. Das beobachtete Verhalten hat sich nicht geändert, außer dass Sie SoftDevice vorab flashen sollten:

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


Die vielleicht einfachste Anwendung für Bluetooth besteht darin, das Gerät in ein Leuchtfeuer zu verwandeln. Das Gerät sendet nur seine Anwesenheit. Ein solches Beispiel befindet sich im SDK mit dem Namen ble_app_beacon . Es wird davon ausgegangen, dass SoftDevice s130 bereits geflasht ist.

Auch hier erschwert die Kommunikation auf niedriger Ebene mit dem Chip alles im Vergleich zur Programmierung über das SDK. Neben der Anpassung der RAM-Größe (dieses Wissen war für mich im Beispiel mit LEDs schwierig) wurde ein weiteres schwer zu verfolgendes Problem festgestellt. Wie sich herausstellte, verwendet der BLE-Stapel einen Taktgenerator, um zeitkritische Aufgaben auszuführen. In den SDK-Beispielen wird ein externer Quarzoszillator angenommen. Als ich dies nach Tausenden von printf erkannte, änderte ich das Konfigurationsflag, um einen synthetischen Taktgenerator zu verwenden, und das Problem wurde gelöst. Der Quellcode des Beacons ist hier .

BLE + Arduino


Als das BLE-Beispiel mit dem nRF5-SDK arbeitete und die Fallen mit RAM und einem Generator kannte, schaute ich noch einmal auf die Arduino-Umgebung. Und wieder gab es das großartige Projekt Sandeepmistry / Arduino-BLEPeripheral (vom selben Typ wie Arduino-nRF5!), Das zusätzlich zu den internen BLE-Einstellungen hervorragende Abstraktionen bietet.

Zu meiner Überraschung musste ich nicht einmal die Bibliothek teilen. Der Autor des arduino-nrf5-Projekts verbrachte Zeit und fügte die Konfiguration aller Karten und Einstellungen hinzu. Die Auswahl des richtigen Taktgenerators für SoftDevice erfolgt nun über eine einfache Auswahl aus dem Dropdown-Menü Tools > Low Frequency Clock > Synthesized . Genial. Ich habe schnell ein Beispiel mit eingeschalteter grüner LED über Bluetooth geschrieben (mit dieser Anwendung ). Seine Arbeit wird im Video gezeigt .

Weitere Pläne


Nachdem ich unzählige Stunden mit diesem Board herumgespielt habe, jucken meine Hände einige Wochen lang, um es weiter in die Waschmaschine zu stecken und es für eine Weile zu vergessen.

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


All Articles