1. BMI160 uitgelezen via I²C
De BMI160 is een sensor gebouwd door het Duitse Bosch Sensortec. In de behuizing van de sensor zitten eigenlijk 2 discrete sensoren verborgen: een Accelerometer en een Gyroscoop. Beide zijn “MEMS” devices. Vaak worden er “Bibliotheken” of “Libraries” ter beschikking gesteld door de fabrikant, 3rd party verkopers of enthousiastelingen, om het gebruik van externe hardware te vereenvoudigen. Ook wij gaan gebruik maken van dergelijke bibliotheken om de implementatie van sensoren te vereenvoudigen. is een sensor gebouwd door het Duitse Bosch Sensortec. In de behuizing van de sensor zitten eigenlijk 2 discrete sensoren verborgen: een Accelerometer en een Gyroscoop. Beide zijn “MEMS” devices. Vaak worden er “Bibliotheken” of “Libraries” ter beschikking gesteld door de fabrikant, 3rd party verkopers of enthousiastelingen, om het gebruik van externe hardware te vereenvoudigen. Ook wij gaan gebruik maken van dergelijke bibliotheken om de implementatie van sensoren te vereenvoudigen.
Voordat we het aansluiten van de sensor overlopen, even een woordje over I²C :
- I²C (Inter-Integrated Circuit) is een zogenaamde 2-wire interface: een 2-draads bus
- Desondanks zijn minimaal 3 draden nodig: een datalijn (SDA), een clocklijn (CLK) en de ground (GND), waardoor alle apparaten dezelfde spanningsreferentie delen.
- De draden zijn “bidirectioneel”, dus de communicatie is “Half-Duplex”, zoals een Walkie-Talkie.
- Er horen pull-up weerstanden te zitten tussen de 3.3V en zowel de SDA als de CLK lijn. (Vaak voor-gemonteerd op het breakout board), 4k7 tot 10 kOhm zijn een veelgebruikte waarden voor relatief trage communicatie.
- Er kunnen maximum 127 apparaten op de bus zitten (7-bit adresseren), maar elk apparaat moet een uniek adres hebben!
- Datalijnen zijn van het open-drain type.
Vaak zie je in oudere schema’s en datasheet nog de termen Master en Slave om aan te geven wie de communicatie initieert. Maar deze termen zijn voor alle recente devices en datasheets aangepast. Nu worden de termen Controller en Target (of Peripheral) gebruikt!

Wiring diagram met open-drain illustratie.

Bus-principe van I²C gedemonstreerd

Timing diagram van I²C communicatie.
Eigenschappen van de BMI160
- Voedingsspanning: 1.7–3.6 V (Breakout bord: 3.2V-6V)
- Stroomverbruik: Gyro + Acc: 950 µA, Slaapmodus: 3 µA
- 16-bit Data Output
- Versnellingsbereik: ±2g -> 16g
- Gyroscoopbereik: ±125°/s -> ±2000°/s
- Versnellings Zero-g Offset: ±40mg
- Gyroscoop Zero-g Offset: ±10°/s
- Interface: I²C of SPI
- Programmeerbare meetsnelheid: 25/32Hz ->1600Hz

Block diagram of data flow
Pin beschijvingen
Aansluiten
Het aansluiten van I²C sensoren is erg eenvoudig:
- Sluit de GND van de ESP aan op de GND van de sensor
- Sluit de SDA van de ESP aan op de SDA van de sensor (kijk op de LAB 2: INFO pagina via welke pinnen je kan communiceren over I²C: Wire_SDA)
- Sluit de SCL van de ESP (Wire_SCL) aan op de SCL van de sensor
- Sluit de GND van de ESP aan op de SA0-pin van de sensor (Addres: 0x68)
- Sluit tenslotte de 3.3V van de ESP aan op de VIN van de sensor.
Tip: De benodigde pull-up weerstanden (1KΩ - “103”) voor I²C zijn al voorgeïnstalleerd op het breakout board, dus die hoef je niet extern aan te sluiten.
Experimenteren met de BMI160
Code demonstratie:
Om de BMI160 uit te lezen kan je de registers rechtstreeks aanspreken, dit zie je in het linker-voorbeeld hieronder. De code aan de rechterzijde heeft dezelfde functionlateit, maar de leesbaarheid is veel hoger en bijgevolg kunnen fouten veel sneller opgespoord worden! Dit toont duidelijk het aan dat het gebruik van bibliotheken je leven als programmateur drastisch kunnen vereenvoudigen, en je toelaten om je te focussen op het implementeren van de functionaliteit.
Indien er geen lib beschikbaar is, dan ben je verplicht om deze zelf te schrijven (of een andere sensor te kiezen). De gegevens die je nodig zou hebben om zelf een lib te maken of de sensor rechtstreeks aan te spreken kan je terugvinden in de datasheet.
vb: Add 0x12 wordt gebruikt om de Acc data te lezen, de beschrijving hiervan kan je terugvinden onderaan pagina 52 van de datasheet.

In de bovenstaande code worden de registers rechtstreeks aangesproken. Dit geeft je meer inzicht in de werking van de sensor.

Dit programma heeft exact dezelfde functionaliteit, maar is veel leesbaarder door het gebruik van de BMI160 bibliotheek.
Bibliotheek installeren
We stellen voor om het ons niet te moeilijk te maken, en gebruik te maken van een goede bibliotheek: “DFROBOT_BMI160”. Deze is geschreven door een bedrijf DFRobot, ze maken development boards, net zoals hetgene wat je nu gaat gebruiken.
Voorbeeldcode
Copy-paste de code hieronder zelf, en kijk of je Accelometer data ontvangt. Je kan de functionaliteit eenvoudig testen, aangezien de sensor ook altijd de gravitatiekracht van aarde zal meten!
// Deze code gebruikt de DFRobot_BMI160-bibliotheek om versnelling te lezen.
#include <DFRobot_BMI160.h>
DFRobot_BMI160 bmi160;
const int8_t i2c_addr = 0x68; // default I2C address for BMI160, AD0-pin at GND
void setup(){
Serial.begin(115200);
if (bmi160.I2cInit(i2c_addr) != BMI160_OK){ //set and init the bmi160 i2c address
Serial.println("Cannot intialize BMI160 sensor, check the wiring!");
while(1);
}
Serial.println("Intialization of the BMI160 sensor OK!");
}
void loop(){
int16_t bmiData[6]; // 0-2: Gyro, 3-5: Accel
if(bmi160.getAccelGyroData(bmiData) == 0){
int16_t ax = bmiData[3];
int16_t ay = bmiData[4];
int16_t az = bmiData[5];
Serial.printf("X:%d,Y:%d,Z:%d\n",ax, ay,az);
}
delay(100);
}
Nieuw in deze code?
Naast de functie “bmi160.getAccelGyroData(bmiData)”, die de acceleratie data opslaat in variabele “bmiData”. Dit is een Array met 6 beschikbare plekken, gedefinieerd met “int16_t bmiData[6]”. Arduino bibliotheken worden in C++ geschreven, en daar wordt de volgende structuur gebruikt voor functie-aanroepen: “object.methode(parameter)”. Wanneer we dit betrekken op onze sensor:
- “bmi160”: het object (instance) van de “DFRobot_BMI160” klasse
- “getAccelGyroData”: is een methode van data object
- “bmiData”: de parameter die wordt meegegeven aan de methode (en waar in dit geval de data in opgeslagen wordt) In het vorige Labo hebben jullie zelf al een functie aangemaakt, deze lijkt in gebruik sterk op een methode, maar het belangrijkste verschil is dat een methode gebonden is aan een specifiek object of klasse, terwijl dit niet het geval is voor een functie.vb: “delay()” is een functie, terwijl “Serial.print()” een methode is!
Wanneer alles naar behoren werkt, pas dan de bovenstaande voorbeeldcode zo aan, zodat je naast de Acceleratiedata ook de Gyroscoopdata kan tonen in de Serial Plotter.
Roep de docent, demonstreer de functionaliteit van de schakeling. Vul de ANS vragen al in tijdens het wachten!
ANS vraag 1a, 1b, 1c, 1d