Dies ist eine Übersetzung. Artikel veröffentlicht am 27. Mai 2018
Fitness-Tracker vor und nach der DemontageAls 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 WaageEinen 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 PadsMit 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 PlatineBitte 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 Stift | Spielplatz | Beschreibung |
---|
SWDIO | IO | Datenausgabe zur Programmierung von SWD |
SWDCLK | CLK | Taktausgang 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 TagTreiber 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 Stift | Spielplatz | Beschreibung |
---|
P0.30 | P1 | Digitales GPIO |
P0.00 | P2 | Digitales 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 AliexpressWenn 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-DatenkontaktspurenWir aktualisieren die Korrespondenztabelle:
NRF51822 Stift | Spielplatz | Beschreibung |
---|
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 anDer 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ängeIch 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 Stift | Spielplatz | Beschreibung |
---|
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 Stift | Spielplatz | Beschreibung |
---|
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.