From b1ab503c89bbf7f0681277d603102cc7b346c17a Mon Sep 17 00:00:00 2001 From: bastienboudet Date: Thu, 3 Feb 2022 10:21:49 +0100 Subject: [PATCH 01/11] addition of uncalibrated gyroscope reports Add the uncalibrated gyroscope report with the full set of related functions --- src/SparkFun_BNO080_Arduino_Library.cpp | 81 ++++++++++++++++++++++++- src/SparkFun_BNO080_Arduino_Library.h | 13 ++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 1ebdfe7..a6c510c 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -291,6 +291,7 @@ uint16_t BNO080::parseInputReport(void) uint16_t data3 = (uint16_t)shtpData[5 + 9] << 8 | shtpData[5 + 8]; uint16_t data4 = 0; uint16_t data5 = 0; //We would need to change this to uin32_t to capture time stamp value on Raw Accel/Gyro/Mag reports + uint16_t data6 = 0; if (dataLength - 5 > 9) { @@ -300,6 +301,11 @@ uint16_t BNO080::parseInputReport(void) { data5 = (uint16_t)shtpData[5 + 13] << 8 | shtpData[5 + 12]; } + if (dataLength - 5 > 13) + { + data6 = (uint16_t)shtpData[5 + 15] << 8 | shtpData[5 + 14]; + } + //Store these generic values to their proper global variable if (shtpData[5] == SENSOR_REPORTID_ACCELEROMETER) @@ -317,12 +323,22 @@ uint16_t BNO080::parseInputReport(void) rawLinAccelZ = data3; } else if (shtpData[5] == SENSOR_REPORTID_GYROSCOPE) - { + { gyroAccuracy = status; rawGyroX = data1; rawGyroY = data2; rawGyroZ = data3; } + else if (shtpData[5] == SENSOR_REPORTID_UNCALIBRATED_GYRO) + { + UncalibGyroAccuracy = status; + rawUncalibGyroX = data1; + rawUncalibGyroY = data2; + rawUncalibGyroZ = data3; + rawBiasX = data4; + rawBiasY = data5; + rawBiasZ = data6; + } else if (shtpData[5] == SENSOR_REPORTID_MAGNETIC_FIELD) { magAccuracy = status; @@ -690,6 +706,62 @@ uint8_t BNO080::getGyroAccuracy() return (gyroAccuracy); } +//Gets the full uncalibrated gyro vector +//x,y,z,bx,by,bz output floats +void BNO080::getUncalibratedGyro(float &x, float &y, float &z, float &bx, float &by, float &bz, uint8_t &accuracy) +{ + x = qToFloat(rawUncalibGyroX, gyro_Q1); + y = qToFloat(rawUncalibGyroY, gyro_Q1); + z = qToFloat(rawUncalibGyroZ, gyro_Q1); + bx = qToFloat(rawBiasX, gyro_Q1); + by = qToFloat(rawBiasY, gyro_Q1); + bz = qToFloat(rawBiasZ, gyro_Q1); + accuracy = UncalibGyroAccuracy; +} +//Return the gyro component +float BNO080::getUncalibratedGyroX() +{ + float gyro = qToFloat(rawUncalibGyroX, gyro_Q1); + return (gyro); +} +//Return the gyro component +float BNO080::getUncalibratedGyroY() +{ + float gyro = qToFloat(rawUncalibGyroY, gyro_Q1); + return (gyro); +} +//Return the gyro component +float BNO080::getUncalibratedGyroZ() +{ + float gyro = qToFloat(rawUncalibGyroZ, gyro_Q1); + return (gyro); +} +//Return the gyro component +float BNO080::getUncalibratedGyroBiasX() +{ + float gyro = qToFloat(rawBiasX, gyro_Q1); + return (gyro); +} +//Return the gyro component +float BNO080::getUncalibratedGyroBiasY() +{ + float gyro = qToFloat(rawBiasY, gyro_Q1); + return (gyro); +} +//Return the gyro component +float BNO080::getUncalibratedGyroBiasZ() +{ + float gyro = qToFloat(rawBiasZ, gyro_Q1); + return (gyro); +} + +//Return the gyro component +uint8_t BNO080::getUncalibratedGyroAccuracy() +{ + return (UncalibGyroAccuracy); +} + + //Gets the full mag vector //x,y,z output floats void BNO080::getMag(float &x, float &y, float &z, uint8_t &accuracy) @@ -1071,6 +1143,7 @@ uint8_t BNO080::resetReason() //See https://en.wikipedia.org/wiki/Q_(number_format) float BNO080::qToFloat(int16_t fixedPointValue, uint8_t qPoint) { + float qFloat = fixedPointValue; qFloat *= pow(2, qPoint * -1); return (qFloat); @@ -1118,6 +1191,12 @@ void BNO080::enableGyro(uint16_t timeBetweenReports) setFeatureCommand(SENSOR_REPORTID_GYROSCOPE, timeBetweenReports); } +//Sends the packet to enable the uncalibrated gyro +void BNO080::enableUncalibratedGyro(uint16_t timeBetweenReports) +{ + setFeatureCommand(SENSOR_REPORTID_UNCALIBRATED_GYRO, timeBetweenReports); +} + //Sends the packet to enable the magnetometer void BNO080::enableMagnetometer(uint16_t timeBetweenReports) { diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 0b1c811..c24811e 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -80,6 +80,7 @@ const byte CHANNEL_GYRO = 5; #define SENSOR_REPORTID_LINEAR_ACCELERATION 0x04 #define SENSOR_REPORTID_ROTATION_VECTOR 0x05 #define SENSOR_REPORTID_GRAVITY 0x06 +#define SENSOR_REPORTID_UNCALIBRATED_GYRO 0x07 #define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08 #define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09 #define SENSOR_REPORTID_GYRO_INTEGRATED_ROTATION_VECTOR 0x2A @@ -156,6 +157,7 @@ class BNO080 void enableAccelerometer(uint16_t timeBetweenReports); void enableLinearAccelerometer(uint16_t timeBetweenReports); void enableGyro(uint16_t timeBetweenReports); + void enableUncalibratedGyro(uint16_t timeBetweenReports); void enableMagnetometer(uint16_t timeBetweenReports); void enableTapDetector(uint16_t timeBetweenReports); void enableStepCounter(uint16_t timeBetweenReports); @@ -197,6 +199,16 @@ class BNO080 float getGyroZ(); uint8_t getGyroAccuracy(); + void getUncalibratedGyro(float &x, float &y, float &z, float &bx, float &by, float &bz, uint8_t &accuracy); + float getUncalibratedGyroX(); + float getUncalibratedGyroY(); + float getUncalibratedGyroZ(); + float getUncalibratedGyroBiasX(); + float getUncalibratedGyroBiasY(); + float getUncalibratedGyroBiasZ(); + uint8_t getUncalibratedGyroAccuracy(); + + void getFastGyro(float &x, float &y, float &z); float getFastGyroX(); float getFastGyroY(); @@ -283,6 +295,7 @@ class BNO080 uint16_t rawAccelX, rawAccelY, rawAccelZ, accelAccuracy; uint16_t rawLinAccelX, rawLinAccelY, rawLinAccelZ, accelLinAccuracy; uint16_t rawGyroX, rawGyroY, rawGyroZ, gyroAccuracy; + uint16_t rawUncalibGyroX, rawUncalibGyroY, rawUncalibGyroZ, rawBiasX, rawBiasY, rawBiasZ, UncalibGyroAccuracy; uint16_t rawMagX, rawMagY, rawMagZ, magAccuracy; uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy; uint16_t rawFastGyroX, rawFastGyroY, rawFastGyroZ; From b4b3bacf842901f4978616efa10b1fd5ced97ad8 Mon Sep 17 00:00:00 2001 From: bastienboudet Date: Thu, 3 Feb 2022 10:52:23 +0100 Subject: [PATCH 02/11] update keyword + add example addition of uncalibrated gyro functions --- .../Example3-Gyro.ino | 74 +++++++++++++++++++ keywords.txt | 11 +++ 2 files changed, 85 insertions(+) create mode 100644 examples/Example22-UncalibratedGyro/Example3-Gyro.ino diff --git a/examples/Example22-UncalibratedGyro/Example3-Gyro.ino b/examples/Example22-UncalibratedGyro/Example3-Gyro.ino new file mode 100644 index 0000000..9dd27f2 --- /dev/null +++ b/examples/Example22-UncalibratedGyro/Example3-Gyro.ino @@ -0,0 +1,74 @@ +/* + Using the BNO080 IMU + By: Bastien Boudet + Date: February 3rd, 2022 + SparkFun code, firmware, and software is released under the MIT License. + Please see LICENSE.md for further details. + + Feel like supporting our work? Buy a board from SparkFun! + https://www.sparkfun.com/products/14586 + + This example shows how to output the parts of the uncalibrated gyro. + + It takes about 1ms at 400kHz I2C to read a record from the sensor, but we are polling the sensor continually + between updates from the sensor. Use the interrupt pin on the BNO080 breakout to avoid polling. + + Hardware Connections: + Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other + Plug the sensor onto the shield + Serial.print it out at 115200 baud to serial monitor. +*/ + +#include + +#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080 +BNO080 myIMU; + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println("BNO080 Read Example"); + + Wire.begin(); + + myIMU.begin(); + + Wire.setClock(400000); //Increase I2C data rate to 400kHz + + myIMU.enableUncalibratedGyro(50); //Send data update every 50ms + + Serial.println(F("Uncalibrated Gyro enabled")); + Serial.println(F("Output in form x, y, z, bx, by, bz in radians per second")); +} + +void loop() +{ + //Look for reports from the IMU + if (myIMU.dataAvailable() == true) + { + float x = myIMU.getUncalibratedGyroX(); + float y = myIMU.getUncalibratedGyroY(); + float z = myIMU.getUncalibratedGyroZ(); + float bx = myIMU.getUncalibratedGyroBiasX(); + float by = myIMU.getUncalibratedGyroBiasY(); + float bz = myIMU.getUncalibratedGyroBiasZ(); + + + Serial.print(x, 2); + Serial.print(F(",")); + Serial.print(y, 2); + Serial.print(F(",")); + Serial.print(z, 2); + Serial.print(F(",")); + + Serial.print(bx, 2); + Serial.print(F(",")); + Serial.print(by, 2); + Serial.print(F(",")); + Serial.print(bz, 2); + Serial.print(F(",")); + + Serial.println(); + } +} diff --git a/keywords.txt b/keywords.txt index 318ed33..9ca6541 100644 --- a/keywords.txt +++ b/keywords.txt @@ -39,6 +39,7 @@ enableARVRStabilizedRotationVector KEYWORD2 enableARVRStabilizedGameRotationVector KEYWORD2 enableAccelerometer KEYWORD2 enableGyro KEYWORD2 +enableUncalibratedGyro KEYWORD2 enableMagnetometer KEYWORD2 enableTapDetector KEYWORD2 enableStepCounter KEYWORD2 @@ -75,6 +76,16 @@ getGyroY KEYWORD2 getGyroZ KEYWORD2 getGyroAccuracy KEYWORD2 +getUncalibratedGyro KEYWORD2 +getUncalibratedGyroX KEYWORD2 +getUncalibratedGyroY KEYWORD2 +getUncalibratedGyroZ KEYWORD2 +getUncalibratedGyroAccuracy KEYWORD2 +getUncalibratedGyroBiasX KEYWORD2 +getUncalibratedGyroBiasY KEYWORD2 +getUncalibratedGyroBiasZ KEYWORD2 + + getFastGyro KEYWORD2 getFastGyroX KEYWORD2 getFastGyroY KEYWORD2 From ab0650effd3993fcd090464e17836cf677be7276 Mon Sep 17 00:00:00 2001 From: Sofian Audry Date: Wed, 2 Mar 2022 15:09:41 -0500 Subject: [PATCH 03/11] Implemented tare functionalities (now, persist/save, clear). --- src/SparkFun_BNO080_Arduino_Library.cpp | 32 +++++++++++++++++++++++++ src/SparkFun_BNO080_Arduino_Library.h | 19 +++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 1ebdfe7..eaa198a 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -1221,6 +1221,21 @@ boolean BNO080::calibrationComplete() return (false); } +void BNO080::tareNow(bool zAxis, uint8_t rotationVectorBasis) +{ + sendTareCommand(TARE_NOW, zAxis ? TARE_AXIS_Z : TARE_AXIS_ALL, rotationVectorBasis); +} + +void BNO080::saveTare() +{ + sendTareCommand(TARE_PERSIST); +} + +void BNO080::clearTare() +{ + sendTareCommand(TARE_SET_REORIENTATION); +} + //Given a sensor's report ID, this tells the BNO080 to begin reporting the values void BNO080::setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports) { @@ -1320,6 +1335,23 @@ void BNO080::sendCalibrateCommand(uint8_t thingToCalibrate) sendCommand(COMMAND_ME_CALIBRATE); } +void BNO080::sendTareCommand(uint8_t command, uint8_t axis, uint8_t rotationVectorBasis) +{ + for (uint8_t x = 3; x < 12; x++) //Clear this section of the shtpData array + shtpData[x] = 0; + + shtpData[3] = command; + + if (command == TARE_NOW) + { + shtpData[4] = axis; // axis setting + shtpData[5] = rotationVectorBasis; // rotation vector + } + + //Using this shtpData packet, send a command + sendCommand(COMMAND_TARE); +} + //Request ME Calibration Status from BNO080 //See page 51 of reference manual void BNO080::requestCalibrationStatus() diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 0b1c811..0cde58f 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -122,6 +122,20 @@ const byte CHANNEL_GYRO = 5; #define CALIBRATE_ACCEL_GYRO_MAG 4 #define CALIBRATE_STOP 5 +#define TARE_NOW 0 +#define TARE_PERSIST 1 +#define TARE_SET_REORIENTATION 2 + +#define TARE_AXIS_ALL 0x07 +#define TARE_AXIS_Z 0x04 + +#define TARE_ROTATION_VECTOR 0 +#define TARE_GAME_ROTATION_VECTOR 1 +#define TARE_GEOMAGNETIC_ROTATION_VECTOR 2 +#define TARE_GYRO_INTEGRATED_ROTATION_VECTOR 3 +#define TARE_AR_VR_STABILIZED_ROTATION_VECTOR 4 +#define TARE_AR_VR_STABILIZED_GAME_ROTATION_VECTOR 5 + #define MAX_PACKET_SIZE 128 //Packets can be up to 32k but we don't have that much RAM. #define MAX_METADATA_SIZE 9 //This is in words. There can be many but we mostly only care about the first 9 (Qs, range, etc) @@ -218,6 +232,10 @@ class BNO080 void requestCalibrationStatus(); //Sends command to get status boolean calibrationComplete(); //Checks ME Cal response for byte 5, R0 - Status + void tareNow(bool zAxis=false, uint8_t rotationVectorBasis=TARE_ROTATION_VECTOR); + void saveTare(); + void clearTare(); + uint8_t getTapDetector(); uint32_t getTimeStamp(); uint16_t getStepCount(); @@ -244,6 +262,7 @@ class BNO080 void setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports, uint32_t specificConfig); void sendCommand(uint8_t command); void sendCalibrateCommand(uint8_t thingToCalibrate); + void sendTareCommand(uint8_t command, uint8_t axis=TARE_AXIS_ALL, uint8_t rotationVectorBasis=TARE_ROTATION_VECTOR); //Metadata functions int16_t getQ1(uint16_t recordID); From df189cc41d34593acd9340b1c5db22c15d426e18 Mon Sep 17 00:00:00 2001 From: Sofian Audry Date: Wed, 2 Mar 2022 15:10:06 -0500 Subject: [PATCH 04/11] Added an example for tare functions. --- examples/Example22-Tare/Example22-Tare.ino | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 examples/Example22-Tare/Example22-Tare.ino diff --git a/examples/Example22-Tare/Example22-Tare.ino b/examples/Example22-Tare/Example22-Tare.ino new file mode 100644 index 0000000..cd94131 --- /dev/null +++ b/examples/Example22-Tare/Example22-Tare.ino @@ -0,0 +1,87 @@ +/* + Using the BNO080 IMU + + Example : Tare function + By: Sofian Audry + Date: March 2nd, 2022 + + Based on: Example9-Calibrate + By: Nathan Seidle + SparkFun Electronics + Date: December 21st, 2017 + SparkFun code, firmware, and software is released under the MIT License. + Please see LICENSE.md for further details. + + Feel like supporting our work? Buy a board from SparkFun! + https://www.sparkfun.com/products/14586 + + This example shows how to use the tare functionalities. + It is best to run a calibration before using the tare functions. + + It takes about 1ms at 400kHz I2C to read a record from the sensor, but we are polling the sensor continually + between updates from the sensor. Use the interrupt pin on the BNO080 breakout to avoid polling. + + Hardware Connections: + Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other + Plug the sensor onto the shield + Serial.print it out at 115200 baud to serial monitor. +*/ +#include + +#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080 +BNO080 myIMU; + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println("BNO080 Read Example"); + + Wire.begin(); + + myIMU.begin(); + + Wire.setClock(400000); //Increase I2C data rate to 400kHz + + //Enable Game Rotation Vector output + myIMU.enableRotationVector(100); //Send data update every 100ms + + //Once magnetic field is 2 or 3, run the Save DCD Now command + Serial.println(F("'t' to tare according to xyz")); + Serial.println(F("'z' to tare according to z axis only")); + Serial.println(F("'s' to save tare settings")); + Serial.println(F("'r' to reset/clear tare orientation registry")); + Serial.println(F("Output in form x, y, z, in uTesla")); +} + +void loop() +{ + if(Serial.available()) + { + byte incoming = Serial.read(); + + switch (incoming) { + case 't': myIMU.tareNow(); break; + case 'z': myIMU.tareNow(true); break; + case 's': myIMU.saveTare(); break; + case 'r': myIMU.clearTare(); break; + default:; + } + } + + //Look for reports from the IMU + if (myIMU.dataAvailable() == true) + { + float roll = (myIMU.getRoll()) * 180.0 / PI; // Convert roll to degrees + float pitch = (myIMU.getPitch()) * 180.0 / PI; // Convert pitch to degrees + float yaw = (myIMU.getYaw()) * 180.0 / PI; // Convert yaw / heading to degrees + + Serial.print(roll, 1); + Serial.print(F(",")); + Serial.print(pitch, 1); + Serial.print(F(",")); + Serial.print(yaw, 1); + + Serial.println(); + } +} From 611911db6cc62959cf84dac2d7d25a414909c061 Mon Sep 17 00:00:00 2001 From: Anant Sharma Date: Mon, 23 Jan 2023 15:17:17 +0530 Subject: [PATCH 05/11] Added functionality to retrieve gravity packets from the device. - Added functionality on the BNO080::parseInputReport(void) to interpret gravity packets. - Added getGravityX, getGravityY and getGravityZ in the same format as the others reports. - Added the function BNO080::enableGravity() which also functions like the other reports. Tested with Teensy 4.0, Adafruit ItsyBitsy and ESP32. --- src/SparkFun_BNO080_Arduino_Library.cpp | 35 ++++++++++++++++++++++++- src/SparkFun_BNO080_Arduino_Library.h | 9 ++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 1ebdfe7..6623d90 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -401,6 +401,12 @@ uint16_t BNO080::parseInputReport(void) calibrationStatus = shtpData[5 + 5]; //R0 - Status (0 = success, non-zero = fail) } } + else if(shtpData[5] == SENSOR_REPORTID_GRAVITY) + { + gravityX = data1; + gravityY = data2; + gravityZ = data3; + } else { //This sensor report ID is unhandled. @@ -663,6 +669,27 @@ void BNO080::getGyro(float &x, float &y, float &z, uint8_t &accuracy) accuracy = gyroAccuracy; } +//Return the gravity component +float BNO080::getGravityX() +{ + float x = qToFloat(gravityX, gravity_Q1); + return x; +} + +//Return the gravity component +float BNO080::getGravityY() +{ + float y = qToFloat(gravityY, gravity_Q1); + return y; +} + +//Return the gravity component +float BNO080::getGravityZ() +{ + float z = qToFloat(gravityZ, gravity_Q1); + return z; +} + //Return the gyro component float BNO080::getGyroX() { @@ -1112,6 +1139,12 @@ void BNO080::enableLinearAccelerometer(uint16_t timeBetweenReports) setFeatureCommand(SENSOR_REPORTID_LINEAR_ACCELERATION, timeBetweenReports); } +//Sends the packet to enable the gravity vector +void BNO080::enableGravity(uint16_t timeBetweenReports) +{ + setFeatureCommand(SENSOR_REPORTID_GRAVITY, timeBetweenReports); +} + //Sends the packet to enable the gyro void BNO080::enableGyro(uint16_t timeBetweenReports) { @@ -1689,4 +1722,4 @@ void BNO080::printHeader(void) } _debugPort->println(); } -} +} \ No newline at end of file diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 0b1c811..1e70326 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -155,6 +155,7 @@ class BNO080 void enableARVRStabilizedGameRotationVector(uint16_t timeBetweenReports); void enableAccelerometer(uint16_t timeBetweenReports); void enableLinearAccelerometer(uint16_t timeBetweenReports); + void enableGravity(uint16_t timeBetweenReports); void enableGyro(uint16_t timeBetweenReports); void enableMagnetometer(uint16_t timeBetweenReports); void enableTapDetector(uint16_t timeBetweenReports); @@ -208,6 +209,10 @@ class BNO080 float getMagZ(); uint8_t getMagAccuracy(); + float getGravityX(); + float getGravityY(); + float getGravityZ(); + void calibrateAccelerometer(); void calibrateGyro(); void calibrateMagnetometer(); @@ -286,6 +291,7 @@ class BNO080 uint16_t rawMagX, rawMagY, rawMagZ, magAccuracy; uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy; uint16_t rawFastGyroX, rawFastGyroY, rawFastGyroZ; + uint16_t gravityX, gravityY, gravityZ; uint8_t tapDetector; uint16_t stepCount; uint32_t timeStamp; @@ -306,4 +312,5 @@ class BNO080 int16_t gyro_Q1 = 9; int16_t magnetometer_Q1 = 4; int16_t angular_velocity_Q1 = 10; -}; + int16_t gravity_Q1 = 8; +}; \ No newline at end of file From 1c1d069f7a9181c9430ff1cd17e7b6acaf9d453d Mon Sep 17 00:00:00 2001 From: Anant Sharma Date: Mon, 23 Jan 2023 15:39:09 +0530 Subject: [PATCH 06/11] Added an example for checking gravity packets --- .../Example23-Gravity/Example23-Gravity.ino | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 examples/Example23-Gravity/Example23-Gravity.ino diff --git a/examples/Example23-Gravity/Example23-Gravity.ino b/examples/Example23-Gravity/Example23-Gravity.ino new file mode 100644 index 0000000..cd0f3d9 --- /dev/null +++ b/examples/Example23-Gravity/Example23-Gravity.ino @@ -0,0 +1,77 @@ +/* + Using the BNO085 for finding the direction of gravity. + By: Anant Sharma + + Date: January 23rd, 2023 + SparkFun code, firmware, and software is released under the MIT License. + Please see LICENSE.md for further details. + Feel like supporting our work? Buy a board from SparkFun! + https://www.sparkfun.com/products/14586 + This example outputs a vector pointing towards the ground. + + It takes about 1ms at 400kHz I2C to read a record from the sensor, but we are polling the sensor continually + between updates from the sensor. Use the interrupt pin on the BNO080 breakout to avoid polling. + + Hardware Connections: + Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other + Plug the sensor onto the shield + + Serial.print it out at 9600 baud to serial monitor. +*/ + +#include +#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080 +BNO080 myIMU; + + + +void setup() { + Serial.begin(9600); + Serial.println(); + Serial.println("BNO080 Read Example"); + + Wire.begin(); + + //Are you using a ESP? Check this issue for more information: https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/issues/16 +// //================================= +// delay(100); // Wait for BNO to boot +// // Start i2c and BNO080 +// Wire.flush(); // Reset I2C +// IMU.begin(BNO080_DEFAULT_ADDRESS, Wire); +// Wire.begin(4, 5); +// Wire.setClockStretchLimit(4000); +// //================================= + + if (myIMU.begin() == false) + { + Serial.println("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."); + while (1); + } + + Wire.setClock(400000); //Increase I2C data rate to 400kHz + + myIMU.enableGravity(10); //Send data update every 50ms + + Serial.println(F("Rotation vector enabled")); + Serial.println(F("Output in form i, j, k, real, accuracy")); + +} + +void loop() { + //Look for reports from the IMU + if (myIMU.dataAvailable() == true) + { + float gravityX = myIMU.getGravityX(); + float gravityY = myIMU.getGravityY(); + float gravityZ = myIMU.getGravityZ(); + + Serial.print(gravityX, 2); + Serial.print(F(",")); + Serial.print(gravityY, 2); + Serial.print(F(",")); + Serial.print(gravityZ, 2); + Serial.print(F(",")); + + Serial.println(); + } +} From e1f2aaa38b9164bd040e8892e1f35efb016f46d6 Mon Sep 17 00:00:00 2001 From: Anant Sharma Date: Mon, 23 Jan 2023 15:56:37 +0530 Subject: [PATCH 07/11] Added gravity accuracy tests --- .../Example23-Gravity/Example23-Gravity.ino | 4 ++ keywords.txt | 7 +++ src/SparkFun_BNO080_Arduino_Library.cpp | 57 ++++++++++++------- src/SparkFun_BNO080_Arduino_Library.h | 4 +- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/examples/Example23-Gravity/Example23-Gravity.ino b/examples/Example23-Gravity/Example23-Gravity.ino index cd0f3d9..3c96e12 100644 --- a/examples/Example23-Gravity/Example23-Gravity.ino +++ b/examples/Example23-Gravity/Example23-Gravity.ino @@ -64,6 +64,7 @@ void loop() { float gravityX = myIMU.getGravityX(); float gravityY = myIMU.getGravityY(); float gravityZ = myIMU.getGravityZ(); + float gravityAccuracy = myIMU.getGravityAccuracy(); Serial.print(gravityX, 2); Serial.print(F(",")); @@ -71,6 +72,9 @@ void loop() { Serial.print(F(",")); Serial.print(gravityZ, 2); Serial.print(F(",")); + Serial.print(gravityAccuracy, 2); + Serial.print(F(",")); + Serial.println(); } diff --git a/keywords.txt b/keywords.txt index 318ed33..277eb0d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -39,6 +39,7 @@ enableARVRStabilizedRotationVector KEYWORD2 enableARVRStabilizedGameRotationVector KEYWORD2 enableAccelerometer KEYWORD2 enableGyro KEYWORD2 +enableGravity KEYWORD2 enableMagnetometer KEYWORD2 enableTapDetector KEYWORD2 enableStepCounter KEYWORD2 @@ -75,6 +76,12 @@ getGyroY KEYWORD2 getGyroZ KEYWORD2 getGyroAccuracy KEYWORD2 +getGravity KEYWORD2 +getGravityX KEYWORD2 +getGravityY KEYWORD2 +getGravityZ KEYWORD2 +getGravityAccuracy KEYWORD2 + getFastGyro KEYWORD2 getFastGyroX KEYWORD2 getFastGyroY KEYWORD2 diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 6623d90..43bc429 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -403,6 +403,7 @@ uint16_t BNO080::parseInputReport(void) } else if(shtpData[5] == SENSOR_REPORTID_GRAVITY) { + gravityAccuracy = status; gravityX = data1; gravityY = data2; gravityZ = data3; @@ -669,27 +670,6 @@ void BNO080::getGyro(float &x, float &y, float &z, uint8_t &accuracy) accuracy = gyroAccuracy; } -//Return the gravity component -float BNO080::getGravityX() -{ - float x = qToFloat(gravityX, gravity_Q1); - return x; -} - -//Return the gravity component -float BNO080::getGravityY() -{ - float y = qToFloat(gravityY, gravity_Q1); - return y; -} - -//Return the gravity component -float BNO080::getGravityZ() -{ - float z = qToFloat(gravityZ, gravity_Q1); - return z; -} - //Return the gyro component float BNO080::getGyroX() { @@ -717,6 +697,41 @@ uint8_t BNO080::getGyroAccuracy() return (gyroAccuracy); } +//Gets the full gravity vector +//x,y,z output floats +void BNO080::getGravity(float &x, float &y, float &z, uint8_t &accuracy) +{ + x = qToFloat(gravityX, gravity_Q1); + y = qToFloat(gravityX, gravity_Q1); + z = qToFloat(gravityX, gravity_Q1); + accuracy = gravityAccuracy; +} + +float BNO080::getGravityX() +{ + float x = qToFloat(gravityX, gravity_Q1); + return x; +} + +//Return the gravity component +float BNO080::getGravityY() +{ + float y = qToFloat(gravityY, gravity_Q1); + return y; +} + +//Return the gravity component +float BNO080::getGravityZ() +{ + float z = qToFloat(gravityZ, gravity_Q1); + return z; +} + +uint8_t BNO080::getGravityAccuracy() +{ + return (gravityAccuracy); +} + //Gets the full mag vector //x,y,z output floats void BNO080::getMag(float &x, float &y, float &z, uint8_t &accuracy) diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 1e70326..ae7a550 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -209,9 +209,11 @@ class BNO080 float getMagZ(); uint8_t getMagAccuracy(); + void getGravity(float &x, float &y, float &z, uint8_t &accuracy); float getGravityX(); float getGravityY(); float getGravityZ(); + uint8_t getGravityAccuracy(); void calibrateAccelerometer(); void calibrateGyro(); @@ -291,7 +293,7 @@ class BNO080 uint16_t rawMagX, rawMagY, rawMagZ, magAccuracy; uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy; uint16_t rawFastGyroX, rawFastGyroY, rawFastGyroZ; - uint16_t gravityX, gravityY, gravityZ; + uint16_t gravityX, gravityY, gravityZ, gravityAccuracy; uint8_t tapDetector; uint16_t stepCount; uint32_t timeStamp; From c5620eaf1d1f968c37756d35d11cc71723b8cbb1 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Jan 2023 11:43:33 +0000 Subject: [PATCH 08/11] Rename the Uncalibrated Gyro example --- .../Example24-UncalibratedGyro.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{Example22-UncalibratedGyro/Example3-Gyro.ino => Example24-UncalibratedGyro/Example24-UncalibratedGyro.ino} (100%) diff --git a/examples/Example22-UncalibratedGyro/Example3-Gyro.ino b/examples/Example24-UncalibratedGyro/Example24-UncalibratedGyro.ino similarity index 100% rename from examples/Example22-UncalibratedGyro/Example3-Gyro.ino rename to examples/Example24-UncalibratedGyro/Example24-UncalibratedGyro.ino From 6c5e5e203a43a41e06a54c849302ebcce711e372 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Jan 2023 11:48:31 +0000 Subject: [PATCH 09/11] Update keywords.txt --- keywords.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/keywords.txt b/keywords.txt index 901de25..1bb5798 100644 --- a/keywords.txt +++ b/keywords.txt @@ -119,6 +119,11 @@ saveCalibration KEYWORD2 requestCalibrationStatus KEYWORD2 calibrationComplete KEYWORD2 +tareNow KEYWORD2 +saveTare KEYWORD2 +clearTare KEYWORD2 +sendTareCommand KEYWORD2 + getTapDetector KEYWORD2 getTimeStamp KEYWORD2 getStepCount KEYWORD2 From 680a09f124e295cc8aeab9b7a8689524e27d79e1 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Jan 2023 11:59:26 +0000 Subject: [PATCH 10/11] v1.1.12 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 357fe5d..45b8c84 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun BNO080 Cortex Based IMU -version=1.1.11 +version=1.1.12 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=Library for the SparkFun Qwiic VR IMU - BNO080/BNO085 From 8e5a9b8d47ab568c461db34516555c1b8e7f5612 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Jan 2023 11:59:59 +0000 Subject: [PATCH 11/11] Resolve warnings-as-errors --- src/SparkFun_BNO080_Arduino_Library.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 6fa16a0..d7cf257 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -138,6 +138,7 @@ boolean BNO080::beginSPI(uint8_t user_CSPin, uint8_t user_WAKPin, uint8_t user_I if (receivePacket() == true) { if (shtpData[0] == SHTP_REPORT_PRODUCT_ID_RESPONSE) + { if (_printDebug == true) { _debugPort->print(F("SW Version Major: 0x")); @@ -155,6 +156,7 @@ boolean BNO080::beginSPI(uint8_t user_CSPin, uint8_t user_WAKPin, uint8_t user_I _debugPort->println(SW_Version_Patch, HEX); } return (true); + } } return (false); //Something went wrong @@ -476,7 +478,7 @@ float BNO080::getPitch() dqy = dqy/norm; dqz = dqz/norm; - float ysqr = dqy * dqy; + //float ysqr = dqy * dqy; // pitch (y-axis rotation) float t2 = +2.0 * (dqw * dqy - dqz * dqx); @@ -1452,7 +1454,9 @@ void BNO080::sendCalibrateCommand(uint8_t thingToCalibrate) shtpData[5] = 1; } else if (thingToCalibrate == CALIBRATE_STOP) + { ; //Do nothing, bytes are set to zero + } //Make the internal calStatus variable non-zero (operation failed) so that user can test while we wait calibrationStatus = 1;