Absolute orientation sensors have applications in augmented reality, navigation, gaming, personal fitness, biomechanics and context awareness. The Bosch BNO055 is a 9-axis absolute orientation sensor. The BNO055 fuses data from an accelerometer, gyroscope and magnetometer to determine absolute orientation. Adafruit have created a breakout board for the BNO055, facilitating use of the sensor in open hardware projects. Moreover, Adafruit have developed a driver for reading sensor data from their BNO055 breakout board.
For the 2018-2019 Biomaker Winter Challenge I developed a XOD library for the Adafruit BNO055 breakout. My XOD library wraps the Adafruit Unified BNO055 Driver, following the guidelines provided in the XOD documentation. In this project report I will describe how my XOD library can be used.
BNO055 absolute orientation sensor
The arduino communicates with the BNO055 via I²C (Inter-Integrated Circuit). For the full pinout of the BNO055 breakout see the Adafruit documentation. In the examples described in this project we will use only four pins:
- Vin: 5V power supply input
- GND: common/ground pin for power and logic
- SCL: I²C clock pin
- SDA: I²C data pin
Make the following connections between the BNO055 breakout board and the Arduino Uno:
- Connect Vin on the BNO055 breakout to the 5V power supply of the Arduino Uno.
- Connect GND to GND (common ground).
- Connect the SCL pin to A5 (I²C clock pin) on the Arduino Uno.
- Connect the SDA pin to A4 (I²C data pin) on the Arduino Uno.
In XOD IDE, hit “File → Add Library” and enter the full library name:
See Using libraries for more information.
Following installation in the IDE workspace, the library will be visible in the project browser. To find out the function of a node, select the node and hit
H to invoke help:
The library provides many nodes to expose most of the functionality in the underlying C++ libraries. However, many casual users of the library will probably find that they only need to use one node: abs-orient-sensor.
The library contains several example patches to demonstrate the functionality of the nodes. Let's take a look at some of these example patches.
Before using a BNO055 absolute orientation sensor in a project we may wish to check that it is working correctly. Open the example-test-sensor patch in the XOD IDE:
Inputs to abs-orient-sensor:
- ID (number) – User defined unique ID for this device.
- ADDRESS (byte) – I²C address of the bno055. Default is 28h. If ADR pin of Adafruit breakout board is set high (connected to 3V), then the I²C address becomes 29h.
- WAIT (number) – Time (seconds) to wait between completing one reading and initiating another.
Outputs from abs-orient-sensor:
- X (number) – Orientation in X-axis (heading/yaw) in degrees. 0° to 360° (turning clockwise increases values).
- Y (number) – Orientation in Y-axis (roll) in degrees. -90° to +90° (increasing with increasing inclination).
- Z (number) – Orientation in Z-axis (pitch) in degrees. +180° to -180° (turning clockwise decreases values).
- SYS (byte) – System calibration on a scale of 0-3. 0 = uncalibrated; 3= fully calibrated.
- ACC (byte) – Accelerometer calibration on a scale of 0-3. 0 = uncalibrated; 3= fully calibrated.
- GYRO (byte) – Gyroscope calibration on a scale of 0-3. 0 = uncalibrated; 3= fully calibrated.
- MAG (byte) – Magnetometer calibration on a scale of 0-3. 0 = uncalibrated; 3= fully calibrated.
- OK (pulse) – Pulses after each read of sensor.
- ERR (pulse) – Pulses on error.
Notice that in the example-test-sensor patch we are using count nodes to record the number pulses from the OK and ERR outputs. To upload the patch to the Arduino Uno, hit "Deploy → Upload to Arduino...". The following dialog will appear:
Tick "Debug after upload" checkbox before hitting "Upload". The patch will start to run in debug mode:
In the above example the abs-orient-sensor is reporting the following euler angles:
- X (heading/yaw): 279°
- Y (roll): -68°
- Z (pitch): 134°
System, gyroscope and magnetometer are fully calibrated (03h), but the accelerometer is uncalibrated (00h). A total of 765 readings have been made and zero errors have been recorded.
A note on calibration
Embedded software constantly calibrates the accelerometer, gyroscope and magnetometer of the BNO055. However, Bosch have not documented the calibration algorithms. Once powered on, the BNO055 will start outputting sensor data. Factory set offsets mean that valid data may be output before the calibration process is complete. However, if the system calibration status (SYS) is 00h, data should be ignored. A system calibration status of 00h indicates that the device hasn't found magnetic north, and so orientation data will be inaccurate.
According to Adafruit, calibration of the BNO055 requires the following conditions to be met:
Gyroscope: The device must be standing still in any position
Magnetometer: In the past 'figure 8' motions were required in 3 dimensions, but with recent devices fast magnetic compensation takes place with sufficient normal movement of the device
Accelerometer: The BNO055 must be placed in 6 standing positions for +X, -X, +Y, -Y, +Z and -Z. This is the most onerous sensor to calibrate, but the best solution to generate the calibration data is to find a block of wood or similar object, and place the sensor on each of the 6 'faces' of the block, which will help to maintain sensor alignment during the calibration process. You should still be able to get reasonable quality data from the BNO055, however, even if the accelerometer isn't entirely or perfectly calibrated.
Open the example-text-lcd-16x2-i2c patch in the XOD IDE. This patch outputs orientation in euler angles and system calibration status to an LCD screen with two rows, each containing 16 characters.
The top row of the LCD screen is used for the "headings", i.e.:
X Y Z C
where X, Y and Z are the euler angles and C is the system calibration status.
The bottom row of the LCD screen is used to display the value of each of these measurements. Output from the abs-orient-sensor node requires formatting before it can be displayed on the LCD screen. The pad-with-zeroes nodes are used to make the X, Y and Z values fixed width. The less and if-else nodes are used to determine if the Y and Z values are negative, and to prefix these values with a minus sign if needed.
The nine inputs to the concat node are:
- X coordinate padded to three digits [1:3]*
- blank space to separate X and Y coordinates *
- if Y coordinate is negative a minus sign, otherwise a blank space *
- Y coordinate padded to two digits [6-7]*
- blank space to separate Y and Z coordinates *
- if Z coordinate is negative a minus sign, otherwise a blank space *
- Z coordinate padded to three digits [10-12]*
- three blank spaces to separate Z coordinate and system calibration status [13-15]*
- system calibration status *
*numbers in square brackets correspond to characters in bottom row of LCD screen.
The LCD screen we are using communicates with the Arduino Uno via I²C. The terminals of the LCD screen (see photo below) are wired to the Arduino Uno as follows:
- LCD GND – Arduino Uno GND
- LCD VCC – Arduino Uno 5V
- LCD SCL – Arduino Uno A5
- LCD SDA – Arduino Uno A4
The I²C address of the LCD screen used in this project is 38h. if you are using an LCD display with a different I²C address you will need to change the value of ADDR on the text-lcd-16x2-i2c node before uploading the patch to the Arduino Uno. The expected output should be similar to this:
The patch example-4d-ulcd demonstrates how output from the abs-orient-sensor node can be sent to a 4D systems gen4-uLCD-32DT display using Max Danilin's 4d-ulcd library. Below is a screenshot of the patch, but it is better to view the patch in the XOD IDE. The patch is annotated with comments, so no further description will be given here.
This patch is designed to be used with a user interface defined in the following file:
Use 4D Systems' Workshop4 IDE to compile and upload this user interface to the gen4-uLCD-32DT device. If you are unfamiliar with 4D Systems' displays, please refer to this guide.
Some users may prefer to work with quaternions rather than euler angles. The library includes abs-orient-sensor-quaternion which describes orientation in quaternions. The patch example-test-sensor-quaternion demonstrates the use of the node abs-orient-sensor-quaternion. It should be uploaded to the Arduino Uno in debug mode so that the output can be monitored on watch nodes.
The library provides nodes for reading the raw data from the accelerometer, gyroscope, magnetometer and thermometer in the BNO055. Patch example-read-raw-data monitors all raw data being collected by the device. It should be run in debug mode.
Chip revision data
XOD nodes have been developed for several inertial measurement units such as accelerometers and gyroscopes (https://xod.io/docs/reference/supported-hardware/). However, my library appears to be the first to provide support for an absolute orientation sensor in XOD. An absolute orientation sensor is a potentially useful tool for open hardware projects in both the environmental and biomedical sciences.