From 2a5b1982ef6d1d6021e47edf9cff26b1b38fdc1d Mon Sep 17 00:00:00 2001 From: Guillaume Walck Date: Tue, 20 Aug 2019 19:08:35 +0200 Subject: [PATCH 1/3] Added support for reading multiple variables at the same time --- .../Example16-AccessMultiple.ino | 163 ++++++++++++++++++ keywords.txt | 7 +- src/SparkFun_BNO080_Arduino_Library.cpp | 61 +++++++ src/SparkFun_BNO080_Arduino_Library.h | 6 + 4 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 examples/Example16-AccessMultiple/Example16-AccessMultiple.ino diff --git a/examples/Example16-AccessMultiple/Example16-AccessMultiple.ino b/examples/Example16-AccessMultiple/Example16-AccessMultiple.ino new file mode 100644 index 0000000..af76a98 --- /dev/null +++ b/examples/Example16-AccessMultiple/Example16-AccessMultiple.ino @@ -0,0 +1,163 @@ +/* + 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 output several data types using helper methods. + + Using SPI1 on Teensy4.0 +*/ + + +#include +#include + +#include "SparkFun_BNO080_Arduino_Library.h" +BNO080 myIMU; + +const byte imuMOSIPin = 26; +const byte imuMISOPin = 1; +const byte imuSCKPin = 27; +const byte imuCSPin = 0; +//Further IMU pins +const byte imuWAKPin = 24; //PS0 +const byte imuINTPin = 25; //INT +const byte imuRSTPin = 2; //RST + +bool imu_initialized = false; +bool imu_calibrated = false; + +// internal copies of the IMU data +float ax, ay, az, gx, gy, gz, mx, my, mz, qx, qy, qz, qw; // (qx, qy, qz, qw = to i,j,k, real) + +bool timer_started = false; + +void setup() { + // set the Slave Select Pins as outputs: + pinMode (imuCSPin, OUTPUT); + + // initialize serial communication at 115200 bits per second: + Serial.begin(115200); + Serial.setTimeout(500); //timeout of 500 ms + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB + } + + // set up the SPI pins utilized on Teensy 4.0 + SPI1.setMOSI(imuMOSIPin); + SPI1.setMISO(imuMISOPin); + SPI1.setSCK(imuSCKPin); + // initialize SPI1: + SPI1.begin(); + + //Setup BNO080 to use SPI1 interface with max BNO080 clk speed of 3MHz + imu_initialized = myIMU.beginSPI(imuCSPin, imuWAKPin, imuINTPin, imuRSTPin, 3000000, SPI1); //changed from slaveCPin + + // Default periodicity (IMU_REFRESH_PERIOD ms) + if (imu_initialized) + { + 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, in m/s^2")); + Serial.println(F("Gyro enabled, Output in form x, y, z, 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, in uTesla")); + } +} + + +void loop() { + + //Look for data from the IMU + if (imu_initialized) + { + if(!imu_calibrated) + { + myIMU.requestCalibrationStatus(); + if(myIMU.calibrationComplete() == true) + { + Serial.println("Device is calibrated"); + imu_calibrated = true; + } + } + + if (myIMU.dataAvailable() == true) + { + byte linAccuracy = 0; + byte gyroAccuracy = 0; + byte magAccuracy = 0; + float quatRadianAccuracy = 0; + byte quatAccuracy = 0; + + 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); + + + if (imu_calibrated) + { + 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); + + } + } + } + else + { + Serial.println("BNO080 not detected. Check your jumpers and the hookup guide. Freezing..."); + while (1); + } +} + +//Given a 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..ceccfba 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..695da24 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(); From 00741aee12726c733b3436bd7cea0cfb840a821c Mon Sep 17 00:00:00 2001 From: Guillaume Walck Date: Fri, 18 Sep 2020 16:53:19 +0200 Subject: [PATCH 2/3] Fixed wrong argument --- .../Example18-AccessMultiple.ino} | 0 src/SparkFun_BNO080_Arduino_Library.cpp | 4 ++-- src/SparkFun_BNO080_Arduino_Library.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename examples/{Example16-AccessMultiple/Example16-AccessMultiple.ino => Example18-AccessMultiple/Example18-AccessMultiple.ino} (100%) diff --git a/examples/Example16-AccessMultiple/Example16-AccessMultiple.ino b/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino similarity index 100% rename from examples/Example16-AccessMultiple/Example16-AccessMultiple.ino rename to examples/Example18-AccessMultiple/Example18-AccessMultiple.ino diff --git a/src/SparkFun_BNO080_Arduino_Library.cpp b/src/SparkFun_BNO080_Arduino_Library.cpp index ceccfba..430f8ed 100644 --- a/src/SparkFun_BNO080_Arduino_Library.cpp +++ b/src/SparkFun_BNO080_Arduino_Library.cpp @@ -487,13 +487,13 @@ float BNO080::getYaw() //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) +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); + radAccuracy = qToFloat(rawQuatRadianAccuracy, rotationVector_Q1); accuracy = quatAccuracy; } diff --git a/src/SparkFun_BNO080_Arduino_Library.h b/src/SparkFun_BNO080_Arduino_Library.h index 695da24..f679551 100644 --- a/src/SparkFun_BNO080_Arduino_Library.h +++ b/src/SparkFun_BNO080_Arduino_Library.h @@ -169,7 +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); + void getQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy); float getQuatI(); float getQuatJ(); float getQuatK(); From 0857fcc478c37cc293b72145a6df9bde6312c2fe Mon Sep 17 00:00:00 2001 From: Guillaume Walck Date: Fri, 18 Sep 2020 16:54:01 +0200 Subject: [PATCH 3/3] Rewrote examples-18 to separate I2C and SPI --- .../Example18-AccessMultiple.ino | 223 ++++++++---------- .../Example18-AccessMultiple.ino | 162 +++++++++++++ 2 files changed, 258 insertions(+), 127 deletions(-) create mode 100644 examples/SPI/Example18-AccessMultiple/Example18-AccessMultiple.ino diff --git a/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino b/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino index af76a98..16236d9 100644 --- a/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino +++ b/examples/Example18-AccessMultiple/Example18-AccessMultiple.ino @@ -5,155 +5,124 @@ Date: September 08th, 2020 License: This code is public domain. - This example shows how to output several data types using helper methods. + This example shows how to access multiple data of one type using helper methods. - Using SPI1 on Teensy4.0 -*/ + 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 -#include "SparkFun_BNO080_Arduino_Library.h" +#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080 BNO080 myIMU; -const byte imuMOSIPin = 26; -const byte imuMISOPin = 1; -const byte imuSCKPin = 27; -const byte imuCSPin = 0; -//Further IMU pins -const byte imuWAKPin = 24; //PS0 -const byte imuINTPin = 25; //INT -const byte imuRSTPin = 2; //RST - -bool imu_initialized = false; -bool imu_calibrated = false; - -// internal copies of the IMU data -float ax, ay, az, gx, gy, gz, mx, my, mz, qx, qy, qz, qw; // (qx, qy, qz, qw = to i,j,k, real) - -bool timer_started = false; - -void setup() { - // set the Slave Select Pins as outputs: - pinMode (imuCSPin, OUTPUT); - - // initialize serial communication at 115200 bits per second: - Serial.begin(115200); - Serial.setTimeout(500); //timeout of 500 ms - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB +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); } - // set up the SPI pins utilized on Teensy 4.0 - SPI1.setMOSI(imuMOSIPin); - SPI1.setMISO(imuMISOPin); - SPI1.setSCK(imuSCKPin); - // initialize SPI1: - SPI1.begin(); + Wire.setClock(400000); //Increase I2C data rate to 400kHz - //Setup BNO080 to use SPI1 interface with max BNO080 clk speed of 3MHz - imu_initialized = myIMU.beginSPI(imuCSPin, imuWAKPin, imuINTPin, imuRSTPin, 3000000, SPI1); //changed from slaveCPin + 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) - // Default periodicity (IMU_REFRESH_PERIOD ms) - if (imu_initialized) - { - 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, in m/s^2")); - Serial.println(F("Gyro enabled, Output in form x, y, z, 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, in uTesla")); - } + 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 (imu_initialized) + if (myIMU.dataAvailable() == true) { - if(!imu_calibrated) - { - myIMU.requestCalibrationStatus(); - if(myIMU.calibrationComplete() == true) - { - Serial.println("Device is calibrated"); - imu_calibrated = true; - } - } - - if (myIMU.dataAvailable() == true) - { - byte linAccuracy = 0; - byte gyroAccuracy = 0; - byte magAccuracy = 0; - float quatRadianAccuracy = 0; - byte quatAccuracy = 0; - - 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); - - - if (imu_calibrated) - { - 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); + // 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); - - } - } - } - else - { - Serial.println("BNO080 not detected. Check your jumpers and the hookup guide. Freezing..."); - while (1); + + 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 a accuracy number, print what it means +//Given an accuracy number, print what it means void printAccuracyLevel(byte accuracyNumber) { if (accuracyNumber == 0) Serial.println(F("Unreliable")); 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")); +}