
In diesem Teil des Tutorials bauen wir auf Teil 5 des Tutorials auf und fügen Unterstützung für den LIS2DH12 an Bord des RuuviTag Modells + hinzu. Der finale Code dieses Blogbeitrags kann auf Ruuvi GitHub im ruuviblog-Branch, Tag 3.6.0-alpha, heruntergeladen werden.
Bitte folge Teil 1 der Serie für Details zum Klonen des Repositories und Kompilieren des Codes. Die finale Hex-Datei dieses Tutorials kann vom Ruuvi Jenkins heruntergeladen werden.

Hinzufügen von LIS2DH12-Treibern
SPI-Wrapper
STMicroelectronics bietet C-Treiber für einige ihrer Sensoren an, darunter den LIS2DH12. Wir werden ihr Github-Projekt als Submodul zu unserem Projekt hinzufügen. Wie der Bosch BME280-Treiber erwartet auch der LIS2DH12-Treiber Schnittstellenfunktionen zum Schreiben und Lesen.
int32_t platform_write(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len)int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len)Erweitern wir unsere SPI–Schnittstelle um LIS2DH12-Unterstützung:

Die Funktionen sind fast identisch mit denen des BME280, aber unser Rückgabewert ist vom Typ int32_t und das Handle ist ein void-Zeiger. Zusätzlich hat der LIS2DH12 eine spezielle Handhabung des Lesens/Schreibens über den SPI-Bus und von Mehrbyte-Lese-/Schreibvorgängen. Der Lese-/Schreibmodus wird durch das höchstwertige Bit der Registeradresse bestimmt, und das zweithöchstwertige Bit der reg_addr muss gesetzt werden, wenn wir mehr als ein Byte gleichzeitig übertragen möchten.
Implementierung der Sensorschnittstelle
Die Sensorschnittstelle hat genau die gleichen Funktionen wie unser Umweltsensor, nur data_get setzt einen anderen Datentyp auf den void-Zeiger. Streng genommen könnten wir Beschleunigungsdaten an den Umweltsensordaten-Typ übergeben, da beide uint64_t und drei Floats haben, aber die Definition der Einheit im Datentyp verdeutlicht die Bedeutung jedes Floats.

Vorerst werden wir keine gepufferten Lesevorgänge vom LIS2DH12 First-In-First-Out (FIFO) implementieren, da dies für die Ruuvi-Datenformate nicht erforderlich ist. Vielleicht werden wir die Schnittstelle später erweitern, oder wir werden FIFO als einen weiteren Sonderfall betrachten, der von der Anwendung behandelt werden muss.
Die Implementierung selbst umfasst über 600 Zeilen, wobei der größte Teil aus Eingabeprüfungen und Switch-Cases besteht. Der Selbsttest muss die Sensoren abtasten und überprüfen, ob sich die Ausgabe der Achsen wie angegeben ändert.

Hier stoßen wir an die Grenzen unseres Sensorkonfigurationsdatenformats. Der LIS2DH12 könnte im 8-Bit-Modus bis zu 5 kHz erreichen, während unser Sensorabtastratenwert nur bis zu 200 Hz darstellen kann. Wieder einmal halten wir die Dinge einfach und begrenzen unseren Sensor auf 200 Hz Abtastung. Wenn jemand eine Vibrationsanalyse am RuuviTag durchführen und höhere Abtastraten benötigt, kann er den LIS2DH12-Treiber direkt anstelle dieser Schnittstelle verwenden.
Die Funktion der digitalen Signalverarbeitung (DSP) ist ebenfalls etwas knifflig, da das LIS2DH12-Datenblatt uns nicht wirklich sagt, was das Register für die Hochpass-Grenzfrequenz (HPCF) bewirkt. Der ST-Treiber enthält etwas mehr Informationen, da es eine Enumeration lis2dh12_hpcf_t gibt, die die Einstellungen mit einer Skala von LIGHT bis AGGRESSIVE benennt. Wir akzeptieren den DSP-Parameter von 0 bis 3 und definieren 0 als die am wenigsten aggressive und 3 als die aggressivste Einstellung. Es gibt auch eine Konfigurationsoption für die Verwendung eines Hochpasses für Interrupt-Funktionen, aber diese werden wir vorerst ignorieren.
Abfrage des LIS2DH12 im Programm
Nachdem der Treiber implementiert ist, testen wir ihn, indem wir die Beschleunigungswerte zusammen mit den Umgebungswerten bei einem Tastendruck ausgeben. Die Anpassung der Hauptfunktion ist einfach:

Wir haben die Initialisierung des Beschleunigungssensors in Zeile 49 hinzugefügt und die Tastenaufgabe in Zeile 53 auf task_button_on_press geändert. Unsere Tastenaufgabe ruft die Umgebungs- und Beschleunigungsaufgaben auf und lässt die rote LED blinken. Die Initialisierung des Beschleunigungssensors ähnelt der Initialisierung des Umweltsensors: Wir laden die Standardkonfiguration aus application_config.h und schreiben sie in den Sensor.

Die Datenleseaufgabe ähnelt ebenfalls der Umweltsensoraufgabe. Wir lesen die Daten vom Sensor und geben sie auf der Konsole aus.


Der Beschleunigungssensor zeigt insgesamt 1,068 G an (Quadratwurzel der Quadrate der X-, Y- und Z-Komponenten), was nahe genug an den erwarteten 1,000 G liegt. Die Umgebungswerte sind plausibel, die Temperatur ist etwas hoch, da das nRF52-DK unter meinem Ruuvi-Devkit den RuuviTag etwas aufheizt.
Überprüfen wir den Stromverbrauch:

Der Stromverbrauch beträgt jetzt 5,4 μA, gegenüber 3,4 μA im letzten Teil. Dies ist ein erwartetes Verhalten, da der LIS2DH12 bei 1 Hz und 10 Bit Auflösung eine Abtastung von 2 μA verbrauchen soll. Das Lesen der Probe selbst macht keinen großen Unterschied im Vergleich zum Warten, bis der BME280 den 16-fachen Oversampling-Prozess abgeschlossen hat, wie unten gezeigt. Die Abtastung kann mit der einfachen Umgebungsabtastung im vorherigen Beitrag verglichen werden.

Testen
Im Laufe der Blogserie wurden einige Dinge auf die lange Bank geschoben. Obwohl wir sowohl Vanilla-ARMGCC– als auch Segger Embedded Studio (SES)-Builds unterstützen, testet unser Jenkins derzeit nur, ob er das Programm mit ARMGCC kompilieren kann. Mindestens zwei Probleme sind bekannt:
- Unser Linker-Skript unterscheidet sich zwischen ARMGCC– und SES-Builds.
- Unser ARMGCC-Build unterstützt das Drucken von Floats und 64-Bit-Ganzzahlen nicht.
Obwohl SES das generierte Linker-Skript ausgibt, führt das Verknüpfen der .hex-Datei mit unserer ARMGCC-Version nicht zu einer lauffähigen Version der .hex-Datei. Vielleicht könnte dies durch ein Update unseres ARMGCC auf Version 7–2017-q4-major behoben werden, die dieselbe ist, die SES verwendet, aber wir bleiben bei der von Nordic Semiconductor getesteten Toolchain mit 6–2017-q2-update. Daher müssen wir akzeptieren, dass die Linker-Skripte unterschiedlich sein werden.
Wir müssen das ARMGCC-Makefile ein wenig ändern, um die Floats auszugeben, indem wir Folgendes hinzufügen:
LDFLAGS += -u _printf_floatweist den Linker an, die Float-Unterstützung zu unserem printf hinzuzufügen.
Nach dem Flashen des ARMGCC-kompilierten Hex können wir überprüfen, ob die LEDs in der Reihenfolge ROT–GRÜN blinken, unser Programm also gestartet ist und den Selbsttest als erfolgreich betrachtet. Die Real Time Transfer (RTT)-Protokolle deuten darauf hin, dass die Sensoren gelesen werden und plausible Werte zurückgeben.

Ein Problem ist offensichtlich: Unsere Druckfunktion gibt den 64-Bit-Zeitstempel nicht korrekt aus. Vorerst werden wir dieses Problem im Backlog belassen.
Fazit
Wir haben jetzt eine grundlegende Unterstützung für beide externen Sensoren an Bord des RuuviTag. Wir haben auch eine generische Schnittstelle zu den Sensoren, die es uns ermöglicht, Updates an den Sensoren an Bord vorzunehmen, ohne die Anwendung zu beeinträchtigen, die auf den Empfang der Daten angewiesen ist.
Die nächsten Teile der Serie werden die grundlegende Funktionalität der verbleibenden Peripheriegeräte hinzufügen, die für den aktuellen RuuviTag-Betrieb benötigt werden, wie z. B. Bluetooth Low Energy (BLE)-Broadcasting und Near-Field Communication (NFC)-Lesen. Sollte es der Zeitplan zulassen, werden wir auch automatische Tests für die Sensoren und andere Peripheriegeräte entwickeln.
Bleib dran und folge @ojousima und @ruuvicom auf Twitter für #FirmwareFriday-Beiträge!