From 467286cd743f20251c693b786ee1e33bd45253d2 Mon Sep 17 00:00:00 2001 From: Matt Bradford Date: Sun, 1 Aug 2021 12:48:32 +1000 Subject: [PATCH] Implement hasReset() to track Reset Complete response. --- .../Example21-ResetCheck.ino | 85 +++++++++++++++++++ keywords.txt | 1 + src/SparkFun_BNO080_Arduino_Library.cpp | 19 +++++ src/SparkFun_BNO080_Arduino_Library.h | 6 ++ 4 files changed, 111 insertions(+) create mode 100644 examples/Example21-ResetCheck/Example21-ResetCheck.ino diff --git a/examples/Example21-ResetCheck/Example21-ResetCheck.ino b/examples/Example21-ResetCheck/Example21-ResetCheck.ino new file mode 100644 index 0000000..a2c76b0 --- /dev/null +++ b/examples/Example21-ResetCheck/Example21-ResetCheck.ino @@ -0,0 +1,85 @@ +/* + Using the BNO080 IMU hasReset() function + By: @mattbradford83 + Date: 1 August 2021 + SparkFun code, firmware, and software is released under the MIT License. + Please see LICENSE.md for further details. + + This example shows how check for a "Reset Complete" packet from the sensor, + which is helpful when used in tandem with resetReason(). The sensor will be + reset each time 25 readings are received to demonstrate. + +*/ + +#include + +#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080 + +#define BNO08X_ADDR 0x4A +//#define BNO08X_ADDR 0x4B + +BNO080 myIMU; + +int cyclecount = 0; + + +// After a reset, reports need to be re-enabled. +void enableReports() { + myIMU.enableGyro(50); //Send data update every 50ms +} + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println("BNO080 Read Example"); + + Wire.begin(); + Wire.flush(); + if (!myIMU.begin(BNO08X_ADDR)) { + Serial.println("Could Not Enable BNO Sensor! Check your I2C Address."); + return; + } + + enableReports(); + + Serial.println(F("Gyro enabled")); + Serial.println(F("Output in form x, y, z, in radians per second")); +} + +void loop() +{ + // One of these will appear at the very start because of the power on reset. + // Check resetReason() for the difference between different resets. + if (myIMU.hasReset()) { + Serial.println(" ------------------ BNO085 has reset. ------------------ "); + Serial.printf(" Reason: %i\n",myIMU.resetReason()); + enableReports(); // We'll need to re-enable reports after any reset. + } + + //Look for reports from the IMU + if (myIMU.dataAvailable()) + { + cyclecount++; + Serial.printf("[%2i] ",cyclecount); + + float x = myIMU.getGyroX(); + float y = myIMU.getGyroY(); + float z = myIMU.getGyroZ(); + + Serial.print(x, 2); + Serial.print(F(",")); + Serial.print(y, 2); + Serial.print(F(",")); + Serial.print(z, 2); + Serial.print(F(",")); + + Serial.println(); + + if (cyclecount == 25) { + myIMU.softReset(); + cyclecount=0; + } + + } +} diff --git a/keywords.txt b/keywords.txt index 89dc28e..318ed33 100644 --- a/keywords.txt +++ b/keywords.txt @@ -19,6 +19,7 @@ enableDebugging KEYWORD2 softReset KEYWORD2 resetReason KEYWORD2 +hasReset KEYWORD2 modeOn KEYWORD2 modeSleep KEYWORD2 diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 179f624..6c84081 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -999,6 +999,16 @@ void BNO080::modeSleep(void) ; //delay(1); } +// Indicates if we've received a Reset Complete packet. Once it's been read, +// the state will reset to false until another Reset Complete packet is found. +bool BNO080::hasReset() { + if (_hasReset) { + _hasReset = false; + return true; + } + return false; +} + //Get the reason for the last reset //1 = POR, 2 = Internal reset, 3 = Watchdog, 4 = External reset, 5 = Other uint8_t BNO080::resetReason() @@ -1447,6 +1457,15 @@ boolean BNO080::receivePacket(void) getData(dataLength); } + // Quickly check for reset complete packet. No need for a seperate parser. + // This function is also called after soft reset, so we need to catch this + // packet here otherwise we need to check for the reset packet in multiple + // places. + if (shtpHeader[2] == CHANNEL_EXECUTABLE && shtpData[0] == EXECUTABLE_RESET_COMPLETE) + { + _hasReset = true; + } + return (true); //We're done! } diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 025f9c8..0b1c811 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -100,6 +100,9 @@ const byte CHANNEL_GYRO = 5; #define FRS_RECORDID_MAGNETIC_FIELD_CALIBRATED 0xE309 #define FRS_RECORDID_ROTATION_VECTOR 0xE30B +// Reset complete packet (BNO08X Datasheet p.24 Figure 1-27) +#define EXECUTABLE_RESET_COMPLETE 0x1 + //Command IDs from section 6.4, page 42 //These are used to calibrate, initialize, set orientation, tare etc the sensor #define COMMAND_ERRORS 1 @@ -131,6 +134,7 @@ class BNO080 void enableDebugging(Stream &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used. void softReset(); //Try to reset the IMU via software + bool hasReset(); //Returns true if the sensor has reported a reset. Reading this will unflag the reset. uint8_t resetReason(); //Query the IMU for the reason it last reset void modeOn(); //Use the executable channel to turn the BNO on void modeSleep(); //Use the executable channel to put the BNO to sleep @@ -273,6 +277,8 @@ class BNO080 uint8_t _int; uint8_t _rst; + bool _hasReset = false; // Keeps track of any Reset Complete packets we receive. + //These are the raw sensor values (without Q applied) pulled from the user requested Input Report uint16_t rawAccelX, rawAccelY, rawAccelZ, accelAccuracy; uint16_t rawLinAccelX, rawLinAccelY, rawLinAccelZ, accelLinAccuracy;