A simple single-file program to test the BNO055 breakout board from Adafruit. There are two BNO055 libraries on MBED, as well as Arduino source code on the Adafruit website, but none of it worked for me, so I wrote this simple example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**
00002  * A simple single-file program to test the BNO055 breakout board from Adafruit.
00003  * There are two BNO055 libraries on MBED, as well as Arduino source code on the Adafruit website,
00004  * but none of it worked for me, so I wrote this simple example.
00005  *
00006  * Some notes:
00007  * 1.) You will probably need to reset your microcontroller a few times. The BNO055 is correctly initialized when
00008  *      the ID is read correctly and the temperature is not zero (i.e. initBNO055() should return true).
00009  * 2.) The BNO055 breakout board uses an external crystal. If you are not using an external crystal, delete the
00010  *      I2C write message that sets the chip to using external crystal.
00011  */
00012 
00013 #include "mbed.h"
00014 
00015 Serial pc(USBTX,USBRX);
00016 I2C i2c(D7, D6);
00017 
00018 const int bno055_addr = 0x28 << 1;
00019 
00020 const int BNO055_ID_ADDR                                          = 0x00;
00021 const int BNO055_EULER_H_LSB_ADDR                                 = 0x1A;
00022 const int BNO055_TEMP_ADDR                                        = 0x34;
00023 const int BNO055_OPR_MODE_ADDR                                    = 0x3D;
00024 const int BNO055_CALIB_STAT_ADDR                                  = 0x35;
00025 const int BNO055_SYS_STAT_ADDR                                    = 0x39;
00026 const int BNO055_SYS_ERR_ADDR                                     = 0x3A;
00027 const int BNO055_AXIS_MAP_CONFIG_ADDR                             = 0x41;
00028 const int BNO055_SYS_TRIGGER_ADDR                                 = 0x3F;
00029 
00030 typedef struct CalibStatus_t
00031 {
00032     int mag;
00033     int acc;
00034     int gyr;
00035     int sys;
00036 } CalibStatus;
00037 
00038 typedef struct Euler_t
00039 {
00040     float heading;
00041     float pitch;
00042     float roll;
00043 } Euler;
00044 
00045 
00046 /**
00047  * Function to write to a single 8-bit register
00048  */
00049 void writeReg(int regAddr, char value)
00050 {
00051     char wbuf[2];
00052     wbuf[0] = regAddr;
00053     wbuf[1] = value;
00054     i2c.write(bno055_addr, wbuf, 2, false);  
00055 }
00056 
00057 /**
00058  * Function to read from a single 8-bit register
00059  */
00060 char readReg(int regAddr)
00061 {
00062     char rwbuf = regAddr;
00063     i2c.write(bno055_addr, &rwbuf, 1, false);
00064     i2c.read(bno055_addr, &rwbuf, 1, false);
00065     return rwbuf;
00066 }
00067 
00068 /**
00069  * Returns the calibration status of each component
00070  */
00071 CalibStatus readCalibrationStatus()
00072 {
00073     CalibStatus status;
00074     int regVal = readReg(BNO055_CALIB_STAT_ADDR);
00075         
00076     status.mag = regVal & 0x03;
00077     status.acc = (regVal >> 2) & 0x03;
00078     status.gyr = (regVal >> 4) & 0x03;
00079     status.sys = (regVal >> 6) & 0x03;
00080     
00081     return status;
00082 }
00083 
00084 
00085 /**
00086  * Checks that there are no errors on the accelerometer
00087  */
00088 bool bno055Healthy()
00089 {
00090     int sys_error = readReg(BNO055_SYS_ERR_ADDR);
00091     wait(0.001);
00092     int sys_stat = readReg(BNO055_SYS_STAT_ADDR);
00093     wait(0.001);
00094     
00095     if(sys_error == 0 && sys_stat == 5)
00096         return true;
00097     else
00098         return false;
00099 }
00100     
00101 
00102 /**
00103  * Configure and initialize the BNO055
00104  */
00105 bool initBNO055()
00106 {
00107     unsigned char regVal;
00108     i2c.frequency(400000);
00109     bool startupPass = true;
00110     
00111     // Do some basic power-up tests
00112     regVal = readReg(BNO055_ID_ADDR);
00113     if(regVal == 0xA0)
00114         pc.printf("BNO055 successfully detected!\r\n");
00115     else {
00116         pc.printf("ERROR: no BNO055 detected\r\n");
00117         startupPass = false;
00118     }
00119         
00120     regVal = readReg(BNO055_TEMP_ADDR);
00121     pc.printf("Chip temperature is: %d C\r\n", regVal);
00122     
00123     if(regVal == 0)
00124         startupPass = false;
00125  
00126     // Change mode to CONFIG
00127     writeReg(BNO055_OPR_MODE_ADDR, 0x00);
00128     wait(0.2);
00129     
00130     regVal = readReg(BNO055_OPR_MODE_ADDR);
00131     pc.printf("Change to mode: %d\r\n", regVal);
00132     wait(0.1);
00133     
00134     // Remap axes
00135     writeReg(BNO055_AXIS_MAP_CONFIG_ADDR, 0x06);    // b00_00_01_10
00136     wait(0.1);    
00137 
00138     // Set to external crystal
00139     writeReg(BNO055_SYS_TRIGGER_ADDR, 0x80);
00140     wait(0.2);    
00141 
00142     // Change mode to NDOF
00143     writeReg(BNO055_OPR_MODE_ADDR, 0x0C);
00144     wait(0.2);
00145  
00146     regVal = readReg(BNO055_OPR_MODE_ADDR);
00147     pc.printf("Change to mode: %d\r\n", regVal);
00148     wait(0.1);
00149     
00150     return startupPass;
00151 }
00152 
00153 /**
00154  * Reads the Euler angles, zeroed out
00155  */
00156 Euler getEulerAngles()
00157 {
00158     char buf[16];
00159     Euler e;
00160     
00161     // Read in the Euler angles
00162     buf[0] = BNO055_EULER_H_LSB_ADDR;
00163     i2c.write(bno055_addr, buf, 1, false);
00164     i2c.read(bno055_addr, buf, 6, false);
00165     
00166     short int euler_head = buf[0] + (buf[1] << 8);
00167     short int euler_roll = buf[2] + (buf[3] << 8);
00168     short int euler_pitch = buf[4] + (buf[5] << 8);
00169     
00170     e.heading = ((float)euler_head) / 16.0;
00171     e.roll = ((float)euler_roll) / 16.0;
00172     e.pitch = ((float)euler_pitch) / 16.0;
00173     
00174     return e;
00175 }
00176 
00177 int main() {
00178 
00179     bool startupPassed;
00180     Euler e;
00181 
00182     // Initialize
00183     pc.baud(115200);
00184     wait(0.5);
00185     startupPassed = initBNO055();   // Note: set LED to RED if this fails
00186  
00187     // Read orientation values
00188     while(true)
00189     {
00190         // Make sure that there are no errors
00191         if(!bno055Healthy())
00192             pc.printf("ERROR: BNO055 has an error/status problem!!!\r\n");
00193         
00194         // Read in the Euler angles
00195         e = getEulerAngles();
00196  
00197         wait(0.001);
00198  
00199         // Read in the calibration status
00200         CalibStatus calStat = readCalibrationStatus();
00201         
00202         printf("Heading: %7.2f \tRoll: %7.2f \tPitch: %7.2f \tMAG: %d ACC: %d GYR: %d SYS: %d\r\n", e.heading, e.roll, e.pitch,
00203             calStat.mag, calStat.acc, calStat.gyr, calStat.sys);
00204         
00205         wait(0.05);
00206     }
00207 }