Communicating with BNO055 on Raspberry Pi using i2c-gpio

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
RJohnW
 
Posts: 5
Joined: Tue Mar 21, 2017 3:37 pm

Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by RJohnW »

I'm using the BNO055 sensor module, and for well-documented reasons involving an I2C clock stretching bug on Raspberry Pi's SOC, I cannot use the hardware I2C bus to talk to the sensor. The default alternative for Raspberry Pi is to use the serial port, which is also not good for my purposes because I would like to use that for debugging. Instead I would like to use a GPIO (bit-banged) I2C interface, enabled using the i2c-gpio device driver in Linux. I've wired the BNO055 I2C signals to the default gpios per this link:

http://raspberrypi.stackexchange.com/qu ... spberry-pi

I now have a device at /dev/i2c-3, so the above steps work. I can also identify the BNO055 on the i2c-3 bus:

Code: Select all

pi@robotpi:~/projects/Adafruit_Python_BNO055 $ i2cdetect 3
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-3.
I will probe address range 0x03-0x77.
Continue? [Y/n] Y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --  
My next step was to see if the sensor is alive using the Python library provided by Adafruit here:

https://github.com/adafruit/Adafruit_Python_BNO055

I downloaded and installed that library. Using the simpletest.py app, I ran into the following expected problem:

pi@robotpi:~/projects/Adafruit_Python_BNO055/examples $ python simpletest.py
Traceback (most recent call last):
File "simpletest.py", line 46, in <module>
if not bno.begin():
File "build/bdist.linux-armv7l/egg/Adafruit_BNO055/BNO055.py", line 383, in begin
File "build/bdist.linux-armv7l/egg/Adafruit_BNO055/BNO055.py", line 359, in _config_mode
File "build/bdist.linux-armv7l/egg/Adafruit_BNO055/BNO055.py", line 417, in set_mode
File "build/bdist.linux-armv7l/egg/Adafruit_BNO055/BNO055.py", line 312, in _write_byte
File "build/bdist.linux-armv7l/egg/Adafruit_BNO055/BNO055.py", line 259, in _serial_send
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 484, in write
raise writeTimeoutError
serial.serialutil.SerialTimeoutException: Write timeout

Obviously this is expected because I knew I needed to tell it not to use the default for Raspberry PI (serial bus), and I knew that I needed to tell itwhat I2C bus to use. So, I attempted to do this in simpletest.py:

Code: Select all

# 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)
bno = BNO055.BNO055(i2c=3, rst=18)
This gave me the error:

Code: Select all

pi@robotpi:~/projects/Adafruit_Python_BNO055/examples $ python simpletest.py 
Traceback (most recent call last):
  File "simpletest.py", line 35, in <module>
    bno = BNO055.BNO055(i2c=3, rst=18)
  File "build/bdist.linux-armv7l/egg/Adafruit_BNO055/BNO055.py", line 246, in __init__
AttributeError: 'int' object has no attribute 'get_i2c_device'
OK, so now I know that I need to figure out how to modify the code to allow it to use the correct bus. The problem I'm running into is, I believe, in the BNO055 module here:

Code: Select all

        if serial_port is not None:
            # Use serial communication if serial_port name is provided.
            # Open the serial port at 115200 baud, 8N1.  Add a 5 second timeout
            # to prevent hanging if device is disconnected.
            self._serial = serial.Serial(serial_port, 115200, timeout=serial_timeout_sec,
                                         writeTimeout=serial_timeout_sec)
        else:
            # Use I2C if no serial port is provided.
            # Assume we're using platform's default I2C bus if none is specified.
            if i2c is None:
                import Adafruit_GPIO.I2C as I2C
                i2c = I2C
                
            # Save a reference to the I2C device instance for later communication.
            self._i2c_device = i2c.get_i2c_device(address, **kwargs)
So, i2c is expected to be "None" and not anything else. This enables the default device driver for the platform to be used, but not an alternative bus (or override).

I've modified the device to use i2c as a bus number and pass that to the initialization function for the BNO055. This allows the bus to be overridden.

https://github.com/johnweber/Adafruit_P ... 2c70e7f56f

After doing this, the SOC on the Raspberry Pi can now communicate with the BNO055 using the i2c-gpio device driver. However, this is my first experience with this code and I'm not sure if the below output is completely good.

Code: Select all

pi@robotpi:~/projects/Adafruit_Python_BNO055/examples $ python simpletest.py 
System status: 5
Self test result (0x0F is normal): 0x0D
Software version:   785
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=-1.56 Pitch=0.25	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-1.56 Pitch=0.25	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-1.56 Pitch=0.25	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Heading=0.00 Roll=-1.56 Pitch=0.25	Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
Hope this helps someone else that might want to do this same thing.
Last edited by RJohnW on Tue Mar 28, 2017 2:03 pm, edited 2 times in total.

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: Communicating with BNO055 sensor on Raspberry Pi using i

Post by gammaburst »

Great you got that working. Do you get good speed, such as 100 readings per second?

Your output data looks ok. Don't be surprised if the Euler angles seem erratic or wrong when you steeply tilt the sensor - it's a BNO Euler math bug. I use its quaternion instead.

I too created a bit-banged I2C for BNO055 and RPi. It has an animated OpenGL display:
viewtopic.php?f=8&t=110999&p=555352#p555352

User avatar
RJohnW
 
Posts: 5
Joined: Tue Mar 21, 2017 3:37 pm

Re: Communicating with BNO055 sensor on Raspberry Pi using i

Post by RJohnW »

I haven't tested it yet to see how well the i2c-gpio works. For now, I'm just pleased that it does work. I'll let you know how it goes. I'll definitely use the quaternion instead of the Euler angles - so thanks for the heads-up there.

User avatar
RJohnW
 
Posts: 5
Joined: Tue Mar 21, 2017 3:37 pm

Re: Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by RJohnW »

Update - I haven't tried this at 100 Hz but it works very well at 10 Hz. I also converted the Python code to C++.

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by adafruit_support_mike »

Nice work! Thanks for posting your progress so far!

User avatar
alisonrosenzweig
 
Posts: 2
Joined: Thu Mar 15, 2018 2:59 pm

Re: Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by alisonrosenzweig »

I'm trying to follow along but not super experienced. Any chance you could explain a little bit more how to connect the BNO055 to the RasPi / how the wiring differs from the startup guide (https://cdn-learn.adafruit.com/download ... -black.pdf) (or link to instructions for how to elsewhere)?

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by adafruit_support_mike »

If you’re not experienced in that kind of programming, I’d suggest using a Serial connection between the RasPi and the BNO055.

The BNO055 uses an I2C signal technique called ‘pulse stretching’: if it needs time to calculate a value, it holds the SCL line low until it’s ready to respond. That delay on the SCL line should tell the bus master to stop and wait.

Pulse stretching is an official part of the I2C standard, but the RasPi’s microprocessors don’t support it well. There’s some low-level hacking you can do to keep pulse stretching from crashing completely, but it takes experience tinkering with the guts of Linux to make that work.

The alternative is to use a Serial connection between the BNO055 and the RasPi. Most RasPis can do Serial communication through their GPIO pins, and the ones that don’t (the Pi3 and Zero-W) can be reconfigured. All RasPis can do Serial communication through a USB-to-Serial converter like the CP2104 though:

https://www.adafruit.com/product/3309

That’s the easiest way to make the BNO055 talk to a RasPi.

User avatar
alisonrosenzweig
 
Posts: 2
Joined: Thu Mar 15, 2018 2:59 pm

Re: Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by alisonrosenzweig »

Thanks for your reply!

I have it set up that way right now, but am using the sensor on mobile robots so was hoping to use Bluetooth to get the data to the computer sending out commands to the robots. (My understanding is that you have to disable Bluetooth on the RasPi when using the serial port in this way - though definitely let me know if I'm mistaken about that). I'll investigate using web sockets to solve this in case Bluetooth isn't a viable option.

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Communicating with BNO055 on Raspberry Pi using i2c-gpio

Post by adafruit_support_mike »

Yeah, to use the BLE module you have to give it the good UART.

You can also connect to the BNO055 through a USB-to-Serial converter like the CP2104:

https://www.adafruit.com/product/3309

That's our preferred way to make any kind of Serial connection to a RasPi honestly.. no board-dependent funkiness.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”