diff --git a/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino b/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino new file mode 100644 index 0000000..16236d9 --- /dev/null +++ b/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino @@ -0,0 +1,132 @@ +/* + Using the BNO080 IMU with helper methods + By: Guillaume Walck + + Date: September 08th, 2020 + License: This code is public domain. + + This example shows how to access multiple data of one type using helper methods. + + 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 Multiple 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.enableLinearAccelerometer(50); // m/s^2 no gravity + myIMU.enableRotationVector(50); // quat + myIMU.enableGyro(50); // rad/s + //myIMU.enableMagnetometer(50); // cannot be enabled at the same time as RotationVector (will not produce data) + + Serial.println(F("LinearAccelerometer enabled, Output in form x, y, z, accuracy, in m/s^2")); + Serial.println(F("Gyro enabled, Output in form x, y, z, accuracy, in radians per second")); + Serial.println(F("Rotation vector, Output in form i, j, k, real, accuracy")); + //Serial.println(F("Magnetometer enabled, Output in form x, y, z, accuracy, in uTesla")); +} + + +void loop() { + + //Look for data from the IMU + if (myIMU.dataAvailable() == true) + { + // internal copies of the IMU data + float ax, ay, az, gx, gy, gz, qx, qy, qz, qw; // mx, my, mz, (qx, qy, qz, qw = i,j,k, real) + byte linAccuracy = 0; + byte gyroAccuracy = 0; + //byte magAccuracy = 0; + float quatRadianAccuracy = 0; + byte quatAccuracy = 0; + + // get IMU data in one go for each sensor type + myIMU.getLinAccel(ax, ay, az, linAccuracy); + myIMU.getGyro(gx, gy, gz, gyroAccuracy); + myIMU.getQuat(qx, qy, qz, qw, quatRadianAccuracy, quatAccuracy); + //myIMU.getMag(mx, my, mz, magAccuracy); + + + Serial.print(F("acc :")); + Serial.print(ax, 2); + Serial.print(F(",")); + Serial.print(ay, 2); + Serial.print(F(",")); + Serial.print(az, 2); + Serial.print(F(",")); + Serial.print(az, 2); + Serial.print(F(",")); + printAccuracyLevel(linAccuracy); + + Serial.print(F("gyro:")); + Serial.print(gx, 2); + Serial.print(F(",")); + Serial.print(gy, 2); + Serial.print(F(",")); + Serial.print(gz, 2); + Serial.print(F(",")); + printAccuracyLevel(gyroAccuracy); +/* + Serial.print(F("mag :")); + Serial.print(mx, 2); + Serial.print(F(",")); + Serial.print(my, 2); + Serial.print(F(",")); + Serial.print(mz, 2); + Serial.print(F(",")); + printAccuracyLevel(magAccuracy); +*/ + + Serial.print(F("quat:")); + Serial.print(qx, 2); + Serial.print(F(",")); + Serial.print(qy, 2); + Serial.print(F(",")); + Serial.print(qz, 2); + Serial.print(F(",")); + Serial.print(qw, 2); + Serial.print(F(",")); + printAccuracyLevel(quatAccuracy); + } +} + +//Given an accuracy number, print what it means +void printAccuracyLevel(byte accuracyNumber) +{ + if (accuracyNumber == 0) Serial.println(F("Unreliable")); + else if (accuracyNumber == 1) Serial.println(F("Low")); + else if (accuracyNumber == 2) Serial.println(F("Medium")); + else if (accuracyNumber == 3) Serial.println(F("High")); +} diff --git a/examples/SPI/Example18-AccessMultiple/Example18-AccessMultiple.ino b/examples/SPI/Example18-AccessMultiple/Example18-AccessMultiple.ino new file mode 100644 index 0000000..bcc0c79 --- /dev/null +++ b/examples/SPI/Example18-AccessMultiple/Example18-AccessMultiple.ino @@ -0,0 +1,162 @@ +/* + Using the BNO080 IMU with helper methods + By: Guillaume Walck + + Date: September 08th, 2020 + License: This code is public domain. + + This example shows how to use the SPI interface on the BNO080. It's fairly involved + and requires 7 comm wires (plus 2 power), soldering the PS1 jumper, and clearing + the I2C jumper. We recommend using the Qwiic I2C interface, but if you need speed + SPI is the way to go. + + This example shows how to access multiple data of one type using helper methods. + + Hardware modifications: + The PS1 jumper must be closed + The PS0 jumper must be open. PS0/WAKE is connected and the WAK pin is used to bring the IC out of sleep. + The I2C pull up jumper must be cleared/open + + Hardware Connections: + Don't hook the BNO080 to a normal 5V Uno! Either use the Qwiic system or use a + microcontroller that runs at 3.3V. + Arduino 13 = BNO080 SCK + 12 = SO + 11 = SI + 10 = !CS + 9 = WAK + 8 = !INT + 7 = !RST + 3.3V = 3V3 + GND = GND +*/ + +#include +#include + +#include "SparkFun_BNO080_Arduino_Library.h" +BNO080 myIMU; + +//These pins can be any GPIO +byte imuCSPin = 10; +byte imuWAKPin = 9; +byte imuINTPin = 8; +byte imuRSTPin = 7; + +//GPIO pins for SPI1 on teensy4.0 +//byte imuCSPin = 0; +//byte imuWAKPin = 24; //PS0 +//byte imuINTPin = 25; //INT +//byte imuRSTPin = 2; //RST +// SPI1 on Teensy 4.0 uses COPI Pin = 26 CIPO Pin = 1, SCK Pin = 27 +//byte imuCOPIPin = 26; +//byte imuCIPOPin = 1; +//byte imuSCKPin = 27; + +void setup() { + Serial.begin(115200); + Serial.println(); + Serial.println("BNO080 SPI Multiple Read Example"); + + myIMU.enableDebugging(Serial); //Pipe debug messages to Serial port + + // set up the SPI pins utilized on Teensy 4.0 + //SPI1.setMOSI(imuCOPIPin); + //SPI1.setMISO(imuCIPOPin); + //SPI1.setSCK(imuSCKPin); + // initialize SPI1: + //SPI1.begin(); + + if (myIMU.beginSPI(imuCSPin, imuWAKPin, imuINTPin, imuRSTPin) == false) + { + Serial.println("BNO080 over SPI not detected. Are you sure you have all 6 connections? Freezing..."); + while(1); + } + + //You can also call begin with SPI clock speed and SPI port hardware + //myIMU.beginSPI(imuCSPin, imuWAKPin, imuINTPin, imuRSTPin, 1000000); + //myIMU.beginSPI(imuCSPin, imuWAKPin, imuINTPin, imuRSTPin, 3000000, SPI1); + + myIMU.enableLinearAccelerometer(50); // m/s^2 no gravity + myIMU.enableRotationVector(50); // quat + myIMU.enableGyro(50); // rad/s + //myIMU.enableMagnetometer(50); // cannot be enabled at the same time as RotationVector (will not produce data) + + Serial.println(F("LinearAccelerometer enabled, Output in form x, y, z, accuracy, in m/s^2")); + Serial.println(F("Gyro enabled, Output in form x, y, z, accuracy, in radians per second")); + Serial.println(F("Rotation vector, Output in form i, j, k, real, accuracy")); + //Serial.println(F("Magnetometer enabled, Output in form x, y, z, accuracy, in uTesla")); +} + +void loop() +{ + Serial.println("Doing other things"); + delay(10); //You can do many other things. We spend most of our time printing and delaying. + + //Look for data from the IMU + if (myIMU.dataAvailable() == true) + { + // internal copies of the IMU data + float ax, ay, az, gx, gy, gz, qx, qy, qz, qw; // mx, my, mz, // (qx, qy, qz, qw = i,j,k, real) + byte linAccuracy = 0; + byte gyroAccuracy = 0; + //byte magAccuracy = 0; + float quatRadianAccuracy = 0; + byte quatAccuracy = 0; + + // get IMU data in one go for each sensor type + myIMU.getLinAccel(ax, ay, az, linAccuracy); + myIMU.getGyro(gx, gy, gz, gyroAccuracy); + myIMU.getQuat(qx, qy, qz, qw, quatRadianAccuracy, quatAccuracy); + //myIMU.getMag(mx, my, mz, magAccuracy); + + Serial.print(F("acc :")); + Serial.print(ax, 2); + Serial.print(F(",")); + Serial.print(ay, 2); + Serial.print(F(",")); + Serial.print(az, 2); + Serial.print(F(",")); + Serial.print(az, 2); + Serial.print(F(",")); + printAccuracyLevel(linAccuracy); + + Serial.print(F("gyro:")); + Serial.print(gx, 2); + Serial.print(F(",")); + Serial.print(gy, 2); + Serial.print(F(",")); + Serial.print(gz, 2); + Serial.print(F(",")); + printAccuracyLevel(gyroAccuracy); +/* + Serial.print(F("mag :")); + Serial.print(mx, 2); + Serial.print(F(",")); + Serial.print(my, 2); + Serial.print(F(",")); + Serial.print(mz, 2); + Serial.print(F(",")); + printAccuracyLevel(magAccuracy); +*/ + Serial.print(F("quat:")); + Serial.print(qx, 2); + Serial.print(F(",")); + Serial.print(qy, 2); + Serial.print(F(",")); + Serial.print(qz, 2); + Serial.print(F(",")); + Serial.print(qw, 2); + Serial.print(F(",")); + printAccuracyLevel(quatAccuracy); + } +} + +//Given an accuracy number, print what it means +void printAccuracyLevel(byte accuracyNumber) +{ + if (accuracyNumber == 0) Serial.println(F("Unreliable")); + else if (accuracyNumber == 1) Serial.println(F("Low")); + else if (accuracyNumber == 2) Serial.println(F("Medium")); + else if (accuracyNumber == 3) Serial.println(F("High")); +} diff --git a/keywords.txt b/keywords.txt index 41541cd..fd0100a 100644 --- a/keywords.txt +++ b/keywords.txt @@ -50,6 +50,7 @@ dataAvailable KEYWORD2 parseInputReport KEYWORD2 parseCommandReport KEYWORD2 +getQuat KEYWORD2 getQuatI KEYWORD2 getQuatJ KEYWORD2 getQuatK KEYWORD2 @@ -57,26 +58,30 @@ getQuatReal KEYWORD2 getQuatRadianAccuracy KEYWORD2 getQuatAccuracy KEYWORD2 +getAccel KEYWORD2 getAccelX KEYWORD2 getAccelY KEYWORD2 getAccelZ KEYWORD2 getAccelAccuracy KEYWORD2 +getGyro KEYWORD2 getGyroX KEYWORD2 getGyroY KEYWORD2 getGyroZ KEYWORD2 getGyroAccuracy KEYWORD2 +getFastGyro KEYWORD2 getFastGyroX KEYWORD2 getFastGyroY KEYWORD2 getFastGyroZ KEYWORD2 - +getMag KEYWORD2 getMagX KEYWORD2 getMagY KEYWORD2 getMagZ KEYWORD2 getMagAccuracy KEYWORD2 +getLinAccel KEYWORD2 getLinAccelX KEYWORD2 getLinAccelY KEYWORD2 getLinAccelZ KEYWORD2 diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index 8f6c548..430f8ed 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -485,6 +485,18 @@ float BNO080::getYaw() return (yaw); } +//Gets the full quaternion +//i,j,k,real output floats +void BNO080::getQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy) +{ + i = qToFloat(rawQuatI, rotationVector_Q1); + j = qToFloat(rawQuatJ, rotationVector_Q1); + k = qToFloat(rawQuatK, rotationVector_Q1); + real = qToFloat(rawQuatReal, rotationVector_Q1); + radAccuracy = qToFloat(rawQuatRadianAccuracy, rotationVector_Q1); + accuracy = quatAccuracy; +} + //Return the rotation vector quaternion I float BNO080::getQuatI() { @@ -526,6 +538,16 @@ uint8_t BNO080::getQuatAccuracy() return (quatAccuracy); } +//Gets the full acceleration +//x,y,z output floats +void BNO080::getAccel(float &x, float &y, float &z, uint8_t &accuracy) +{ + x = qToFloat(rawAccelX, accelerometer_Q1); + y = qToFloat(rawAccelY, accelerometer_Q1); + z = qToFloat(rawAccelZ, accelerometer_Q1); + accuracy = accelAccuracy; +} + //Return the acceleration component float BNO080::getAccelX() { @@ -555,6 +577,16 @@ uint8_t BNO080::getAccelAccuracy() // linear acceleration, i.e. minus gravity +//Gets the full lin acceleration +//x,y,z output floats +void BNO080::getLinAccel(float &x, float &y, float &z, uint8_t &accuracy) +{ + x = qToFloat(rawLinAccelX, linear_accelerometer_Q1); + y = qToFloat(rawLinAccelY, linear_accelerometer_Q1); + z = qToFloat(rawLinAccelZ, linear_accelerometer_Q1); + accuracy = accelLinAccuracy; +} + //Return the acceleration component float BNO080::getLinAccelX() { @@ -582,6 +614,16 @@ uint8_t BNO080::getLinAccelAccuracy() return (accelLinAccuracy); } +//Gets the full gyro vector +//x,y,z output floats +void BNO080::getGyro(float &x, float &y, float &z, uint8_t &accuracy) +{ + x = qToFloat(rawGyroX, gyro_Q1); + y = qToFloat(rawGyroY, gyro_Q1); + z = qToFloat(rawGyroZ, gyro_Q1); + accuracy = gyroAccuracy; +} + //Return the gyro component float BNO080::getGyroX() { @@ -609,6 +651,16 @@ uint8_t BNO080::getGyroAccuracy() return (gyroAccuracy); } +//Gets the full mag vector +//x,y,z output floats +void BNO080::getMag(float &x, float &y, float &z, uint8_t &accuracy) +{ + x = qToFloat(rawMagX, magnetometer_Q1); + y = qToFloat(rawMagY, magnetometer_Q1); + z = qToFloat(rawMagZ, magnetometer_Q1); + accuracy = magAccuracy; +} + //Return the magnetometer component float BNO080::getMagX() { @@ -636,6 +688,15 @@ uint8_t BNO080::getMagAccuracy() return (magAccuracy); } +//Gets the full high rate gyro vector +//x,y,z output floats +void BNO080::getFastGyro(float &x, float &y, float &z) +{ + x = qToFloat(rawFastGyroX, angular_velocity_Q1); + y = qToFloat(rawFastGyroY, angular_velocity_Q1); + z = qToFloat(rawFastGyroZ, angular_velocity_Q1); +} + // Return the high refresh rate gyro component float BNO080::getFastGyroX() { diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 3a8c2c3..f679551 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -169,6 +169,7 @@ class BNO080 uint16_t parseInputReport(void); //Parse sensor readings out of report uint16_t parseCommandReport(void); //Parse command responses out of report + void getQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy); float getQuatI(); float getQuatJ(); float getQuatK(); @@ -176,25 +177,30 @@ class BNO080 float getQuatRadianAccuracy(); uint8_t getQuatAccuracy(); + void getAccel(float &x, float &y, float &z, uint8_t &accuracy); float getAccelX(); float getAccelY(); float getAccelZ(); uint8_t getAccelAccuracy(); + void getLinAccel(float &x, float &y, float &z, uint8_t &accuracy); float getLinAccelX(); float getLinAccelY(); float getLinAccelZ(); uint8_t getLinAccelAccuracy(); + void getGyro(float &x, float &y, float &z, uint8_t &accuracy); float getGyroX(); float getGyroY(); float getGyroZ(); uint8_t getGyroAccuracy(); + void getFastGyro(float &x, float &y, float &z); float getFastGyroX(); float getFastGyroY(); float getFastGyroZ(); + void getMag(float &x, float &y, float &z, uint8_t &accuracy); float getMagX(); float getMagY(); float getMagZ();