Hello everybody,
I have a few questions and a problem with the Bosch BNO055 sensor.
First, I do not find Adafruit's introductions to the sensor / library very helpful. That's why I researched and tested myself. I want to use the Sensor to get 9-axis absolute orientation.
Now i think i understand the most important thing about the sensor.
The sensor takes care of OnChip's mathematical calculations and can process Accel, Mag and Gyro themselves. In order to process meaningful data, the chip permanently performs a calibration. one should wait for a complete calibration to use the results data. Since the calibration will be lost after a power out, it should be saved. The chip expects the "config" mode to save the calibration back. however, the Adafruit library does this automatically and sets the right modes.
I hope my knowledge is correct so far.
Since I currently use a MKR Zero without EEPROM, I save the calibration on an SD card instead of the EEPROM.
This brings me to my problem: After writing the calibration back to the Bosch BNO055, the calibration status for the magnetometer is discarded. I do not understand why. I checked the raw data twice.
I use this setup:
Serial.println(" - Init BNO055");
if(!bno.begin()){ Serial.println(" failed - check wiring or I2C ADDR!"); } else {
delay(500);
bno.setExtCrystalUse(false);
bno.setMode(bno.OPERATION_MODE_NDOF);
}
I use this function to save:
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!!!");
}
I use this function to read / restore:
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);
Serial.println("Offsets on BNO055:");
adafruit_bno055_offsets_t sensorOffsetsOnChip;
bno.getSensorOffsets(sensorOffsetsOnChip);
SerialPrintLnBnoSensorOffsets(sensorOffsetsOnChip);
} else {
Serial.println("Could not open file " + sensorFileName);
}
This is my output: :![]()
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
The Output shows, that i have calibrated the sensor correct (manually moved the chip, ...), than saved the Data to SD Card, than read the Data from SD Card (like i would do after power off) and write it to the Sensor. After the last step, the calibration for the magnetometer was discarded and set to 0!
I dont know why! The Output shows that the Offset's are fine so far (after reading, saving, ...).
I would be very happy if someone with bno055 experience could see if I made a mistake somewhere or the behavior is correct (and I misunderstood something about the calibration).
One thing I still do not understand:
Where should be magnetic north (x=0) if I put the chip flat on the table?
Please see atteched image.
