Example/test programs for my BNO080 driver.

Dependencies:   BNO080

BNO080 Driver Examples

These examples show how to use some of the functionality on my BNO080 driver. To get started with MBed CLI:

Build Instructions

$ hg clone https://MultipleMonomials@os.mbed.com/users/MultipleMonomials/code/BNO080-Examples/
$ cd BNO080-Examples
$ mbed deploy
$ mbed compile

Files at this revision

API Documentation at this revision

Comitter:
Jamie Smith
Date:
Tue Nov 24 15:27:32 2020 -0800
Parent:
4:85b98cc04a0a
Commit message:
Update for BNO080Async

Changed in this revision

BNO080.lib Show annotated file Show diff for this revision Revisions of this file
BNOTestSuite.cpp Show annotated file Show diff for this revision Revisions of this file
BNOTestSuite.h Show annotated file Show diff for this revision Revisions of this file
--- a/BNO080.lib	Tue Jul 21 22:00:26 2020 -0700
+++ b/BNO080.lib	Tue Nov 24 15:27:32 2020 -0800
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/MultipleMonomials/code/BNO080/#a121b6c8d662
+https://os.mbed.com/users/MultipleMonomials/code/BNO080/#430f5302f9e1
--- a/BNOTestSuite.cpp	Tue Jul 21 22:00:26 2020 -0700
+++ b/BNOTestSuite.cpp	Tue Nov 24 15:27:32 2020 -0800
@@ -22,13 +22,20 @@
 {
 	const size_t update_rate_ms = 200;
 
-	imu.enableReport(BNO080::ROTATION, update_rate_ms);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::ROTATION, update_rate_ms);
+	imu.unlockMutex();
 
 	while (true)
 	{
-		ThisThread::sleep_for(1ms * update_rate_ms);
+		// note: this sleep here is important!
+		// It prevents the mutex from being locked 100% of the time, which
+		// would keep the IMU's thread from running.
+		ThisThread::sleep_for((1ms * update_rate_ms) / 2);
 
-        if(imu.updateData())
+		imu.lockMutex();
+		imu.updateData();
+        if(imu.hasNewData(BNO080::ROTATION))
 		{
         	TVector3 eulerRadians = imu.rotationVector.euler();
         	TVector3 eulerDegrees = eulerRadians * RAD_TO_DEG;
@@ -38,27 +45,27 @@
 
         	pc.printf(", Accuracy: %.02f", (imu.rotationAccuracy * RAD_TO_DEG));
 
-        	pc.printf(", Status: %s\n", imu.getReportStatusString(BNO080::ROTATION));
+        	pc.printf(", Status: %s\n", imu.getReportStatusString(BNO080Base::ROTATION));
 		}
-		else
-		{
-			pc.printf("IMU was not ready with data packet!\r\n");
-		}
-    }
+		imu.unlockMutex();
+	}
 }
 
 void BNOTestSuite::test_readRotationAcceleration()
 {
-	imu.enableReport(BNO080::ROTATION, 1000);
-	imu.enableReport(BNO080::TOTAL_ACCELERATION, 500);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::ROTATION, 1000);
+	imu.enableReport(BNO080Base::TOTAL_ACCELERATION, 500);
+	imu.unlockMutex();
 
 	while (true)
 	{
 		ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
-			if (imu.hasNewData(BNO080::ROTATION))
+			if (imu.hasNewData(BNO080Base::ROTATION))
 			{
 				pc.printf("IMU Rotation Euler: ");
 				TVector3 eulerRadians = imu.rotationVector.euler();
@@ -66,23 +73,29 @@
 				eulerDegrees.print(pc, true);
 				pc.printf("\n");
 			}
-			if (imu.hasNewData(BNO080::TOTAL_ACCELERATION))
+			if (imu.hasNewData(BNO080Base::TOTAL_ACCELERATION))
 			{
 				pc.printf("IMU Total Acceleration: ");
 				imu.totalAcceleration.print(pc, true);
 				pc.printf("\n");
 			}
 		}
+		imu.unlockMutex();
 	}
 }
 
 void BNOTestSuite::test_tapDetector()
 {
-	imu.enableReport(BNO080::TAP_DETECTOR, 10);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::TAP_DETECTOR, 10);
+	imu.unlockMutex();
+
 	pc.printf("Listening for taps...\n");
 
 	while(true)
 	{
+		ThisThread::sleep_for(1ms);
+		imu.lockMutex();
 		if(imu.updateData())
 		{
 			if(imu.tapDetected)
@@ -91,6 +104,7 @@
 				imu.tapDetected = false;
 			}
 		}
+		imu.unlockMutex();
 	}
 }
 
@@ -98,12 +112,15 @@
 {
 	const size_t update_rate_ms = 200;
 
-	imu.enableReport(BNO080::GAME_ROTATION, update_rate_ms);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::GAME_ROTATION, update_rate_ms);
+	imu.unlockMutex();
 
 	while (true)
 	{
-		ThisThread::sleep_for(1ms * update_rate_ms);
+		ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
 			pc.printf("IMU Game Rotation Euler: [");
@@ -111,19 +128,18 @@
 			TVector3 eulerDegrees = eulerRadians * RAD_TO_DEG;
 			eulerDegrees.print(pc, true);
 
-			pc.printf("], Status: %s\n", imu.getReportStatusString(BNO080::GAME_ROTATION));
+			pc.printf("], Status: %s\n", imu.getReportStatusString(BNO080Base::GAME_ROTATION));
 		}
-		else
-		{
-			pc.printf("IMU was not ready with data packet!\r\n");
-		}
+		imu.unlockMutex();
 	}
 }
 
 void BNOTestSuite::test_tare()
 {
 	const size_t update_rate_ms = 100;
-	imu.enableReport(BNO080::ROTATION, update_rate_ms);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::ROTATION, update_rate_ms);
+	imu.unlockMutex();
 
 	Timer runningTime;
 	runningTime.start();
@@ -132,8 +148,9 @@
 
 	while (true)
 	{
-		ThisThread::sleep_for(1ms * update_rate_ms);
+		ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
 			pc.printf("IMU Rotation Euler: [");
@@ -141,31 +158,31 @@
 			TVector3 eulerDegrees = eulerRadians * RAD_TO_DEG;
 			eulerDegrees.print(pc, true);
 
-			pc.printf("], Status: %s\n", imu.getReportStatusString(BNO080::ROTATION));
-		}
-		else
-		{
-			pc.printf("IMU was not ready with data packet!\r\n");
+			pc.printf("], Status: %s\n", imu.getReportStatusString(BNO080Base::ROTATION));
 		}
 
-		if(runningTime.read() > 2 && !sentTareCmd)
+		if(runningTime.elapsed_time() > 2s && !sentTareCmd)
 		{
 			pc.printf("2 seconds have passed, sending tare command...\n");
 			imu.tare();
 			sentTareCmd = true;
 		}
+		imu.unlockMutex();
 	}
 }
 
 void BNOTestSuite::test_magCalibration()
 {
 	// enable calibration for the magnetometer
+	imu.lockMutex();
 	bool success = imu.enableCalibration(false, false, true);
 
 	const size_t update_rate_ms = 200;
-	imu.enableReport(BNO080::GAME_ROTATION, update_rate_ms);
-	imu.enableReport(BNO080::MAG_FIELD, update_rate_ms);
-	imu.enableReport(BNO080::MAG_FIELD_UNCALIBRATED, update_rate_ms);
+	imu.enableReport(BNO080Base::GAME_ROTATION, update_rate_ms);
+	imu.enableReport(BNO080Base::MAG_FIELD, update_rate_ms);
+	imu.enableReport(BNO080Base::MAG_FIELD_UNCALIBRATED, update_rate_ms);
+
+	imu.unlockMutex();
 
 	if(success)
 	{
@@ -179,14 +196,15 @@
 
 	while (true)
 	{
-		ThisThread::sleep_for(1ms * update_rate_ms);
+		ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
 			pc.printf("IMU Magnetic Field: [");
 			imu.magFieldUncalibrated.print(pc, true);
 
-			pc.printf("] uTesla, Status: %hhu (should be 2-3 when calibration is complete), ", imu.getReportStatus(BNO080::MAG_FIELD));
+			pc.printf("] uTesla, Status: %hhu (should be 2-3 when calibration is complete), ", imu.getReportStatus(BNO080Base::MAG_FIELD));
 
 			pc.printf("Hard iron offsets: [");
 			imu.hardIronOffset.print(pc, true);
@@ -194,73 +212,80 @@
 			pc.printf("]\n");
 
 		}
-		else
-		{
-			pc.printf("IMU was not ready with data packet!\r\n");
-		}
+		imu.unlockMutex();
+
 	}
 
 }
 
 void BNOTestSuite::test_stabilityClassifier()
 {
-	imu.enableReport(BNO080::STABILITY_CLASSIFIER, 200);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::STABILITY_CLASSIFIER, 200);
+	imu.unlockMutex();
 
 	while (true)
 	{
         ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
-			if (imu.hasNewData(BNO080::STABILITY_CLASSIFIER))
+			if (imu.hasNewData(BNO080Base::STABILITY_CLASSIFIER))
 			{
 				pc.printf("Stability: ");
 
 				switch(imu.stability)
 				{
-					case BNO080::UNKNOWN:
+					case BNO080Base::UNKNOWN:
 						pc.printf("Unknown\n");
 						break;
-					case BNO080::ON_TABLE:
+					case BNO080Base::ON_TABLE:
 						pc.printf("On Table\n");
 						break;
-					case BNO080::STATIONARY:
+					case BNO080Base::STATIONARY:
 						pc.printf("Stationary\n");
 						break;
-					case BNO080::STABLE:
+					case BNO080Base::STABLE:
 						pc.printf("Stable\n");
 						break;
-					case BNO080::MOTION:
+					case BNO080Base::MOTION:
 						pc.printf("Motion\n");
 						break;
 				}
 			}
 		}
+		imu.unlockMutex();
+
 	}
 
 }
 
 void BNOTestSuite::test_metadata()
 {
+	imu.lockMutex();
 	pc.printf("Printing metadata for Linear Acceleration:\r\n");
-	imu.printMetadataSummary(BNO080::LINEAR_ACCELERATION);
+	imu.printMetadataSummary(BNO080Base::LINEAR_ACCELERATION);
 
 	pc.printf("Printing metadata for Rotation Vector:\r\n");
-	imu.printMetadataSummary(BNO080::ROTATION);
+	imu.printMetadataSummary(BNO080Base::ROTATION);
 
 	pc.printf("Printing metadata for Magnetic Field:\r\n");
-	imu.printMetadataSummary(BNO080::MAG_FIELD);
+	imu.printMetadataSummary(BNO080Base::MAG_FIELD);
 
 	pc.printf("Printing metadata for Tap Detector:\r\n");
-	imu.printMetadataSummary(BNO080::TAP_DETECTOR);
+	imu.printMetadataSummary(BNO080Base::TAP_DETECTOR);
+	imu.unlockMutex();
 
 }
 
 void BNOTestSuite::test_orientation()
 {
 	const size_t update_rate_ms = 200;
-	imu.enableReport(BNO080::TOTAL_ACCELERATION, update_rate_ms);
-	imu.enableReport(BNO080::ROTATION, update_rate_ms);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::TOTAL_ACCELERATION, update_rate_ms);
+	imu.enableReport(BNO080Base::ROTATION, update_rate_ms);
+	imu.unlockMutex();
 
 	Timer runningTime;
 	runningTime.start();
@@ -269,11 +294,12 @@
 
 	while (true)
 	{
-		ThisThread::sleep_for(1ms * update_rate_ms);
+		ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
-			if (imu.hasNewData(BNO080::ROTATION))
+			if (imu.hasNewData(BNO080Base::ROTATION))
 			{
 				pc.printf("IMU Rotation Euler: ");
 				TVector3 eulerRadians = imu.rotationVector.euler();
@@ -281,7 +307,7 @@
 				eulerDegrees.print(pc, true);
 				pc.printf("\n");
 			}
-			if (imu.hasNewData(BNO080::TOTAL_ACCELERATION))
+			if (imu.hasNewData(BNO080Base::TOTAL_ACCELERATION))
 			{
 				pc.printf("IMU Total Acceleration: ");
 				imu.totalAcceleration.print(pc, true);
@@ -289,7 +315,7 @@
 			}
 		}
 
-		if(runningTime.read() > 2 && !setOrientation)
+		if(runningTime.elapsed_time() > 2s && !setOrientation)
 		{
 			pc.printf("2 seconds have passed, sending set orientation command...\n");
 			setOrientation = true;
@@ -298,6 +324,7 @@
 			// (values from BNO datasheet page 41)
 			imu.setSensorOrientation(Quaternion(0, -1, 0, 0));
 		}
+		imu.unlockMutex();
 	}
 }
 
@@ -314,21 +341,25 @@
 	// rotate sensor 180 degrees about Y axis
 	//with these quaternion values x axis is oriented to point toward BRB, Z points up and Y points out towards you when you face the unit
 	// see page 5 and 11 of hillcrestlabs FSM30X datasheet
-	imu.setPermanentOrientation(Quaternion(0,-1, 0, 0)); 
-	
+	imu.lockMutex();
+	imu.setPermanentOrientation(Quaternion(0,-1, 0, 0));
+	imu.unlockMutex();
+
 	// reset to default orientation
 	//imu.setPermanentOrientation(Quaternion(0, 0, 0, 0));
 
 	orientationTimer.stop();
-	pc.printf("Done setting orientation (took %.03f seconds)\r\n", orientationTimer.read());
+	pc.printf("Done setting orientation (took %.03f seconds)\r\n", std::chrono::duration<float>{orientationTimer.elapsed_time()}.count());
 
 }
 
 void BNOTestSuite::test_disable()
 {
 	const size_t update_rate_ms = 200;
-	imu.enableReport(BNO080::TOTAL_ACCELERATION, update_rate_ms);
-	imu.enableReport(BNO080::ROTATION, update_rate_ms);
+	imu.lockMutex();
+	imu.enableReport(BNO080Base::TOTAL_ACCELERATION, update_rate_ms);
+	imu.enableReport(BNO080Base::ROTATION, update_rate_ms);
+	imu.unlockMutex();
 
 	Timer runningTime;
 	runningTime.start();
@@ -339,9 +370,10 @@
 	{
 		ThisThread::sleep_for(1ms * update_rate_ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
-			if (imu.hasNewData(BNO080::ROTATION))
+			if (imu.hasNewData(BNO080Base::ROTATION))
 			{
 				pc.printf("IMU Rotation Euler: ");
 				TVector3 eulerRadians = imu.rotationVector.euler();
@@ -349,7 +381,7 @@
 				eulerDegrees.print(pc, true);
 				pc.printf("\n");
 			}
-			if (imu.hasNewData(BNO080::TOTAL_ACCELERATION))
+			if (imu.hasNewData(BNO080Base::TOTAL_ACCELERATION))
 			{
 				pc.printf("IMU Total Acceleration: ");
 				imu.totalAcceleration.print(pc, true);
@@ -357,23 +389,26 @@
 			}
 		}
 
-		if(runningTime.read() > 2 && !disabledRotation)
+		if(runningTime.elapsed_time() > 2s && !disabledRotation)
 		{
 			pc.printf("2 seconds have passed, disabling rotation report...\n");
 			disabledRotation = true;
 
-			imu.disableReport(BNO080::ROTATION);
+			imu.disableReport(BNO080Base::ROTATION);
 		}
+		imu.unlockMutex();
 	}
 }
 
 void BNOTestSuite::test_accelCalibration()
 {
 	// enable calibration for the magnetometer
+	imu.lockMutex();
 	bool success = imu.enableCalibration(true, false, false);
 
 	const size_t update_rate_ms = 200;
-	imu.enableReport(BNO080::Report::TOTAL_ACCELERATION, update_rate_ms);
+	imu.enableReport(BNO080Base::Report::TOTAL_ACCELERATION, update_rate_ms);
+	imu.unlockMutex();
 
 	if(success)
 	{
@@ -387,20 +422,17 @@
 
 	while (true)
 	{
-		ThisThread::sleep_for(1ms * update_rate_ms);
+		ThisThread::sleep_for(1ms);
 
+		imu.lockMutex();
 		if(imu.updateData())
 		{
 			pc.printf("IMU Total Acceleration: [");
 			imu.totalAcceleration.print(pc, true);
-			pc.printf("] m/s^2, Status: %hhu (should be 2-3 when calibration is complete), ", imu.getReportStatus(BNO080::Report::TOTAL_ACCELERATION));
+			pc.printf("] m/s^2, Status: %hhu (should be 2-3 when calibration is complete), ", imu.getReportStatus(BNO080Base::Report::TOTAL_ACCELERATION));
 			pc.printf("]\r\n");
 
 		}
-		else
-		{
-			pc.printf("IMU was not ready with data packet!\r\n");
-		}
 
 		if(serial.readable())
 		{
@@ -414,26 +446,15 @@
 				pc.getc();
 			}
 		}
+		imu.unlockMutex();
 	}
 
 }
 
 int main()
 {
-	pc.printf("============================================================\n");
-
-	// reset and connect to IMU
-	while(!imu.begin())
-	{
-		pc.printf("Failed to connect to IMU!\r\n");
-        ThisThread::sleep_for(500);
-	}
-
-	//Declare test harness
-	BNOTestSuite harness;
-
 	int test = -1;
-	pc.printf("\r\n\nHamster BNO Test Suite:\r\n");
+	pc.printf("\r\n\nBNO080 Test Suite:\r\n");
 
 	//MENU. ADD OPTION PER EACH TEST
 	pc.printf("Select a test: \n\r");
@@ -454,6 +475,17 @@
 	pc.scanf("%d", &test);
 	pc.printf("Running test %d:\r\n\n", test);
 
+	pc.printf("============================================================\n");
+
+	// reset and connect to IMU
+	while(!imu.begin())
+	{
+		pc.printf("Failed to connect to IMU!\r\n");
+		ThisThread::sleep_for(500ms);
+	}
+
+	//Declare test harness
+	BNOTestSuite harness;
 
 	//SWITCH. ADD CASE PER EACH TEST
 	switch(test){
@@ -493,6 +525,9 @@
 		case 12:
 			harness.test_disable();
 			break;
+		case 13:
+			harness.test_accelCalibration();
+			break;
 		default:
 			printf("Invalid test number. Please run again.\r\n");
 			return 1;
--- a/BNOTestSuite.h	Tue Jul 21 22:00:26 2020 -0700
+++ b/BNOTestSuite.h	Tue Nov 24 15:27:32 2020 -0800
@@ -8,13 +8,16 @@
 #include <mbed.h>
 
 #include "BNO080.h"
+#include "BNO080Async.h"
 #include "SerialStream.h"
 
 BufferedSerial serial(USBTX, USBRX, 115200);
 SerialStream<BufferedSerial> pc(serial);
 
 // These pin assignments are specific to my dev setup -- you'll need to change them
-BNO080 imu(&pc, p28, p27, p16, p30, 0x4a, 100000); 
+BNO080I2C imu(&pc, PF_0, PF_1, D13, D12, 0x4a, 400000);
+//BNO080SPI imu(&pc, D12, D13, D11, PB_4, PB_5, PB_3, PA_4, 3000000);
+//BNO080Async imu(&pc, D12, D13, D11, PB_4, PB_5, PB_3, PA_4, 3000000);
 
 class BNOTestSuite{
 public: