Due to high demand expect some shipping delays at this time, orders may not ship for 1-2 business days.
0

Adafruit Bosch BNO055 - Calibration Status and read/write Se
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Adafruit Bosch BNO055 - Calibration Status and read/write Se

by DrDooom on Wed Nov 22, 2017 6:50 am

hello adafruit team,

I bought an Adafruit Bosch BNO055 sensor quite some time ago. The sensor is the center of my project and further sensors / devices are used depending on which NDOF orientation is obtained from the BNO055.

therefore, the sensor must work as optimally as possible. not extremely accurate, but valid data must be present during the entire runtime.

so I tested something with the chip. everything works as desired. Except for one requirement: restoring / writing calibration offsets ignores the magnetometer offsets. As also described in the FAQ.

Thus, even though the calibration has been restored, the sensor must be calibrated each time it is turned on (for the magnetometer) to obtain valid orientation data.

The problem is that my project does not work without orientation data. And the sensor should be firmly attached to the frame. After the last calibration, the EMF of the frame is not changed anymore. Thus, in my opinion, it would be no problem to write the magnetometer data.

I have already posted the problem in the Arduino forum. https://forum.arduino.cc/index.php?topic=511074.0

I would be very thankful for help. Regards DrDooom.

DrDooom
 
Posts: 12
Joined: Wed Nov 22, 2017 6:30 am

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by PaulRowntree on Wed Nov 22, 2017 9:12 am

I had a a similar need with a fether M0 project, and the BNO055 just turned into more trouble than it was worth. Moved to the NXP 9dof IMU, and it work right away. You have to do the math, but all the code is on line. You do the corrections, so you can apply whatever parameter set you want. Plus, you can run the NXP at more readings/updates per second than the BNO, so the hardship of doing the math yourself isn't a real problem.

Plus the NXP is cheaper. Plus the NXP doesn't do auto-calibrations at random times like the BNO. Plus the NXP calibration doesn't fail when moving above 10 kph.

PaulRowntree
 
Posts: 391
Joined: Sun Apr 03, 2016 12:41 am

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by gammaburst on Wed Nov 22, 2017 10:01 pm

When I power-up my BNO055 project, in any orientation, it reads my previously-stored calibration profile and immediately begins outputting good quaternions relative to NED north-east-down, without having to perform any further calibration steps.

The BNO is finicky about its boot-up sequence, and Bosch's documentation isn't clear. Here's my BNO055 startup procedure:
viewtopic.php?f=25&t=108290&p=541754#p541754

I use the BNO in a stationary application, not a moving vehicle. I prefer its results over simpler fusion algorithms such as Mahony. Lay the BNO flat on a table, shake it strongly from side-to-side, and its pitch/roll remains steady. Mahony wobbles, a little. But yeah, the BNO's auto-calibration is a pain.

gammaburst
 
Posts: 638
Joined: Thu Dec 31, 2015 12:06 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by DrDooom on Thu Nov 23, 2017 1:50 pm

Good evening everyone,

Thank you for the two answers.

@ Paul: Thanks for the info on the NXP IMU. The problem is that we have already developed a waterproof housing for the IMU and the microcontroller already has to take on many tasks. I was very convinced of the BNO055, because it (after calibration) can simply provide the data. I would, if possible, like to stay with the BNO055. Keep the NXP IMU in mind.

@ Gammaburst: Thank you! Very interesting that you did not have the problems. I looked at your starting configuration. You use RST (I have not yet), and apparently access directly to the registers?!? I only use the standard functions of the current Adafruit library. I am not familiar with the writing of registers. :-(

I think that I do not necessarily need RST but makes the correct start safer?
Could it be that Adafruit in her function .setSensorOffsets (...) simply does not write the data for magnetometers into the corresponding register?

By the way: I do not need such a high frequency of 10 ms. I would be satisfied with 20-30 ms.

DrDooom
 
Posts: 12
Joined: Wed Nov 22, 2017 6:30 am

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by DrDooom on Sat Nov 25, 2017 7:10 am

Well, i have checked the library. It seems that the library writes the calibration data correctly. at least the code looks good.

I found the following addresses for the writing. Can someone tell me if the addresses are right?

Code: Select all | TOGGLE FULL SIZE
      /* Magnetometer Offset registers */
      MAG_OFFSET_X_LSB_ADDR                                   = 0X5B,
      MAG_OFFSET_X_MSB_ADDR                                   = 0X5C,
      MAG_OFFSET_Y_LSB_ADDR                                   = 0X5D,
      MAG_OFFSET_Y_MSB_ADDR                                   = 0X5E,
      MAG_OFFSET_Z_LSB_ADDR                                   = 0X5F,
      MAG_OFFSET_Z_MSB_ADDR                                   = 0X60,


By the way. I read the Bosch BNO055 Docu. This are the addresses according to Bosch:
Code: Select all | TOGGLE FULL SIZE
MAG_OFFSET_X_LSB     0x5B
MAG_OFFSET_X_MSB    0x56C
MAG_OFFSET_Y_LSB     0x5D
MAG_OFFSET_Y_MSB    0x5E
MAG_OFFSET_Z_LSB     0x5F
MAG_OFFSET_Z_MSB    0x60

Does MAG_OFFSET_X_MSB 0x56C match MAG_OFFSET_X_MSB_ADDR = 0X5C?


In the Docu there is one thing i dont understand:
Code: Select all | TOGGLE FULL SIZE
3.11.4 Reuse of Calibration Profile

Once  the  device  is  calibrated,  the  calibration  profile  can  be  reused  to  get  the  correct orientation  data  immediately  after  ‘Power  of  Reset’ (prior  togoing  through  the  steps mentioned  in  the  above  section).

......

## Setting Calibration profile ###
It  is  important  that  the  correct  offsets  and  corresponding  sensor  radius  are  used.
Incorrect offsets  may  result  in  unreliable  orientation  data  even  at  calibration  accuracy  level  3.  To  set the calibration profile the following steps need to be taken
1. Select the operation mode to CONFIG_MODE
2. Write the corresponding sensor offsets and radius data
3. Change operation mode to fusion mode


The last thing to do is 3. Change operation mode to fusion mode. Is the normal NDOF Mode meant? I think so.

But...there is no Note about unwritten Magnetometer Calib Data!!! So the behavior cant be desired by Bosch.



Does anyone have an idea how I can fix the problem? :-( Should I also change my startup configuration?

DrDooom
 
Posts: 12
Joined: Wed Nov 22, 2017 6:30 am

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by jps2000 on Sat Nov 25, 2017 9:11 am

Hi
0x56C is a typo in the specification and should read 0x5C; Note that you have to restore also MAG radius LSB and MSB ( Register 0x69 and 0x6A) !!!
Reading and writing cal registers only work in the config mode
With fusion mode NDOF is meant ( but can be also any other)

I also found that to change an operation mode you need always to go first to config mode.
so switching directly from NDOF to IMUPLUS for example is not working
so NDOF --> CONFIG --> IMUPLUS works.

jps2000
 
Posts: 690
Joined: Fri Jun 02, 2017 4:12 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by gammaburst on Tue Nov 28, 2017 5:46 am

Here's my BNO055 startup code, including loading my calibration profile. Your profile will be different.

You don't have my custom I/O functions, but you can probably use similar Adafruit or Arduino functions. My code runs on a MicroBlaze processor inside an FPGA.

Code: Select all | TOGGLE FULL SIZE
void bno055_startup(void)
{
  // My calibration profile: created by performing a successful NDOF calibration, then copying registers 0x55 to 0x6A into this array
  unsigned char mycal[22] = {0x0E,0x00,0x23,0x00,0xCD,0xFF, 0xE6,0x00,0x10,0x00,0xF6,0xFF, 0x00,0x00,0x00,0x00,0xFD,0xFF, 0xE8,0x03, 0x4E,0x02};

  HI_RST();                             // send reset pulse
  delay(1e-6);
  LO_RST();
  delay(800e-3);                        // ???? data sheet says reset-to-config-mode takes 650ms typical, but what's max time? I measure 560ms,

  // optional axis remap (my BNO is mounted vertically
  imu_write(AXIS_MAP_CONFIG, 0x18);     // xx,01,10,00   Y, Z, X
  imu_write(AXIS_MAP_SIGN, 0x04);       // xxxxx,1,0,0  -X,+Z,+Y  (beware opposite order)

  for (int n=0; n<22; n++)              // apply calibration profile *after* setting map registers
    imu_write(0x55+n, mycal[n]);        // write calibration coefficients

  imu_write(OPR_MODE, 0x0C);            // enable NDOF mode
  delay(10e-3);                         // ???? data sheet says switching mode takes 7ms, but is that typical or max?

  // startup complete! begin reading data registers every 10 milliseconds...
}

gammaburst
 
Posts: 638
Joined: Thu Dec 31, 2015 12:06 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by DrDooom on Tue Nov 28, 2017 5:58 am

Thank u JPS,

i am writing all calib data, inc. magnetometer radius, back to the BNO055 via the Adafruit library.

I have read the functions of the library. The functions take care of the correct mode. So the mode will automatically changed to config if registers will be changed.

So i dont know whats wrong. I have written an email to the Bosch Support Team. But since I am a private person I have no great hope that someone will take care of the problem. :o(

Unfortunately, nobody seems to have the problem. Did you work with the Bosch BNO055 and wrote back the calib offsets? eg with the Adafruit library?

--------------
Hallo Gammaburst,
great. I will adjust the startup config. although I think that the biggest difference has to do with the reset.

Maybe I will also write a separate function to write the register and in the function of each register check. To ensure that the data on the BNO055 is correct.

Thank u both.

DrDooom
 
Posts: 12
Joined: Wed Nov 22, 2017 6:30 am

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by jps2000 on Tue Nov 28, 2017 7:34 am

You should always check before storing cal data that sys calib status is 3 .
See 4.3.54 CALIB_STAT 0x35.
This is what I found:
GYR : 0 and 3 only
MAG 0,1,2,3 (every axis)
ACC 0,1,3?
SYS 0,1,2,3 (Always 0 in IMU, 0 bis 3 in NDOF and NDOF_FMC_OFF

Note that the device must not be started in a different magnetic environment than during calibration.
Inside a concrete building with a lot of iron or close to a computer/ speaker etc the compass may be heavily disorientated.

Do you store the cal data in the EEPROM?
In the 328P the programmer unfortunately clears the data @ every upload. This has to do with fuse setting.

Mail to Bosch support team seems rather hopeless.

Yes, I used the adafruit library. But I stopped working with the BNO055 and switched to the BNO080 which is doing much much better.

I keep my BNO055 stock and wait that Hillcrest publishes a firmware to reprogram the BNO055 chips.

jps2000
 
Posts: 690
Joined: Fri Jun 02, 2017 4:12 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by DrDooom on Sun Dec 03, 2017 6:34 pm

OK sorry. I have shown the technical information only in the other linked thread (my opening post). I will post here again the whole code and also the console output.

I currently use an Arduino MKR Zero without EEPROM (only for development) and therefore save the calibration data on an SD card. However, I have checked the calibration data several times. everything is OK. The console output (further down) also shows which calibration data is stored and which is read. The values are fine! But after restoring the values the Adafruit BNO055 simply discards the magnetometer data.

The code:
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>

#include <SPI.h>
#include "SdFat.h"


/*
 ############################################################
 MKR Zero: Select Pin für die SD Bibliothek: SDCARD_SS_PIN
 SD    Bibliothek (File Class)              File Reading: "while(file.available()){ file.read(); }":        70.55kb / Sek (File = 381909 byte) -> int. SD Card Reader
 SD    Bibliothek (File Class)              File Reading: "while(...){ file.read(byteBuffer, 1000); }":    153.28kb / Sek (File = 381909 byte) -> int. SD Card Reader
 SD    Bibliothek (SdFile+Sd2Card+SdVolume) File Reading: "while(...){ file.read(byteBuffer, 1000); }":    183.50kb / Sek (File = 381909 byte) -> int. SD Card Reader
 SDfat Bibliothek (File Class)              File Reading: "while(file.available()){ file.read(); }":        86.78kb / Sek (File = 381909 byte) -> ext. SD Card Reader
 SDfat Bibliothek (File Class)              File Reading: "while(...){ file.read(byteBuffer, 1000); }":    214.34kb / Sek (File = 381909 byte) -> ext. SD Card Reader
 SDfat Bibliothek (SdFile Class)            File Reading: "while(file.available()){ file.read(); }":        90.21kb / Sek (File = 381909 byte) -> ext. SD Card Reader
 SDfat Bibliothek (SdFile Class)            File Reading: "while(...){ file.read(byteBuffer, 1000); }":    214.11kb / Sek (File = 381909 byte) -> ext. SD Card Reader
 ############################################################
*/
const long SERIAL_BAUD  = 9600;//Serial
const int PIN_INTLED_OUT = LED_BUILTIN;
const int PIN_INT_SD_CS = SDCARD_SS_PIN;

bool   pinIntLedIsHigh = false;
long   pinIntLedNextTime = 0;

String serialBuffer = "";
char   serialTerminatorChar = '\n';

SdFat sd;
String  sensorFileName = "sensor.dat";

Adafruit_BNO055 bno = Adafruit_BNO055(55);
bool bnoTestActive = false;
long bnoTestNextTime = 0;

void MultiByteLeToInt32(uint8_t   byte1, uint8_t  byte2, uint8_t   byte3, uint8_t byte4, uint32_t &number){ number = 0; number += (uint32_t)byte1 << 24; number += (uint32_t)byte2 << 16; number += (uint32_t)byte3 << 8; number += (uint32_t)byte4; }
void MultiByteLeToInt16(uint8_t   byte1, uint8_t  byte2, uint16_t &number){ number = 0; number += (uint16_t)byte1 <<  8; number += (uint16_t)byte2; }
void Int16ToMultiByteLe(uint16_t number, uint8_t &byte1, uint8_t  &byte2) { byte1 = (uint8_t)(number >> 8); byte2 = (uint8_t)number; }


void SerialPrintBnoSensorData(sensors_event_t event){
  Serial.print("X: "); Serial.print(event.orientation.x, 4);
  Serial.print("\tY: "); Serial.print(event.orientation.y, 4);
  Serial.print("\tZ: "); Serial.print(event.orientation.z, 4);
}
void SerialPrintBnoSensorCalibration(uint8_t calSystem, uint8_t calGyro, uint8_t calAccel, uint8_t calMag, bool isFullyCalibrated){
  Serial.print("Calibration: " + (String)calSystem + " system, " + (String)calGyro + " gyro, " + (String)calAccel + " accel, " + (String)calMag + " mag" + "\t" + (String)(isFullyCalibrated?"Is fully calibrated!!!":"Is not fully calibrated"));
}
void SerialPrintLnBnoSensorOffsets(adafruit_bno055_offsets_t &sensorOffset){
  Serial.println("Accel: " + (String)sensorOffset.accel_offset_x + " " + (String)sensorOffset.accel_offset_y + " " + (String)sensorOffset.accel_offset_z + " ");
  Serial.println("Gyro:  " + (String)sensorOffset.gyro_offset_x  + " " + (String)sensorOffset.gyro_offset_y  + " " + (String)sensorOffset.gyro_offset_z  + " ");
  Serial.println("Mag:   " + (String)sensorOffset.mag_offset_x   + " " + (String)sensorOffset.mag_offset_y   + " " + (String)sensorOffset.mag_offset_z   + " ");
  Serial.println("Accel Radius: " + (String)sensorOffset.accel_radius);
  Serial.println("Mag   Radius: " + (String)sensorOffset.mag_radius);
}
void SerialPrintLnBnoSensorData(sensors_event_t event){ SerialPrintBnoSensorData(event); Serial.println(""); }
void SerialPrintLnBnoSensorCalibration(uint8_t calSystem, uint8_t calGyro, uint8_t calAccel, uint8_t calMag, bool isFullyCalibrated){ SerialPrintBnoSensorCalibration(calSystem, calGyro, calAccel, calMag, isFullyCalibrated); Serial.println(""); }

void setup() {//################################### SETUP ###################################
  Serial.begin(SERIAL_BAUD);
  delay(500);
  while (!Serial);//Warten bis eine Serielle Verbindung kommt!
  Serial.println("### Setup ###");
  Serial.println(" - Serial");
  Serial.println("   Buffer: " + (String)Serial.availableForWrite() + " bytes");
  Serial.println(" - Pin Modes");
  pinMode(PIN_INTLED_OUT, OUTPUT);
 
  Serial.println(" - Set Pins High/Low");
  digitalWrite(PIN_INTLED_OUT, HIGH);
 
  Serial.println(" - Init SD Card");
  while(!sd.begin(PIN_INT_SD_CS)){ Serial.println("   failed"); delay(1000); } Serial.println("   done");//SDfat

  Serial.println(" - Init BNO055");
  if(!bno.begin()){ Serial.println("   failed - check wiring or I2C ADDR!");  } else {
    delay(500);
    Serial.println("   - ExtCrystalUse false");
    bno.setExtCrystalUse(false);
    Serial.println("   - Mode          OPERATION_MODE_NDOF");
    bno.setMode(bno.OPERATION_MODE_NDOF);
    sensor_t sensor;
    bno.getSensor(&sensor);
    Serial.println("   > Sensor:       " + (String)sensor.name);
    Serial.println("   > Driver Ver:   " + (String)sensor.version);
    Serial.println("   > Unique ID:    " + (String)sensor.sensor_id);
    //Serial.println("   > Max Value:    " + (String)sensor.max_value);
    //Serial.println("   > Min Value:    " + (String)sensor.min_value);
    //Serial.println("   > Resolution:   " + (String)sensor.resolution);
    Serial.println("   done");
  }
  Serial.println("### Setup finished ###");
 
}

void loop() {//################################### LOOP ###################################
  //### Internal LED ###
  if(millis()>=pinIntLedNextTime){
    pinIntLedNextTime = millis() + (!pinIntLedIsHigh?150:850);
    pinIntLedIsHigh = !pinIntLedIsHigh;
    digitalWrite(PIN_INTLED_OUT, pinIntLedIsHigh?HIGH:LOW);
  }
  //### BNO Test ###
  if(millis()>=bnoTestNextTime){
    bnoTestNextTime = millis() + 500;
    if(bnoTestActive){
      sensors_event_t event;
      bno.getEvent(&event);
      SerialPrintBnoSensorData(event);
      Serial.print("\t");
      uint8_t calSystem, calGyro, calAccel, calMag;
      calSystem = calGyro = calAccel = calMag = 0;
      bno.getCalibration(&calSystem, &calGyro, &calAccel, &calMag);
      SerialPrintLnBnoSensorCalibration(calSystem, calGyro, calAccel, calMag, bno.isFullyCalibrated());
    }
  }
  if(Serial.available()){
    char oneChar = Serial.read();
    if(oneChar != serialTerminatorChar){
      serialBuffer += oneChar;
    } else {
      if(serialBuffer=="hallo" || serialBuffer=="hello"){
        Serial.println("[" + serialBuffer + "] -> Arduino MKR Zero here!");
      } else if(serialBuffer=="bno test"){
        bnoTestActive = !bnoTestActive;
      } else if(serialBuffer=="bno debug"){
        Serial.println("[" + serialBuffer + "] ###################################################");
        Serial.println("### Current Data ###");
        sensors_event_t event;
        bno.getEvent(&event);
        SerialPrintLnBnoSensorData(event);
        Serial.println("### Current Calibration ###");
        uint8_t calSystem, calGyro, calAccel, calMag;
        calSystem = calGyro = calAccel = calMag = 0;
        bno.getCalibration(&calSystem, &calGyro, &calAccel, &calMag);
        SerialPrintLnBnoSensorCalibration(calSystem, calGyro, calAccel, calMag, bno.isFullyCalibrated());
        Serial.println("### Current Sensor Offset's ###");
        adafruit_bno055_offsets_t sensorOffsets;
        bno.getSensorOffsets(sensorOffsets);
        SerialPrintLnBnoSensorOffsets(sensorOffsets);
      } else if(serialBuffer=="bno save"){
        Serial.println("[" + serialBuffer + "] ###################################################");
        Serial.println("Saving offsets...");
        if(bno.isFullyCalibrated()){
          File file = sd.open(sensorFileName, O_CREAT | O_WRITE | O_TRUNC);
          if(file){
            adafruit_bno055_offsets_t sensorOffsets;
            bno.getSensorOffsets(sensorOffsets);
            file.write((uint8_t)(sensorOffsets.accel_offset_x >> 8)); file.write((uint8_t)sensorOffsets.accel_offset_x);
            file.write((uint8_t)(sensorOffsets.accel_offset_y >> 8)); file.write((uint8_t)sensorOffsets.accel_offset_y);
            file.write((uint8_t)(sensorOffsets.accel_offset_z >> 8)); file.write((uint8_t)sensorOffsets.accel_offset_z);
            file.write((uint8_t)(sensorOffsets.gyro_offset_x  >> 8)); file.write((uint8_t)sensorOffsets.gyro_offset_x);
            file.write((uint8_t)(sensorOffsets.gyro_offset_y  >> 8)); file.write((uint8_t)sensorOffsets.gyro_offset_y);
            file.write((uint8_t)(sensorOffsets.gyro_offset_z  >> 8)); file.write((uint8_t)sensorOffsets.gyro_offset_z);
            file.write((uint8_t)(sensorOffsets.mag_offset_x   >> 8)); file.write((uint8_t)sensorOffsets.mag_offset_x);
            file.write((uint8_t)(sensorOffsets.mag_offset_y   >> 8)); file.write((uint8_t)sensorOffsets.mag_offset_y);
            file.write((uint8_t)(sensorOffsets.mag_offset_z   >> 8)); file.write((uint8_t)sensorOffsets.mag_offset_z);
            file.write((uint8_t)(sensorOffsets.accel_radius   >> 8)); file.write((uint8_t)sensorOffsets.accel_radius);
            file.write((uint8_t)(sensorOffsets.mag_radius     >> 8)); file.write((uint8_t)sensorOffsets.mag_radius);
            file.close();
            Serial.println("Offsets written to CONFIG:");
            SerialPrintLnBnoSensorOffsets(sensorOffsets);
          } else {
            Serial.println("Could not create file " + sensorFileName);
          }
        }else {
          Serial.println("ERROR: skipped because the sensor is not fully calibrated!!!");
        }
      } else if(serialBuffer=="bno load"){
        Serial.println("[" + serialBuffer + "] ###################################################");
        Serial.println("Loading offsets...");
        File file = sd.open(sensorFileName, O_READ);
        if(file){
          Serial.println("openend with " + (String)file.size() + " bytes");
          adafruit_bno055_offsets_t sensorOffsets;
          int i = 0;
          while(file.available()){
            byte fileByte = file.read();
            if(i== 0){ sensorOffsets.accel_offset_x = ((uint16_t)fileByte) << 8; } if(i== 1){ sensorOffsets.accel_offset_x += fileByte; }
            if(i== 2){ sensorOffsets.accel_offset_y = ((uint16_t)fileByte) << 8; } if(i== 3){ sensorOffsets.accel_offset_y += fileByte; }
            if(i== 4){ sensorOffsets.accel_offset_z = ((uint16_t)fileByte) << 8; } if(i== 5){ sensorOffsets.accel_offset_z += fileByte; }
            if(i== 6){ sensorOffsets.gyro_offset_x  = ((uint16_t)fileByte) << 8; } if(i== 7){ sensorOffsets.gyro_offset_x  += fileByte; }
            if(i== 8){ sensorOffsets.gyro_offset_y  = ((uint16_t)fileByte) << 8; } if(i== 9){ sensorOffsets.gyro_offset_y  += fileByte; }
            if(i==10){ sensorOffsets.gyro_offset_z  = ((uint16_t)fileByte) << 8; } if(i==11){ sensorOffsets.gyro_offset_z  += fileByte; }
            if(i==12){ sensorOffsets.mag_offset_x   = ((uint16_t)fileByte) << 8; } if(i==13){ sensorOffsets.mag_offset_x   += fileByte; }
            if(i==14){ sensorOffsets.mag_offset_y   = ((uint16_t)fileByte) << 8; } if(i==15){ sensorOffsets.mag_offset_y   += fileByte; }
            if(i==16){ sensorOffsets.mag_offset_z   = ((uint16_t)fileByte) << 8; } if(i==17){ sensorOffsets.mag_offset_z   += fileByte; }
            if(i==18){ sensorOffsets.accel_radius   = ((uint16_t)fileByte) << 8; } if(i==19){ sensorOffsets.accel_radius   += fileByte; }
            if(i==20){ sensorOffsets.mag_radius     = ((uint16_t)fileByte) << 8; } if(i==21){ sensorOffsets.mag_radius     += fileByte; }
            i++;
          }
          file.close();
          Serial.println("Offsets in CONFIG:");
          SerialPrintLnBnoSensorOffsets(sensorOffsets);
         
          bno.setSensorOffsets(sensorOffsets);//Mode muss nicht umgestellt werden, das erledigt die Bibliothek selbst!!!
          Serial.println("Offsets on BNO055:");
          adafruit_bno055_offsets_t sensorOffsetsOnChip;
          bno.getSensorOffsets(sensorOffsetsOnChip);
          SerialPrintLnBnoSensorOffsets(sensorOffsetsOnChip);
        } else {
          Serial.println("Could not open file " + sensorFileName);
        }
      } else if(serialBuffer=="test"){
        Serial.println("[" + serialBuffer + "] ###################################################");
        //Serial.println("Nothing to test");
        /*
        uint16_t source = 65528;
        uint8_t byte1 = 0;
        uint8_t byte2 = 0;
        uint16_t destination = 0;
        Int16ToMultiByteLe(source, byte1, byte2);
        MultiByteLeToInt16(byte1, byte2, destination);
        Serial.println("Value " + (String)source + " converted to " + (String)byte1 + " | " + (String)byte2);
        Serial.println("MultiByte " + (String)byte1 + " | " + (String)byte2 + " converted to value " + (String)destination);
        /**/
       
        Serial.println("Reading Config...");
        File file = sd.open(sensorFileName, O_READ);
        if(file){
          Serial.println("openend with " + (String)file.size() + " bytes, content raw bytes:");
          while(file.available()){ Serial.print((String)(int)file.read() + " "); }
          Serial.println(""); file.close();
        } else { Serial.println("could not open file"); }/**/
        Serial.println("done");
      }
      serialBuffer = "";
    }
  }
}


The code works as follows: you can use the serial commands "bno test" to get a permanent output of the orientation and the calibration status. with "bno save" (if system calibration 3) the entire calibration is written to the sd card. With "bno load" all calibration data are read from the sd card and sent to the BNO055.

Console Output:
Code: Select all | TOGGLE FULL SIZE
X: 4.4375   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
X: 4.4375   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
X: 4.4375   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
X: 4.4375   Y: 70.8750   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
[bno save] ###################################################
Saving offsets...

Offsets written to CONFIG:
Accel: 65521 65524 9
Gyro:  65535 2 0
Mag:   65208 189 496
Accel Radius: 1000
Mag   Radius: 957
##############################################################
X: 3.8750   Y: 70.8750   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
X: 3.0000   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
X: 2.1875   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
[bno load] ###################################################
Loading offsets...
openend with 22 bytes

Offsets in CONFIG:
Accel: 65521 65524 9
Gyro:  65535 2 0
Mag:   65208 189 496
Accel Radius: 1000
Mag   Radius: 957

->Written to BNO055

Offsets on BNO055:
Accel: 65521 65524 9
Gyro:  65535 2 0
Mag:   65208 189 496
Accel Radius: 1000
Mag   Radius: 947
##############################################################
X: 0.0000   Y: 0.0000   Z: 0.0000   Calibration: 3 system, 3 gyro, 3 accel, 3 mag   Is fully calibrated!!!
X: 2.1250   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 0 mag   Is not fully calibrated
X: 2.1250   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 0 mag   Is not fully calibrated
X: 2.1250   Y: 70.9375   Z: 5.8125   Calibration: 3 system, 3 gyro, 3 accel, 0 mag   Is not fully calibrated


I created the output by starting the permanent output with "bno test". then I calibrated the chip (up to sys calibration 3), then saved it with "bno save" and reloaded the data ~ 3 sec. after the saving with "bno load". So, the magnetic environment has not changed because i did not touch/move the chip after full calibration / save / load! The output shows that shortly after loading the magnetometer calibration drops to 0.

I simply not understand why!

DrDooom
 
Posts: 12
Joined: Wed Nov 22, 2017 6:30 am

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by jps2000 on Mon Dec 04, 2017 2:01 am

Hi
I argue that the mag cal indicator automatically goes to zero when switching between modes (NDOF to config and back)
You may give this a try by just doing that without writing cal registers.
On the other hand you see that system cal remains 3 which is a good thing.
So have a look if heading output is +/- correct after reading cal back and forget the mag cal output. Likely this is just misleading.

However the automatic cal of the BNO055 and hence its performance is a nightmare per se and lead to plenty responses in the forum here and elsewhere.

Wir können auch deutsch reden --> Des is a ziemlicher Schmarrn

jps2000
 
Posts: 690
Joined: Fri Jun 02, 2017 4:12 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by jps2000 on Mon Dec 04, 2017 2:26 am

Maybe another point:
the cal values seem to be close to the borders ( see page 33 of the spec)
""The range of the radius for the acc is +/-1000 and for the mag is +/-960""

jps2000
 
Posts: 690
Joined: Fri Jun 02, 2017 4:12 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by duckman01 on Mon Dec 04, 2017 5:55 am

I would suggest you stop putting any more effort into the BNO055, if you read more posts re the IMU you will see that it doesn't work.
It losses it cal, won't update data output correctly, then when velocity is applied to the IMU it losses the plot. Stop wasting your time on this heap of junk.
My 3 are already in the rubbish bin.
Try the NXP Precision, but don't buy the Adafruit one buy the NXP 1, as it has the Kalman filter.

duckman01
 
Posts: 107
Joined: Thu Jun 02, 2016 6:34 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by jps2000 on Mon Dec 04, 2017 7:20 am

I really like to encourage Adafruit to switch to the BNO080 and offer such a breakout instead. There all the problems seem to be solved

jps2000
 
Posts: 690
Joined: Fri Jun 02, 2017 4:12 pm

Re: Adafruit Bosch BNO055 - Calibration Status and read/writ

by duckman01 on Mon Dec 04, 2017 6:08 pm

jps2000, re the 080.
Which part of the device (as there are 3 models) are you using and $ paid.
Im am mainly interested in the tilt error as mine is used for a yacht compass for an auto pilot. What is the max error you have seen when the 080 is tilted 45 degrees, taking samples from horizontal then tilting 45 degree 1 way then the other, move back to horizontal change heading 15 degrees and tilt again, all around the complete compass.
So down in Tasmania our mag flux tilt is 72 degrees up and as such our headings are worst on a southerly heading and the tilt error is high because of the small amount of magnetisum to work on the horizontal.
So far the 050 and NXP precision are about equal at 3.6 degree error, but then the 050 failed in every other way.
The NXP prob is the heading is unstable by +-2 degrees when left stationary for extend period
Pesky Products USFS, Kris says it is good for 2 degree error but this isn't really the case, his has continuous cal mode and that is were the prob is, also the warm start doesn't start it as you would expect and it can change the heading by 100 degrees before it settles down. At best this has 3 degree tilt error but in reality it is consistently 6 degrees
Pololu V3 is the most reliable/stable heading (+-<0.2 movement when stationary for an extended time) but has up to 13 degree tilt error. This is the unit lm using but it is in a gimbal.
Also bought a Maretron SSC200 ($500) a really top of the line unit supposedly <2 degrees (RMS, so they cheat by saying those words as it changes it to 57 % of the time or double it (4) for 95% time) it at it's worst is 6 degrees.
Have on order a CMPS11, but now see they tricked me a bit as l thought there accuracy was going to be 1 or 2 degrees, but they state theirs in % not degrees, so it maybe 3.6 to 7.2 degrees, still to prove 1 way or the other.

duckman01
 
Posts: 107
Joined: Thu Jun 02, 2016 6:34 pm

Please be positive and constructive with your questions and comments.