• BNO055 Nine Degree of Freedom IMU with built in Quaternion function

    Thanks to @trusktr for finding this chip at Adafruit.
    https://www.adafruit.com/product/2472

    https://learn.adafruit.com/adafruit-bno0­55-absolute-orientation-sensor/overview

    Connections

    I hooked the breakout board to a PICO with short wires and began to get results with code that follows.
    +3 to Vin, GND to GND, A8 to SCL, B4 to SDA
    I changed to a longer set of wires so I can move the breakout board around without the PICO USB connector coming loose, and the performance became intermittent. Looking at the schematic I tried
    Connecting the Vin and 3vo pins together on the breakout board and fixed the problem for use with the 3 Volts from the PICO. The Vin connected to a MIC6225-3.3 Voltage regulator input and the 3vo pin to the output.

    Almost a Module

    The attached code is almost a module. Some issues remain to be resolved but I am getting some interesting results. The output values are not scaled and are just the signed 16 bit integers.
    Most of the knobs for the chip are accessed using a data structure that defines the register, mask and shift for the particular bits (a document will follow as the module is completed)
    In NDOF mode (12) the output looks like this:

    A=,-232,-1,-1,M=,-1,-1,-1,G=,-1,-1,-1
    Heading=,5541,Roll,-247,Pitch,-111
    Q=,-16091,-699,-2305
    Lin=,-1925,27,-5
    Grav=,6,-1,-1
    Temperature= 74 F
    syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-24,3,25,Moffset=,-24,62,-297,G­offset=,0,-1,-2
    Aradius=,1000,Mradius=,867
     
    A=,-211,-1,-1,M=,-1,-1,-1,G=,-1,-1,-1
    Heading=,5510,Roll,-243,Pitch,-117
    Q=,-16057,-718,-2294
    Lin=,-2198,16,7
    Grav=,10,-1,-1
    Temperature= 74 F
    syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-24,3,25,Moffset=,-24,62,-297,G­offset=,0,-1,-2
    Aradius=,1000,Mradius=,867
    >clearInterval();
    

    In AMG mode the output looks like this

    A=,69,-930,-244,M=,-1,-1,-1,G=,-1,-1,-1
    Heading=,0,Roll,0,Pitch,0
    Q=,0,0,0
    Lin=,0,0,0
    Grav=,0,0,0
    Temperature= 72 F
    syscal= 0 Gyrcal= 0 Acccal= 0 Magcal= 0
    Aoffset=,-21,6,19,Moffset=,47,23,-1,Goff­set=,-1,-1,-1
    Aradius=,-1,Mradius=,-1
     
    A=,67,-932,-240,M=,-1,-1,-1,G=,-1,-1,-1
    Heading=,0,Roll,0,Pitch,0
    Q=,0,0,0
    Lin=,0,0,0
    Grav=,0,0,0
    Temperature= 72 F
    syscal= 0 Gyrcal= 0 Acccal= 0 Magcal= 0
    Aoffset=,-21,6,19,Moffset=,47,23,-1,Goff­set=,-1,-1,-1
    Aradius=,-1,Mradius=,-1
    >clearInterval();
    
    Issues that remain are:
    Using the external clock on the Adafruit board,
    Writing the offsets and radius to the chip and a way to save them on the PICO
    Sorting out the scale factors on the output as they change with the units settings and operating mode settings.
    Changing the code into a module.

    2 Attachments

  • Nice, thanks! That looks like a really nice bit of kit - it's great to have all the sensor fusion stuff built in!

  • It's early in the learning curve on this one but so far I like it a lot.

    In mode 12 NDOF, you just slowly move the chip into the six positions of the cube and watch for the calibration register numbers to all equal 3, then you are calibrated. A lot easier than prior chips.

    Units can be degrees or radians per second square, F or C temperature from two sources,
    m/s^2 or mg acceleration units and both gravity and linear acceleration outputs.

    When you mount the chip in your model airplane or other project, it has the ability to reassign the axis designations and signs (to keep the coordinate system either left or right handed).

    Try Amazon for a lower price.

  • BMO055 Module progress

    Place the attached BMO055.js in the modules directory of your WebIDE project.
    Run testBMO055.js.
    Try editing the unit selections or the operating mode to see what happens. I’ve tested modes 7 and 12.

    The test code follows
    //testBMO055.js 7 Jun 2017
    var W;
    // For accelerometer slowly position chip on 6 faces of a cube.
    // For magnetometer move chip in verical figure 8 pattern
    // For gyroscope leve chip in one position for a bit
    // When the calibration status numbers are all eqaul to three
    //calibration has been achieved
    function showCalibStatus(){
    console.log("syscal= "+W.Bitread(W.REGval.SYS_Calib_Status)+
    " Gyrcal= "+W.Bitread(W.REGval.GYR_Calib_Status)+
    " Acccal= "+W.Bitread(W.REGval.ACC_Calib_Status)+
    " Magcal= "+W.Bitread(W.REGval. MAG_Calib_Status));
    }//end showCalibStatus
    
    function showTemp(){
     console.log("Temperature= "+W.getTemperature()+" "+W.Tunitstr);
    }//end showTemp(
    
    function showAMG(){ 
    W.getAMG();
    console.log("A=,"+W.ACC[0]+","+W.ACC[1]+­","+W.ACC[2]+","+W.ACC_Unitstr);
    console.log("M=,"+W.Mag[0]+","+W.Mag[1]+­","+W.Mag[2]+","+W.Magunitstr);
    console.log("G=,"+W.Gyr[0]+","+W.Gyr[1]+­","+W.Gyr[2]+","+W.GYR_Unitstr);
    }//end showAMG
    
    function showIMU(){ //fusion modes
    W.getIMU();
    console.log("Heading=,"+W.Head[0]+",Roll­,"+W.Head[1]+",Pitch,"+W.Head[2]+W.Angle­str);
    console.log("Q=(,"+W.Quant[0]+","+W.Quan­t[1]+","+W.Quant[2]+","+W.Quant[3]+",)"+­W.Qstr);
    console.log("Lin=,"+W.Lin[0]+","+W.Lin[1­]+","+W.Lin[2]+","+W.ACC_Unitstr);
     console.log("Grav=,"+W.Grav[0]+","+W.Gra­v[1]+","+W.Grav[2]+","+W.ACC_Unitstr);
    
    }//end showIMU
    
    var Off;
    
    
    function showOffsets(){
     Off=W.readOffsets();
     console.log("Aoffset=,"+Off[0]+","+Off[1­]+","+Off[2]+
     ",Moffset=,"+Off[3]+","+Off[4]+","+Off[5­]+
     ",Goffset=,"+Off[6]+","+Off[7]+","+Off[8­]);
     console.log("Aradius=,"+Off[9]+",Mradius­=,"+Off[10]);
    }//end showOffsets
    
    function start(){
    // define the I2C connection
     I2C3.setup({ scl :A8, sda: B4} );
    // define the bus address of the BNO055 chip
     var BusAddress= 0x28;//If ADR pin at 3V 0x29
    //load the BNO055 module  
     W=require("BNO055").connect(I2C3,BusAddr­ess);
    // W=new BNO055(I2C3,BusAddress);
     W.run();//Get it started Needs work
    //W.RST_SYS(); //not working yet
    
    //display all knobs and indicators
     W.showBits(); 
    
    
    //W.External_Clk(); //not working yet
    
    //to configure the chip must be in Opmode 0
    W.Bitwrite(W.REGval.Operation_Mode,0);
    
    /* setupTemperature source 0= Accelerometer, 1= Gyro; unit 0=C, 1=F **/
    W.setupTemperature(1,1);//(source,unit)
    
    // choose units to display
    W.setEULunits(0);  //0 deg,1 rad
    W.setGYRunits(0);  //0 deg,1 rad
    W.setACCunits(0); // 0 m/s,1 mg
    
    //chip registers are paged
    //to direct read output need to be on page 0
     W.selectPage(0); 
    
    // choose am operating mode
    /*
    ##### Operation_Mode
    0=CONFIG MODE 
    1=ACCONLY
    2=MAGONLY
    3=GYROONLY
    4=ACCMAG
    5=ACCGYRO
    6=MAGGYRO
    7=AMG
    8=IMU
    9=COMPASS
    10=M4G
    11=NDOF_FMC_OFF
    12=NDOF
    */
    W.Bitwrite(W.REGval.Operation_Mode,12);
    
    //do a timed loop that acquires and displays data
    var i;
    setInterval(function () {
    console.log(" ");
    showAMG();
    showIMU();
    showTemp();
    showCalibStatus();
    showOffsets();
    
    }, 500);
    
    }//end start
    
    //function startPgm(){
    //Wait for program to load
    setTimeout(function () {
     start();
    }, 1000);
    //}//end startPgm
    
    The output follows

    Note the all three values in syscal, showing that the chip is calibrated.

    A=,-0.63,0.02,9.81,m/s^2
    M=,-0.0625,-0.0625,-0.0625,uT
    G=,-0.0625,-0.0625,-0.0625,deg/s
    Heading=,275.125,Roll,-7.5625,Pitch,0.56­25deg
    Q=(,6033.5,-395.5,373,5514.5,)E-14
    Lin=,0.64,-0.02,0.26,m/s^2
    Grav=,-1.29,-0.09,9.72,m/s^2
    Temperature= 74 F
    syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-29,15,18,Moffset=,-230,196,-11­56,Goffset=,-1,-1,0
    Aradius=,1000,Mradius=,372
     
    A=,-1.12,0.17,9.37,m/s^2
    M=,22.5625,7.75,-42.0625,uT
    G=,7.75,-14.3125,-0.0625,deg/s
    Heading=,304.75,Roll,-5.5625,Pitch,-2deg­
    Q=(,7249,-56,422,3792.5,)E-14
    Lin=,-0.01,-0.01,-0.01,m/s^2
    Grav=,-0.01,-0.01,-0.01,m/s^2
    Temperature= 76 F
    syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-29,15,18,Moffset=,-230,196,-11­56,Goffset=,-1,-1,0
    Aradius=,1000,Mradius=,372
     
    A=,-0.63,0.03,9.27,m/s^2
    M=,-0.0625,-0.0625,-0.0625,uT
    G=,-0.0625,-0.0625,-0.0625,deg/s
    Heading=,330.875,Roll,-2.0625,Pitch,0.5d­eg
    Q=(,-0.5,-0.5,-0.5,-0.5,)E-14
    Lin=,-0.01,-0.01,-0.01,m/s^2
    Grav=,-0.01,-0.01,-0.01,m/s^2
    Temperature= 76 F
    syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-29,15,18,Moffset=,-230,196,-11­56,Goffset=,-1,-1,0
    Aradius=,1000,Mradius=,372
     
    A=,-1.13,-0.07,9.47,m/s^2
    M=,0.25,16.0625,-13.25,uT
    G=,-0.0625,-0.0625,-0.0625,deg/s
    Heading=,5.1875,Roll,-2.1875,Pitch,-1.75­deg
    Q=(,8181,134.5,153,-372,)E-14
    Lin=,-0.26,-0.1,0.63,m/s^2
    Grav=,-0.01,-0.01,-0.01,m/s^2
    Temperature= 76 F
    syscal= 2 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-29,15,18,Moffset=,-230,196,-11­56,Goffset=,-1,-1,0
    Aradius=,1000,Mradius=,372
     
    A=,-0.61,0.79,9.54,m/s^2
    M=,-0.0625,-0.0625,-0.0625,uT
    G=,-0.0625,-0.0625,-0.0625,deg/s
    Heading=,30.8125,Roll,-3.125,Pitch,-1.5d­eg
    Q=(,7893,164,190.5,-2178,)E-14
    Lin=,-0.1,-0.48,1.04,m/s^2
    Grav=,-0.01,-0.01,-0.01,m/s^2
    Temperature= 76 F
    syscal= 2 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-29,15,18,Moffset=,-230,196,-11­56,Goffset=,-1,-1,0
    Aradius=,1000,Mradius=,372
     
    A=,-0.17,0.27,10.13,m/s^2
    M=,-11.5,12.5,-45.6875,uT
    G=,3.1875,-0.0625,-0.0625,deg/s
    Heading=,39.5625,Roll,-1.5625,Pitch,-0.7­5deg
    Q=(,7707.5,90.5,87,-2773,)E-14
    Lin=,0.06,0.23,-0.01,m/s^2
    Grav=,-0.26,0.13,9.8,m/s^2
    Temperature= 76 F
    syscal= 2 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-29,15,18,Moffset=,-230,196,-11­56,Goffset=,-1,-1,0
    Aradius=,1000,Mradius=,372
    >clearInterval();
    =undefined
    >
    
    Not finished yet
    1. External clock
    2. Reset
    3. POST and chip ID checks
    4. How to save and load calibration data
    5. Testing Interrupts
    6. Things and bugs I haven’t found yet

    Some links

    https://www.bosch-sensortec.com/bst/prod­ucts/all_products/bno055

    Quaternions
    https://github.com/kriswiner/LSM9DS1/com­mit/73a372a62c166a79fbdac46b8d3322430bf7­5428

    http://x-io.co.uk/res/doc/madgwick_inter­nal_report.pdf

    http://diydrones.com/profiles/blogs/seba­stian-oh-madgwicks-filter

    http://vigir.missouri.edu/~gdesouza/Rese­arch/Conference_CDs/RehabWeekZ%C3%BCrich­/icorr/papers/Madgwick_Estimation%20of%2­0IMU%20and%20MARG%20orientation%20using%­20a%20gradient%20descent%20algorithm_ICO­RR2011.pdf


    2 Attachments

  • Removed

  • Solved the reset and external clock problem
    Reset

    The reset requires a delay after the command is issued.
    This was solved by using a callback structure in the module

    exports.connect = function(i2c,BusAddress,callback) {
      var W= new BNO055(i2c,BusAddress);
      W.RST_SYS();
    setTimeout(function () {
       callback();
    }, 1000);
       return W;
    };
    

    Which changes the code in the test program.

    //load the BMO055 module  
     W=require("BNO055").connect(I2C3,BusAddr­ess,function(){
    ///lots of code here in the callback
    });//end require
    
    External Clock

    The call to change the clock souce also requires a delay which is addressed using a callback function
    In the module:

    BNO055.prototype.External_Clk=function(a­,callback){
     this.selectPage(0);
     if(a)
     this.WriteByte(this.Page0Regs.SYS_TRIGGE­R,0x80);
     else
     this.WriteByte(this.Page0Regs.SYS_TRIGGE­R,0x00);
    setTimeout(function () {
       callback();
    }, 50);
    };
    

    The code in the test program:

    //load the BMO055 module  
     W=require("BNO055").connect(I2C3,BusAddr­ess,function(){
    W.External_Clk(1,function(){ //1=external 0=internal clock
    //Lots of code
    //do a timed loop that acquires and displays data
    var i;
    setInterval(function () {
    console.log(" ");
    showAMG();
    showIMU();
    showTemp();
    showCalibStatus();
    showOffsets();
    
    }, 500);//display rate
    });//end set external clock 
     });//end require
    }//end start
    

    2 Attachments

  • BNO055 Module Improvements
    24Jun2017

    BNO055 Module Improvements 24Jun2017

    The BNO055.js module was used to implement an application as described here:
    Using an IMU to control an airplane image

    http://forum.espruino.com/conversations/­306319/

    It was discovered that the Pitch data values from the module were changing for a fixed position of the sensor. The BNO055.js module was updated to correct this problem, the reset function and external clock functions were also added.
    The attached program savCalBNO055.js is setup for a PICO connected to a BNO055 board. A normally open pushbutton connected from ground to pin B7 is used to save the calibration data to EEROM on the PICO. When all four of the calibration status indications equal 3, save the calibrations.
    Once a calibration has been saved, the program has to be restarted. The presence of calibration in the EEROM is detected and they are read, displayed and loaded into the BNO055 chip. Here is and example:

    sysstatus= 0
    syscal= 0 Gyrcal= 0 Acccal= 0 Magcal= 0
    sysstatus= 0
    Calibration is defined
    Aoffset=,-6,3,8,Moffset=,-14,90,-142,Gof­fset=,0,0,0,Aradius=,1000,Mradius=,816
    

    Here is a data example.

    sysstatus= 5
    A=,0.47,-9.54,-1.62,m/s^2
    M=,20.1875,-7,11.1875,uT
    G=,-0.25,-0.3125,0.375,deg/s
    Heading=,359.9375,Roll,2.6875,Pitch,99.7­5deg
    Q=(,5276.5,-6259,-47.5,2.5,)E-14
    Lin=,-0.01,0.1,-0.06,m/s^2
    Grav=,0.46,-1.97,-1.66,m/s^2
    Temperature= 64 F
    syscal= 0 Gyrcal= 3 Acccal= 3 Magcal= 3
    Aoffset=,-6,3,8,Moffset=,-14,90,-142,Gof­fset=,0,0,0,Aradius=,1000,Mradius=,816
    

    2 Attachments

  • Great, thanks! I'm surprised that the 'all in one' reading failed, as it's a pretty standard thing to do with I2C devices. Did you ever find out why?

  • The Vogon poet of the datasheet didn't provide any handshake information so I'm where the Dragons roam as to why this change worked. If planning a mission to Mars using this code, it would be prudent to ring up Bosch and ask. The other alternative is to look at their coding examples for a hint. It works on my table but will it work in other environments?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

BNO055 Nine Degree of Freedom IMU with built in Quaternion function

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions