Propeller Activity Board + SimpleIDE + Adafruit BNO055

My computer programming class is in a little robot maze competition using the Activity bot. We purchased an Adafruit BNO055 IMU fusion sensor. It appears that the Activity Board supports I2C communication so we figured there should be some tutorials out there on how to use this sensor. However through much searching we have come up empty. Adafruit has tutorials for Adruino, raspberry PI, but as we are new to programming we have not been able to convert them to our needs. I was wondering if it is possible to use this sensor, and if someone could help us get started or point us to a usable resource.

Comments

  • DavidZemonDavidZemon Posts: 2,780
    edited 2016-02-18 - 20:23:25
    I would encourage you to start with the Arduino code for the BNO055 and then port it to the Propeller. You have a few different options for I2C communication to replace the Arduino's Wire class and that should be the only part that needs conversion I think.

    So, how do you get started with I2C? You probably want to start here (http://learn.parallax.com/propeller-c-simple-protocols/diy-i2c), on Parallax's own website. Once you're comfortable with the general concept of serial communication and I2C's addressing scheme, take a look at your three different C/C++ options:

    1) i2c_*() functions in the "Simple" libraries. These C functions come with SimpleIDE and were written by Parallax. I believe they are documented in various places. I host doxygen documentation here for these functions (note that I am not a Parallax employee or affiliated in any way with Parallax).

    2) Use PropWare's I2C class. This is my favorite, because I wrote it. It is documented here and you can read these instructions for getting PropWare up and running in SimpleIDE. Take a look at this example usage of using it to read from and write to the board's EEPROM chip.

    3) Use libpropeller's I2C class. I actually started PropWare's I2C classes by copying and pasting these. Documented here. One big difference is that you can use libpropeller::I2C in SimpleIDE simply by copying i2c.h and i2cbase.h into your project. PropWare's classes require a few more dependencies than that which is why I recommend following the linked instructions if you go that route.

    Alright! That should keep you busy for a bit right? :D
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: https://ci.zemon.name?guest=1
  • Someone here has used this sensor: http://forums.parallax.com/discussion/163121/adafruit-9-dof-breakout-for-quads

    I suspect that code is in Spin, but it shouldn't be terribly difficult to port it over, using the i2c_ resources David mentioned above.
  • TryingToTeach,
    As a starting point for the BNO055 module I can recommend rjo's BNO055roughdraft2 program in the link provided by Jason above.
    In this program I2C is easily handled by an existing object.
    Once you can see the output of the BNO055 registers and become confident with the module it is quite easy to move on to your own application.
    I suggest you build a simple demonstration gimbal for the module - your students could have a lot of fun, and there is a lot of educational potential!
  • After working through all your suggestions I am still at a loss. Can someone point me in the correct direction from the code below.



    #include "simpletools.h"
    #include "simplei2c.h"

    #define BNO055_ADDRESS_B (0x29)
    #define BNO055_CHIP_ID_ADDR 0x00

    int main() // Main function
    {
    int8_t temp;
    char data[] = {0,0,0,0,0,0,0,0};
    pause(1000);
    print("Begin test:\n");
    i2c *bus = i2c_newbus(1, 0, 0); // New I2C bus SCL=P1, SDA=P0

    print("%c", HOME);
    while(1) // Repeat indefinitely
    {
    print("%c", HOME);
    print("reading:\n");
    i2c_out(bus, 0x29 , BNO055_CHIP_ID_ADDR, 1, data, 8);
    while(i2c_busy(bus,0x29));
    print("while done:\n");
    i2c_in(bus, 0x29 , BNO055_CHIP_ID_ADDR, 1, data, 8);
    print("data=%d\n", data[0], CLREOL);
    pause(1000);
    }

    }
  • DavidZemon wrote: »
    2) Use PropWare's I2C class. This is my favorite, because I wrote it. It is documented here and you can read these instructions for getting PropWare up and running in SimpleIDE. Take a look at this example usage of using it to read from and write to the board's EEPROM chip.

    Do you have an example not using the EEPROM chip?

    Also can you help me with how to change the scl and sda from default.
  • DavidZemonDavidZemon Posts: 2,780
    edited 2016-03-09 - 22:12:00
    DavidZemon wrote: »
    2) Use PropWare's I2C class. This is my favorite, because I wrote it. It is documented here and you can read these instructions for getting PropWare up and running in SimpleIDE. Take a look at this example usage of using it to read from and write to the board's EEPROM chip.

    Do you have an example not using the EEPROM chip?

    Also can you help me with how to change the scl and sda from default.

    The PCF8591 object in PropWare uses I2C communication. You can find its source here.

    The constructor for PropWare::I2C takes three parameters, but all of them have default values which is why my examples do not use any parameters. If you wanted to use pins 0 and 1 on the Propeller as SCL and SDA respectively, you could construct an instance like so:
    int main () {
        const PropWare::I2C pwI2C(PropWare::Pin::P0, PropWare::P1);
        pwOut << "EEPROM ack = " << pwI2C.ping(SHIFTED_DEVICE_ADDR) << '\n';
        return 0;
    }
    

    or to make it more legible, and easier to tell which pins are used for what
    const PropWare::Pin::Mask SCL = PropWare::Pin::P0;
    const PropWare::Pin::Mask SDA = PropWare::Pin::P1;
    
    int main () {
        const PropWare::I2C pwI2C(SCL, SDA);
        pwOut << "EEPROM ack = " << pwI2C.ping(SHIFTED_DEVICE_ADDR) << '\n';
        return 0;
    }
    
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: https://ci.zemon.name?guest=1
  • I tried running the following code. I continue to get BNO055 ack = false. Do you see any errors in the code?

    Thanks for your help so far.


    #include <PropWare/i2c.h>
    #include <PropWare/printer/printer.h>
    #include <simpletools.h>
    
    const uint8_t  SHIFTED_DEVICE_ADDR = 0x29;
    
    
    int main () {
        high(26);
        pwOut << "Start" << '\n';
        const PropWare::I2C pwI2C(PropWare::Pin::P0, PropWare::Pin::P1);
        pwOut << "BNO055 ack = " << pwI2C.ping(SHIFTED_DEVICE_ADDR) << '\n';
        high(27);
        pause(100);
        return 0;
    }
    
  • From the datasheet, I can see that 0x29 is the 7-bit address. The PropWare::I2C constructor requires the shifted, 8-bit address. Try this one small change in your code, in line 5:
    #include <PropWare/i2c.h>
    #include <PropWare/printer/printer.h>
    #include <simpletools.h>
    
    const uint8_t  SHIFTED_DEVICE_ADDR = 0x29 << 1;
    
    
    int main () {
        high(26);
        pwOut << "Start" << '\n';
        const PropWare::I2C pwI2C(PropWare::Pin::P0, PropWare::Pin::P1);
        pwOut << "BNO055 ack = " << pwI2C.ping(SHIFTED_DEVICE_ADDR) << '\n';
        high(27);
        pause(100);
        return 0;
    }
    
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: https://ci.zemon.name?guest=1
  • Unfortunately that edit did not solve all the issues. The output is still BNO055 ack = FALSE. I found someone who had an arduino board hooked it up and it worked wonderfully. So my sensor is not the issue.

    Any Other ideas?

    Thanks for the help.
  • TryingToTeach - I sent you a PM describing how I can help
  • Unfortunately that edit did not solve all the issues. The output is still BNO055 ack = FALSE. I found someone who had an arduino board hooked it up and it worked wonderfully. So my sensor is not the issue.

    Any Other ideas?

    Thanks for the help.

    That's tough now, since I don't have my own BNO055 to test with. Is it possible that you have P0 and P1 mixed up? It's certainly an easy thing to try.

    Aside from that, I don't think I can be any more help without at least one of the following:

    1) A picture of your circuit, with wires and their connection points all clearly visible
    2) Output from a logic analyzer or oscilloscope showing the I2C communication.
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: https://ci.zemon.name?guest=1
  • Thanks for all the help. However, for right now I am going to quit the project. The deadline was fast approaching so I just bought an arduino board. Now everything is up an running. I don't like being a quitter, but the time cost equation made it an easy choice.

    Thanks again.
  • Sorry to hear that, but I certainly understand. When the deadline approaches, you just get it done. Let us know if we can help again in the future.
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
    CI Server: https://ci.zemon.name?guest=1
  • I'm interested in how you use the BNO055 in a maze. I made an LED paintbrush with one.

    Use the test code that shows the status registers. You need all 3's for reliable Z axis or it will drift. If you don't move it far you can use previous calibration values in the code to save time and awkward flipping around of your robot. Also try not to bump into anything, I found that will cause some Z drift.
  • The main thing we are going to use it for is to help make 90 degree turns. We found that encoder values on the wheels are not accurate enough, and the maze is all right angles and fairly small. We are currently using adafruits example and using orientation.x to check the rotation and then correct. We then use a front and side ultrasonic sensor and a left wall following algorithm to solve the maze. Our main goal is to improve on our strategy from last year which included ramming the wall to straighten the robot and then back up and straighten until the too large of robot for the maze could turn appropriately. (reminder: low budget high school students programming to learn, not for prizes: otherwise our robot should look like this)
Sign In or Register to comment.