Fully featured I2C and SPI driver for CEVA (Hilcrest)'s BNO080 and FSM300 Inertial Measurement Units.

Dependents:   BNO080-Examples BNO080-Examples

BNO080 Driver

by Jamie Smith / USC Rocket Propulsion Lab

After lots of development, we are proud to present our driver for the Hilcrest BNO080 IMU! This driver is inspired by SparkFun and Nathan Seidle's Arduino driver for this chip, but has been substantially rewritten and adapted.

It supports the main features of the chip, such as reading rotation and acceleration data, as well as some of its more esoteric functionality, such as counting steps and detecting whether the device is being hand-held.

Features

  • Support for 15 different data reports from the IMU, from acceleration to rotation to tap detection
  • Support for reading of sensor data, and automatic checking of update rate against allowed values in metadata
  • BNO_DEBUG switch enabling verbose, detailed output about communications with the chip for ease of debugging
  • Ability to tare sensor rotation and set mounting orientation
  • Can operate in several execution modes: polling I2C, polling SPI, and threaded SPI (which handles timing-critical functions in a dedicated thread, and automatically activates when the IMU has data available)
    • Also has experimental support for using asynchronous SPI transactions, allowing other threads to execute while communication with the BNO is occurring. Note that this functionality requires a patch to Mbed OS source code due to Mbed bug #13941
  • Calibration function
  • Reasonable code size for what you get: the library uses about 4K of flash and one instance of the object uses about 1700 bytes of RAM.

Documentation

Full Doxygen documentation is available online here

Example Code

Here's a simple example:

BNO080 Rotation Vector and Acceleration

#include <mbed.h>
#include <BNO080.h>

int main()
{
	Serial pc(USBTX, USBRX);

	// Create IMU, passing in output stream, pins, I2C address, and I2C frequency
	// These pin assignments are specific to my dev setup -- you'll need to change them
	BNO080I2C imu(&pc, p28, p27, p16, p30, 0x4a, 100000); 

	pc.baud(115200);
	pc.printf("============================================================\n");

	// Tell the IMU to report rotation every 100ms and acceleration every 200ms
	imu.enableReport(BNO080::ROTATION, 100);
	imu.enableReport(BNO080::TOTAL_ACCELERATION, 200);

	while (true)
	{
		wait(.001f);
		
		// poll the IMU for new data -- this returns true if any packets were received
		if(imu.updateData())
		{
			// now check for the specific type of data that was received (can be multiple at once)
			if (imu.hasNewData(BNO080::ROTATION))
			{
				// convert quaternion to Euler degrees and print
				pc.printf("IMU Rotation Euler: ");
				TVector3 eulerRadians = imu.rotationVector.euler();
				TVector3 eulerDegrees = eulerRadians * (180.0 / M_PI);
				eulerDegrees.print(pc, true);
				pc.printf("\n");
			}
			if (imu.hasNewData(BNO080::TOTAL_ACCELERATION))
			{
				// print the acceleration vector using its builtin print() method
				pc.printf("IMU Total Acceleration: ");
				imu.totalAcceleration.print(pc, true);
				pc.printf("\n");
			}
		}
	}

}


If you want more, a comprehensive, ready-to-run set of examples is available on my BNO080-Examples repository.

Credits

This driver makes use of a lightweight, public-domain library for vectors and quaternions available here.

Changelog

Version 2.1 (Nov 24 2020)

  • Added BNO080Async, which provides a threaded implementation of the SPI driver. This should help get the best performance and remove annoying timing requirements on the code calling the driver
  • Added experimental USE_ASYNC_SPI option
  • Fixed bug in v2.0 causing calibrations to fail

Version 2.0 (Nov 18 2020)

  • Added SPI support
  • Refactored buffer system so that SPI could be implemented as a subclass. Unfortunately this does substantially increase the memory usage of the driver, but I believe that the benefits are worth it.

Version 1.3 (Jul 21 2020)

  • Fix deprecation warnings and compile errors in Mbed 6
  • Fix compile errors in Arm Compiler (why doesn't it have M_PI????)

Version 1.2 (Jan 30 2020)

  • Removed accidental IRQ change
  • Fixed hard iron offset reading incorrectly due to missing cast

Version 1.1 (Jun 14 2019)

  • Added support for changing permanent orientation
  • Add FRS writing functions
  • Removed some errant printfs

Version 1.0 (Dec 29 2018)

  • Initial Mbed OS release
Committer:
Jamie Smith
Date:
Tue Jul 21 21:37:10 2020 -0700
Revision:
6:5ba996be5312
Parent:
3:197ad972fb7c
Child:
8:199c7fad233d
Update for MBed OS 6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jamie Smith 1:aac28ffd63ed 1 /*
Jamie Smith 1:aac28ffd63ed 2 * This is USC RPL's ARM MBed BNO080 IMU driver, by Jamie Smith.
Jamie Smith 1:aac28ffd63ed 3 *
Jamie Smith 1:aac28ffd63ed 4 * It is based on SparkFun and Nathan Seidle's Arduino driver for this chip, but is substantially rewritten and adapted.
Jamie Smith 1:aac28ffd63ed 5 * It also supports some extra features, such as setting the mounting orientation and
Jamie Smith 1:aac28ffd63ed 6 * enabling some additional data reports.
Jamie Smith 1:aac28ffd63ed 7 *
Jamie Smith 1:aac28ffd63ed 8 * This driver uses no dynamic allocation, but does allocate a couple hundred bytes of class variables as buffers.
Jamie Smith 1:aac28ffd63ed 9 * This should allow you to monitor its memory usage using MBed's size printout.
Jamie Smith 1:aac28ffd63ed 10 *
Jamie Smith 1:aac28ffd63ed 11 * The BNO080 is a very complex chip; it's capable of monitoring and controlling other sensors and making
Jamie Smith 1:aac28ffd63ed 12 * intelligent decisions and calculations using its data. Accordingly, the protocol for communicating with it
Jamie Smith 1:aac28ffd63ed 13 * is quite complex, and it took me quite a while to wrap my head around it. If you need to modify or debug
Jamie Smith 1:aac28ffd63ed 14 * this driver, look at the CPP file for an overview of the chip's communication protocol.
Jamie Smith 1:aac28ffd63ed 15 *
Jamie Smith 1:aac28ffd63ed 16 * Note: this driver only supports I2C. I attempted to create an SPI version, but as far as I can tell,
Jamie Smith 1:aac28ffd63ed 17 * the BNO's SPI interface has a bug that causes you to be unable to wake the chip from sleep in some conditions.
Jamie Smith 1:aac28ffd63ed 18 * Until this is fixed, SPI on it is virtually unusable.
Jamie Smith 1:aac28ffd63ed 19 */
Jamie Smith 1:aac28ffd63ed 20
Jamie Smith 1:aac28ffd63ed 21 #ifndef HAMSTER_BNO080_H
Jamie Smith 1:aac28ffd63ed 22 #define HAMSTER_BNO080_H
Jamie Smith 1:aac28ffd63ed 23
Jamie Smith 1:aac28ffd63ed 24 #include <mbed.h>
Jamie Smith 1:aac28ffd63ed 25 #include <quaternion.h>
Jamie Smith 1:aac28ffd63ed 26
Jamie Smith 1:aac28ffd63ed 27 #include "BNO080Constants.h"
Jamie Smith 1:aac28ffd63ed 28
Jamie Smith 1:aac28ffd63ed 29 // useful define when working with orientation quaternions
Jamie Smith 3:197ad972fb7c 30 #define SQRT_2 1.414213562f
Jamie Smith 1:aac28ffd63ed 31
Jamie Smith 1:aac28ffd63ed 32 /**
Jamie Smith 1:aac28ffd63ed 33 Class to drive the BNO080 9-axis IMU.
Jamie Smith 1:aac28ffd63ed 34
Jamie Smith 1:aac28ffd63ed 35 There should be one instance of this class per IMU chip. I2C address and pin assignments are passed in the constructor.
Jamie Smith 1:aac28ffd63ed 36 */
Jamie Smith 1:aac28ffd63ed 37 class BNO080
Jamie Smith 1:aac28ffd63ed 38 {
Jamie Smith 1:aac28ffd63ed 39 /**
Jamie Smith 1:aac28ffd63ed 40 * Serial stream to print debug info to. Used for errors, and debugging output if debugging is enabled.
Jamie Smith 1:aac28ffd63ed 41 */
Jamie Smith 6:5ba996be5312 42 Stream * _debugPort;
Jamie Smith 1:aac28ffd63ed 43
Jamie Smith 1:aac28ffd63ed 44 /**
Jamie Smith 1:aac28ffd63ed 45 * I2C port object. Provides physical layer communications with the chip.
Jamie Smith 1:aac28ffd63ed 46 */
Jamie Smith 1:aac28ffd63ed 47 I2C _i2cPort;
Jamie Smith 1:aac28ffd63ed 48
Jamie Smith 1:aac28ffd63ed 49 /// user defined port speed
Jamie Smith 1:aac28ffd63ed 50 int _i2cPortSpeed;
Jamie Smith 1:aac28ffd63ed 51
Jamie Smith 1:aac28ffd63ed 52 /// i2c address of IMU (7 bits)
Jamie Smith 1:aac28ffd63ed 53 uint8_t _i2cAddress;
Jamie Smith 1:aac28ffd63ed 54
Jamie Smith 1:aac28ffd63ed 55 /// Interrupt pin -- signals to the host that the IMU has data to send
Jamie Smith 1:aac28ffd63ed 56 DigitalIn _int;
Jamie Smith 1:aac28ffd63ed 57
Jamie Smith 1:aac28ffd63ed 58 // Reset pin -- resets IMU when held low.
Jamie Smith 1:aac28ffd63ed 59 DigitalOut _rst;
Jamie Smith 1:aac28ffd63ed 60
Jamie Smith 1:aac28ffd63ed 61 // packet storage
Jamie Smith 1:aac28ffd63ed 62 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 63
Jamie Smith 1:aac28ffd63ed 64 #define SHTP_HEADER_SIZE 4
Jamie Smith 1:aac28ffd63ed 65
Jamie Smith 3:197ad972fb7c 66 // Arbitrarily chosen, but should hopefully be large enough for all packets we need.
Jamie Smith 3:197ad972fb7c 67 // If you enable lots of sensor reports and get an error, you might need to increase this.
Jamie Smith 1:aac28ffd63ed 68 #define STORED_PACKET_SIZE 128
Jamie Smith 1:aac28ffd63ed 69
Jamie Smith 1:aac28ffd63ed 70 /// Each SHTP packet has a header of 4 uint8_ts
Jamie Smith 1:aac28ffd63ed 71 uint8_t shtpHeader[SHTP_HEADER_SIZE];
Jamie Smith 1:aac28ffd63ed 72
Jamie Smith 1:aac28ffd63ed 73 /// Stores data contained in each packet. Packets can contain an arbitrary amount of data, but
Jamie Smith 1:aac28ffd63ed 74 /// rarely get over a hundred bytes unless you have a million sensor reports enabled.
Jamie Smith 1:aac28ffd63ed 75 /// The only long packets we actually care about are batched sensor data packets.
Jamie Smith 1:aac28ffd63ed 76 uint8_t shtpData[STORED_PACKET_SIZE];
Jamie Smith 1:aac28ffd63ed 77
Jamie Smith 1:aac28ffd63ed 78 /// Length of packet that was received into buffer. Does NOT include header bytes.
Jamie Smith 1:aac28ffd63ed 79 uint16_t packetLength;
Jamie Smith 1:aac28ffd63ed 80
Jamie Smith 1:aac28ffd63ed 81 /// Current sequence number for each channel, incremented after transmission.
Jamie Smith 2:2269b723d16a 82 uint8_t sequenceNumber[6];
Jamie Smith 1:aac28ffd63ed 83
Jamie Smith 1:aac28ffd63ed 84 /// Commands have a seqNum as well. These are inside command packet, the header uses its own seqNum per channel
Jamie Smith 2:2269b723d16a 85 uint8_t commandSequenceNumber;
Jamie Smith 1:aac28ffd63ed 86
Jamie Smith 1:aac28ffd63ed 87
Jamie Smith 1:aac28ffd63ed 88 // frs metadata
Jamie Smith 1:aac28ffd63ed 89 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 90
Jamie Smith 1:aac28ffd63ed 91 /// Record ID of the metadata record currently stored in the metadataRecord[] buffer.
Jamie Smith 1:aac28ffd63ed 92 /// Used so that we can avoid requerying the FRS record if we need to make multiple metadata reads
Jamie Smith 1:aac28ffd63ed 93 /// in succession.
Jamie Smith 1:aac28ffd63ed 94 uint16_t bufferMetadataRecord;
Jamie Smith 1:aac28ffd63ed 95
Jamie Smith 1:aac28ffd63ed 96 /// currently we only need the first 10 words of the metadata
Jamie Smith 1:aac28ffd63ed 97 #define METADATA_BUFFER_LEN 10
Jamie Smith 1:aac28ffd63ed 98
Jamie Smith 1:aac28ffd63ed 99 /// Buffer for current metadata record.
Jamie Smith 2:2269b723d16a 100 uint32_t metadataRecord[METADATA_BUFFER_LEN];
Jamie Smith 1:aac28ffd63ed 101
Jamie Smith 1:aac28ffd63ed 102 // data storage
Jamie Smith 1:aac28ffd63ed 103 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 104
Jamie Smith 1:aac28ffd63ed 105 // 1 larger than the largest sensor report ID
Jamie Smith 1:aac28ffd63ed 106 #define STATUS_ARRAY_LEN MAX_SENSOR_REPORTID + 1
Jamie Smith 1:aac28ffd63ed 107
Jamie Smith 1:aac28ffd63ed 108 /// stores status of each sensor, indexed by report ID
Jamie Smith 2:2269b723d16a 109 uint8_t reportStatus[STATUS_ARRAY_LEN];
Jamie Smith 1:aac28ffd63ed 110
Jamie Smith 1:aac28ffd63ed 111 /// stores whether a sensor has been updated since the last call to hasNewData()
Jamie Smith 2:2269b723d16a 112 bool reportHasBeenUpdated[STATUS_ARRAY_LEN];
Jamie Smith 1:aac28ffd63ed 113
Jamie Smith 1:aac28ffd63ed 114 public:
Jamie Smith 1:aac28ffd63ed 115
Jamie Smith 1:aac28ffd63ed 116 // list of reports
Jamie Smith 1:aac28ffd63ed 117 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 118
Jamie Smith 1:aac28ffd63ed 119 /// List of all sensor reports that the IMU supports.
Jamie Smith 2:2269b723d16a 120 enum Report
Jamie Smith 1:aac28ffd63ed 121 {
Jamie Smith 1:aac28ffd63ed 122 /**
Jamie Smith 1:aac28ffd63ed 123 * Total acceleration of the IMU in world space.
Jamie Smith 1:aac28ffd63ed 124 * See BNO datasheet section 2.1.1
Jamie Smith 1:aac28ffd63ed 125 */
Jamie Smith 1:aac28ffd63ed 126 TOTAL_ACCELERATION = SENSOR_REPORTID_ACCELEROMETER,
Jamie Smith 1:aac28ffd63ed 127
Jamie Smith 1:aac28ffd63ed 128 /**
Jamie Smith 1:aac28ffd63ed 129 * Acceleration of the IMU not including the acceleration of gravity.
Jamie Smith 1:aac28ffd63ed 130 * See BNO datasheet section 2.1.1
Jamie Smith 1:aac28ffd63ed 131 */
Jamie Smith 1:aac28ffd63ed 132 LINEAR_ACCELERATION = SENSOR_REPORTID_LINEAR_ACCELERATION,
Jamie Smith 1:aac28ffd63ed 133
Jamie Smith 1:aac28ffd63ed 134 /**
Jamie Smith 1:aac28ffd63ed 135 * Acceleration of gravity felt by the IMU.
Jamie Smith 1:aac28ffd63ed 136 * See BNO datasheet section 2.1.1
Jamie Smith 1:aac28ffd63ed 137 */
Jamie Smith 1:aac28ffd63ed 138 GRAVITY_ACCELERATION = SENSOR_REPORTID_GRAVITY,
Jamie Smith 1:aac28ffd63ed 139
Jamie Smith 1:aac28ffd63ed 140 /**
Jamie Smith 1:aac28ffd63ed 141 * (calibrated) gyroscope reading of the rotational speed of the IMU.
Jamie Smith 1:aac28ffd63ed 142 * See BNO datasheet section 2.1.2
Jamie Smith 1:aac28ffd63ed 143 */
Jamie Smith 1:aac28ffd63ed 144 GYROSCOPE = SENSOR_REPORTID_GYROSCOPE_CALIBRATED,
Jamie Smith 1:aac28ffd63ed 145
Jamie Smith 1:aac28ffd63ed 146 /**
Jamie Smith 1:aac28ffd63ed 147 * (calibrated) reading of Earth's magnetic field levels.
Jamie Smith 1:aac28ffd63ed 148 * See BNO datasheet section 2.1.3
Jamie Smith 1:aac28ffd63ed 149 */
Jamie Smith 1:aac28ffd63ed 150 MAG_FIELD = SENSOR_REPORTID_MAGNETIC_FIELD_CALIBRATED,
Jamie Smith 1:aac28ffd63ed 151
Jamie Smith 1:aac28ffd63ed 152 /**
Jamie Smith 1:aac28ffd63ed 153 * Uncalibrated reading of magnetic field levels, without any hard iron offsets applied
Jamie Smith 1:aac28ffd63ed 154 * See BNO datasheet section 2.1.3
Jamie Smith 1:aac28ffd63ed 155 */
Jamie Smith 1:aac28ffd63ed 156 MAG_FIELD_UNCALIBRATED = SENSOR_REPORTID_MAGNETIC_FIELD_UNCALIBRATED,
Jamie Smith 1:aac28ffd63ed 157
Jamie Smith 1:aac28ffd63ed 158 /**
Jamie Smith 1:aac28ffd63ed 159 * Fused reading of the IMU's rotation in space using all three sensors. This is the most accurate reading
Jamie Smith 1:aac28ffd63ed 160 * of absolute orientation that the IMU can provide.
Jamie Smith 1:aac28ffd63ed 161 * See BNO datasheet section 2.2.4
Jamie Smith 1:aac28ffd63ed 162 */
Jamie Smith 1:aac28ffd63ed 163 ROTATION = SENSOR_REPORTID_ROTATION_VECTOR,
Jamie Smith 1:aac28ffd63ed 164
Jamie Smith 1:aac28ffd63ed 165 /**
Jamie Smith 1:aac28ffd63ed 166 * Fused reading of rotation from accelerometer and magnetometer readings. This report is designed to decrease
Jamie Smith 1:aac28ffd63ed 167 * power consumption (by turning off the gyroscope) in exchange for reduced responsiveness.
Jamie Smith 1:aac28ffd63ed 168 */
Jamie Smith 1:aac28ffd63ed 169 GEOMAGNETIC_ROTATION = SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR,
Jamie Smith 1:aac28ffd63ed 170
Jamie Smith 1:aac28ffd63ed 171 /**
Jamie Smith 1:aac28ffd63ed 172 * Fused reading of the IMU's rotation in space. Unlike the regular rotation vector, the Game Rotation Vector
Jamie Smith 1:aac28ffd63ed 173 * is not referenced against the magnetic field and the "zero yaw" point is arbitrary.
Jamie Smith 1:aac28ffd63ed 174 * See BNO datasheet section 2.2.2
Jamie Smith 1:aac28ffd63ed 175 */
Jamie Smith 1:aac28ffd63ed 176 GAME_ROTATION = SENSOR_REPORTID_GAME_ROTATION_VECTOR,
Jamie Smith 1:aac28ffd63ed 177
Jamie Smith 1:aac28ffd63ed 178 /**
Jamie Smith 1:aac28ffd63ed 179 * Detects a user tapping on the device containing the IMU.
Jamie Smith 1:aac28ffd63ed 180 * See BNO datasheet section 2.4.2
Jamie Smith 1:aac28ffd63ed 181 */
Jamie Smith 1:aac28ffd63ed 182 TAP_DETECTOR = SENSOR_REPORTID_TAP_DETECTOR,
Jamie Smith 1:aac28ffd63ed 183
Jamie Smith 1:aac28ffd63ed 184 /**
Jamie Smith 1:aac28ffd63ed 185 * Detects whether the device is on a table, being held stably, or being moved.
Jamie Smith 1:aac28ffd63ed 186 * See BNO datasheet section 2.4.1
Jamie Smith 1:aac28ffd63ed 187 */
Jamie Smith 1:aac28ffd63ed 188 STABILITY_CLASSIFIER = SENSOR_REPORTID_STABILITY_CLASSIFIER,
Jamie Smith 1:aac28ffd63ed 189
Jamie Smith 1:aac28ffd63ed 190 /**
Jamie Smith 1:aac28ffd63ed 191 * Detects a user taking a step with the IMU worn on their person.
Jamie Smith 1:aac28ffd63ed 192 * See BNO datasheet section 2.4.3
Jamie Smith 1:aac28ffd63ed 193 */
Jamie Smith 1:aac28ffd63ed 194 STEP_DETECTOR = SENSOR_REPORTID_STEP_DETECTOR,
Jamie Smith 1:aac28ffd63ed 195
Jamie Smith 1:aac28ffd63ed 196 /**
Jamie Smith 1:aac28ffd63ed 197 * Detects how many steps a user has taken.
Jamie Smith 1:aac28ffd63ed 198 * See BNO datasheet section 2.4.4
Jamie Smith 1:aac28ffd63ed 199 */
Jamie Smith 1:aac28ffd63ed 200 STEP_COUNTER = SENSOR_REPORTID_STEP_COUNTER,
Jamie Smith 1:aac28ffd63ed 201
Jamie Smith 1:aac28ffd63ed 202 /**
Jamie Smith 1:aac28ffd63ed 203 * Detects when the IMU has made a "significant" motion, defined as moving a few steps and/or accelerating significantly.
Jamie Smith 1:aac28ffd63ed 204 *
Jamie Smith 1:aac28ffd63ed 205 * NOTE: this report automatically disables itself after sending a report, so you'll have to reenable it each time a motion i s detected.
Jamie Smith 1:aac28ffd63ed 206 * See BNO datasheet section 2.4.6
Jamie Smith 1:aac28ffd63ed 207 */
Jamie Smith 1:aac28ffd63ed 208 SIGNIFICANT_MOTION = SENSOR_REPORTID_SIGNIFICANT_MOTION,
Jamie Smith 1:aac28ffd63ed 209
Jamie Smith 1:aac28ffd63ed 210 /**
Jamie Smith 1:aac28ffd63ed 211 * Detects when the IMU is being shaken.
Jamie Smith 1:aac28ffd63ed 212 * See BNO datasheet section 2.4.7
Jamie Smith 1:aac28ffd63ed 213 */
Jamie Smith 1:aac28ffd63ed 214 SHAKE_DETECTOR = SENSOR_REPORTID_SHAKE_DETECTOR
Jamie Smith 1:aac28ffd63ed 215 };
Jamie Smith 1:aac28ffd63ed 216
Jamie Smith 1:aac28ffd63ed 217 // data variables to read reports from
Jamie Smith 1:aac28ffd63ed 218 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 219
Jamie Smith 1:aac28ffd63ed 220 // @{
Jamie Smith 1:aac28ffd63ed 221 /// Version info read from the IMU when it starts up
Jamie Smith 1:aac28ffd63ed 222 uint8_t majorSoftwareVersion;
Jamie Smith 1:aac28ffd63ed 223 uint8_t minorSoftwareVersion;
Jamie Smith 1:aac28ffd63ed 224 uint16_t patchSoftwareVersion;
Jamie Smith 1:aac28ffd63ed 225 uint32_t partNumber;
Jamie Smith 1:aac28ffd63ed 226 uint32_t buildNumber;
Jamie Smith 1:aac28ffd63ed 227 // @}
Jamie Smith 1:aac28ffd63ed 228
Jamie Smith 1:aac28ffd63ed 229
Jamie Smith 1:aac28ffd63ed 230 /**
Jamie Smith 1:aac28ffd63ed 231 * Readout from Accleration report.
Jamie Smith 1:aac28ffd63ed 232 * Represents total acceleration in m/s^2 felt by the BNO's accelerometer.
Jamie Smith 1:aac28ffd63ed 233 */
Jamie Smith 1:aac28ffd63ed 234 TVector3 totalAcceleration;
Jamie Smith 1:aac28ffd63ed 235
Jamie Smith 1:aac28ffd63ed 236 /**
Jamie Smith 1:aac28ffd63ed 237 * Readout from Linear Acceleration report.
Jamie Smith 1:aac28ffd63ed 238 * Represents acceleration felt in m/s^2 by the BNO's accelerometer not including the force of gravity.
Jamie Smith 1:aac28ffd63ed 239 */
Jamie Smith 1:aac28ffd63ed 240 TVector3 linearAcceleration;
Jamie Smith 1:aac28ffd63ed 241
Jamie Smith 1:aac28ffd63ed 242 /**
Jamie Smith 1:aac28ffd63ed 243 * Readout from Gravity report.
Jamie Smith 1:aac28ffd63ed 244 * Represents the force of gravity in m/s^2 felt by the BNO's accelerometer.
Jamie Smith 1:aac28ffd63ed 245 */
Jamie Smith 1:aac28ffd63ed 246 TVector3 gravityAcceleration;
Jamie Smith 1:aac28ffd63ed 247
Jamie Smith 1:aac28ffd63ed 248 /**
Jamie Smith 1:aac28ffd63ed 249 * Readout from Calibrated Gyroscope report
Jamie Smith 1:aac28ffd63ed 250 * Represents the angular velocities of the chip in rad/s in the X, Y, and Z axes
Jamie Smith 1:aac28ffd63ed 251 */
Jamie Smith 1:aac28ffd63ed 252 TVector3 gyroRotation;
Jamie Smith 1:aac28ffd63ed 253
Jamie Smith 1:aac28ffd63ed 254 /**
Jamie Smith 1:aac28ffd63ed 255 * Readout from the Magnetic Field Calibrated report.
Jamie Smith 1:aac28ffd63ed 256 * Represents the magnetic field read by the chip in uT in the X, Y, and Z axes
Jamie Smith 1:aac28ffd63ed 257 */
Jamie Smith 1:aac28ffd63ed 258 TVector3 magField;
Jamie Smith 1:aac28ffd63ed 259
Jamie Smith 1:aac28ffd63ed 260 /**
Jamie Smith 1:aac28ffd63ed 261 * Readout from the Magnetic Field Uncalibrated report.
Jamie Smith 1:aac28ffd63ed 262 * Represents the magnetic field read by the chip in uT in the X, Y, and Z axes, without hard iron offsets applied
Jamie Smith 1:aac28ffd63ed 263 */
Jamie Smith 1:aac28ffd63ed 264 TVector3 magFieldUncalibrated;
Jamie Smith 1:aac28ffd63ed 265
Jamie Smith 1:aac28ffd63ed 266 /**
Jamie Smith 1:aac28ffd63ed 267 * Auxiliary readout from the Magnetic Field Uncalibrated report.
Jamie Smith 1:aac28ffd63ed 268 * Represents the hard iron offsets that the chip is using in each axis in uT.
Jamie Smith 1:aac28ffd63ed 269 */
Jamie Smith 1:aac28ffd63ed 270 TVector3 hardIronOffset;
Jamie Smith 1:aac28ffd63ed 271
Jamie Smith 1:aac28ffd63ed 272 /**
Jamie Smith 1:aac28ffd63ed 273 * Readout from the Rotation Vector report.
Jamie Smith 1:aac28ffd63ed 274 * Represents the rotation of the IMU (relative to magnetic north) in radians.
Jamie Smith 1:aac28ffd63ed 275 */
Jamie Smith 1:aac28ffd63ed 276 Quaternion rotationVector;
Jamie Smith 1:aac28ffd63ed 277
Jamie Smith 1:aac28ffd63ed 278 /**
Jamie Smith 1:aac28ffd63ed 279 * Auxiliary accuracy readout from the Rotation Vector report.
Jamie Smith 1:aac28ffd63ed 280 * Represents the estimated accuracy of the rotation vector in radians.
Jamie Smith 1:aac28ffd63ed 281 */
Jamie Smith 1:aac28ffd63ed 282 float rotationAccuracy;
Jamie Smith 1:aac28ffd63ed 283
Jamie Smith 1:aac28ffd63ed 284 /**
Jamie Smith 1:aac28ffd63ed 285 * Readout from the Game Rotation Vector report.
Jamie Smith 1:aac28ffd63ed 286 * Represents the rotation of the IMU in radians. Unlike the regular rotation vector, the Game Rotation Vector
Jamie Smith 1:aac28ffd63ed 287 * is not referenced against the magnetic field and the "zero yaw" point is arbitrary.
Jamie Smith 1:aac28ffd63ed 288 */
Jamie Smith 1:aac28ffd63ed 289 Quaternion gameRotationVector;
Jamie Smith 1:aac28ffd63ed 290
Jamie Smith 1:aac28ffd63ed 291 /**
Jamie Smith 1:aac28ffd63ed 292 * Readout from the Geomagnetic Rotation Vector report.
Jamie Smith 1:aac28ffd63ed 293 * Represents the geomagnetic rotation of the IMU (relative to magnetic north) in radians.
Jamie Smith 1:aac28ffd63ed 294 */
Jamie Smith 1:aac28ffd63ed 295 Quaternion geomagneticRotationVector;
Jamie Smith 1:aac28ffd63ed 296
Jamie Smith 1:aac28ffd63ed 297 /**
Jamie Smith 1:aac28ffd63ed 298 * Auxiliary accuracy readout from the Geomagnetic Rotation Vector report.
Jamie Smith 1:aac28ffd63ed 299 * Represents the estimated accuracy of the rotation vector in radians.
Jamie Smith 1:aac28ffd63ed 300 */
Jamie Smith 1:aac28ffd63ed 301 float geomagneticRotationAccuracy;
Jamie Smith 1:aac28ffd63ed 302
Jamie Smith 1:aac28ffd63ed 303 /**
Jamie Smith 1:aac28ffd63ed 304 * Tap readout from the Tap Detector report. This flag is set to true whenever a tap is detected, and you should
Jamie Smith 1:aac28ffd63ed 305 * manually clear it when you have processed the tap.
Jamie Smith 1:aac28ffd63ed 306 */
Jamie Smith 1:aac28ffd63ed 307 bool tapDetected;
Jamie Smith 1:aac28ffd63ed 308
Jamie Smith 1:aac28ffd63ed 309 /**
Jamie Smith 1:aac28ffd63ed 310 * Whether the last tap detected was a single or double tap.
Jamie Smith 1:aac28ffd63ed 311 */
Jamie Smith 1:aac28ffd63ed 312 bool doubleTap;
Jamie Smith 1:aac28ffd63ed 313
Jamie Smith 1:aac28ffd63ed 314 /**
Jamie Smith 1:aac28ffd63ed 315 * Enum to represent the different stability types.
Jamie Smith 1:aac28ffd63ed 316 *
Jamie Smith 1:aac28ffd63ed 317 * See BNO datasheet section 2.4.1 and SH-2 section 6.5.31.2 for details.
Jamie Smith 1:aac28ffd63ed 318 */
Jamie Smith 2:2269b723d16a 319 enum Stability
Jamie Smith 1:aac28ffd63ed 320 {
Jamie Smith 1:aac28ffd63ed 321 /// Unknown stability type.
Jamie Smith 1:aac28ffd63ed 322 UNKNOWN = 0,
Jamie Smith 1:aac28ffd63ed 323
Jamie Smith 1:aac28ffd63ed 324 /// At rest on a stable surface with very little motion
Jamie Smith 1:aac28ffd63ed 325 ON_TABLE = 1,
Jamie Smith 1:aac28ffd63ed 326
Jamie Smith 1:aac28ffd63ed 327 /// Motion is stable, but the duration requirement for stability has not been met.
Jamie Smith 1:aac28ffd63ed 328 /// Can only occur during gyroscope calibration (why? beats me!)
Jamie Smith 1:aac28ffd63ed 329 STATIONARY = 2,
Jamie Smith 1:aac28ffd63ed 330
Jamie Smith 1:aac28ffd63ed 331 /// Stable (has been below the acceleration threshold for the required duration)
Jamie Smith 1:aac28ffd63ed 332 STABLE = 3,
Jamie Smith 1:aac28ffd63ed 333
Jamie Smith 1:aac28ffd63ed 334 /// IMU is moving.
Jamie Smith 1:aac28ffd63ed 335 MOTION = 4
Jamie Smith 1:aac28ffd63ed 336 };
Jamie Smith 1:aac28ffd63ed 337
Jamie Smith 1:aac28ffd63ed 338 /**
Jamie Smith 1:aac28ffd63ed 339 * Readout from the stability classifier.
Jamie Smith 1:aac28ffd63ed 340 * Current stability status of the IMU.
Jamie Smith 1:aac28ffd63ed 341 */
Jamie Smith 2:2269b723d16a 342 Stability stability;
Jamie Smith 1:aac28ffd63ed 343
Jamie Smith 1:aac28ffd63ed 344 /**
Jamie Smith 1:aac28ffd63ed 345 * Readout from the Step Detector report. This flag is set to true whenever a step is detected, and you should
Jamie Smith 1:aac28ffd63ed 346 * manually clear it when you have processed the step.
Jamie Smith 1:aac28ffd63ed 347 */
Jamie Smith 2:2269b723d16a 348 bool stepDetected;
Jamie Smith 1:aac28ffd63ed 349
Jamie Smith 1:aac28ffd63ed 350 /**
Jamie Smith 1:aac28ffd63ed 351 * Readout from the Step Counter report. This count increases as the user takes steps, but can also decrease
Jamie Smith 1:aac28ffd63ed 352 * if the IMU decides that a motion was not a step.
Jamie Smith 1:aac28ffd63ed 353 */
Jamie Smith 1:aac28ffd63ed 354 uint16_t stepCount;
Jamie Smith 1:aac28ffd63ed 355
Jamie Smith 1:aac28ffd63ed 356 /**
Jamie Smith 1:aac28ffd63ed 357 * Readout from the Significant Motion Detector report. This flag is set to true whenever significant motion is detected, and you should
Jamie Smith 1:aac28ffd63ed 358 * manually clear it when you have processed the event.
Jamie Smith 1:aac28ffd63ed 359 */
Jamie Smith 2:2269b723d16a 360 bool significantMotionDetected;
Jamie Smith 1:aac28ffd63ed 361
Jamie Smith 1:aac28ffd63ed 362 /**
Jamie Smith 1:aac28ffd63ed 363 * Readout from the Shake Detector report. This flag is set to true whenever shaking is detected, and you should
Jamie Smith 1:aac28ffd63ed 364 * manually clear it when you have processed the event.
Jamie Smith 1:aac28ffd63ed 365 */
Jamie Smith 2:2269b723d16a 366 bool shakeDetected;
Jamie Smith 1:aac28ffd63ed 367
Jamie Smith 1:aac28ffd63ed 368 // @{
Jamie Smith 1:aac28ffd63ed 369 /// The axis/axes that shaking was detected in in the latest shaking report.
Jamie Smith 2:2269b723d16a 370 bool xAxisShake;
Jamie Smith 2:2269b723d16a 371 bool yAxisShake;
Jamie Smith 2:2269b723d16a 372 bool zAxisShake;
Jamie Smith 1:aac28ffd63ed 373 // @}
Jamie Smith 1:aac28ffd63ed 374
Jamie Smith 1:aac28ffd63ed 375 // Management functions
Jamie Smith 1:aac28ffd63ed 376 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 377
Jamie Smith 1:aac28ffd63ed 378 /**
Jamie Smith 1:aac28ffd63ed 379 * Construct a BNO080, providing pins and parameters.
Jamie Smith 1:aac28ffd63ed 380 *
Jamie Smith 1:aac28ffd63ed 381 * This doesn't actally initialize the chip, you will need to call begin() for that.
Jamie Smith 1:aac28ffd63ed 382 *
Jamie Smith 1:aac28ffd63ed 383 * NOTE: while some schematics tell you to connect the BOOTN pin to the processor, this driver does not use or require it.
Jamie Smith 1:aac28ffd63ed 384 * Just tie it to VCC per the datasheet.
Jamie Smith 1:aac28ffd63ed 385 *
Jamie Smith 1:aac28ffd63ed 386 * @param debugPort Serial port to write output to. Cannot be nullptr.
Jamie Smith 1:aac28ffd63ed 387 * @param user_SDApin Hardware I2C SDA pin connected to the IMU
Jamie Smith 1:aac28ffd63ed 388 * @param user_SCLpin Hardware I2C SCL pin connected to the IMU
Jamie Smith 1:aac28ffd63ed 389 * @param user_INTPin Input pin connected to HINTN
Jamie Smith 1:aac28ffd63ed 390 * @param user_RSTPin Output pin connected to NRST
Jamie Smith 1:aac28ffd63ed 391 * @param i2cAddress I2C address. The BNO defaults to 0x4a, but can also be set to 0x4b via a pin.
Jamie Smith 1:aac28ffd63ed 392 * @param i2cPortSpeed I2C frequency. The BNO's max is 400kHz.
Jamie Smith 1:aac28ffd63ed 393 */
Jamie Smith 6:5ba996be5312 394 BNO080(Stream *debugPort,
Jamie Smith 1:aac28ffd63ed 395 PinName user_SDApin,
Jamie Smith 1:aac28ffd63ed 396 PinName user_SCLpin,
Jamie Smith 1:aac28ffd63ed 397 PinName user_INTPin,
Jamie Smith 1:aac28ffd63ed 398 PinName user_RSTPin,
Jamie Smith 1:aac28ffd63ed 399 uint8_t i2cAddress=0x4a,
Jamie Smith 3:197ad972fb7c 400 int i2cPortSpeed=100000);
Jamie Smith 1:aac28ffd63ed 401
Jamie Smith 1:aac28ffd63ed 402 /**
Jamie Smith 1:aac28ffd63ed 403 * Resets and connects to the IMU. Verifies that it's connected, and reads out its version
Jamie Smith 1:aac28ffd63ed 404 * info into the class variables above.
Jamie Smith 1:aac28ffd63ed 405 *
Jamie Smith 1:aac28ffd63ed 406 * If this function is failing, it would be a good idea to turn on BNO_DEBUG in the cpp file to get detailed output.
Jamie Smith 1:aac28ffd63ed 407 *
Jamie Smith 1:aac28ffd63ed 408 * @return whether or not initialization was successful
Jamie Smith 1:aac28ffd63ed 409 */
Jamie Smith 1:aac28ffd63ed 410 bool begin();
Jamie Smith 1:aac28ffd63ed 411
Jamie Smith 1:aac28ffd63ed 412 /**
Jamie Smith 1:aac28ffd63ed 413 * Tells the IMU to use its current rotation vector as the "zero" rotation vector and to reorient
Jamie Smith 1:aac28ffd63ed 414 * all outputs accordingly.
Jamie Smith 1:aac28ffd63ed 415 *
Jamie Smith 1:aac28ffd63ed 416 * @param zOnly If true, only the rotation about the Z axis (the heading) will be tared.
Jamie Smith 1:aac28ffd63ed 417 */
Jamie Smith 1:aac28ffd63ed 418 void tare(bool zOnly = false);
Jamie Smith 1:aac28ffd63ed 419
Jamie Smith 1:aac28ffd63ed 420 /**
Jamie Smith 1:aac28ffd63ed 421 * Tells the IMU to begin a dynamic sensor calibration. To calibrate the IMU, call this function and move
Jamie Smith 1:aac28ffd63ed 422 * the IMU according to the instructions in the "BNO080 Sensor Calibration Procedure" app note
Jamie Smith 1:aac28ffd63ed 423 * (http://www.hillcrestlabs.com/download/59de9014566d0727bd002ae7).
Jamie Smith 1:aac28ffd63ed 424 *
Jamie Smith 1:aac28ffd63ed 425 * To tell when the calibration is complete, look at the status bits for Game Rotation Vector (for accel and gyro)
Jamie Smith 1:aac28ffd63ed 426 * and Magnetic Field (for the magnetometer).
Jamie Smith 1:aac28ffd63ed 427 *
Jamie Smith 1:aac28ffd63ed 428 * The gyro and accelerometer should only need to be calibrated once, but the magnetometer will need to be recalibrated
Jamie Smith 1:aac28ffd63ed 429 * every time the orientation of ferrous metals around the IMU changes (e.g. when it is put into a new enclosure).
Jamie Smith 1:aac28ffd63ed 430 *
Jamie Smith 1:aac28ffd63ed 431 * The new calibration will not be saved in flash until you call saveCalibration().
Jamie Smith 1:aac28ffd63ed 432 *
Jamie Smith 1:aac28ffd63ed 433 * NOTE: calling this with all false values will cancel any calibration in progress. However, the calibration data being created will
Jamie Smith 1:aac28ffd63ed 434 * remain in use until the next chip reset (I think!)
Jamie Smith 1:aac28ffd63ed 435 *
Jamie Smith 1:aac28ffd63ed 436 * @param calibrateAccel Whether to calibrate the accelerometer.
Jamie Smith 1:aac28ffd63ed 437 * @param calibrateGyro Whether to calibrate the gyro.
Jamie Smith 1:aac28ffd63ed 438 * @param calibrateMag Whether to calibrate the magnetometer.
Jamie Smith 1:aac28ffd63ed 439 *
Jamie Smith 1:aac28ffd63ed 440 * @return whether the operation succeeded
Jamie Smith 1:aac28ffd63ed 441 */
Jamie Smith 1:aac28ffd63ed 442 bool enableCalibration(bool calibrateAccel, bool calibrateGyro, bool calibrateMag);
Jamie Smith 1:aac28ffd63ed 443
Jamie Smith 1:aac28ffd63ed 444 /**
Jamie Smith 1:aac28ffd63ed 445 * Saves the calibration started with startCalibration() and ends the calibration.
Jamie Smith 1:aac28ffd63ed 446 * You will want to call this once the status bits read as "accuracy high".
Jamie Smith 1:aac28ffd63ed 447 *
Jamie Smith 1:aac28ffd63ed 448 * WARNING: if you paid for a factory calibrated IMU, then this WILL OVERWRITE THE FACTORY CALIBRATION in whatever sensors
Jamie Smith 1:aac28ffd63ed 449 * are being calibrated. Use with caution!
Jamie Smith 1:aac28ffd63ed 450 *
Jamie Smith 1:aac28ffd63ed 451 * @return whether the operation succeeded
Jamie Smith 1:aac28ffd63ed 452 */
Jamie Smith 1:aac28ffd63ed 453 bool saveCalibration();
Jamie Smith 1:aac28ffd63ed 454
Jamie Smith 1:aac28ffd63ed 455 /**
Jamie Smith 1:aac28ffd63ed 456 * Sets the orientation quaternion, telling the sensor how it's mounted
Jamie Smith 1:aac28ffd63ed 457 * in relation to world space.
Jamie Smith 1:aac28ffd63ed 458 * See page 40 of the BNO080 datasheet.
Jamie Smith 1:aac28ffd63ed 459 *
Jamie Smith 1:aac28ffd63ed 460 * NOTE: this driver provides the macro SQRT_2 to help with entering values from that table.
Jamie Smith 1:aac28ffd63ed 461 *
Jamie Smith 1:aac28ffd63ed 462 * NOTE 2: this setting does not persist and will have to be re-applied every time the chip is reset.
Jamie Smith 3:197ad972fb7c 463 * Use setPermanentOrientation() for that.
Jamie Smith 1:aac28ffd63ed 464 *
Jamie Smith 1:aac28ffd63ed 465 * @param orientation quaternion mapping from IMU space to world space.
Jamie Smith 1:aac28ffd63ed 466 */
Jamie Smith 1:aac28ffd63ed 467 void setSensorOrientation(Quaternion orientation);
Jamie Smith 1:aac28ffd63ed 468
Jamie Smith 3:197ad972fb7c 469 /**
Jamie Smith 3:197ad972fb7c 470 * Sets the orientation quaternion, telling the sensor how it's mounted
Jamie Smith 3:197ad972fb7c 471 * in relation to world space. See page 40 of the BNO080 datasheet.
Jamie Smith 3:197ad972fb7c 472 *
Jamie Smith 3:197ad972fb7c 473 * Unlike setSensorOrientation(), this setting will persist across sensor restarts.
Jamie Smith 3:197ad972fb7c 474 * However, it will also take a few hundred milliseconds to write.
Jamie Smith 3:197ad972fb7c 475 *
Jamie Smith 3:197ad972fb7c 476 * @param orientation quaternion mapping from IMU space to world space.
Jamie Smith 3:197ad972fb7c 477 *
Jamie Smith 3:197ad972fb7c 478 * @return true if the operation succeeded, false if it failed.
Jamie Smith 3:197ad972fb7c 479 */
Jamie Smith 3:197ad972fb7c 480 bool setPermanentOrientation(Quaternion orientation);
Jamie Smith 3:197ad972fb7c 481
Jamie Smith 1:aac28ffd63ed 482 // Report functions
Jamie Smith 1:aac28ffd63ed 483 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 484
Jamie Smith 1:aac28ffd63ed 485 /**
Jamie Smith 1:aac28ffd63ed 486 * Checks for new data packets queued on the IMU.
Jamie Smith 1:aac28ffd63ed 487 * If there are packets queued, receives all of them and updates
Jamie Smith 1:aac28ffd63ed 488 * the class variables with the results.
Jamie Smith 1:aac28ffd63ed 489 *
Jamie Smith 1:aac28ffd63ed 490 * @return True iff new data packets of any kind were received. If you need more fine-grained data change reporting,
Jamie Smith 1:aac28ffd63ed 491 * check out hasNewData().
Jamie Smith 1:aac28ffd63ed 492 */
Jamie Smith 1:aac28ffd63ed 493 bool updateData();
Jamie Smith 1:aac28ffd63ed 494
Jamie Smith 1:aac28ffd63ed 495
Jamie Smith 1:aac28ffd63ed 496 /**
Jamie Smith 1:aac28ffd63ed 497 * Gets the status of a report as a 2 bit number.
Jamie Smith 1:aac28ffd63ed 498 * per SH-2 section 6.5.1, this is interpreted as: <br>
Jamie Smith 1:aac28ffd63ed 499 * 0 - unreliable <br>
Jamie Smith 1:aac28ffd63ed 500 * 1 - accuracy low <br>
Jamie Smith 1:aac28ffd63ed 501 * 2 - accuracy medium <br>
Jamie Smith 1:aac28ffd63ed 502 * 3 - accuracy high <br>
Jamie Smith 1:aac28ffd63ed 503 * of course, these are only updated if a given report is enabled.
Jamie Smith 1:aac28ffd63ed 504 * @param report
Jamie Smith 1:aac28ffd63ed 505 * @return
Jamie Smith 1:aac28ffd63ed 506 */
Jamie Smith 1:aac28ffd63ed 507 uint8_t getReportStatus(Report report);
Jamie Smith 1:aac28ffd63ed 508
Jamie Smith 1:aac28ffd63ed 509 /**
Jamie Smith 1:aac28ffd63ed 510 * Get a string for printout describing the status of a sensor.
Jamie Smith 1:aac28ffd63ed 511 * @return
Jamie Smith 1:aac28ffd63ed 512 */
Jamie Smith 1:aac28ffd63ed 513 const char* getReportStatusString(Report report);
Jamie Smith 1:aac28ffd63ed 514
Jamie Smith 1:aac28ffd63ed 515 /**
Jamie Smith 1:aac28ffd63ed 516 * Checks if a specific report has gotten new data since the last call to this function.
Jamie Smith 1:aac28ffd63ed 517 * @param report The report to check.
Jamie Smith 1:aac28ffd63ed 518 * @return Whether the report has received new data.
Jamie Smith 1:aac28ffd63ed 519 */
Jamie Smith 1:aac28ffd63ed 520 bool hasNewData(Report report);
Jamie Smith 1:aac28ffd63ed 521
Jamie Smith 1:aac28ffd63ed 522 /**
Jamie Smith 1:aac28ffd63ed 523 * Enable a data report from the IMU. Look at the comments above to see what the reports do.
Jamie Smith 1:aac28ffd63ed 524 * This function checks your polling period against the report's max speed in the IMU's metadata,
Jamie Smith 1:aac28ffd63ed 525 * and reports an error if you're trying to poll too fast.
Jamie Smith 1:aac28ffd63ed 526 *
Jamie Smith 1:aac28ffd63ed 527 * @param timeBetweenReports time in milliseconds between data updates.
Jamie Smith 1:aac28ffd63ed 528 */
Jamie Smith 1:aac28ffd63ed 529 void enableReport(Report report, uint16_t timeBetweenReports);
Jamie Smith 1:aac28ffd63ed 530
Jamie Smith 1:aac28ffd63ed 531 /**
Jamie Smith 1:aac28ffd63ed 532 * Disable a data report from the IMU.
Jamie Smith 1:aac28ffd63ed 533 *
Jamie Smith 1:aac28ffd63ed 534 * @param report The report to disable.
Jamie Smith 1:aac28ffd63ed 535 */
Jamie Smith 1:aac28ffd63ed 536 void disableReport(Report report);
Jamie Smith 1:aac28ffd63ed 537
Jamie Smith 1:aac28ffd63ed 538 /**
Jamie Smith 1:aac28ffd63ed 539 * Gets the serial number (used to uniquely identify each individual device).
Jamie Smith 1:aac28ffd63ed 540 *
Jamie Smith 1:aac28ffd63ed 541 * NOTE: this function should work according to the datasheet, but the device I was testing with appears to have
Jamie Smith 1:aac28ffd63ed 542 * an empty serial number record as shipped, and I could never get anything out of it. Your mileage may vary.
Jamie Smith 1:aac28ffd63ed 543 *
Jamie Smith 1:aac28ffd63ed 544 * @return The serial number, or 0 on error.
Jamie Smith 1:aac28ffd63ed 545 */
Jamie Smith 1:aac28ffd63ed 546 uint32_t getSerialNumber();
Jamie Smith 1:aac28ffd63ed 547
Jamie Smith 1:aac28ffd63ed 548 // Metadata functions
Jamie Smith 1:aac28ffd63ed 549 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 550
Jamie Smith 1:aac28ffd63ed 551 /**
Jamie Smith 1:aac28ffd63ed 552 * Gets the range of a report as reported by the IMU. Units are the same as the report's output data.
Jamie Smith 1:aac28ffd63ed 553 * @return
Jamie Smith 1:aac28ffd63ed 554 */
Jamie Smith 1:aac28ffd63ed 555 float getRange(Report report);
Jamie Smith 1:aac28ffd63ed 556
Jamie Smith 1:aac28ffd63ed 557 /**
Jamie Smith 1:aac28ffd63ed 558 * Gets the resolution of a report as reported by the IMU. Units are the same as the report's output data.
Jamie Smith 1:aac28ffd63ed 559 * @param report
Jamie Smith 1:aac28ffd63ed 560 * @return
Jamie Smith 1:aac28ffd63ed 561 */
Jamie Smith 1:aac28ffd63ed 562 float getResolution(Report report);
Jamie Smith 1:aac28ffd63ed 563
Jamie Smith 1:aac28ffd63ed 564 /**
Jamie Smith 1:aac28ffd63ed 565 * Get the power used by a report when it's operating, according to the IMU.
Jamie Smith 1:aac28ffd63ed 566 * @param report
Jamie Smith 1:aac28ffd63ed 567 * @return Power used in mA.
Jamie Smith 1:aac28ffd63ed 568 */
Jamie Smith 1:aac28ffd63ed 569 float getPower(Report report);
Jamie Smith 1:aac28ffd63ed 570
Jamie Smith 1:aac28ffd63ed 571 /**
Jamie Smith 1:aac28ffd63ed 572 * Gets the smallest polling period that a report supports.
Jamie Smith 1:aac28ffd63ed 573 * @return Period in seconds.
Jamie Smith 1:aac28ffd63ed 574 */
Jamie Smith 1:aac28ffd63ed 575 float getMinPeriod(Report report);
Jamie Smith 1:aac28ffd63ed 576
Jamie Smith 1:aac28ffd63ed 577 /**
Jamie Smith 1:aac28ffd63ed 578 * Gets the larges polling period that a report supports.
Jamie Smith 1:aac28ffd63ed 579 * Some reports don't have a max period, in which case this function will return -1.0.
Jamie Smith 1:aac28ffd63ed 580 *
Jamie Smith 1:aac28ffd63ed 581 * @return Period in seconds, or -1.0 on error.
Jamie Smith 1:aac28ffd63ed 582 */
Jamie Smith 1:aac28ffd63ed 583 float getMaxPeriod(Report report);
Jamie Smith 1:aac28ffd63ed 584
Jamie Smith 1:aac28ffd63ed 585 /**
Jamie Smith 1:aac28ffd63ed 586 * Prints a summary of a report's metadata to the
Jamie Smith 1:aac28ffd63ed 587 * debug stream. Should be useful for debugging and setting up reports since lots of this data
Jamie Smith 1:aac28ffd63ed 588 * isn't given in the datasheets.
Jamie Smith 1:aac28ffd63ed 589 *
Jamie Smith 1:aac28ffd63ed 590 * Note: to save string constant space, this function is only available when BNO_DEBUG is 1.
Jamie Smith 1:aac28ffd63ed 591 */
Jamie Smith 1:aac28ffd63ed 592 void printMetadataSummary(Report report);
Jamie Smith 1:aac28ffd63ed 593
Jamie Smith 1:aac28ffd63ed 594 private:
Jamie Smith 1:aac28ffd63ed 595
Jamie Smith 1:aac28ffd63ed 596 // Internal metadata functions
Jamie Smith 1:aac28ffd63ed 597 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 598
Jamie Smith 1:aac28ffd63ed 599 /**
Jamie Smith 1:aac28ffd63ed 600 * Gets the version of the metadata stored in the buffer.
Jamie Smith 1:aac28ffd63ed 601 * We might see version 3 and 4 records, and they have different layouts.
Jamie Smith 1:aac28ffd63ed 602 * @return
Jamie Smith 1:aac28ffd63ed 603 */
Jamie Smith 1:aac28ffd63ed 604 uint16_t getMetaVersion() {return static_cast<uint16_t>(metadataRecord[3] >> 16);}
Jamie Smith 1:aac28ffd63ed 605
Jamie Smith 1:aac28ffd63ed 606 // @{
Jamie Smith 1:aac28ffd63ed 607 /**
Jamie Smith 1:aac28ffd63ed 608 * Gets the Q point from a report's metadata, which essentially defines where the decimal point goes in the sensor's output.
Jamie Smith 1:aac28ffd63ed 609 * The 1/2/3 Q values are used in different places in the metadata, see SH-2 section 5.1 for details.
Jamie Smith 1:aac28ffd63ed 610 * @param report
Jamie Smith 1:aac28ffd63ed 611 * @return
Jamie Smith 1:aac28ffd63ed 612 */
Jamie Smith 1:aac28ffd63ed 613 int16_t getQ1(Report report);
Jamie Smith 1:aac28ffd63ed 614 int16_t getQ2(Report report);
Jamie Smith 1:aac28ffd63ed 615 int16_t getQ3(Report report);
Jamie Smith 1:aac28ffd63ed 616 // @}
Jamie Smith 1:aac28ffd63ed 617
Jamie Smith 1:aac28ffd63ed 618 // internal utility functions
Jamie Smith 1:aac28ffd63ed 619 //-----------------------------------------------------------------------------------------------------------------
Jamie Smith 1:aac28ffd63ed 620
Jamie Smith 1:aac28ffd63ed 621 /**
Jamie Smith 1:aac28ffd63ed 622 * Processes the packet currently stored in the buffer, and updates class variables to reflect the data it contains
Jamie Smith 1:aac28ffd63ed 623 */
Jamie Smith 1:aac28ffd63ed 624 void processPacket();
Jamie Smith 1:aac28ffd63ed 625
Jamie Smith 1:aac28ffd63ed 626 /**
Jamie Smith 1:aac28ffd63ed 627 * Processes the sensor data packet currently stored in the buffer.
Jamie Smith 1:aac28ffd63ed 628 * Only called from processPacket()
Jamie Smith 1:aac28ffd63ed 629 */
Jamie Smith 1:aac28ffd63ed 630 void parseSensorDataPacket();
Jamie Smith 1:aac28ffd63ed 631
Jamie Smith 1:aac28ffd63ed 632 /**
Jamie Smith 1:aac28ffd63ed 633 * Call to wait for a packet with the given parameters to come in.
Jamie Smith 1:aac28ffd63ed 634 *
Jamie Smith 1:aac28ffd63ed 635 * @param channel Channel of the packet
Jamie Smith 1:aac28ffd63ed 636 * @param reportID Report ID (first data byte) of the packet
Jamie Smith 1:aac28ffd63ed 637 * @param timeout how long to wait for the packet
Jamie Smith 1:aac28ffd63ed 638 * @return true if the packet has been received, false if it timed out
Jamie Smith 1:aac28ffd63ed 639 */
Jamie Smith 1:aac28ffd63ed 640 bool waitForPacket(int channel, uint8_t reportID, float timeout = .125f);
Jamie Smith 1:aac28ffd63ed 641
Jamie Smith 1:aac28ffd63ed 642 /**
Jamie Smith 1:aac28ffd63ed 643 * Given a Q value, converts fixed point floating to regular floating point number.
Jamie Smith 1:aac28ffd63ed 644 * @param fixedPointValue
Jamie Smith 1:aac28ffd63ed 645 * @param qPoint
Jamie Smith 1:aac28ffd63ed 646 * @return
Jamie Smith 1:aac28ffd63ed 647 */
Jamie Smith 1:aac28ffd63ed 648 float qToFloat(int16_t fixedPointValue, uint8_t qPoint);
Jamie Smith 1:aac28ffd63ed 649
Jamie Smith 1:aac28ffd63ed 650 /**
Jamie Smith 1:aac28ffd63ed 651 * Given a Q value, converts fixed point floating to regular floating point number.
Jamie Smith 1:aac28ffd63ed 652 * This version is used for the unsigned 32-bit values in metadata records.
Jamie Smith 1:aac28ffd63ed 653 * @param fixedPointValue
Jamie Smith 1:aac28ffd63ed 654 * @param qPoint
Jamie Smith 1:aac28ffd63ed 655 * @return
Jamie Smith 1:aac28ffd63ed 656 */
Jamie Smith 1:aac28ffd63ed 657 float qToFloat_dword(uint32_t fixedPointValue, int16_t qPoint);
Jamie Smith 1:aac28ffd63ed 658
Jamie Smith 1:aac28ffd63ed 659 /**
Jamie Smith 1:aac28ffd63ed 660 * Given a floating point value and a Q point, convert to Q
Jamie Smith 1:aac28ffd63ed 661 * See https://en.wikipedia.org/wiki/Q_(number_format)
Jamie Smith 1:aac28ffd63ed 662 * @param qFloat
Jamie Smith 1:aac28ffd63ed 663 * @param qPoint
Jamie Smith 1:aac28ffd63ed 664 * @return
Jamie Smith 1:aac28ffd63ed 665 */
Jamie Smith 1:aac28ffd63ed 666 int16_t floatToQ(float qFloat, uint8_t qPoint);
Jamie Smith 1:aac28ffd63ed 667
Jamie Smith 1:aac28ffd63ed 668 /**
Jamie Smith 3:197ad972fb7c 669 * Given a floating point value and a Q point, convert to Q
Jamie Smith 3:197ad972fb7c 670 * See https://en.wikipedia.org/wiki/Q_(number_format)
Jamie Smith 3:197ad972fb7c 671 *
Jamie Smith 3:197ad972fb7c 672 * This version is used for the signed 32-bit values in metadata records.
Jamie Smith 3:197ad972fb7c 673 *
Jamie Smith 3:197ad972fb7c 674 * @param qFloat
Jamie Smith 3:197ad972fb7c 675 * @param qPoint
Jamie Smith 3:197ad972fb7c 676 * @return
Jamie Smith 3:197ad972fb7c 677 */
Jamie Smith 3:197ad972fb7c 678 int32_t floatToQ_dword(float qFloat, uint16_t qPoint);
Jamie Smith 3:197ad972fb7c 679
Jamie Smith 3:197ad972fb7c 680 /**
Jamie Smith 1:aac28ffd63ed 681 * Tell the sensor to do a command.
Jamie Smith 1:aac28ffd63ed 682 * See SH-2 Reference Manual section 6.3.8 page 42, Command request
Jamie Smith 1:aac28ffd63ed 683 * The caller is expected to set shtpData 3 though 11 prior to calling
Jamie Smith 1:aac28ffd63ed 684 */
Jamie Smith 1:aac28ffd63ed 685 void sendCommand(uint8_t command);
Jamie Smith 1:aac28ffd63ed 686
Jamie Smith 1:aac28ffd63ed 687 /**
Jamie Smith 1:aac28ffd63ed 688 * Given a sensor's report ID, this tells the BNO080 to begin reporting the values.
Jamie Smith 1:aac28ffd63ed 689 *
Jamie Smith 1:aac28ffd63ed 690 * @param reportID
Jamie Smith 1:aac28ffd63ed 691 * @param timeBetweenReports
Jamie Smith 1:aac28ffd63ed 692 * @param specificConfig the specific config word. Useful for personal activity classifier.
Jamie Smith 1:aac28ffd63ed 693 */
Jamie Smith 1:aac28ffd63ed 694 void setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports, uint32_t specificConfig = 0);
Jamie Smith 1:aac28ffd63ed 695
Jamie Smith 1:aac28ffd63ed 696 /**
Jamie Smith 1:aac28ffd63ed 697 * Read a record from the FRS (Flash Record System) on the IMU. FRS records are composed of 32-bit words,
Jamie Smith 1:aac28ffd63ed 698 * with the size of each record determined by the record type.
Jamie Smith 1:aac28ffd63ed 699 *
Jamie Smith 1:aac28ffd63ed 700 * Will block until the entire record has been read.
Jamie Smith 1:aac28ffd63ed 701 * @param recordID Record ID to read. See SH-2 figures 28 and 29 for a list of these. Sometimes also called
Jamie Smith 1:aac28ffd63ed 702 * the "FRS Type" by the datasheet (???).
Jamie Smith 1:aac28ffd63ed 703 * @param readBuffer Buffer to read data into.
Jamie Smith 1:aac28ffd63ed 704 * @param readLength Amount of words to read from the record. Must be <= the length of the record.
Jamie Smith 1:aac28ffd63ed 705 *
Jamie Smith 1:aac28ffd63ed 706 * @return whether the request succeeded
Jamie Smith 1:aac28ffd63ed 707 */
Jamie Smith 1:aac28ffd63ed 708 bool readFRSRecord(uint16_t recordID, uint32_t* readBuffer, uint16_t readLength);
Jamie Smith 1:aac28ffd63ed 709
Jamie Smith 1:aac28ffd63ed 710 /**
Jamie Smith 3:197ad972fb7c 711 * Write a record to the FRS (Flash Record System) on the IMU. FRS records are composed of 32-bit words,
Jamie Smith 3:197ad972fb7c 712 * with the size of each record determined by the record type.
Jamie Smith 3:197ad972fb7c 713 *
Jamie Smith 3:197ad972fb7c 714 * Will block until the entire record has been written.
Jamie Smith 3:197ad972fb7c 715 * @param recordID Record ID to write. See SH-2 figures 28 and 29 for a list of these. Sometimes also called
Jamie Smith 3:197ad972fb7c 716 * the "FRS Type" by the datasheet (???).
Jamie Smith 3:197ad972fb7c 717 * @param buffer Buffer to write data into.
Jamie Smith 3:197ad972fb7c 718 * @param length Amount of words to write to the record. Must be <= the length of the record.
Jamie Smith 3:197ad972fb7c 719 *
Jamie Smith 3:197ad972fb7c 720 * @return whether the request succeeded
Jamie Smith 3:197ad972fb7c 721 */
Jamie Smith 3:197ad972fb7c 722 bool writeFRSRecord(uint16_t recordID, uint32_t* buffer, uint16_t length);
Jamie Smith 3:197ad972fb7c 723
Jamie Smith 3:197ad972fb7c 724 /**
Jamie Smith 1:aac28ffd63ed 725 * Reads a packet from the IMU and stores it in the class variables.
Jamie Smith 1:aac28ffd63ed 726 *
Jamie Smith 1:aac28ffd63ed 727 * @param timeout how long to wait for there to be a packet
Jamie Smith 1:aac28ffd63ed 728 *
Jamie Smith 1:aac28ffd63ed 729 * @return whether a packet was recieved.
Jamie Smith 1:aac28ffd63ed 730 */
Jamie Smith 1:aac28ffd63ed 731 bool receivePacket(float timeout=.2f);
Jamie Smith 1:aac28ffd63ed 732
Jamie Smith 1:aac28ffd63ed 733 /**
Jamie Smith 1:aac28ffd63ed 734 * Sends the current shtpData contents to the BNO. It's a good idea to disable interrupts before you call this.
Jamie Smith 1:aac28ffd63ed 735 *
Jamie Smith 1:aac28ffd63ed 736 * @param channelNumber the channel to send on
Jamie Smith 1:aac28ffd63ed 737 * @param dataLength How many bits of shtpData to send
Jamie Smith 1:aac28ffd63ed 738 * @return
Jamie Smith 1:aac28ffd63ed 739 */
Jamie Smith 1:aac28ffd63ed 740 bool sendPacket(uint8_t channelNumber, uint8_t dataLength);
Jamie Smith 1:aac28ffd63ed 741
Jamie Smith 1:aac28ffd63ed 742 /**
Jamie Smith 1:aac28ffd63ed 743 * Prints the current shtp packet stored in the buffer.
Jamie Smith 1:aac28ffd63ed 744 * @param length
Jamie Smith 1:aac28ffd63ed 745 */
Jamie Smith 1:aac28ffd63ed 746 void printPacket();
Jamie Smith 1:aac28ffd63ed 747
Jamie Smith 1:aac28ffd63ed 748 /**
Jamie Smith 1:aac28ffd63ed 749 * Erases the current SHTP packet buffer so new data can be written
Jamie Smith 1:aac28ffd63ed 750 */
Jamie Smith 1:aac28ffd63ed 751 void zeroBuffer();
Jamie Smith 1:aac28ffd63ed 752
Jamie Smith 1:aac28ffd63ed 753 /**
Jamie Smith 1:aac28ffd63ed 754 * Loads the metadata for this report into the metadata buffer.
Jamie Smith 1:aac28ffd63ed 755 * @param report
Jamie Smith 1:aac28ffd63ed 756 * @return Whether the operation succeeded.
Jamie Smith 1:aac28ffd63ed 757 */
Jamie Smith 1:aac28ffd63ed 758 bool loadReportMetadata(Report report);
Jamie Smith 1:aac28ffd63ed 759
Jamie Smith 1:aac28ffd63ed 760 };
Jamie Smith 1:aac28ffd63ed 761
Jamie Smith 1:aac28ffd63ed 762
Jamie Smith 1:aac28ffd63ed 763 #endif //HAMSTER_BNO080_H