BNO055
The BNO055 is an intelligent MEMS sensor developed by Bosch Sensortec. It combines a 9-axis absolute-orientation sensor and sensor fusion capabilities into a single package. This compact device simplifies the process of obtaining meaningful sensor data by handling sensor fusion internally, saving developers from the complexities of implementing fusion algorithms themselves.
The sensor has multiple modes (see Adafruit_BNO055.h lines 61-75). The differences between the modes are the sensors used to calculate the orientation and the output information available. The mode used was:
Functionality
Accelerometer: Measures three-axis acceleration, including both gravity and linear motion, in meters per second squared (m/s²) at a rate of 100Hz.
Magnetometer: Detects three-axis magnetic field strength in microtesla (µT) at 20Hz.
Gyroscope: Reports three-axis rotation speed (angular velocity) in radians per second (rad/s) at 100Hz. The high-speed ARM Cortex-M0 based processor within the BNO055 handles sensor fusion and real-time requirements.
Outputs
Absolute Orientation (Euler Vector): This format gives three-axis orientation data based on a 360° sphere. It provides stable orientation output at a rate of 100Hz.
Absolute Orientation (Quaternion): If you need more accurate data manipulation, the BNO055 outputs a four-point quaternion. Quaternions are useful for complex rotations and are also available at 100Hz.
Angular Velocity Vector: This vector represents three-axis rotation speed (angular velocity) in rad/s.
Linear Acceleration Vector: Excluding gravity, it provides three-axis linear acceleration data at 100Hz.
Gravity Vector: Represents three-axis gravitational acceleration (minus any movement) at 100Hz.
Temperature: The BNO055 also reports ambient temperature in degrees Celsius at 1Hz.
Calibration
Before using the BNO055 sensor, it's essential to calibrate it properly. The calibration process ensures accurate data from the gyroscope, accelerometer, and magnetometer.
Here is the explanation of the process. Depending on the axis you move the BNO055, it calibrates a specific axis.
For example: - To calibrate the gyroscope, keep the device stationary in any position. - For the magnetometer, recent devices perform fast magnetic compensation without requiring specific 'figure 8' motions. - To calibrate the accelerometer, place the BNO055 in six standing positions: +X, -X, +Y, -Y, +Z, and -Z. Use a block of wood or a similar object to maintain alignment during calibration.
Remember that the BNO055 starts supplying sensor data as soon as it's powered on, even before the calibration process is complete. In NDOF mode, discard data while the system calibration status is 0 (indicating incomplete calibration). Once the system calibration status reaches 1 or higher, the heading will reflect the absolute value once the BNO055 finds magnetic north.
BNO Class
The BNO class wraps the Adafruit library and adds phase correction and orientation reset
functionality used by the control system.
Phase correction — At startup, resetOrientation() reads the current X and Z angles
from the sensor and stores them as offsets (phaseCorrection_ and phaseCorrectionY_).
All subsequent angle readings subtract these offsets, so the robot always starts with a
heading of zero regardless of its physical orientation when powered on.
Single read per call — getOrientationY() previously triggered two separate I2C reads
in the same cycle, which could return slightly different values and cause inconsistent pitch
readings. It now calls updateBNO() only once per call, matching the behavior of
getOrientationX() and ensuring both axes always reflect the same sensor snapshot.
z_rotation helper — getOrientationX() also computes z_rotation, a signed
version of the heading in the range −180° to +180°. This is used by the heading PID when
the target angle is zero, since the raw 0–360° value could wrap around and cause the PID to
spin the wrong way near north.
Orientation reset — resetOrientation() re-initializes the sensor and re-captures
both correction offsets in one call. resetOrientationX() does the same for the heading
axis only, used when only the yaw needs to be zeroed without disturbing the pitch reference.