Software

Installation

To install the software for this project you'll need to make sure your Raspberry Pi is running the latest Raspbian operating system, or your BeagleBone Black is running the latest Debian operating system.  Make sure your board is connected to the internet through a wireless or wired network connection too.

Connect to your board in a command line terminal and run the following commands to install the necessary dependencies:

sudo apt-get update
sudo apt-get install -y build-essential python-dev python-smbus python-pip git

Next run the following commands to download and install the latest version of the BNO055 Python module code from GitHub:

cd ~
git clone https://github.com/adafruit/Adafruit_Python_BNO055.git
cd Adafruit_Python_BNO055
sudo python setup.py install

If you see the installation fail with an error message go back and check the dependencies above were installed and try again.  Also make sure your board is connected to the internet as the installation will download and install some required Python modules.

Once the module is installed you're ready to start using it.  See the section below for details on running the examples and using the BNO055 module.

Usage

To learn how to use the BNO055 Python module I'll walk through running the included simpletest.py example below.  Before you get started make sure you've wired up the sensor and installed the library code following the steps above.  

Also note if you're using the sensor on a Raspberry Pi or other device in UART mode be sure you've followed the steps to disable the kernel from accessing the serial port at the same time as the BNO055 sensor!

Connect to the board in a command terminal and navigate to the library examples folder by running the following command:

cd ~/Adafruit_Python_BNO055/examples

Before you run the example you might need to change the code to intialize the BNO055 sensor depending on how it's connected to your board.  Open the file using the nano text editor by running:

nano simpletest.py

Then navigate down to this section of the example code:

# Create and configure the BNO sensor connection.  Make sure only ONE of the
# below 'bno = ...' lines is uncommented:
# Raspberry Pi configuration with serial UART and RST connected to GPIO 18:
bno = BNO055.BNO055(serial_port='/dev/ttyAMA0', rst=18)
# BeagleBone Black configuration with default I2C connection (SCL=P9_19, SDA=P9_20),
# and RST connected to pin P9_12:
#bno = BNO055.BNO055(rst='P9_12')

Like the comments mention you'll want to leave only one of the bno = ... lines uncommented depending on how it's connected to your board.  For a Raspberry Pi that's using the serial port and GPIO 18 as the reset pin leave this line uncommented:

bno = BNO055.BNO055(serial_port='/dev/ttyAMA0', rst=18)

If you're using a different serial port or GPIO for the reset line then adjust the serial_port and rst parameters of the initializer appropriately.

However for a BeagleBone Black that's using the hardware I2C bus and pin P9_12 as the reset pin leave only this line uncommented:

bno = BNO055.BNO055(rst='P9_12')

If you're using a different I2C bus you can specify it by adding a bus= parameter to the call, like bus=0 for using the /dev/i2c0 bus.  You can also change the reset pin to any free digital GPIO (just be careful that the chosen pin is available as a GPIO with the current device tree overlays--if in doubt stick with the default P9_12 pin).

For either the Raspberry Pi or BeagleBone Black If you're not using the reset line with the sensor you can remove the rst=... part of the initializer call.  In this mode a software reset command will be sent to reset the board instead of using the hardwired reset pin.

Once you've finished modifying the file save it and exit nano by pressing Ctrl-S, enter, and then Ctrl-X.

Now run the code as a root user with sudo by executing:

sudo python simpletest.py

If everything is working correctly you should see something like the following after a few seconds:

System status: 5
Self test result (0x0F is normal): 0x0F
Software version:   776
Bootloader version: 21
Accelerometer ID:   0xFB
Magnetometer ID:    0x32
Gyroscope ID:       0x0F

Reading BNO055 data, press Ctrl-C to quit...
Heading=0.00 Roll=0.00 Pitch=0.00	Sys_cal=0 Gyro_cal=0 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-0.69 Pitch=0.81	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-0.69 Pitch=0.81	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-0.69 Pitch=0.81	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-0.69 Pitch=0.81	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-0.69 Pitch=0.81	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0

If you see an error message carefully check that the BNO055 is connected to the hardware as shown on the previous page.  Make sure the software and its dependencies are installed as shown above too.

If you receive errors on a Raspberry Pi in UART mode make sure you've disabled the kernel's use of the serial port as mentioned above and on the previous page.  Also don't try to use the BNO055 in I2C mode with the Raspberry Pi as the Pi's I2C hardware has buggy behavior with I2C clock stretching that the BNO055 sensor uses.

If you receive errors on a BeagleBone Black in I2C mode make sure you don't have any device tree overlays loaded that might have changed the behavior of the I2C pins.  The stock BeagleBone Black device tree configuration should expose the I2C and GPIO pins that are used in this guide.

Once the example code is running you can see it start out by printing diagnostic details about the BNO055 sensor.  You can learn more about the sensor status and other values in its datasheet, but a status of 5 means the fusion algorithm is running and a self test result of 0x0F means all of the sensors are working as expected.

Every second the orientation data for the sensor is printed as Euler angles that represent the heading, roll, and pitch of the sensor in degrees.

In addition to orientation the calibration level of each sensor is printed each second.  Calibrating the BNO055 sensor is very important to ensure you get good orientation readings.  You can see the system (the fusion algorithm) and each sensor has a separate calibration level.  A level of 0 is uncalibrated and 3 is fully calibrated (with 1 and 2 being levels of partial calibration).  You'll learn more about how to calibrate the sensor on the next page.

To learn how to use the library I'll walk through the code for it in a little more detail.  Stop running the simpletest.py example (by pressing Ctrl-C) and then open the file in a text editor (like nano).  You can see the file starts by importing some required dependencies and the Adafruit_BNO055 module:

import logging
import sys
import time

from Adafruit_BNO055 import BNO055

Next the code creates and configures a BNO055 sensor instance.  You've already seen this part of the code described above when preparing to run the example.

After creating and configuring the BNO055 sensor the code optionally turns on Python's logging module output (if a -v parameter is passed when running the script--this is useful to see the raw commands sent and received with the BNO055 sensor), and then initializes the BNO055 sensor.

# Enable verbose debug logging if -v is passed as a parameter.
if len(sys.argv) == 2 and sys.argv[1].lower() == '-v':
    logging.basicConfig(level=logging.DEBUG)

# Initialize the BNO055 and stop if something went wrong.
if not bno.begin():
    raise RuntimeError('Failed to initialize BNO055! Is the sensor connected?')

It's very important to initialize the BNO055 sensor by calling the begin() function.  This function will return true if it succeeds in initializing the sensor and false if it fails for some reason.  The function might also throw an exception that provides more details about why the sensor failed to initialize.

Next you can see how status and diagnostic information is retrieved using the get_system_status() and get_revision() functions.

# Print system status and self test result.
status, self_test, error = bno.get_system_status()
print('System status: {0}'.format(status))
print('Self test result (0x0F is normal): 0x{0:02X}'.format(self_test))
# Print out an error if system status is in error mode.
if status == 0x01:
    print('System error: {0}'.format(error))
    print('See datasheet section 4.3.59 for the meaning.')

# Print BNO055 software revision and other diagnostic data.
sw, bl, accel, mag, gyro = bno.get_revision()
print('Software version:   {0}'.format(sw))
print('Bootloader version: {0}'.format(bl))
print('Accelerometer ID:   0x{0:02X}'.format(accel))
print('Magnetometer ID:    0x{0:02X}'.format(mag))
print('Gyroscope ID:       0x{0:02X}\n'.format(gyro))

Now the main loop of the program runs.  You can see the read_euler() function returns a tuple of heading, roll, and pitch data.  In addition the get_calibration_status() function is called to retrieve the calibration level for each part of the sensors.

print('Reading BNO055 data, press Ctrl-C to quit...')
while True:
    # Read the Euler angles for heading, roll, pitch (all in degrees).
    heading, roll, pitch = bno.read_euler()
    # Read the calibration status, 0=uncalibrated and 3=fully calibrated.
    sys, gyro, accel, mag = bno.get_calibration_status()
    # Print everything out.
    print('Heading={0:0.2F} Roll={1:0.2F} Pitch={2:0.2F}\tSys_cal={3} Gyro_cal={4} Accel_cal={5} Mag_cal={6}'.format(
          heading, roll, pitch, sys, gyro, accel, mag))

That's really all you need to use to initialize and get orientation from the BNO055 sensor!  However the code continues with commented examples of how to read other data from the sensor, including:

  • Orientation as a quaternion (a useful orientation representation that fixes some problems with Euler angles, see more information from Wikipedia).
  • Temperature of the sensor (in degrees Celsius).
  • Raw magnetometer reading for the X, Y, Z axis (in micro-Teslas).
  • Raw gyroscope reading for the X, Y, Z axis (in degrees per second).
  • Raw accelerometer reading for the X, Y, Z axis (in meters per second squared).
  • Linear acceleration reading for the X, Y, Z axis (in meters per second squared).  This is the acceleration from movement of the object, not from the downward pull of gravity.  
  • Gravity acceleration reading for the X, Y, Z axis (in meters per second squared).  This is just the force of gravity on the object.

In addition you can view a description of the BNO055 library functions using the pydoc tool:

pydoc Adafruit_BNO055.BNO055

If you run into problems with the library or would like to contribute then check out the library's home on GitHub for issues and sending pull requests.

Continue to the next page to learn how to run a more complex BNO055 example that rotates a 3D model on a webpage using the sensor.

Last updated on 2015-07-20 at 02.27.24 PM Published on 2015-07-20 at 02.28.06 PM