├── .gitattributes
├── .github
└── workflows
│ └── add_issue_to_project.yml
├── .gitignore
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE.md
├── README.md
├── examples
├── Example_01_RotationVector
│ └── Example_01_RotationVector.ino
├── Example_02_Accelerometer
│ └── Example_02_Accelerometer.ino
├── Example_03_Gyro
│ └── Example_03_Gyro.ino
├── Example_04_Magnetometer
│ └── Example_04_Magnetometer.ino
├── Example_05_StepCounter
│ └── Example_05_StepCounter.ino
├── Example_06_StabilityClassifier
│ └── Example_06_StabilityClassifier.ino
├── Example_07_ActivityClassifier
│ └── Example_07_ActivityClassifier.ino
├── Example_08_AdvancedConfig
│ └── Example_08_AdvancedConfig.ino
├── Example_09_LinearAccelerometer
│ └── Example_09_LinearAccelerometer.ino
├── Example_10_TimeStamp
│ └── Example_10_TimeStamp.ino
├── Example_11_RawReadings
│ └── Example_11_RawReadings.ino
├── Example_12_GyroIntegratedRotationVector
│ └── Example_12_GyroIntegratedRotationVector.ino
├── Example_13_EulerAngles
│ └── Example_13_EulerAngles.ino
├── Example_14_Tare
│ └── Example_14_Tare.ino
├── Example_15_Gravity
│ └── Example_15_Gravity.ino
├── Example_16_UncalibratedGyro
│ └── Example_16_UncalibratedGyro.ino
├── Example_17_ResetCheck
│ └── Example_17_ResetCheck.ino
├── Example_18_Sleep
│ └── Example_18_Sleep.ino
├── Example_19_GeomagneticRotationVector_to_EulerAngles
│ └── Example_19_GeomagneticRotationVector_to_EulerAngles.ino
├── Example_20_CalibrationSettings
│ └── Example_20_CalibrationSettings.ino
└── SPI
│ ├── Example_01_SPI_RotationVector
│ └── Example_01_SPI_RotationVector.ino
│ ├── Example_02_SPI_ResetCheck
│ └── Example_02_SPI_ResetCheck.ino
│ └── Example_03_SPI_Sleep
│ └── Example_03_SPI_Sleep.ino
├── keywords.txt
├── library.properties
└── src
├── NOTICE.txt
├── SparkFun_BNO08x_Arduino_Library.cpp
├── SparkFun_BNO08x_Arduino_Library.h
├── sh2.c
├── sh2.h
├── sh2_SensorValue.c
├── sh2_SensorValue.h
├── sh2_err.h
├── sh2_hal.h
├── sh2_util.c
├── sh2_util.h
├── shtp.c
└── shtp.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.github/workflows/add_issue_to_project.yml:
--------------------------------------------------------------------------------
1 | name: Add new issue to our main project
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 |
8 | jobs:
9 | add-to-project:
10 | name: Add issue to project
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/add-to-project@main
14 | with:
15 | # You can target a project in a different organization
16 | # to the issue
17 | project-url: https://github.com/orgs/sparkfun/projects/19
18 | github-token: ${{ secrets.DEFECT_ADD_TO_PROJECT }}
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ### How to Contribute
2 |
3 | Thank you so *much* for offering to help out. We truly appreciate it.
4 |
5 | If you'd like to contribute, start by searching through the [issues](https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/issues) and [pull requests](https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/pulls) to see whether someone else has raised a similar idea or question.
6 |
7 | If you decide to add a feature to this library, please create a PR following these best practices:
8 |
9 | - Change as little as possible. Do not sumbit a PR that changes 100 lines of whitespace. Break up into multiple PRs if necessary.
10 | - If you've added a new feature document it with a simple example sketch. This serves both as a test of your PR and as a quick way for users to quickly learn how to use your new feature.
11 | - If you add new functions also add them to keywords.txt so that they are properly highlighted in Arduino. [Read more](https://www.arduino.cc/en/Hacking/libraryTutorial).
12 | - Please submit your PR using the [release-candidate branch](https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/tree/release-candidate). That way, we can merge and test your PR quickly without changing the _main_ branch
13 |
14 | ## Style guide
15 |
16 | Please read and follow the [Arduino API style guide](https://www.arduino.cc/en/Reference/APIStyleGuide). Also read and consider the [Arduino style guide](https://www.arduino.cc/en/Reference/StyleGuide).
17 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Subject of the issue
2 | Describe your issue here.
3 |
4 | ### Your workbench
5 | * What development board or microcontroller are you using?
6 | * What version of hardware or breakout board are you using?
7 | * How is the breakout board to your microcontroller?
8 | * How is everything being powered?
9 | * Are there any additional details that may help us help you?
10 |
11 | ### Steps to reproduce
12 | Tell us how to reproduce this issue. Please post stripped down example code demonstrating your issue.
13 |
14 | ### Expected behavior
15 | Tell us what should happen
16 |
17 | ### Actual behavior
18 | Tell us what happens instead
19 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | SparkFun License Information
2 | ============================
3 |
4 | SparkFun uses two different licenses for our files — one for hardware and one for code.
5 |
6 | Hardware
7 | ---------
8 |
9 | **SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).**
10 |
11 | Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode).
12 |
13 | You are free to:
14 |
15 | Share — copy and redistribute the material in any medium or format
16 | Adapt — remix, transform, and build upon the material
17 | for any purpose, even commercially.
18 | The licensor cannot revoke these freedoms as long as you follow the license terms.
19 | Under the following terms:
20 |
21 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
22 | ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
23 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
24 | Notices:
25 |
26 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
27 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
28 |
29 |
30 | Code
31 | --------
32 |
33 | **SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).**
34 |
35 | The MIT License (MIT)
36 |
37 | Copyright (c) 2023 SparkFun Electronics
38 |
39 | Permission is hereby granted, free of charge, to any person obtaining a copy
40 | of this software and associated documentation files (the "Software"), to deal
41 | in the Software without restriction, including without limitation the rights
42 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43 | copies of the Software, and to permit persons to whom the Software is
44 | furnished to do so, subject to the following conditions:
45 |
46 | The above copyright notice and this permission notice shall be included in all
47 | copies or substantial portions of the Software.
48 |
49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55 | SOFTWARE.
56 |
57 | /************* Attribution to prior included work ****************/
58 |
59 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
60 |
61 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
62 | CEVA Sensor Hub Driver, found here:
63 | https://github.com/ceva-dsp/sh2
64 |
65 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
66 | for Adafruit Industries. Found here:
67 | https://github.com/adafruit/Adafruit_BNO08x
68 |
69 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
70 | BusIO library found here:
71 | https://github.com/adafruit/Adafruit_BusIO
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SparkFun VR IMU BNO08X Arduino Library
2 | ===========================================================
3 |
4 | [](https://www.sparkfun.com/products/22857)
5 |
6 | [*SparkFun VR IMU Breakout - BNO086 (Qwiic)(SEN-22857)*](https://www.sparkfun.com/products/22857)
7 |
8 | An Arduino Library for the BNO08x IMU combination triple axis accelerometer/gyro/magnetometer packaged with an ARM Cortex M0+ running powerful algorithms.
9 |
10 | The BNO08x IMU has a combination triple axis accelerometer/gyro/magnetometer packaged with an ARM© Cortex™ M0+ running powerful algorithms. This enables the BNO08x Inertial Measurement Unit (IMU) to produce accurate rotation vector headings with an error of 2 degrees or less. It's what we've been waiting for: all the sensor data is combined into meaningful, accurate IMU information.
11 |
12 | This IC was designed to be implemented in Android based cellular phones to handle all the computations necessary for virtual reality goggles using only your phone. The sensor is quite powerful but with power comes a complex interface. We've written an I2C based library that provides the rotation vector (the reading most folks want from an IMU) as well as raw acceleration, gyro, and magnetometer readings. The sensor is capable of communicating over SPI and UART as well!
13 |
14 | In addition the BNO08x IMU provides a built-in step counter, tap detector, activity classifier (are you running, walking, or sitting still?), and a shake detector. We are duly impressed.
15 |
16 | This Arduino Library was built off the [original library](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library) written by Nathan Seidle ([SparkFun](http://www.sparkfun.com)).
17 |
18 | Thanks to all those who have helped improve this library!
19 |
20 | This BNO086 Library - CEVA-DSP Sh2 Driver-based improvements:
21 | * SFSailor for providing code for Geomagnetic Rotation Vector [issue #10](https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/issues/10)
22 | * LazaroFilm for adding setReorientation() [PR15](https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/pull/15)
23 | * rah2501 for fixing an INT/RST pin bug [PR13](https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/pull/13)
24 |
25 | Original BNO080 Library improvements:
26 | * blendmaster for adding [Linear Accel report](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/4)
27 | * per1234 for fixing our [keywords file](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/12)
28 | * fm4dd for typo - [PR 19](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/19)
29 | * tstellanova for heading accuracy correction - [PR 40](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/40)
30 | * badVibes for gyro integrated rotation vector support - [PR 41](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/41)
31 | * Filimindji for AR/VR Stabilized RotationVector and AR/VR Stabilized GameRotationVector support - [PR 46](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/46)
32 | * ya-mouse for the getreadings improvements - [PR 55](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/55)
33 | * Guillaume for the read-multiple-values helper functions and the interrupt example - [PR56](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/56) & [PR59](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/59)
34 | * aedancullen for the tap detector - [PR 64](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/64)
35 | * mattbradford83 for the hasReset code and example - [PR 92](https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/pull/92)
36 |
37 |
38 |
39 | Repository Contents
40 | -------------------
41 |
42 | * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
43 | * **/src** - Source files for the library (.cpp, .h).
44 | * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE.
45 | * **library.properties** - General library properties for the Arduino package manager.
46 | * **[CONTRIBUTING.md](./CONTRIBUTING.md)** - guidance on how to contribute to this library.
47 |
48 | Documentation
49 | --------------
50 |
51 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
52 | * **[Hookup Guide](https://docs.sparkfun.com/SparkFun_VR_IMU_Breakout_BNO086_QWIIC/)** - Basic hookup guide for the SparkFun VR IMU Breakout - BNO086.
53 | * **[Product Repository](https://github.com/sparkfun/SparkFun_VR_IMU_Breakout_BNO086_QWIIC)** - Main repository for the BNO086 (including hardware files)
54 |
55 | License Information
56 | -------------------
57 |
58 | This product is _**open source**_!
59 |
60 | Please review the LICENSE.md file for license information.
61 |
62 | If you have any questions or concerns on licensing, please contact technical support on our [SparkFun forums](https://forum.sparkfun.com/viewforum.php?f=152).
63 |
64 | Distributed as-is; no warranty is given.
65 |
66 | - Your friends at SparkFun.
67 |
68 | __
69 |
--------------------------------------------------------------------------------
/examples/Example_01_RotationVector/Example_01_RotationVector.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output the i/j/k/real parts of the rotation vector.
5 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
6 |
7 | By: Nathan Seidle
8 | SparkFun Electronics
9 | Date: December 21st, 2017
10 | SparkFun code, firmware, and software is released under the MIT License.
11 | Please see LICENSE.md for further details.
12 |
13 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
14 |
15 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
16 | CEVA Sensor Hub Driver, found here:
17 | https://github.com/ceva-dsp/sh2
18 |
19 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
20 | for Adafruit Industries. Found here:
21 | https://github.com/adafruit/Adafruit_BNO08x
22 |
23 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
24 | BusIO library found here:
25 | https://github.com/adafruit/Adafruit_BusIO
26 |
27 | Hardware Connections:
28 | IoT RedBoard --> BNO08x
29 | QWIIC --> QWIIC
30 | A4 --> INT
31 | A5 --> RST
32 |
33 | BNO08x "mode" jumpers set for I2C (default):
34 | PSO: OPEN
35 | PS1: OPEN
36 |
37 | Serial.print it out at 115200 baud to serial monitor.
38 |
39 | Feel like supporting our work? Buy a board from SparkFun!
40 | https://www.sparkfun.com/products/22857
41 | */
42 |
43 | #include
44 |
45 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
46 | BNO08x myIMU;
47 |
48 | // For the most reliable interaction with the SHTP bus, we need
49 | // to use hardware reset control, and to monitor the H_INT pin.
50 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
51 | // Note, these can be other GPIO if you like.
52 | // Define as -1 to disable these features.
53 | #define BNO08X_INT A4
54 | //#define BNO08X_INT -1
55 | #define BNO08X_RST A5
56 | //#define BNO08X_RST -1
57 |
58 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
59 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
60 |
61 | void setup() {
62 | Serial.begin(115200);
63 |
64 | while(!Serial) delay(10); // Wait for Serial to become available.
65 | // Necessary for boards with native USB (like the SAMD51 Thing+).
66 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
67 | // Comment out this while loop, or it will prevent the remaining code from running.
68 |
69 | Serial.println();
70 | Serial.println("BNO08x Read Example");
71 |
72 | Wire.begin();
73 |
74 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
75 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
76 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
77 | while (1)
78 | ;
79 | }
80 | Serial.println("BNO08x found!");
81 |
82 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
83 |
84 | setReports();
85 |
86 | Serial.println("Reading events");
87 | delay(100);
88 | }
89 |
90 | // Here is where you define the sensor outputs you want to receive
91 | void setReports(void) {
92 | Serial.println("Setting desired reports");
93 | if (myIMU.enableRotationVector() == true) {
94 | Serial.println(F("Rotation vector enabled"));
95 | Serial.println(F("Output in form i, j, k, real, accuracy"));
96 | } else {
97 | Serial.println("Could not enable rotation vector");
98 | }
99 | }
100 |
101 | void loop() {
102 | delay(10);
103 |
104 | if (myIMU.wasReset()) {
105 | Serial.print("sensor was reset ");
106 | setReports();
107 | }
108 |
109 | // Has a new event come in on the Sensor Hub Bus?
110 | if (myIMU.getSensorEvent() == true) {
111 |
112 | // is it the correct sensor data we want?
113 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
114 |
115 | float quatI = myIMU.getQuatI();
116 | float quatJ = myIMU.getQuatJ();
117 | float quatK = myIMU.getQuatK();
118 | float quatReal = myIMU.getQuatReal();
119 | float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
120 |
121 | Serial.print(quatI, 2);
122 | Serial.print(F(","));
123 | Serial.print(quatJ, 2);
124 | Serial.print(F(","));
125 | Serial.print(quatK, 2);
126 | Serial.print(F(","));
127 | Serial.print(quatReal, 2);
128 | Serial.print(F(","));
129 | Serial.print(quatRadianAccuracy, 2);
130 |
131 | Serial.println();
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/examples/Example_02_Accelerometer/Example_02_Accelerometer.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output accelerometer values.
5 |
6 | By: Nathan Seidle
7 | SparkFun Electronics
8 | Date: December 21st, 2017
9 | SparkFun code, firmware, and software is released under the MIT License.
10 | Please see LICENSE.md for further details.
11 |
12 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
13 |
14 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
15 | CEVA Sensor Hub Driver, found here:
16 | https://github.com/ceva-dsp/sh2
17 |
18 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
19 | for Adafruit Industries. Found here:
20 | https://github.com/adafruit/Adafruit_BNO08x
21 |
22 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
23 | BusIO library found here:
24 | https://github.com/adafruit/Adafruit_BusIO
25 |
26 | Hardware Connections:
27 | IoT RedBoard --> BNO08x
28 | QWIIC --> QWIIC
29 | A4 --> INT
30 | A5 --> RST
31 |
32 | BNO08x "mode" jumpers set for I2C (default):
33 | PSO: OPEN
34 | PS1: OPEN
35 |
36 | Serial.print it out at 115200 baud to serial monitor.
37 |
38 | Feel like supporting our work? Buy a board from SparkFun!
39 | https://www.sparkfun.com/products/22857
40 | */
41 |
42 | #include
43 |
44 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
45 | BNO08x myIMU;
46 |
47 | // For the most reliable interaction with the SHTP bus, we need
48 | // to use hardware reset control, and to monitor the H_INT pin.
49 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
50 | // Note, these can be other GPIO if you like.
51 | // Define as -1 to disable these features.
52 | #define BNO08X_INT A4
53 | //#define BNO08X_INT -1
54 | #define BNO08X_RST A5
55 | //#define BNO08X_RST -1
56 |
57 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
58 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
59 |
60 | void setup() {
61 | Serial.begin(115200);
62 |
63 | while(!Serial) delay(10); // Wait for Serial to become available.
64 | // Necessary for boards with native USB (like the SAMD51 Thing+).
65 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
66 | // Comment out this while loop, or it will prevent the remaining code from running.
67 |
68 | Serial.println();
69 | Serial.println("BNO08x Read Example");
70 |
71 | Wire.begin();
72 |
73 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
74 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
75 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
76 | while (1)
77 | ;
78 | }
79 | Serial.println("BNO08x found!");
80 |
81 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
82 |
83 | setReports();
84 |
85 | Serial.println("Reading events");
86 | delay(100);
87 | }
88 |
89 | // Here is where you define the sensor outputs you want to receive
90 | void setReports(void) {
91 | Serial.println("Setting desired reports");
92 | if (myIMU.enableAccelerometer() == true) {
93 | Serial.println(F("Accelerometer enabled"));
94 | Serial.println(F("Output in form x, y, z, in m/s^2"));
95 | } else {
96 | Serial.println("Could not enable accelerometer");
97 | }
98 | }
99 |
100 | void loop() {
101 | delay(10);
102 |
103 | if (myIMU.wasReset()) {
104 | Serial.print("sensor was reset ");
105 | setReports();
106 | }
107 |
108 | // Has a new event come in on the Sensor Hub Bus?
109 | if (myIMU.getSensorEvent() == true) {
110 |
111 | // is it the correct sensor data we want?
112 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ACCELEROMETER) {
113 |
114 | float x = myIMU.getAccelX();
115 | float y = myIMU.getAccelY();
116 | float z = myIMU.getAccelZ();
117 |
118 | Serial.print(x, 2);
119 | Serial.print(F(","));
120 | Serial.print(y, 2);
121 | Serial.print(F(","));
122 | Serial.print(z, 2);
123 |
124 | Serial.println();
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/examples/Example_03_Gyro/Example_03_Gyro.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output the parts of the calibrated gyro.
5 |
6 | By: Nathan Seidle
7 | SparkFun Electronics
8 | Date: December 21st, 2017
9 | SparkFun code, firmware, and software is released under the MIT License.
10 | Please see LICENSE.md for further details.
11 |
12 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
13 |
14 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
15 | CEVA Sensor Hub Driver, found here:
16 | https://github.com/ceva-dsp/sh2
17 |
18 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
19 | for Adafruit Industries. Found here:
20 | https://github.com/adafruit/Adafruit_BNO08x
21 |
22 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
23 | BusIO library found here:
24 | https://github.com/adafruit/Adafruit_BusIO
25 |
26 | Hardware Connections:
27 | IoT RedBoard --> BNO08x
28 | QWIIC --> QWIIC
29 | A4 --> INT
30 | A5 --> RST
31 |
32 | BNO08x "mode" jumpers set for I2C (default):
33 | PSO: OPEN
34 | PS1: OPEN
35 |
36 | Serial.print it out at 115200 baud to serial monitor.
37 |
38 | Feel like supporting our work? Buy a board from SparkFun!
39 | https://www.sparkfun.com/products/22857
40 | */
41 |
42 | #include
43 |
44 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
45 |
46 | BNO08x myIMU;
47 |
48 | // For the most reliable interaction with the SHTP bus, we need
49 | // to use hardware reset control, and to monitor the H_INT pin.
50 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
51 | // Note, these can be other GPIO if you like.
52 | // Define as -1 to disable these features.
53 | #define BNO08X_INT A4
54 | //#define BNO08X_INT -1
55 | #define BNO08X_RST A5
56 | //#define BNO08X_RST -1
57 |
58 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
59 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
60 |
61 | void setup() {
62 | Serial.begin(115200);
63 |
64 | while(!Serial) delay(10); // Wait for Serial to become available.
65 | // Necessary for boards with native USB (like the SAMD51 Thing+).
66 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
67 | // Comment out this while loop, or it will prevent the remaining code from running.
68 |
69 | Serial.println();
70 | Serial.println("BNO08x Read Example");
71 |
72 | Wire.begin();
73 |
74 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
75 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
76 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
77 | while (1)
78 | ;
79 | }
80 | Serial.println("BNO08x found!");
81 |
82 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
83 |
84 | setReports();
85 |
86 | Serial.println("Reading events");
87 | delay(100);
88 | }
89 |
90 | // Here is where you define the sensor outputs you want to receive
91 | void setReports(void) {
92 | Serial.println("Setting desired reports");
93 | if (myIMU.enableGyro() == true) {
94 | Serial.println(F("Gyro enabled"));
95 | Serial.println(F("Output in form x, y, z, in radians per second"));
96 | } else {
97 | Serial.println("Could not enable gyro");
98 | }
99 | }
100 |
101 | void loop() {
102 | delay(10);
103 |
104 | if (myIMU.wasReset()) {
105 | Serial.print("sensor was reset ");
106 | setReports();
107 | }
108 |
109 | // Has a new event come in on the Sensor Hub Bus?
110 | if (myIMU.getSensorEvent() == true) {
111 |
112 | // is it the correct sensor data we want?
113 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_GYROSCOPE_CALIBRATED) {
114 |
115 | float x = myIMU.getGyroX();
116 | float y = myIMU.getGyroY();
117 | float z = myIMU.getGyroZ();
118 |
119 | Serial.print(x, 2);
120 | Serial.print(F(","));
121 | Serial.print(y, 2);
122 | Serial.print(F(","));
123 | Serial.print(z, 2);
124 |
125 | Serial.println();
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/examples/Example_04_Magnetometer/Example_04_Magnetometer.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output the parts of the magnetometer.
5 |
6 | By: Nathan Seidle
7 | SparkFun Electronics
8 | Date: December 21st, 2017
9 | SparkFun code, firmware, and software is released under the MIT License.
10 | Please see LICENSE.md for further details.
11 |
12 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
13 |
14 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
15 | CEVA Sensor Hub Driver, found here:
16 | https://github.com/ceva-dsp/sh2
17 |
18 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
19 | for Adafruit Industries. Found here:
20 | https://github.com/adafruit/Adafruit_BNO08x
21 |
22 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
23 | BusIO library found here:
24 | https://github.com/adafruit/Adafruit_BusIO
25 |
26 | Hardware Connections:
27 | IoT RedBoard --> BNO08x
28 | QWIIC --> QWIIC
29 | A4 --> INT
30 | A5 --> RST
31 |
32 | BNO08x "mode" jumpers set for I2C (default):
33 | PSO: OPEN
34 | PS1: OPEN
35 |
36 | Serial.print it out at 115200 baud to serial monitor.
37 |
38 | Feel like supporting our work? Buy a board from SparkFun!
39 | https://www.sparkfun.com/products/22857
40 | */
41 |
42 | #include
43 |
44 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
45 |
46 | BNO08x myIMU;
47 |
48 | // For the most reliable interaction with the SHTP bus, we need
49 | // to use hardware reset control, and to monitor the H_INT pin.
50 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
51 | // Note, these can be other GPIO if you like.
52 | // Define as -1 to disable these features.
53 | #define BNO08X_INT A4
54 | //#define BNO08X_INT -1
55 | #define BNO08X_RST A5
56 | //#define BNO08X_RST -1
57 |
58 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
59 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
60 |
61 | void setup() {
62 | Serial.begin(115200);
63 |
64 | while(!Serial) delay(10); // Wait for Serial to become available.
65 | // Necessary for boards with native USB (like the SAMD51 Thing+).
66 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
67 | // Comment out this while loop, or it will prevent the remaining code from running.
68 |
69 | Serial.println();
70 | Serial.println("BNO08x Read Example");
71 |
72 | Wire.begin();
73 |
74 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
75 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
76 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
77 | while (1)
78 | ;
79 | }
80 | Serial.println("BNO08x found!");
81 |
82 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
83 |
84 | setReports();
85 |
86 | Serial.println("Reading events");
87 | delay(100);
88 | }
89 |
90 | // Here is where you define the sensor outputs you want to receive
91 | void setReports(void) {
92 | Serial.println("Setting desired reports");
93 | if (myIMU.enableMagnetometer() == true) {
94 | Serial.println(F("Magnetometer enabled"));
95 | Serial.println(F("Output in form x, y, z, in uTesla"));
96 | } else {
97 | Serial.println("Could not enable magnetometer");
98 | }
99 | }
100 |
101 | void loop() {
102 | delay(10);
103 |
104 | if (myIMU.wasReset()) {
105 | Serial.print("sensor was reset ");
106 | setReports();
107 | }
108 |
109 | // Has a new event come in on the Sensor Hub Bus?
110 | if (myIMU.getSensorEvent() == true) {
111 |
112 | // is it the correct sensor data we want?
113 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_MAGNETIC_FIELD) {
114 |
115 | float x = myIMU.getMagX();
116 | float y = myIMU.getMagY();
117 | float z = myIMU.getMagZ();
118 | byte accuracy = myIMU.getMagAccuracy();
119 |
120 | Serial.print(x, 2);
121 | Serial.print(F(","));
122 | Serial.print(y, 2);
123 | Serial.print(F(","));
124 | Serial.print(z, 2);
125 | Serial.print(F(","));
126 | printAccuracyLevel(accuracy);
127 |
128 | Serial.println();
129 | }
130 | }
131 | }
132 |
133 | //Given a accuracy number, print what it means
134 | void printAccuracyLevel(byte accuracyNumber)
135 | {
136 | if(accuracyNumber == 0) Serial.print(F("Unreliable"));
137 | else if(accuracyNumber == 1) Serial.print(F("Low"));
138 | else if(accuracyNumber == 2) Serial.print(F("Medium"));
139 | else if(accuracyNumber == 3) Serial.print(F("High"));
140 | }
141 |
--------------------------------------------------------------------------------
/examples/Example_05_StepCounter/Example_05_StepCounter.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows the step count. Tap the IC a few times to emulate a step.
5 |
6 | By: Nathan Seidle
7 | SparkFun Electronics
8 | Date: December 21st, 2017
9 | SparkFun code, firmware, and software is released under the MIT License.
10 | Please see LICENSE.md for further details.
11 |
12 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
13 |
14 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
15 | CEVA Sensor Hub Driver, found here:
16 | https://github.com/ceva-dsp/sh2
17 |
18 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
19 | for Adafruit Industries. Found here:
20 | https://github.com/adafruit/Adafruit_BNO08x
21 |
22 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
23 | BusIO library found here:
24 | https://github.com/adafruit/Adafruit_BusIO
25 |
26 | Hardware Connections:
27 | IoT RedBoard --> BNO08x
28 | QWIIC --> QWIIC
29 | A4 --> INT
30 | A5 --> RST
31 |
32 | BNO08x "mode" jumpers set for I2C (default):
33 | PSO: OPEN
34 | PS1: OPEN
35 |
36 | Serial.print it out at 115200 baud to serial monitor.
37 |
38 | Feel like supporting our work? Buy a board from SparkFun!
39 | https://www.sparkfun.com/products/22857
40 | */
41 |
42 | #include
43 |
44 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
45 | BNO08x myIMU;
46 |
47 | // For the most reliable interaction with the SHTP bus, we need
48 | // to use hardware reset control, and to monitor the H_INT pin.
49 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
50 | // Note, these can be other GPIO if you like.
51 | // Define as -1 to disable these features.
52 | #define BNO08X_INT A4
53 | //#define BNO08X_INT -1
54 | #define BNO08X_RST A5
55 | //#define BNO08X_RST -1
56 |
57 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
58 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
59 |
60 | void setup() {
61 | Serial.begin(115200);
62 |
63 | while(!Serial) delay(10); // Wait for Serial to become available.
64 | // Necessary for boards with native USB (like the SAMD51 Thing+).
65 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
66 | // Comment out this while loop, or it will prevent the remaining code from running.
67 |
68 | Serial.println();
69 | Serial.println("BNO08x Read Example");
70 |
71 | Wire.begin();
72 |
73 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
74 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
75 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
76 | while (1)
77 | ;
78 | }
79 | Serial.println("BNO08x found!");
80 |
81 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
82 |
83 | setReports();
84 |
85 | Serial.println("Reading events");
86 | delay(100);
87 | }
88 |
89 | // Here is where you define the sensor outputs you want to receive
90 | void setReports(void) {
91 | Serial.println("Setting desired reports");
92 | if (myIMU.enableStepCounter(500) == true) { //Send data update every 500ms
93 | Serial.println(F("Step Counter enabled"));
94 | Serial.println(F("Step count since sketch started:"));
95 | } else {
96 | Serial.println("Could not step counter");
97 | }
98 | }
99 |
100 | void loop() {
101 | delay(500); // step counter needs a little longer of delay (200ms or more)
102 |
103 | if (myIMU.wasReset()) {
104 | Serial.print("sensor was reset ");
105 | setReports();
106 | }
107 |
108 | // Has a new event come in on the Sensor Hub Bus?
109 | if (myIMU.getSensorEvent() == true) {
110 |
111 | // is it the correct sensor data we want?
112 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_STEP_COUNTER) {
113 |
114 | unsigned int steps = myIMU.getStepCount();
115 |
116 | Serial.print(steps);
117 |
118 | Serial.println();
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/examples/Example_06_StabilityClassifier/Example_06_StabilityClassifier.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to use the stability classifier:
5 | Are we on a table, stationary, stable, or moving?
6 |
7 | By: Nathan Seidle
8 | SparkFun Electronics
9 | Date: December 21st, 2017
10 | SparkFun code, firmware, and software is released under the MIT License.
11 | Please see LICENSE.md for further details.
12 |
13 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
14 |
15 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
16 | CEVA Sensor Hub Driver, found here:
17 | https://github.com/ceva-dsp/sh2
18 |
19 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
20 | for Adafruit Industries. Found here:
21 | https://github.com/adafruit/Adafruit_BNO08x
22 |
23 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
24 | BusIO library found here:
25 | https://github.com/adafruit/Adafruit_BusIO
26 |
27 | Hardware Connections:
28 | IoT RedBoard --> BNO08x
29 | QWIIC --> QWIIC
30 | A4 --> INT
31 | A5 --> RST
32 |
33 | BNO08x "mode" jumpers set for I2C (default):
34 | PSO: OPEN
35 | PS1: OPEN
36 |
37 | Serial.print it out at 115200 baud to serial monitor.
38 |
39 | Feel like supporting our work? Buy a board from SparkFun!
40 | https://www.sparkfun.com/products/22857
41 | */
42 |
43 | #include
44 |
45 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
46 | BNO08x myIMU;
47 |
48 | // For the most reliable interaction with the SHTP bus, we need
49 | // to use hardware reset control, and to monitor the H_INT pin.
50 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
51 | // Note, these can be other GPIO if you like.
52 | // Define as -1 to disable these features.
53 | #define BNO08X_INT A4
54 | //#define BNO08X_INT -1
55 | #define BNO08X_RST A5
56 | //#define BNO08X_RST -1
57 |
58 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
59 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
60 |
61 | void setup() {
62 | Serial.begin(115200);
63 |
64 | while(!Serial) delay(10); // Wait for Serial to become available.
65 | // Necessary for boards with native USB (like the SAMD51 Thing+).
66 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
67 | // Comment out this while loop, or it will prevent the remaining code from running.
68 |
69 | Serial.println();
70 | Serial.println("BNO08x Read Example");
71 |
72 | Wire.begin();
73 |
74 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
75 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
76 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
77 | while (1)
78 | ;
79 | }
80 | Serial.println("BNO08x found!");
81 |
82 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
83 |
84 | setReports();
85 |
86 | Serial.println("Reading events");
87 | delay(100);
88 | }
89 |
90 | // Here is where you define the sensor outputs you want to receive
91 | void setReports(void) {
92 | Serial.println("Setting desired reports");
93 |
94 | if (myIMU.enableStabilityClassifier() == true) {
95 | Serial.println(F("Stability Classifier enabled"));
96 | } else {
97 | Serial.println("Could not enable Stability Classifier");
98 | }
99 | }
100 |
101 | void loop() {
102 | delay(10);
103 |
104 | if (myIMU.wasReset()) {
105 | Serial.print("sensor was reset ");
106 | setReports();
107 | }
108 |
109 | // Has a new event come in on the Sensor Hub Bus?
110 | if (myIMU.getSensorEvent() == true) {
111 |
112 | // is it the correct sensor data we want?
113 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_STABILITY_CLASSIFIER) {
114 |
115 | byte classification = myIMU.getStabilityClassifier();
116 |
117 | if(classification == STABILITY_CLASSIFIER_UNKNOWN) Serial.print(F("Unknown classification"));
118 | else if(classification == STABILITY_CLASSIFIER_ON_TABLE) Serial.print(F("On table"));
119 | else if(classification == STABILITY_CLASSIFIER_STATIONARY) Serial.print(F("Stationary"));
120 | else if(classification == STABILITY_CLASSIFIER_STABLE) Serial.print(F("Stable"));
121 | else if(classification == STABILITY_CLASSIFIER_MOTION) Serial.print(F("Motion"));
122 | else if(classification == STABILITY_CLASSIFIER_RESERVED) Serial.print(F("[Reserved]"));
123 |
124 | Serial.println();
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/examples/Example_07_ActivityClassifier/Example_07_ActivityClassifier.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This is a fun one! The BNO08x can guess at what activity you are doing:
5 |
6 | In vehicle
7 | On bicycle
8 | On foot
9 | Still
10 | Tilting
11 | Walking
12 | Running
13 | On stairs
14 | This example shows how to read the confidence levels of each activity
15 |
16 | By: Nathan Seidle
17 | SparkFun Electronics
18 | Date: December 21st, 2017
19 | SparkFun code, firmware, and software is released under the MIT License.
20 | Please see LICENSE.md for further details.
21 |
22 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
23 |
24 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
25 | CEVA Sensor Hub Driver, found here:
26 | https://github.com/ceva-dsp/sh2
27 |
28 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
29 | for Adafruit Industries. Found here:
30 | https://github.com/adafruit/Adafruit_BNO08x
31 |
32 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
33 | BusIO library found here:
34 | https://github.com/adafruit/Adafruit_BusIO
35 |
36 | Hardware Connections:
37 | IoT RedBoard --> BNO08x
38 | QWIIC --> QWIIC
39 | A4 --> INT
40 | A5 --> RST
41 |
42 | BNO08x "mode" jumpers set for I2C (default):
43 | PSO: OPEN
44 | PS1: OPEN
45 |
46 | Serial.print it out at 115200 baud to serial monitor.
47 |
48 | Feel like supporting our work? Buy a board from SparkFun!
49 | https://www.sparkfun.com/products/22857
50 | */
51 |
52 | #include
53 |
54 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
55 |
56 | BNO08x myIMU;
57 |
58 | // For the most reliable interaction with the SHTP bus, we need
59 | // to use hardware reset control, and to monitor the H_INT pin.
60 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
61 | // Note, these can be other GPIO if you like.
62 | // Define as -1 to disable these features.
63 | #define BNO08X_INT A4
64 | //#define BNO08X_INT -1
65 | #define BNO08X_RST A5
66 | //#define BNO08X_RST -1
67 |
68 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
69 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
70 |
71 | void setup() {
72 | Serial.begin(115200);
73 |
74 | while(!Serial) delay(10); // Wait for Serial to become available.
75 | // Necessary for boards with native USB (like the SAMD51 Thing+).
76 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
77 | // Comment out this while loop, or it will prevent the remaining code from running.
78 |
79 | Serial.println();
80 | Serial.println("BNO08x Read Example");
81 |
82 | Wire.begin();
83 |
84 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
85 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
86 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
87 | while (1)
88 | ;
89 | }
90 | Serial.println("BNO08x found!");
91 |
92 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
93 |
94 | setReports();
95 |
96 | Serial.println("Reading events");
97 | delay(100);
98 | }
99 |
100 | // Here is where you define the sensor outputs you want to receive
101 | void setReports(void) {
102 |
103 | Serial.println("Setting desired reports");
104 |
105 | //See page 73 of reference manual. There is a 32 bit word where each
106 | //bit enables a different possible activity. Currently there are only 8
107 | //possible. Let's enable all of them!
108 | uint32_t enableActivities = 0x1F; //Enable all 9 possible activities including Unknown
109 |
110 | //Send data update every 1000ms, with sensor specific config word
111 |
112 | if (myIMU.enableActivityClassifier(1000, enableActivities) == true) {
113 | Serial.println(F("Activity Classifier enabled"));
114 | } else {
115 | Serial.println("Could not enable Activity Classifier");
116 | }
117 | }
118 |
119 | void loop() {
120 | delay(1000); // Personal Activity Classifier needs longer delay here than other examples
121 |
122 | if (myIMU.wasReset()) {
123 | Serial.print("sensor was reset ");
124 | setReports();
125 | }
126 |
127 | // Has a new event come in on the Sensor Hub Bus?
128 | if (myIMU.getSensorEvent() == true) {
129 |
130 | // is it the correct sensor data we want?
131 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER) {
132 |
133 | byte mostLikelyActivity = myIMU.getActivityClassifier();
134 |
135 | Serial.print("Most likely activity: ");
136 | printActivityName(mostLikelyActivity);
137 | Serial.println();
138 |
139 | Serial.println("Confidence levels:");
140 | for(int x = 0 ; x < 9 ; x++)
141 | {
142 | printActivityName(x);
143 | Serial.print(F(") "));
144 | Serial.print(myIMU.getActivityConfidence(x));
145 | Serial.print(F("%"));
146 | Serial.println();
147 | }
148 |
149 | Serial.println();
150 | }
151 | }
152 | }
153 |
154 | //Given a number between 0 and 8, print the name of the activity
155 | //See page 73 of reference manual for activity list
156 | void printActivityName(byte activityNumber)
157 | {
158 | if(activityNumber == 0) Serial.print("Unknown");
159 | else if(activityNumber == 1) Serial.print("In vehicle");
160 | else if(activityNumber == 2) Serial.print("On bicycle");
161 | else if(activityNumber == 3) Serial.print("On foot");
162 | else if(activityNumber == 4) Serial.print("Still");
163 | else if(activityNumber == 5) Serial.print("Tilting");
164 | else if(activityNumber == 6) Serial.print("Walking");
165 | else if(activityNumber == 7) Serial.print("Running");
166 | else if(activityNumber == 8) Serial.print("On stairs");
167 | }
168 |
--------------------------------------------------------------------------------
/examples/Example_08_AdvancedConfig/Example_08_AdvancedConfig.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to configure the sensor with different I2C address
5 | (0x4A) and different Wire ports (Wire1, on SDA:25, SCL:17).
6 |
7 | Note, for this example to work, you must close the address jumper on the
8 | bottom of the PCB, and wire up SDA/SCL to their newly defined pins (25/17).
9 |
10 | It will output the i/j/k/real parts of the rotation vector.
11 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
12 |
13 | By: Nathan Seidle
14 | SparkFun Electronics
15 | Date: December 21st, 2017
16 | SparkFun code, firmware, and software is released under the MIT License.
17 | Please see LICENSE.md for further details.
18 |
19 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
20 |
21 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
22 | CEVA Sensor Hub Driver, found here:
23 | https://github.com/ceva-dsp/sh2
24 |
25 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
26 | for Adafruit Industries. Found here:
27 | https://github.com/adafruit/Adafruit_BNO08x
28 |
29 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
30 | BusIO library found here:
31 | https://github.com/adafruit/Adafruit_BusIO
32 |
33 | IoT RedBoard --> BNO08x
34 | 3.3V --> 3.3V
35 | GND --> GND
36 | SCL1 (D17) --> SCL
37 | SDA1 (D25) --> SDA
38 | A4 --> INT
39 | A5 --> RST
40 |
41 | Note: Make sure to close the ADR jumper on the back of the board as well.
42 |
43 | Serial.print it out at 115200 baud to serial monitor.
44 |
45 | Feel like supporting our work? Buy a board from SparkFun!
46 | https://www.sparkfun.com/products/22857
47 | */
48 |
49 | #include
50 |
51 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
52 | BNO08x myIMU;
53 |
54 | // For the most reliable interaction with the SHTP bus, we need
55 | // to use hardware reset control, and to monitor the H_INT pin.
56 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
57 | // Note, these can be other GPIO if you like.
58 | // Define as -1 to disable these features.
59 | #define BNO08X_INT A4
60 | //#define BNO08X_INT -1
61 | #define BNO08X_RST A5
62 | //#define BNO08X_RST -1
63 |
64 | //#define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
65 | #define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
66 |
67 | // define some pins for our new I2C port, aka "Wire1"
68 | // on a SparkFun ESP32 IoT REdboard, these can be most pins, except those that
69 | // are only inputs.
70 | #define I2C_SDA1 25
71 | #define I2C_SCL1 17
72 |
73 | void setup() {
74 | Serial.begin(115200);
75 |
76 | while(!Serial) delay(10); // Wait for Serial to become available.
77 | // Necessary for boards with native USB (like the SAMD51 Thing+).
78 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
79 | // Comment out this while loop, or it will prevent the remaining code from running.
80 |
81 | Serial.println();
82 | Serial.println("BNO08x Read Example");
83 |
84 | Wire1.begin(I2C_SDA1, I2C_SCL1, 100000);
85 |
86 | // Wire1.begin(); // Some Arduino boards have pre-defined Wire1 SDA/SCL pins,
87 | // When using these, you don't have to supply the pin arguments, and they
88 | // are usually labled on the board as "SDA1" and "SCL1".
89 |
90 | // The first argument of our BNO08x begin() function is the I2C address of the
91 | // sensor, either 0x4B (default) or 0x4A. The second is the TwoWire I2C port
92 | // to use. Wire, Wire1, etc.
93 | if (myIMU.begin(BNO08X_ADDR, Wire1, BNO08X_INT, BNO08X_RST) == false) {
94 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
95 | while (1)
96 | ;
97 | }
98 | Serial.println("BNO08x found!");
99 |
100 | // Wire1.setClock(400000); //Increase I2C data rate to 400kHz
101 |
102 | setReports();
103 |
104 | Serial.println("Reading events");
105 | delay(100);
106 | }
107 |
108 | // Here is where you define the sensor outputs you want to receive
109 | void setReports(void) {
110 | Serial.println("Setting desired reports");
111 | if (myIMU.enableRotationVector() == true) {
112 | Serial.println(F("Rotation vector enabled"));
113 | Serial.println(F("Output in form i, j, k, real, accuracy"));
114 | } else {
115 | Serial.println("Could not enable rotation vector");
116 | }
117 | }
118 |
119 | void loop() {
120 | delay(10);
121 |
122 | if (myIMU.wasReset()) {
123 | Serial.print("sensor was reset ");
124 | setReports();
125 | }
126 |
127 | // Has a new event come in on the Sensor Hub Bus?
128 | if (myIMU.getSensorEvent() == true) {
129 |
130 | // is it the correct sensor data we want?
131 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
132 |
133 | float quatI = myIMU.getQuatI();
134 | float quatJ = myIMU.getQuatJ();
135 | float quatK = myIMU.getQuatK();
136 | float quatReal = myIMU.getQuatReal();
137 | float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
138 |
139 | Serial.print(quatI, 2);
140 | Serial.print(F(","));
141 | Serial.print(quatJ, 2);
142 | Serial.print(F(","));
143 | Serial.print(quatK, 2);
144 | Serial.print(F(","));
145 | Serial.print(quatReal, 2);
146 | Serial.print(F(","));
147 | Serial.print(quatRadianAccuracy, 2);
148 |
149 | Serial.println();
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/examples/Example_09_LinearAccelerometer/Example_09_LinearAccelerometer.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output linear accelerometer values.
5 |
6 | By: Nathan Seidle
7 | SparkFun Electronics
8 | Date: December 21st, 2017
9 | SparkFun code, firmware, and software is released under the MIT License.
10 | Please see LICENSE.md for further details.
11 |
12 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
13 |
14 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
15 | CEVA Sensor Hub Driver, found here:
16 | https://github.com/ceva-dsp/sh2
17 |
18 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
19 | for Adafruit Industries. Found here:
20 | https://github.com/adafruit/Adafruit_BNO08x
21 |
22 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
23 | BusIO library found here:
24 | https://github.com/adafruit/Adafruit_BusIO
25 |
26 | Hardware Connections:
27 | IoT RedBoard --> BNO08x
28 | QWIIC --> QWIIC
29 | A4 --> INT
30 | A5 --> RST
31 |
32 | BNO08x "mode" jumpers set for I2C (default):
33 | PSO: OPEN
34 | PS1: OPEN
35 |
36 | Serial.print it out at 115200 baud to serial monitor.
37 |
38 | Feel like supporting our work? Buy a board from SparkFun!
39 | https://www.sparkfun.com/products/22857
40 | */
41 |
42 | #include
43 |
44 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
45 |
46 | BNO08x myIMU;
47 |
48 | // For the most reliable interaction with the SHTP bus, we need
49 | // to use hardware reset control, and to monitor the H_INT pin.
50 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
51 | // Note, these can be other GPIO if you like.
52 | // Define as -1 to disable these features.
53 | #define BNO08X_INT A4
54 | //#define BNO08X_INT -1
55 | #define BNO08X_RST A5
56 | //#define BNO08X_RST -1
57 |
58 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
59 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
60 |
61 | void setup() {
62 | Serial.begin(115200);
63 |
64 | while(!Serial) delay(10); // Wait for Serial to become available.
65 | // Necessary for boards with native USB (like the SAMD51 Thing+).
66 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
67 | // Comment out this while loop, or it will prevent the remaining code from running.
68 |
69 | Serial.println();
70 | Serial.println("BNO08x Read Example");
71 |
72 | Wire.begin();
73 |
74 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
75 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
76 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
77 | while (1)
78 | ;
79 | }
80 | Serial.println("BNO08x found!");
81 |
82 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
83 |
84 | setReports();
85 |
86 | Serial.println("Reading events");
87 | delay(100);
88 | }
89 |
90 | // Here is where you define the sensor outputs you want to receive
91 | void setReports(void) {
92 | Serial.println("Setting desired reports");
93 | if (myIMU.enableLinearAccelerometer() == true) {
94 | Serial.println(F("Linear Accelerometer enabled"));
95 | Serial.println(F("Output in form x, y, z, in m/s^2"));
96 | } else {
97 | Serial.println("Could not enable linear accelerometer");
98 | }
99 | }
100 |
101 | void loop() {
102 | delay(10);
103 |
104 | if (myIMU.wasReset()) {
105 | Serial.print("sensor was reset ");
106 | setReports();
107 | }
108 |
109 | // Has a new event come in on the Sensor Hub Bus?
110 | if (myIMU.getSensorEvent() == true) {
111 |
112 | // is it the correct sensor data we want?
113 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_LINEAR_ACCELERATION) {
114 |
115 | float x = myIMU.getLinAccelX();
116 | float y = myIMU.getLinAccelY();
117 | float z = myIMU.getLinAccelZ();
118 | byte linAccuracy = myIMU.getLinAccelAccuracy();
119 |
120 | Serial.print(x, 2);
121 | Serial.print(F(","));
122 | Serial.print(y, 2);
123 | Serial.print(F(","));
124 | Serial.print(z, 2);
125 | Serial.print(F(","));
126 | Serial.print(linAccuracy);
127 |
128 | Serial.println();
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/examples/Example_10_TimeStamp/Example_10_TimeStamp.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output the timestamp for each reading.
5 |
6 | It outputs the timestampe/i/j/k/real/accuracy parts of the rotation vector.
7 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
8 |
9 | By: Nathan Seidle
10 | SparkFun Electronics
11 | Date: December 21st, 2017
12 | SparkFun code, firmware, and software is released under the MIT License.
13 | Please see LICENSE.md for further details.
14 |
15 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
16 |
17 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
18 | CEVA Sensor Hub Driver, found here:
19 | https://github.com/ceva-dsp/sh2
20 |
21 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
22 | for Adafruit Industries. Found here:
23 | https://github.com/adafruit/Adafruit_BNO08x
24 |
25 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
26 | BusIO library found here:
27 | https://github.com/adafruit/Adafruit_BusIO
28 |
29 | Hardware Connections:
30 | IoT RedBoard --> BNO08x
31 | QWIIC --> QWIIC
32 | A4 --> INT
33 | A5 --> RST
34 |
35 | BNO08x "mode" jumpers set for I2C (default):
36 | PSO: OPEN
37 | PS1: OPEN
38 |
39 | Serial.print it out at 115200 baud to serial monitor.
40 |
41 | Feel like supporting our work? Buy a board from SparkFun!
42 | https://www.sparkfun.com/products/22857
43 | */
44 |
45 | #include
46 |
47 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
48 | BNO08x myIMU;
49 |
50 | // For the most reliable interaction with the SHTP bus, we need
51 | // to use hardware reset control, and to monitor the H_INT pin.
52 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
53 | // Note, these can be other GPIO if you like.
54 | // Define as -1 to disable these features.
55 | #define BNO08X_INT A4
56 | //#define BNO08X_INT -1
57 | #define BNO08X_RST A5
58 | //#define BNO08X_RST -1
59 |
60 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
61 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
62 |
63 | void setup() {
64 | Serial.begin(115200);
65 |
66 | while(!Serial) delay(10); // Wait for Serial to become available.
67 | // Necessary for boards with native USB (like the SAMD51 Thing+).
68 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
69 | // Comment out this while loop, or it will prevent the remaining code from running.
70 |
71 | Serial.println();
72 | Serial.println("BNO08x Read Example");
73 |
74 | Wire.begin();
75 |
76 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
77 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
78 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
79 | while (1)
80 | ;
81 | }
82 | Serial.println("BNO08x found!");
83 |
84 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
85 |
86 | setReports();
87 |
88 | Serial.println("Reading events");
89 | delay(100);
90 | }
91 |
92 | // Here is where you define the sensor outputs you want to receive
93 | void setReports(void) {
94 | Serial.println("Setting desired reports");
95 | if (myIMU.enableRotationVector() == true) {
96 | Serial.println(F("Rotation vector enabled"));
97 | Serial.println(F("Output in form i, j, k, real, accuracy"));
98 | } else {
99 | Serial.println("Could not enable rotation vector");
100 | }
101 | }
102 |
103 | void loop() {
104 | delay(10);
105 |
106 | if (myIMU.wasReset()) {
107 | Serial.print("sensor was reset ");
108 | setReports();
109 | }
110 |
111 | // Has a new event come in on the Sensor Hub Bus?
112 | if (myIMU.getSensorEvent() == true) {
113 |
114 | // is it the correct sensor data we want?
115 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
116 |
117 | uint64_t timeStamp = myIMU.getTimeStamp();
118 | float quatI = myIMU.getQuatI();
119 | float quatJ = myIMU.getQuatJ();
120 | float quatK = myIMU.getQuatK();
121 | float quatReal = myIMU.getQuatReal();
122 | float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
123 |
124 | Serial.print(timeStamp);
125 | Serial.print(F(","));
126 | Serial.print(quatI, 2);
127 | Serial.print(F(","));
128 | Serial.print(quatJ, 2);
129 | Serial.print(F(","));
130 | Serial.print(quatK, 2);
131 | Serial.print(F(","));
132 | Serial.print(quatReal, 2);
133 | Serial.print(F(","));
134 | Serial.print(quatRadianAccuracy, 2);
135 |
136 | Serial.println();
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/examples/Example_11_RawReadings/Example_11_RawReadings.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output the raw accel, gryo and mag values.
5 |
6 | It outputs the timestampe/i/j/k/real/accuracy parts of the rotation vector.
7 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
8 |
9 | By: Nathan Seidle
10 | SparkFun Electronics
11 | Date: December 21st, 2017
12 | SparkFun code, firmware, and software is released under the MIT License.
13 | Please see LICENSE.md for further details.
14 |
15 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
16 |
17 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
18 | CEVA Sensor Hub Driver, found here:
19 | https://github.com/ceva-dsp/sh2
20 |
21 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
22 | for Adafruit Industries. Found here:
23 | https://github.com/adafruit/Adafruit_BNO08x
24 |
25 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
26 | BusIO library found here:
27 | https://github.com/adafruit/Adafruit_BusIO
28 |
29 | Hardware Connections:
30 | IoT RedBoard --> BNO08x
31 | QWIIC --> QWIIC
32 | A4 --> INT
33 | A5 --> RST
34 |
35 | BNO08x "mode" jumpers set for I2C (default):
36 | PSO: OPEN
37 | PS1: OPEN
38 |
39 | Serial.print it out at 115200 baud to serial monitor.
40 |
41 | Feel like supporting our work? Buy a board from SparkFun!
42 | https://www.sparkfun.com/products/22857
43 | */
44 |
45 | #include
46 |
47 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
48 |
49 | BNO08x myIMU;
50 |
51 | // For the most reliable interaction with the SHTP bus, we need
52 | // to use hardware reset control, and to monitor the H_INT pin.
53 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
54 | // Note, these can be other GPIO if you like.
55 | // Define as -1 to disable these features.
56 | #define BNO08X_INT A4
57 | //#define BNO08X_INT -1
58 | #define BNO08X_RST A5
59 | //#define BNO08X_RST -1
60 |
61 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
62 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
63 |
64 | // variables to store all our incoming values
65 |
66 | // raw accel
67 | int16_t x;
68 | int16_t y;
69 | int16_t z;
70 |
71 | // raw gyros
72 | int16_t gx;
73 | int16_t gy;
74 | int16_t gz;
75 |
76 | // raw mags
77 | int16_t mx;
78 | int16_t my;
79 | int16_t mz;
80 |
81 | unsigned long previousDebugMillis = 0;
82 | #define DEBUG_INTERVAL_MILLISECONDS 30
83 |
84 | void setup() {
85 | Serial.begin(115200);
86 |
87 | while(!Serial) delay(10); // Wait for Serial to become available.
88 | // Necessary for boards with native USB (like the SAMD51 Thing+).
89 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
90 | // Comment out this while loop, or it will prevent the remaining code from running.
91 |
92 | Serial.println();
93 | Serial.println("BNO08x Read Example");
94 |
95 | Wire.begin();
96 |
97 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
98 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
99 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
100 | while (1)
101 | ;
102 | }
103 | Serial.println("BNO08x found!");
104 |
105 | //Wire.setClock(400000); //Increase I2C data rate to 400kHz
106 |
107 | setReports();
108 |
109 | Serial.println("Reading events");
110 | delay(100);
111 | }
112 |
113 | // Here is where you define the sensor outputs you want to receive
114 | void setReports(void) {
115 | Serial.println("Setting desired reports");
116 |
117 | if (myIMU.enableAccelerometer(1) == true) {
118 | Serial.println(F("Accelerometer enabled"));
119 | } else {
120 | Serial.println("Could not enable accelerometer");
121 | }
122 |
123 | if (myIMU.enableRawAccelerometer(1) == true) {
124 | Serial.println(F("Raw Accelerometer enabled"));
125 | } else {
126 | Serial.println("Could not enable raw accelerometer");
127 | }
128 |
129 | if (myIMU.enableGyro(1) == true) {
130 | Serial.println(F("Gyro enabled"));
131 | } else {
132 | Serial.println("Could not enable gyro");
133 | }
134 |
135 | if (myIMU.enableRawGyro(1) == true) {
136 | Serial.println(F("Raw Gyro enabled"));
137 | } else {
138 | Serial.println("Could not enable raw gyro");
139 | }
140 |
141 | if (myIMU.enableMagnetometer(1) == true) {
142 | Serial.println(F("Magnetometer enabled"));
143 | } else {
144 | Serial.println("Could not enable Magnetometer");
145 | }
146 |
147 | if (myIMU.enableRawMagnetometer(1) == true) {
148 | Serial.println(F("Raw Magnetometer enabled"));
149 | } else {
150 | Serial.println("Could not enable Raw Magnetometer");
151 | }
152 |
153 | Serial.println(F("Raw MEMS readings enabled"));
154 | Serial.println(F("Output is: (accel) x y z (gyro) x y z (mag) x y z"));
155 | }
156 |
157 | void loop() {
158 | delayMicroseconds(10);
159 |
160 | if (myIMU.wasReset()) {
161 | Serial.print("sensor was reset ");
162 | setReports();
163 | }
164 |
165 | // Has a new event come in on the Sensor Hub Bus?
166 | if (myIMU.getSensorEvent() == true)
167 | {
168 |
169 | // keep track of if we've recieved an updated value on any one of the
170 | // reports we're looking for.
171 | uint8_t reportID = myIMU.getSensorEventID();
172 |
173 | switch (reportID)
174 | {
175 | case SENSOR_REPORTID_RAW_ACCELEROMETER:
176 | x = myIMU.getRawAccelX();
177 | y = myIMU.getRawAccelY();
178 | z = myIMU.getRawAccelZ();
179 | break;
180 | case SENSOR_REPORTID_RAW_GYROSCOPE:
181 | gx = myIMU.getRawGyroX();
182 | gy = myIMU.getRawGyroY();
183 | gz = myIMU.getRawGyroZ();
184 | break;
185 | case SENSOR_REPORTID_RAW_MAGNETOMETER:
186 | mx = myIMU.getRawMagX();
187 | my = myIMU.getRawMagY();
188 | mz = myIMU.getRawMagZ();
189 | break;
190 | default:
191 | break;
192 | }
193 |
194 | // Only print data to the terminal at a user defined interval
195 | // Each data type (accel or gyro or mag) is reported from the
196 | // BNO086 as separate messages.
197 | // To allow for all these separate messages to arrive, and thus
198 | // have updated data on all axis/types,
199 | // The report intervals for each datatype must be much faster
200 | // than our debug interval.
201 |
202 | // time since last debug data printed to terminal
203 | int timeSinceLastSerialPrint = (millis() - previousDebugMillis);
204 |
205 | // Only print data to the terminal at a user deficed interval
206 | if(timeSinceLastSerialPrint > DEBUG_INTERVAL_MILLISECONDS)
207 | {
208 | Serial.print(x);
209 | Serial.print("\t");
210 | Serial.print(y);
211 | Serial.print("\t");
212 | Serial.print(z);
213 | Serial.print("\t");
214 |
215 | Serial.print(gx);
216 | Serial.print("\t");
217 | Serial.print(gy);
218 | Serial.print("\t");
219 | Serial.print(gz);
220 | Serial.print("\t");
221 |
222 | Serial.print(mx);
223 | Serial.print("\t");
224 | Serial.print(my);
225 | Serial.print("\t");
226 | Serial.print(mz);
227 | Serial.print("\t");
228 |
229 | Serial.print(timeSinceLastSerialPrint);
230 |
231 | Serial.println();
232 |
233 | previousDebugMillis = millis();
234 |
235 | }
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/examples/Example_12_GyroIntegratedRotationVector/Example_12_GyroIntegratedRotationVector.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to use the gyro integrated rotation vector.
5 |
6 | It outputs the GyroIntegrated i/j/k/real/angVelX/angVelY/angVelZ parts of the
7 | rotation vector.
8 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
9 |
10 | By: Boštjan Čadež (@badVibes--)
11 | Date: April 3rd, 2020
12 |
13 | By: Nathan Seidle
14 | SparkFun Electronics
15 | Date: December 21st, 2017
16 | SparkFun code, firmware, and software is released under the MIT License.
17 | Please see LICENSE.md for further details.
18 |
19 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
20 |
21 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
22 | CEVA Sensor Hub Driver, found here:
23 | https://github.com/ceva-dsp/sh2
24 |
25 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
26 | for Adafruit Industries. Found here:
27 | https://github.com/adafruit/Adafruit_BNO08x
28 |
29 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
30 | BusIO library found here:
31 | https://github.com/adafruit/Adafruit_BusIO
32 |
33 | Hardware Connections:
34 | IoT RedBoard --> BNO08x
35 | QWIIC --> QWIIC
36 | A4 --> INT
37 | A5 --> RST
38 |
39 | BNO08x "mode" jumpers set for I2C (default):
40 | PSO: OPEN
41 | PS1: OPEN
42 |
43 | Serial.print it out at 115200 baud to serial monitor.
44 |
45 | Feel like supporting our work? Buy a board from SparkFun!
46 | https://www.sparkfun.com/products/22857
47 | */
48 |
49 | #include
50 |
51 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
52 | BNO08x myIMU;
53 |
54 | // For the most reliable interaction with the SHTP bus, we need
55 | // to use hardware reset control, and to monitor the H_INT pin.
56 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
57 | // Note, these can be other GPIO if you like.
58 | // Define as -1 to disable these features.
59 | #define BNO08X_INT A4
60 | //#define BNO08X_INT -1
61 | #define BNO08X_RST A5
62 | //#define BNO08X_RST -1
63 |
64 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
65 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
66 |
67 | void setup() {
68 | Serial.begin(115200);
69 |
70 | while(!Serial) delay(10); // Wait for Serial to become available.
71 | // Necessary for boards with native USB (like the SAMD51 Thing+).
72 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
73 | // Comment out this while loop, or it will prevent the remaining code from running.
74 |
75 | Serial.println();
76 | Serial.println("BNO08x Read Example");
77 |
78 | Wire.begin();
79 |
80 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
81 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
82 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
83 | while (1)
84 | ;
85 | }
86 | Serial.println("BNO08x found!");
87 |
88 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
89 |
90 | setReports();
91 |
92 | Serial.println("Reading events");
93 | delay(100);
94 | }
95 |
96 | // Here is where you define the sensor outputs you want to receive
97 | void setReports(void) {
98 | Serial.println("Setting desired reports");
99 | if (myIMU.enableGyroIntegratedRotationVector() == true) {
100 | Serial.println(F("Gryo Integrated Rotation vector enabled"));
101 | Serial.println(F("Output in form i, j, k, real, gyroX, gyroY, gyroZ"));
102 | } else {
103 | Serial.println("Could not enable gyro integrated rotation vector");
104 | }
105 | }
106 |
107 | void loop() {
108 | delay(10);
109 |
110 | if (myIMU.wasReset()) {
111 | Serial.print("sensor was reset ");
112 | setReports();
113 | }
114 |
115 | // Has a new event come in on the Sensor Hub Bus?
116 | if (myIMU.getSensorEvent() == true) {
117 |
118 | // is it the correct sensor data we want?
119 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_GYRO_INTEGRATED_ROTATION_VECTOR) {
120 |
121 | float RVI = myIMU.getGyroIntegratedRVI();
122 | float RVJ = myIMU.getGyroIntegratedRVJ();
123 | float RVK = myIMU.getGyroIntegratedRVK();
124 | float RVReal = myIMU.getGyroIntegratedRVReal();
125 | float gyroX = myIMU.getGyroIntegratedRVangVelX();
126 | float gyroY = myIMU.getGyroIntegratedRVangVelY();
127 | float gyroZ = myIMU.getGyroIntegratedRVangVelZ();
128 |
129 | Serial.print(RVI, 2);
130 | Serial.print(F(","));
131 | Serial.print(RVJ, 2);
132 | Serial.print(F(","));
133 | Serial.print(RVK, 2);
134 | Serial.print(F(","));
135 | Serial.print(RVReal, 2);
136 | Serial.print(F(","));
137 | Serial.print(gyroX, 2);
138 | Serial.print(F(","));
139 | Serial.print(gyroY, 2);
140 | Serial.print(F(","));
141 | Serial.print(gyroZ, 2);
142 |
143 | Serial.println();
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/examples/Example_13_EulerAngles/Example_13_EulerAngles.ino:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | Using the BNO08x IMU
4 |
5 | Example : Euler Angles
6 | By: Paul Clark
7 | Date: April 28th, 2020
8 |
9 | This example shows how to output the Euler angles: roll, pitch and yaw.
10 | The yaw (compass heading) is tilt-compensated, which is nice.
11 | https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
12 | https://github.com/sparkfun/SparkFun_MPU-9250-DMP_Arduino_Library/issues/5#issuecomment-306509440
13 |
14 | By: Nathan Seidle
15 | SparkFun Electronics
16 | Date: December 21st, 2017
17 | SparkFun code, firmware, and software is released under the MIT License.
18 | Please see LICENSE.md for further details.
19 |
20 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
21 |
22 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
23 | CEVA Sensor Hub Driver, found here:
24 | https://github.com/ceva-dsp/sh2
25 |
26 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
27 | for Adafruit Industries. Found here:
28 | https://github.com/adafruit/Adafruit_BNO08x
29 |
30 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
31 | BusIO library found here:
32 | https://github.com/adafruit/Adafruit_BusIO
33 |
34 | Hardware Connections:
35 | IoT RedBoard --> BNO08x
36 | QWIIC --> QWIIC
37 | A4 --> INT
38 | A5 --> RST
39 |
40 | BNO08x "mode" jumpers set for I2C (default):
41 | PSO: OPEN
42 | PS1: OPEN
43 |
44 | Serial.print it out at 115200 baud to serial monitor.
45 |
46 | Feel like supporting our work? Buy a board from SparkFun!
47 | https://www.sparkfun.com/products/22857
48 | */
49 |
50 | #include
51 |
52 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
53 | BNO08x myIMU;
54 |
55 | // For the most reliable interaction with the SHTP bus, we need
56 | // to use hardware reset control, and to monitor the H_INT pin.
57 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
58 | // Note, these can be other GPIO if you like.
59 | // Define as -1 to disable these features.
60 | #define BNO08X_INT A4
61 | //#define BNO08X_INT -1
62 | #define BNO08X_RST A5
63 | //#define BNO08X_RST -1
64 |
65 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
66 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
67 |
68 | void setup() {
69 | Serial.begin(115200);
70 |
71 | while(!Serial) delay(10); // Wait for Serial to become available.
72 | // Necessary for boards with native USB (like the SAMD51 Thing+).
73 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
74 | // Comment out this while loop, or it will prevent the remaining code from running.
75 |
76 | Serial.println();
77 | Serial.println("BNO08x Read Example");
78 |
79 | Wire.begin();
80 |
81 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
82 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
83 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
84 | while (1)
85 | ;
86 | }
87 | Serial.println("BNO08x found!");
88 |
89 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
90 |
91 | setReports();
92 |
93 | Serial.println("Reading events");
94 | delay(100);
95 | }
96 |
97 | // Here is where you define the sensor outputs you want to receive
98 | void setReports(void) {
99 | Serial.println("Setting desired reports");
100 | if (myIMU.enableRotationVector() == true) {
101 | Serial.println(F("Rotation vector enabled"));
102 | Serial.println(F("Output in form roll, pitch, yaw"));
103 | } else {
104 | Serial.println("Could not enable rotation vector");
105 | }
106 | }
107 |
108 | void loop() {
109 | delay(10);
110 |
111 | if (myIMU.wasReset()) {
112 | Serial.print("sensor was reset ");
113 | setReports();
114 | }
115 |
116 | // Has a new event come in on the Sensor Hub Bus?
117 | if (myIMU.getSensorEvent() == true) {
118 |
119 | // is it the correct sensor data we want?
120 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
121 |
122 | float roll = (myIMU.getRoll()) * 180.0 / PI; // Convert roll to degrees
123 | float pitch = (myIMU.getPitch()) * 180.0 / PI; // Convert pitch to degrees
124 | float yaw = (myIMU.getYaw()) * 180.0 / PI; // Convert yaw / heading to degrees
125 |
126 | Serial.print(roll, 1);
127 | Serial.print(F(","));
128 | Serial.print(pitch, 1);
129 | Serial.print(F(","));
130 | Serial.print(yaw, 1);
131 |
132 | Serial.println();
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/examples/Example_14_Tare/Example_14_Tare.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to use the Tare features of the sensor.
5 | It outputs the roll, pitch and yaw.
6 | Type letters into the terminal to execute Tare commands.
7 |
8 | Example : Tare function
9 | By: Sofian Audry
10 | Date: March 2nd, 2022
11 |
12 | Based on: Example9-Calibrate
13 | By: Nathan Seidle
14 | SparkFun Electronics
15 | Date: December 21st, 2017
16 | SparkFun code, firmware, and software is released under the MIT License.
17 | Please see LICENSE.md for further details.
18 |
19 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
20 |
21 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
22 | CEVA Sensor Hub Driver, found here:
23 | https://github.com/ceva-dsp/sh2
24 |
25 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
26 | for Adafruit Industries. Found here:
27 | https://github.com/adafruit/Adafruit_BNO08x
28 |
29 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
30 | BusIO library found here:
31 | https://github.com/adafruit/Adafruit_BusIO
32 |
33 | Hardware Connections:
34 | IoT RedBoard --> BNO08x
35 | QWIIC --> QWIIC
36 | A4 --> INT
37 | A5 --> RST
38 |
39 | BNO08x "mode" jumpers set for I2C (default):
40 | PSO: OPEN
41 | PS1: OPEN
42 |
43 | Serial.print it out at 115200 baud to serial monitor.
44 |
45 | Feel like supporting our work? Buy a board from SparkFun!
46 | https://www.sparkfun.com/products/22857
47 | */
48 |
49 | #include
50 |
51 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
52 | BNO08x myIMU;
53 |
54 | // For the most reliable interaction with the SHTP bus, we need
55 | // to use hardware reset control, and to monitor the H_INT pin.
56 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
57 | // Note, these can be other GPIO if you like.
58 | // Define as -1 to disable these features.
59 | #define BNO08X_INT A4
60 | //#define BNO08X_INT -1
61 | #define BNO08X_RST A5
62 | //#define BNO08X_RST -1
63 |
64 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
65 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
66 |
67 | void setup() {
68 | Serial.begin(115200);
69 |
70 | while(!Serial) delay(10); // Wait for Serial to become available.
71 | // Necessary for boards with native USB (like the SAMD51 Thing+).
72 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
73 | // Comment out this while loop, or it will prevent the remaining code from running.
74 |
75 | Serial.println();
76 | Serial.println("BNO08x Read Example");
77 |
78 | //Once magnetic field is 2 or 3, run the Save DCD Now command
79 | Serial.println(F("'t' to tare according to xyz"));
80 | Serial.println(F("'z' to tare according to z axis only"));
81 | Serial.println(F("'s' to save tare settings"));
82 | Serial.println(F("'r' to reset/clear tare orientation registry"));
83 | Serial.println(F("Output in form x, y, z, in uTesla"));
84 |
85 | delay(1000); // you have one second to read the menu in the terminal.
86 | // or simply look at the code above, and take all the time you want.
87 |
88 | Wire.begin();
89 |
90 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
91 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
92 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
93 | while (1)
94 | ;
95 | }
96 | Serial.println("BNO08x found!");
97 |
98 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
99 |
100 | setReports();
101 |
102 | Serial.println("Reading events");
103 | delay(100);
104 | }
105 |
106 | // Here is where you define the sensor outputs you want to receive
107 | void setReports(void) {
108 | Serial.println("Setting desired reports");
109 | if (myIMU.enableRotationVector() == true) {
110 | Serial.println(F("Rotation vector enabled"));
111 | Serial.println(F("Output in form roll, pitch, yaw"));
112 | } else {
113 | Serial.println("Could not enable rotation vector");
114 | }
115 | }
116 |
117 | void loop() {
118 | if(Serial.available())
119 | {
120 | byte incoming = Serial.read();
121 |
122 | switch (incoming) {
123 | case 't':
124 | if(myIMU.tareNow()) {Serial.println("TareXYZ Success");}
125 | else {Serial.print ("TareXYZ Failure");}
126 | break;
127 | case 'z':
128 | if(myIMU.tareNow(true)) {Serial.println("TareZ Success");}
129 | else {Serial.print ("TareZ Failure");}
130 | break;
131 | case 's':
132 | if(myIMU.saveTare()) {Serial.println("Save Tare Success");}
133 | else {Serial.print ("Save Tare Failure");}
134 | break;
135 | case 'r':
136 | if(myIMU.clearTare()) {Serial.println("Clear Tare Success");}
137 | else {Serial.print ("Clear Tare Failure");}
138 | break;
139 | default:;
140 | }
141 | }
142 |
143 | delay(10);
144 |
145 | if (myIMU.wasReset()) {
146 | Serial.print("sensor was reset ");
147 | setReports();
148 | }
149 |
150 | // Has a new event come in on the Sensor Hub Bus?
151 | if (myIMU.getSensorEvent() == true) {
152 |
153 | // is it the correct sensor data we want?
154 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
155 |
156 | float roll = (myIMU.getRoll()) * 180.0 / PI; // Convert roll to degrees
157 | float pitch = (myIMU.getPitch()) * 180.0 / PI; // Convert pitch to degrees
158 | float yaw = (myIMU.getYaw()) * 180.0 / PI; // Convert yaw / heading to degrees
159 |
160 | Serial.print(roll, 1);
161 | Serial.print(F(","));
162 | Serial.print(pitch, 1);
163 | Serial.print(F(","));
164 | Serial.print(yaw, 1);
165 |
166 | Serial.println();
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/examples/Example_15_Gravity/Example_15_Gravity.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output sensor data to find the direction of gravity.
5 |
6 | By: Anant Sharma
7 | Date: January 23rd, 2023
8 |
9 | Based on other code written by: Nathan Seidle
10 | SparkFun Electronics
11 | Date: December 21st, 2017
12 | SparkFun code, firmware, and software is released under the MIT License.
13 | Please see LICENSE.md for further details.
14 |
15 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
16 |
17 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
18 | CEVA Sensor Hub Driver, found here:
19 | https://github.com/ceva-dsp/sh2
20 |
21 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
22 | for Adafruit Industries. Found here:
23 | https://github.com/adafruit/Adafruit_BNO08x
24 |
25 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
26 | BusIO library found here:
27 | https://github.com/adafruit/Adafruit_BusIO
28 |
29 | Hardware Connections:
30 | IoT RedBoard --> BNO08x
31 | QWIIC --> QWIIC
32 | A4 --> INT
33 | A5 --> RST
34 |
35 | BNO08x "mode" jumpers set for I2C (default):
36 | PSO: OPEN
37 | PS1: OPEN
38 |
39 | Serial.print it out at 115200 baud to serial monitor.
40 |
41 | Feel like supporting our work? Buy a board from SparkFun!
42 | https://www.sparkfun.com/products/22857
43 | */
44 |
45 | #include
46 |
47 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
48 | BNO08x myIMU;
49 |
50 | // For the most reliable interaction with the SHTP bus, we need
51 | // to use hardware reset control, and to monitor the H_INT pin.
52 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
53 | // Note, these can be other GPIO if you like.
54 | // Define as -1 to disable these features.
55 | #define BNO08X_INT A4
56 | //#define BNO08X_INT -1
57 | #define BNO08X_RST A5
58 | //#define BNO08X_RST -1
59 |
60 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
61 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
62 |
63 | void setup() {
64 | Serial.begin(115200);
65 |
66 | while(!Serial) delay(10); // Wait for Serial to become available.
67 | // Necessary for boards with native USB (like the SAMD51 Thing+).
68 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
69 | // Comment out this while loop, or it will prevent the remaining code from running.
70 |
71 | Serial.println();
72 | Serial.println("BNO08x Read Example");
73 |
74 | Wire.begin();
75 |
76 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
77 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
78 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
79 | while (1)
80 | ;
81 | }
82 | Serial.println("BNO08x found!");
83 |
84 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
85 |
86 | setReports();
87 |
88 | Serial.println("Reading events");
89 | delay(100);
90 | }
91 |
92 | // Here is where you define the sensor outputs you want to receive
93 | void setReports(void) {
94 | Serial.println("Setting desired reports");
95 | if (myIMU.enableGravity() == true) {
96 | Serial.println(F("Gravity enabled"));
97 | Serial.println(F("Output in form x, y, z, accuracy"));
98 | } else {
99 | Serial.println("Could not enable gravity");
100 | }
101 | }
102 |
103 | void loop() {
104 | delay(10);
105 |
106 | if (myIMU.wasReset()) {
107 | Serial.print("sensor was reset ");
108 | setReports();
109 | }
110 |
111 | // Has a new event come in on the Sensor Hub Bus?
112 | if (myIMU.getSensorEvent() == true) {
113 |
114 | // is it the correct sensor data we want?
115 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_GRAVITY) {
116 |
117 | float gravityX = myIMU.getGravityX();
118 | float gravityY = myIMU.getGravityY();
119 | float gravityZ = myIMU.getGravityZ();
120 | float gravityAccuracy = myIMU.getGravityAccuracy();
121 |
122 | Serial.print(gravityX, 2);
123 | Serial.print(F(","));
124 | Serial.print(gravityY, 2);
125 | Serial.print(F(","));
126 | Serial.print(gravityZ, 2);
127 | Serial.print(F(","));
128 | Serial.print(gravityAccuracy, 2);
129 |
130 | Serial.println();
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/examples/Example_16_UncalibratedGyro/Example_16_UncalibratedGyro.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to output the parts of the uncalibrated gyro.
5 |
6 | By: Nathan Seidle
7 | SparkFun Electronics
8 | Date: December 21st, 2017
9 | SparkFun code, firmware, and software is released under the MIT License.
10 | Please see LICENSE.md for further details.
11 |
12 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
13 |
14 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
15 | CEVA Sensor Hub Driver, found here:
16 | https://github.com/ceva-dsp/sh2
17 |
18 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
19 | for Adafruit Industries. Found here:
20 | https://github.com/adafruit/Adafruit_BNO08x
21 |
22 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
23 | BusIO library found here:
24 | https://github.com/adafruit/Adafruit_BusIO
25 |
26 | Hardware Connections:
27 | IoT RedBoard --> BNO08x
28 | QWIIC --> QWIIC
29 | A4 --> INT
30 | A5 --> RST
31 |
32 | BNO08x "mode" jumpers set for I2C (default):
33 | PSO: OPEN
34 | PS1: OPEN
35 |
36 | Serial.print it out at 115200 baud to serial monitor.
37 |
38 | Feel like supporting our work? Buy a board from SparkFun!
39 | https://www.sparkfun.com/products/22857
40 | */
41 |
42 | #include
43 |
44 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
45 |
46 | BNO08x myIMU;
47 |
48 | // For the most reliable interaction with the SHTP bus, we need
49 | // to use hardware reset control, and to monitor the H_INT pin.
50 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
51 | // Note, these can be other GPIO if you like.
52 | // Define as -1 to disable these features.
53 | #define BNO08X_INT A4
54 | //#define BNO08X_INT -1
55 | #define BNO08X_RST A5
56 | //#define BNO08X_RST -1
57 |
58 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
59 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
60 |
61 | void setup() {
62 | Serial.begin(115200);
63 |
64 | while(!Serial) delay(10); // Wait for Serial to become available.
65 | // Necessary for boards with native USB (like the SAMD51 Thing+).
66 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
67 | // Comment out this while loop, or it will prevent the remaining code from running.
68 |
69 | Serial.println();
70 | Serial.println("BNO08x Read Example");
71 |
72 | Wire.begin();
73 |
74 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
75 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
76 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
77 | while (1)
78 | ;
79 | }
80 | Serial.println("BNO08x found!");
81 |
82 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
83 |
84 | setReports();
85 |
86 | Serial.println("Reading events");
87 | delay(100);
88 | }
89 |
90 | // Here is where you define the sensor outputs you want to receive
91 | void setReports(void) {
92 | Serial.println("Setting desired reports");
93 | if (myIMU.enableUncalibratedGyro() == true) {
94 | Serial.println(F("Uncalibrated Gyro enabled"));
95 | Serial.println(F("Output in form x, y, z, bx, by, bz in radians per second"));
96 | } else {
97 | Serial.println("Could not enable uncalibrated gyro");
98 | }
99 | }
100 |
101 | void loop() {
102 | delay(10);
103 |
104 | if (myIMU.wasReset()) {
105 | Serial.print("sensor was reset ");
106 | setReports();
107 | }
108 |
109 | // Has a new event come in on the Sensor Hub Bus?
110 | if (myIMU.getSensorEvent() == true) {
111 |
112 | // is it the correct sensor data we want?
113 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_UNCALIBRATED_GYRO) {
114 |
115 | float x = myIMU.getUncalibratedGyroX();
116 | float y = myIMU.getUncalibratedGyroY();
117 | float z = myIMU.getUncalibratedGyroZ();
118 | float bx = myIMU.getUncalibratedGyroBiasX();
119 | float by = myIMU.getUncalibratedGyroBiasY();
120 | float bz = myIMU.getUncalibratedGyroBiasZ();
121 |
122 |
123 | Serial.print(x, 2);
124 | Serial.print(F(","));
125 | Serial.print(y, 2);
126 | Serial.print(F(","));
127 | Serial.print(z, 2);
128 | Serial.print(F(","));
129 |
130 | Serial.print(bx, 4);
131 | Serial.print(F(","));
132 | Serial.print(by, 4);
133 | Serial.print(F(","));
134 | Serial.print(bz, 4);
135 |
136 | Serial.println();
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/examples/Example_17_ResetCheck/Example_17_ResetCheck.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to reset the sensor and read back the Reset Cause.
5 | The sensor will be reset each time 100 readings are received to demonstrate.
6 |
7 | It outputs the x/y/z of the gyro.
8 |
9 | By: @mattbradford83
10 | Date: 1 August 2021
11 |
12 | By: Nathan Seidle
13 | SparkFun Electronics
14 | Date: December 21st, 2017
15 | SparkFun code, firmware, and software is released under the MIT License.
16 | Please see LICENSE.md for further details.
17 |
18 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
19 |
20 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
21 | CEVA Sensor Hub Driver, found here:
22 | https://github.com/ceva-dsp/sh2
23 |
24 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
25 | for Adafruit Industries. Found here:
26 | https://github.com/adafruit/Adafruit_BNO08x
27 |
28 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
29 | BusIO library found here:
30 | https://github.com/adafruit/Adafruit_BusIO
31 |
32 | Hardware Connections:
33 | IoT RedBoard --> BNO08x
34 | QWIIC --> QWIIC
35 | A4 --> INT
36 | A5 --> RST
37 |
38 | BNO08x "mode" jumpers set for I2C (default):
39 | PSO: OPEN
40 | PS1: OPEN
41 |
42 | Serial.print it out at 115200 baud to serial monitor.
43 |
44 | Feel like supporting our work? Buy a board from SparkFun!
45 | https://www.sparkfun.com/products/22857
46 | */
47 |
48 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
49 | BNO08x myIMU;
50 |
51 | // For the most reliable interaction with the SHTP bus, we need
52 | // to use hardware reset control, and to monitor the H_INT pin.
53 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
54 | // Note, these can be other GPIO if you like.
55 | // Define as -1 to disable these features.
56 | #define BNO08X_INT A4
57 | //#define BNO08X_INT -1
58 | #define BNO08X_RST A5
59 | //#define BNO08X_RST -1
60 |
61 | int cyclecount = 0;
62 |
63 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
64 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
65 |
66 | void setup() {
67 | Serial.begin(115200);
68 |
69 | while(!Serial) delay(10); // Wait for Serial to become available.
70 | // Necessary for boards with native USB (like the SAMD51 Thing+).
71 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
72 | // Comment out this while loop, or it will prevent the remaining code from running.
73 |
74 | Serial.println();
75 | Serial.println("BNO08x Read Example");
76 |
77 | Wire.begin();
78 |
79 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
80 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
81 | while (1)
82 | ;
83 | }
84 | Serial.println("BNO08x found!");
85 |
86 | Serial.print(F("Reset Reason: "));
87 | printResetReasonName(myIMU.getResetReason());
88 | Serial.println();
89 |
90 | setReports();
91 |
92 | Serial.println("Reading events");
93 | delay(100);
94 | }
95 |
96 | // Here is where you define the sensor outputs you want to receive
97 | void setReports(void) {
98 | Serial.println("Setting desired reports");
99 | if (myIMU.enableGyro() == true) {
100 | Serial.println(F("Gyro enabled"));
101 | Serial.println(F("Output in form x, y, z, in radians per second"));
102 | } else {
103 | Serial.println("Could not enable gyro");
104 | }
105 | }
106 |
107 | void loop() {
108 | delay(1);
109 | myIMU.serviceBus();
110 |
111 | // One of these will appear at the very start because of the power on reset.
112 | // Use getResetReason() for the difference between different resets.
113 | if (myIMU.wasReset()) {
114 | Serial.println(" ------------------ BNO08x has reset. ------------------ ");
115 | Serial.print(F("Reset Reason: "));
116 | printResetReasonName(myIMU.getResetReason());
117 | Serial.println();
118 |
119 | setReports(); // We'll need to re-enable reports after any reset.
120 | }
121 |
122 | // Has a new event come in on the Sensor Hub Bus?
123 | if (myIMU.getSensorEvent() == true) {
124 |
125 | // is it the correct sensor data we want?
126 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_GYROSCOPE_CALIBRATED) {
127 |
128 | cyclecount++;
129 |
130 | Serial.print(F("["));
131 | if (cyclecount < 10) Serial.print(F("0"));
132 | Serial.print(cyclecount);
133 | Serial.print(F("] "));
134 |
135 | float x = myIMU.getGyroX();
136 | float y = myIMU.getGyroY();
137 | float z = myIMU.getGyroZ();
138 |
139 | Serial.print(x, 2);
140 | Serial.print(F(","));
141 | Serial.print(y, 2);
142 | Serial.print(F(","));
143 | Serial.print(z, 2);
144 |
145 | Serial.println();
146 |
147 | if (cyclecount == 100) {
148 | myIMU.softReset();
149 | cyclecount = 0;
150 | }
151 | }
152 | }
153 | }
154 |
155 | //Given a number between 0 and 5, print the name of the reset reason
156 | //1 = POR, 2 = Internal reset, 3 = Watchdog, 4 = External reset, 5 = Other
157 | void printResetReasonName(byte resetReasonNumber)
158 | {
159 | if(resetReasonNumber == 1) Serial.print("POR");
160 | else if(resetReasonNumber == 2) Serial.print("Internal reset");
161 | else if(resetReasonNumber == 3) Serial.print("Watchdog");
162 | else if(resetReasonNumber == 4) Serial.print("External reset");
163 | else if(resetReasonNumber == 5) Serial.print("Other");
164 | }
165 |
--------------------------------------------------------------------------------
/examples/Example_18_Sleep/Example_18_Sleep.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to use the sleep features of the sensor.
5 |
6 | *Note, in addition to the qwiic cable it also requires INT and RST.
7 |
8 | It toggles the sleep mode on/off every 5 seconds.
9 |
10 | When awake, this example outputs the i/j/k/real parts of the rotation vector.
11 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
12 |
13 | By: Nathan Seidle
14 | SparkFun Electronics
15 | Date: December 21st, 2017
16 | SparkFun code, firmware, and software is released under the MIT License.
17 | Please see LICENSE.md for further details.
18 |
19 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
20 |
21 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
22 | CEVA Sensor Hub Driver, found here:
23 | https://github.com/ceva-dsp/sh2
24 |
25 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
26 | for Adafruit Industries. Found here:
27 | https://github.com/adafruit/Adafruit_BNO08x
28 |
29 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
30 | BusIO library found here:
31 | https://github.com/adafruit/Adafruit_BusIO
32 |
33 | Hardware Connections:
34 | IoT RedBoard --> BNO08x
35 | QWIIC --> QWIIC
36 | A4 --> INT
37 | A5 --> RST
38 |
39 | BNO08x "mode" jumpers set for I2C (default):
40 | PSO: OPEN
41 | PS1: OPEN
42 |
43 | Plug the sensor into IoT RedBoard via QWIIC cable.
44 | Serial.print it out at 115200 baud to serial monitor.
45 |
46 | Feel like supporting our work? Buy a board from SparkFun!
47 | https://www.sparkfun.com/products/22857
48 | */
49 |
50 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
51 | BNO08x myIMU;
52 |
53 | // For the most reliable interaction with the SHTP bus, we need
54 | // to use hardware reset control, and to monitor the H_INT pin.
55 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
56 | // Note, these can be other GPIO if you like.
57 | // Define as -1 to disable these features.
58 | #define BNO08X_INT A4
59 | //#define BNO08X_INT -1
60 | #define BNO08X_RST A5
61 | //#define BNO08X_RST -1
62 |
63 | unsigned long lastMillis = 0; // Keep track of time
64 | bool lastPowerState = true; // Toggle between "On" and "Sleep"
65 |
66 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
67 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
68 |
69 | void setup() {
70 | Serial.begin(115200);
71 |
72 | while(!Serial) delay(10); // Wait for Serial to become available.
73 | // Necessary for boards with native USB (like the SAMD51 Thing+).
74 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
75 | // Comment out this while loop, or it will prevent the remaining code from running.
76 |
77 | Serial.println();
78 | Serial.println("BNO08x Sleep Example");
79 |
80 | Wire.begin();
81 |
82 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
83 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
84 | while (1)
85 | ;
86 | }
87 | Serial.println("BNO08x found!");
88 |
89 | setReports();
90 |
91 | Serial.println("Reading events");
92 | delay(100);
93 |
94 | lastMillis = millis(); // Keep track of time
95 | }
96 |
97 | // Here is where you define the sensor outputs you want to receive
98 | void setReports(void) {
99 | Serial.println("Setting desired reports");
100 | if (myIMU.enableRotationVector() == true) {
101 | Serial.println(F("Rotation vector enabled"));
102 | Serial.println(F("Output in form i, j, k, real, accuracy"));
103 | } else {
104 | Serial.println("Could not enable rotation vector");
105 | }
106 | }
107 |
108 | void loop() {
109 | delay(10);
110 |
111 | if (lastPowerState) // Are we "On"?
112 | {
113 |
114 | if (myIMU.wasReset()) {
115 | Serial.print("sensor was reset ");
116 | setReports();
117 | }
118 |
119 | // Has a new event come in on the Sensor Hub Bus?
120 | if (myIMU.getSensorEvent() == true) {
121 |
122 | // is it the correct sensor data we want?
123 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
124 |
125 | float quatI = myIMU.getQuatI();
126 | float quatJ = myIMU.getQuatJ();
127 | float quatK = myIMU.getQuatK();
128 | float quatReal = myIMU.getQuatReal();
129 | float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
130 |
131 | Serial.print(quatI, 2);
132 | Serial.print(F(","));
133 | Serial.print(quatJ, 2);
134 | Serial.print(F(","));
135 | Serial.print(quatK, 2);
136 | Serial.print(F(","));
137 | Serial.print(quatReal, 2);
138 | Serial.print(F(","));
139 | Serial.print(quatRadianAccuracy, 2);
140 |
141 | Serial.println();
142 | }
143 | }
144 | }
145 |
146 | //Check if it is time to change the power state
147 | if (millis() > (lastMillis + 5000)) // Change state every 5 seconds
148 | {
149 | lastMillis = millis(); // Keep track of time
150 |
151 | if (lastPowerState) // Are we "On"?
152 | {
153 | Serial.println("Putting BNO08x to sleep...");
154 | myIMU.modeSleep(); // Put BNO to sleep
155 | } else {
156 | Serial.println("Waking up BNO08x");
157 | myIMU.modeOn(); // Turn BNO back on
158 | }
159 |
160 | lastPowerState ^= 1; // Invert lastPowerState (using ex-or)
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/examples/Example_19_GeomagneticRotationVector_to_EulerAngles/Example_19_GeomagneticRotationVector_to_EulerAngles.ino:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | Using the BNO08x IMU
4 |
5 | Example : Geomagnetic Rotation Vector to Euler Angles
6 |
7 | This example was initially created by github user SFSailor November 2023
8 | https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/issues/10
9 | https://forum.sparkfun.com/viewtopic.php?f=83&t=60523&p=245145#p245145
10 |
11 | Modified from original example of Euler Angles
12 | By: Paul Clark
13 | Date: April 28th, 2020
14 |
15 | Using the Geomagnetic Rotation vectors,
16 | This example shows how to output the Euler angles: roll, pitch and yaw.
17 | The yaw (compass heading) is tilt-compensated, which is nice.
18 | https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
19 | https://github.com/sparkfun/SparkFun_MPU-9250-DMP_Arduino_Library/issues/5#issuecomment-306509440
20 |
21 | By: Nathan Seidle
22 | SparkFun Electronics
23 | Date: December 21st, 2017
24 | SparkFun code, firmware, and software is released under the MIT License.
25 | Please see LICENSE.md for further details.
26 |
27 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
28 |
29 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
30 | CEVA Sensor Hub Driver, found here:
31 | https://github.com/ceva-dsp/sh2
32 |
33 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
34 | for Adafruit Industries. Found here:
35 | https://github.com/adafruit/Adafruit_BNO08x
36 |
37 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
38 | BusIO library found here:
39 | https://github.com/adafruit/Adafruit_BusIO
40 |
41 | Hardware Connections:
42 | IoT RedBoard --> BNO08x
43 | QWIIC --> QWIIC
44 | A4 --> INT
45 | A5 --> RST
46 |
47 | BNO08x "mode" jumpers set for I2C (default):
48 | PSO: OPEN
49 | PS1: OPEN
50 |
51 | Serial.print it out at 115200 baud to serial monitor.
52 |
53 | Feel like supporting our work? Buy a board from SparkFun!
54 | https://www.sparkfun.com/products/22857
55 | */
56 |
57 | #include
58 |
59 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
60 | BNO08x myIMU;
61 |
62 | // For the most reliable interaction with the SHTP bus, we need
63 | // to use hardware reset control, and to monitor the H_INT pin.
64 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
65 | // Note, these can be other GPIO if you like.
66 | // Define as -1 to disable these features.
67 | #define BNO08X_INT A4
68 | //#define BNO08X_INT -1
69 | #define BNO08X_RST A5
70 | //#define BNO08X_RST -1
71 |
72 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
73 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
74 |
75 | void setup() {
76 | Serial.begin(115200);
77 |
78 | while(!Serial) delay(10); // Wait for Serial to become available.
79 | // Necessary for boards with native USB (like the SAMD51 Thing+).
80 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
81 | // Comment out this while loop, or it will prevent the remaining code from running.
82 |
83 | Serial.println();
84 | Serial.println("BNO08x Read Example");
85 |
86 | Wire.begin();
87 |
88 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
89 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
90 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
91 | while (1)
92 | ;
93 | }
94 | Serial.println("BNO08x found!");
95 |
96 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
97 |
98 | setReports();
99 |
100 | Serial.println("Reading events");
101 | delay(100);
102 | }
103 |
104 | // Here is where you define the sensor outputs you want to receive
105 | void setReports(void) {
106 | Serial.println("Setting desired reports");
107 | if (myIMU.enableGeomagneticRotationVector() == true) {
108 | Serial.println(F("Geomagnetic Rotation vector enabled"));
109 | Serial.println(F("Output in form roll, pitch, yaw"));
110 | } else {
111 | Serial.println("Could not enable geomagnetic rotation vector");
112 | }
113 | }
114 |
115 | void loop() {
116 | delay(10);
117 |
118 | if (myIMU.wasReset()) {
119 | Serial.print("sensor was reset ");
120 | setReports();
121 | }
122 |
123 | // Has a new event come in on the Sensor Hub Bus?
124 | if (myIMU.getSensorEvent() == true) {
125 |
126 | // is it the correct sensor data we want?
127 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR) {
128 |
129 | float roll = (myIMU.getRoll()) * 180.0 / PI; // Convert roll to degrees
130 | float pitch = (myIMU.getPitch()) * 180.0 / PI; // Convert pitch to degrees
131 | float yaw = (myIMU.getYaw()) * 180.0 / PI; // Convert yaw / heading to degrees
132 |
133 | Serial.print(roll, 1);
134 | Serial.print(F(","));
135 | Serial.print(pitch, 1);
136 | Serial.print(F(","));
137 | Serial.print(yaw, 1);
138 |
139 | Serial.println();
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/examples/Example_20_CalibrationSettings/Example_20_CalibrationSettings.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to adjust settings of the dynamic calibration of the
5 | BNO08x.
6 |
7 | The BNO08x allows you to turn on/off dynamic calibration for each sensor in
8 | the IMU (accel, gyro, or mag).
9 |
10 | Please refer to the BNO08X data sheet Section 3 (page 37)
11 | https://docs.sparkfun.com/SparkFun_VR_IMU_Breakout_BNO086_QWIIC/assets/component_documentation/BNO080_085-Datasheet_v1.16.pdf
12 |
13 | Note, by default, dynamic calibration is enabled for accel and mag.
14 | Some special use cases may require turning on all or any special combo of sensor
15 | dynamic calibration.
16 |
17 | After the calibration settings are set, this example will output the
18 | x/y/z/accuracy of the mag and the i/j/k/real parts of the game rotation vector.
19 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
20 |
21 | Note, the "simple calibration" feature, sh2_startCal(), is not available on
22 | the BNO08x. See this issue for more info:
23 | https://github.com/ceva-dsp/sh2/issues/11
24 |
25 | By: Nathan Seidle
26 | SparkFun Electronics
27 | Date: December 21st, 2017
28 | SparkFun code, firmware, and software is released under the MIT License.
29 | Please see LICENSE.md for further details.
30 |
31 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
32 |
33 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
34 | CEVA Sensor Hub Driver, found here:
35 | https://github.com/ceva-dsp/sh2
36 |
37 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
38 | for Adafruit Industries. Found here:
39 | https://github.com/adafruit/Adafruit_BNO08x
40 |
41 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
42 | BusIO library found here:
43 | https://github.com/adafruit/Adafruit_BusIO
44 |
45 | Hardware Connections:
46 | IoT RedBoard --> BNO08x
47 | QWIIC --> QWIIC
48 | A4 --> INT
49 | A5 --> RST
50 |
51 | BNO08x "mode" jumpers set for I2C (default):
52 | PSO: OPEN
53 | PS1: OPEN
54 |
55 | Serial.print it out at 115200 baud to serial monitor.
56 |
57 | Feel like supporting our work? Buy a board from SparkFun!
58 | https://www.sparkfun.com/products/22857
59 | */
60 |
61 | #include
62 |
63 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
64 | BNO08x myIMU;
65 |
66 | // For the most reliable interaction with the SHTP bus, we need
67 | // to use hardware reset control, and to monitor the H_INT pin.
68 | // The H_INT pin will go low when its okay to talk on the SHTP bus.
69 | // Note, these can be other GPIO if you like.
70 | // Define as -1 to disable these features.
71 | #define BNO08X_INT A4
72 | //#define BNO08X_INT -1
73 | #define BNO08X_RST A5
74 | //#define BNO08X_RST -1
75 |
76 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
77 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
78 |
79 | // variables to store all our incoming values
80 |
81 | // mags
82 | float mx;
83 | float my;
84 | float mz;
85 | byte magAccuracy;
86 |
87 | // quats
88 | float quatI;
89 | float quatJ;
90 | float quatK;
91 | float quatReal;
92 |
93 | unsigned long previousDebugMicros = 0;
94 | #define DEBUG_INTERVAL_MICROSECONDS 10000
95 |
96 | void setup() {
97 | Serial.begin(115200);
98 |
99 | while(!Serial) delay(10); // Wait for Serial to become available.
100 | // Necessary for boards with native USB (like the SAMD51 Thing+).
101 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
102 | // Comment out this while loop, or it will prevent the remaining code from running.
103 |
104 | Serial.println();
105 | Serial.println("BNO08x Calibration Example");
106 |
107 | Wire.begin();
108 |
109 | //if (myIMU.begin() == false) { // Setup without INT/RST control (Not Recommended)
110 | if (myIMU.begin(BNO08X_ADDR, Wire, BNO08X_INT, BNO08X_RST) == false) {
111 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
112 | while (1)
113 | ;
114 | }
115 | Serial.println("BNO08x found!");
116 |
117 | // Wire.setClock(400000); //Increase I2C data rate to 400kHz
118 |
119 | // Enable dynamic calibration for desired sensors (accel, gyro, and mag)
120 | // uncomment/comment out as needed to try various options
121 | if (myIMU.setCalibrationConfig(SH2_CAL_ACCEL || SH2_CAL_GYRO || SH2_CAL_MAG) == true) { // all three sensors
122 | //if (myIMU.setCalibrationConfig(SH2_CAL_ACCEL || SH2_CAL_MAG) == true) { // Default settings
123 | //if (myIMU.setCalibrationConfig(SH2_CAL_ACCEL) == true) { // only accel
124 | Serial.println(F("Calibration Command Sent Successfully"));
125 | } else {
126 | Serial.println("Could not send Calibration Command. Freezing...");
127 | while(1) delay(10);
128 | }
129 |
130 | setReports();
131 |
132 | Serial.println("Reading events");
133 | delay(100);
134 | }
135 |
136 | // Here is where you define the sensor outputs you want to receive
137 | void setReports(void) {
138 | Serial.println("Setting desired reports");
139 |
140 | if (myIMU.enableMagnetometer(1) == true) {
141 | Serial.println(F("Magnetometer enabled"));
142 | Serial.println(F("Output in form x, y, z, in uTesla"));
143 | } else {
144 | Serial.println("Could not enable magnetometer");
145 | }
146 |
147 | if (myIMU.enableGameRotationVector(1) == true) {
148 | Serial.println(F("Game Rotation vector enabled"));
149 | Serial.println(F("Output in form i, j, k, real"));
150 | } else {
151 | Serial.println("Could not enable game rotation vector");
152 | }
153 | }
154 |
155 | void loop() {
156 | delayMicroseconds(10);
157 |
158 | if (myIMU.wasReset()) {
159 | Serial.print("sensor was reset ");
160 | setReports();
161 | }
162 |
163 | // Has a new event come in on the Sensor Hub Bus?
164 | if (myIMU.getSensorEvent() == true) {
165 | // is the event a report of the magnetometer?
166 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_MAGNETIC_FIELD) {
167 | mx = myIMU.getMagX();
168 | my = myIMU.getMagY();
169 | mz = myIMU.getMagZ();
170 | magAccuracy = myIMU.getMagAccuracy();
171 | }
172 | // is the event a report of the game rotation vector?
173 | else if (myIMU.getSensorEventID() == SENSOR_REPORTID_GAME_ROTATION_VECTOR) {
174 | quatI = myIMU.getGameQuatI();
175 | quatJ = myIMU.getGameQuatJ();
176 | quatK = myIMU.getGameQuatK();
177 | quatReal = myIMU.getGameQuatReal();
178 | }
179 | }
180 |
181 | // Only print data to the terminal at a user defined interval
182 | // Each data type (accel or gyro or mag) is reported from the
183 | // BNO086 as separate messages.
184 | // To allow for all these separate messages to arrive, and thus
185 | // have updated data on all axis/types,
186 | // The report intervals for each datatype must be much faster
187 | // than our debug interval.
188 |
189 | // time since last debug data printed to terminal
190 | unsigned long microsSinceLastSerialPrint = (micros() - previousDebugMicros);
191 |
192 | // Only print data to the terminal at a user deficed interval
193 | if(microsSinceLastSerialPrint > DEBUG_INTERVAL_MICROSECONDS)
194 | {
195 | Serial.print(mx, 2);
196 | Serial.print("\t\t");
197 | Serial.print(my, 2);
198 | Serial.print("\t\t");
199 | Serial.print(mz, 2);
200 | Serial.print("\t\t");
201 | printAccuracyLevel(magAccuracy);
202 | Serial.print("\t\t");
203 |
204 | Serial.print(quatI, 2);
205 | Serial.print("\t\t");
206 | Serial.print(quatJ, 2);
207 | Serial.print("\t\t");
208 | Serial.print(quatK, 2);
209 | Serial.print("\t\t");
210 | Serial.print(quatReal, 2);
211 | Serial.print("\t\t");
212 |
213 | Serial.print(microsSinceLastSerialPrint);
214 | Serial.println();
215 | previousDebugMicros = micros();
216 | }
217 |
218 | if(Serial.available())
219 | {
220 | byte incoming = Serial.read();
221 |
222 | if(incoming == 's')
223 | {
224 | // Saves the current dynamic calibration data (DCD) to memory
225 | // Note, The BNO08X stores updated Dynamic Calibration Data (DCD) to RAM
226 | // frequently (every 5 seconds), so this command may not be necessary
227 | // depending on your application.
228 | if (myIMU.saveCalibration() == true) {
229 | Serial.println(F("Calibration data was saved successfully"));
230 | } else {
231 | Serial.println("Save Calibration Failure");
232 | }
233 | }
234 | }
235 | }
236 |
237 | //Given a accuracy number, print what it means
238 | void printAccuracyLevel(byte accuracyNumber)
239 | {
240 | if(accuracyNumber == 0) Serial.print(F("Unreliable"));
241 | else if(accuracyNumber == 1) Serial.print(F("Low"));
242 | else if(accuracyNumber == 2) Serial.print(F("Medium"));
243 | else if(accuracyNumber == 3) Serial.print(F("High"));
244 | }
--------------------------------------------------------------------------------
/examples/SPI/Example_01_SPI_RotationVector/Example_01_SPI_RotationVector.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to communicate with the sensor over SPI.
5 |
6 | It requires a few more connections than the qwiic cable.
7 | In addition to your usual SPI lines (CS/PICO/POCI/SCK),
8 | This also requires INT and RST. These are crucial for timing when talking to
9 | this sensor.
10 |
11 | It outputs the i/j/k/real parts of the rotation vector.
12 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
13 |
14 | By: Nathan Seidle
15 | SparkFun Electronics
16 | Date: December 21st, 2017
17 | SparkFun code, firmware, and software is released under the MIT License.
18 | Please see LICENSE.md for further details.
19 |
20 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
21 |
22 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
23 | CEVA Sensor Hub Driver, found here:
24 | https://github.com/ceva-dsp/sh2
25 |
26 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
27 | for Adafruit Industries. Found here:
28 | https://github.com/adafruit/Adafruit_BNO08x
29 |
30 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
31 | BusIO library found here:
32 | https://github.com/adafruit/Adafruit_BusIO
33 |
34 | Hardware Connections:
35 | IoT RedBoard --> BNO08x
36 | D5 --> CS
37 | PICO --> SI
38 | POCI --> SO
39 | SCK --> SCK
40 | A4 --> INT
41 | A5 --> RST
42 | 3V3 --> 3V3
43 | GND --> GND
44 |
45 | BNO08x "mode" pins set for SPI:
46 | PSO --> 3V3
47 | PS1 --> 3V3
48 |
49 | Serial.print it out at 115200 baud to serial monitor.
50 |
51 | Feel like supporting our work? Buy a board from SparkFun!
52 | https://www.sparkfun.com/products/22857
53 | */
54 |
55 | //#include
56 |
57 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
58 | BNO08x myIMU;
59 |
60 | // For SPI, we need some extra pins defined:
61 | // Note, these can be other GPIO if you like.
62 | #define BNO08X_CS 5
63 | #define BNO08X_INT A4
64 | #define BNO08X_RST A5
65 |
66 | // If using the MicroMod Machine Learning Carrier Board, use these pins:
67 | // for more info see https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/issues/19
68 | //#define BNO08X_CS PWM0
69 | //#define BNO08X_INT D0 // Note, D0 is also the CS pin for the camera, so you'll need to change that if you're using both.
70 | // a good alternative for D0 is PWM1, (A0 and A1 are only inputs on the carrier board).
71 | //#define BNO08X_RST D1
72 |
73 | void setup() {
74 | Serial.begin(115200);
75 |
76 | while(!Serial) delay(10); // Wait for Serial to become available.
77 | // Necessary for boards with native USB (like the SAMD51 Thing+).
78 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
79 | // Comment out this while loop, or it will prevent the remaining code from running.
80 |
81 | Serial.println();
82 | Serial.println("BNO08x Read Example");
83 |
84 | if (myIMU.beginSPI(BNO08X_CS, BNO08X_INT, BNO08X_RST) == false) {
85 | Serial.println("BNO08x not detected. Check your jumpers and the hookup guide. Freezing...");
86 | while (1)
87 | ;
88 | }
89 | Serial.println("BNO08x found!");
90 |
91 | setReports();
92 |
93 | Serial.println("Reading events");
94 | delay(100);
95 | }
96 |
97 | // Here is where you define the sensor outputs you want to receive
98 | void setReports(void) {
99 | Serial.println("Setting desired reports");
100 | if (myIMU.enableRotationVector() == true) {
101 | Serial.println(F("Rotation vector enabled"));
102 | Serial.println(F("Output in form i, j, k, real, accuracy"));
103 | } else {
104 | Serial.println("Could not enable rotation vector");
105 | }
106 | delay(100); // This delay allows enough time for the BNO086 to accept the new
107 | // configuration and clear its reset status
108 | }
109 |
110 | void loop() {
111 | delay(10);
112 |
113 | if (myIMU.wasReset()) {
114 | Serial.print("sensor was reset ");
115 | setReports();
116 | }
117 |
118 | // Has a new event come in on the Sensor Hub Bus?
119 | if (myIMU.getSensorEvent() == true) {
120 |
121 | // is it the correct sensor data we want?
122 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
123 |
124 | float quatI = myIMU.getQuatI();
125 | float quatJ = myIMU.getQuatJ();
126 | float quatK = myIMU.getQuatK();
127 | float quatReal = myIMU.getQuatReal();
128 | float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
129 |
130 | Serial.print(quatI, 2);
131 | Serial.print(F(","));
132 | Serial.print(quatJ, 2);
133 | Serial.print(F(","));
134 | Serial.print(quatK, 2);
135 | Serial.print(F(","));
136 | Serial.print(quatReal, 2);
137 | Serial.print(F(","));
138 | Serial.print(quatRadianAccuracy, 2);
139 |
140 | Serial.println();
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/examples/SPI/Example_02_SPI_ResetCheck/Example_02_SPI_ResetCheck.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how check for a "Reset Complete" message from the sensor,
5 | which is helpful when used in tandem with requestResetReason() and
6 | getResetReason(). The sensor will be reset each time 100 readings are received
7 | to demonstrate.
8 |
9 | It outputs the x/y/z parts of the gyro.
10 |
11 | By: @mattbradford83
12 | Date: 1 August 2021
13 |
14 | By: Nathan Seidle
15 | SparkFun Electronics
16 | Date: December 21st, 2017
17 | SparkFun code, firmware, and software is released under the MIT License.
18 | Please see LICENSE.md for further details.
19 |
20 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
21 |
22 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
23 | CEVA Sensor Hub Driver, found here:
24 | https://github.com/ceva-dsp/sh2
25 |
26 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
27 | for Adafruit Industries. Found here:
28 | https://github.com/adafruit/Adafruit_BNO08x
29 |
30 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
31 | BusIO library found here:
32 | https://github.com/adafruit/Adafruit_BusIO
33 |
34 | Hardware Connections:
35 | IoT RedBoard --> BNO08x
36 | D5 --> CS
37 | PICO --> SI
38 | POCI --> SO
39 | SCK --> SCK
40 | A4 --> INT
41 | A5 --> RST
42 | 3V3 --> 3V3
43 | GND --> GND
44 |
45 | BNO08x "mode" pins set for SPI:
46 | PSO --> 3V3
47 | PS1 --> 3V3
48 |
49 | Serial.print it out at 115200 baud to serial monitor.
50 |
51 | Feel like supporting our work? Buy a board from SparkFun!
52 | https://www.sparkfun.com/products/22857
53 | */
54 |
55 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
56 | BNO08x myIMU;
57 |
58 | // For SPI, we need some extra pins defined:
59 | // Note, these can be other GPIO if you like.
60 | #define BNO08X_CS 5
61 | #define BNO08X_INT A4
62 | #define BNO08X_RST A5
63 |
64 | // If using the MicroMod Machine Learning Carrier Board, use these pins:
65 | // for more info see https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/issues/19
66 | //#define BNO08X_CS PWM0
67 | //#define BNO08X_INT D0 // Note, D0 is also the CS pin for the camera, so you'll need to change that if you're using both.
68 | // a good alternative for D0 is PWM1, (A0 and A1 are only inputs on the carrier board).
69 | //#define BNO08X_RST D1
70 |
71 | int cyclecount = 0;
72 |
73 | #define BNO08X_ADDR 0x4B // SparkFun BNO08x Breakout (Qwiic) defaults to 0x4B
74 | //#define BNO08X_ADDR 0x4A // Alternate address if ADR jumper is closed
75 |
76 | void setup() {
77 | Serial.begin(115200);
78 |
79 | while(!Serial) delay(10); // Wait for Serial to become available.
80 | // Necessary for boards with native USB (like the SAMD51 Thing+).
81 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
82 | // Comment out this while loop, or it will prevent the remaining code from running.
83 |
84 | Serial.println();
85 | Serial.println("BNO08x Read Example");
86 |
87 | Wire.begin();
88 |
89 | if (myIMU.beginSPI(BNO08X_CS, BNO08X_INT, BNO08X_RST) == false) {
90 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
91 | while (1)
92 | ;
93 | }
94 | Serial.println("BNO08x found!");
95 |
96 | Serial.print(F("Reset Reason: "));
97 | printResetReasonName(myIMU.getResetReason());
98 | Serial.println();
99 |
100 | setReports();
101 |
102 | Serial.println("Reading events");
103 | delay(100);
104 | }
105 |
106 | // Here is where you define the sensor outputs you want to receive
107 | void setReports(void) {
108 | Serial.println("Setting desired reports");
109 | if (myIMU.enableGyro() == true) {
110 | Serial.println(F("Gyro enabled"));
111 | Serial.println(F("Output in form x, y, z, in radians per second"));
112 | } else {
113 | Serial.println("Could not enable gyro");
114 | }
115 | delay(100); // This delay allows enough time for the BNO086 to accept the new
116 | // configuration and clear its reset status
117 | }
118 |
119 | void loop() {
120 | delay(1);
121 | myIMU.serviceBus();
122 |
123 | // One of these will appear at the very start because of the power on reset.
124 | // Use requestResetReason() and getResetReason() for the difference between
125 | // different resets.
126 | if (myIMU.wasReset()) {
127 | Serial.println(" ------------------ BNO08x has reset. ------------------ ");
128 | Serial.print(F("Reset Reason: "));
129 | printResetReasonName(myIMU.getResetReason());
130 | Serial.println();
131 |
132 | setReports(); // We'll need to re-enable reports after any reset.
133 | }
134 |
135 | // Has a new event come in on the Sensor Hub Bus?
136 | if (myIMU.getSensorEvent() == true) {
137 |
138 | // is it the correct sensor data we want?
139 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_GYROSCOPE_CALIBRATED) {
140 |
141 | cyclecount++;
142 |
143 | Serial.print(F("["));
144 | if (cyclecount < 10) Serial.print(F("0"));
145 | Serial.print(cyclecount);
146 | Serial.print(F("] "));
147 |
148 | float x = myIMU.getGyroX();
149 | float y = myIMU.getGyroY();
150 | float z = myIMU.getGyroZ();
151 |
152 | Serial.print(x, 2);
153 | Serial.print(F(","));
154 | Serial.print(y, 2);
155 | Serial.print(F(","));
156 | Serial.print(z, 2);
157 |
158 | Serial.println();
159 |
160 | if (cyclecount == 100) {
161 | myIMU.softReset();
162 | cyclecount = 0;
163 | }
164 | }
165 | }
166 | }
167 |
168 |
169 | //Given a number between 0 and 5, print the name of the reset reason
170 | //1 = POR, 2 = Internal reset, 3 = Watchdog, 4 = External reset, 5 = Other
171 | void printResetReasonName(byte resetReasonNumber)
172 | {
173 | if(resetReasonNumber == 1) Serial.print("POR");
174 | else if(resetReasonNumber == 2) Serial.print("Internal reset");
175 | else if(resetReasonNumber == 3) Serial.print("Watchdog");
176 | else if(resetReasonNumber == 4) Serial.print("External reset");
177 | else if(resetReasonNumber == 5) Serial.print("Other");
178 | }
179 |
--------------------------------------------------------------------------------
/examples/SPI/Example_03_SPI_Sleep/Example_03_SPI_Sleep.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Using the BNO08x IMU
3 |
4 | This example shows how to use the sleep features of the sensor.
5 |
6 | It toggles the sleep mode on/off every 5 seconds.
7 |
8 | When awake, this example outputs the i/j/k/real parts of the rotation vector.
9 | https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
10 |
11 | By: Nathan Seidle
12 | SparkFun Electronics
13 | Date: December 21st, 2017
14 | SparkFun code, firmware, and software is released under the MIT License.
15 | Please see LICENSE.md for further details.
16 |
17 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
18 |
19 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
20 | CEVA Sensor Hub Driver, found here:
21 | https://github.com/ceva-dsp/sh2
22 |
23 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
24 | for Adafruit Industries. Found here:
25 | https://github.com/adafruit/Adafruit_BNO08x
26 |
27 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
28 | BusIO library found here:
29 | https://github.com/adafruit/Adafruit_BusIO
30 |
31 | Hardware Connections:
32 | IoT RedBoard --> BNO08x
33 | D5 --> CS
34 | PICO --> SI
35 | POCI --> SO
36 | SCK --> SCK
37 | A4 --> INT
38 | A5 --> RST
39 | 3V3 --> 3V3
40 | GND --> GND
41 |
42 | BNO08x "mode" pins set for SPI:
43 | PSO --> 3V3
44 | PS1 --> 3V3
45 |
46 | Serial.print it out at 115200 baud to serial monitor.
47 |
48 | Feel like supporting our work? Buy a board from SparkFun!
49 | https://www.sparkfun.com/products/22857
50 | */
51 |
52 | #include "SparkFun_BNO08x_Arduino_Library.h" // CTRL+Click here to get the library: http://librarymanager/All#SparkFun_BNO08x
53 | BNO08x myIMU;
54 |
55 | // For SPI, we need some extra pins defined:
56 | // Note, these can be other GPIO if you like.
57 | #define BNO08X_CS 5
58 | #define BNO08X_INT A4
59 | #define BNO08X_RST A5
60 |
61 | // If using the MicroMod Machine Learning Carrier Board, use these pins:
62 | // for more info see https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library/issues/19
63 | //#define BNO08X_CS PWM0
64 | //#define BNO08X_INT D0 // Note, D0 is also the CS pin for the camera, so you'll need to change that if you're using both.
65 | // a good alternative for D0 is PWM1, (A0 and A1 are only inputs on the carrier board).
66 | //#define BNO08X_RST D1
67 |
68 | unsigned long lastMillis = 0; // Keep track of time
69 | bool lastPowerState = true; // Toggle between "On" and "Sleep"
70 |
71 | void setup() {
72 | Serial.begin(115200);
73 |
74 | while(!Serial) delay(10); // Wait for Serial to become available.
75 | // Necessary for boards with native USB (like the SAMD51 Thing+).
76 | // For a final version of a project that does not need serial debug (or a USB cable plugged in),
77 | // Comment out this while loop, or it will prevent the remaining code from running.
78 |
79 | Serial.println();
80 | Serial.println("BNO08x Sleep Example");
81 |
82 | if (myIMU.beginSPI(BNO08X_CS, BNO08X_INT, BNO08X_RST) == false) {
83 | Serial.println("BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
84 | while (1)
85 | ;
86 | }
87 | Serial.println("BNO08x found!");
88 |
89 | setReports();
90 |
91 | Serial.println("Reading events");
92 | delay(100);
93 |
94 | lastMillis = millis(); // Keep track of time
95 | }
96 |
97 | // Here is where you define the sensor outputs you want to receive
98 | void setReports(void) {
99 | Serial.println("Setting desired reports");
100 | if (myIMU.enableRotationVector() == true) {
101 | Serial.println(F("Rotation vector enabled"));
102 | Serial.println(F("Output in form i, j, k, real, accuracy"));
103 | } else {
104 | Serial.println("Could not enable rotation vector");
105 | }
106 | delay(100); // This delay allows enough time for the BNO086 to accept the new
107 | // configuration and clear its reset status
108 | }
109 |
110 | void loop() {
111 | delay(10);
112 |
113 | if (lastPowerState) // Are we "On"?
114 | {
115 |
116 | if (myIMU.wasReset()) {
117 | Serial.print("sensor was reset ");
118 | setReports();
119 | }
120 |
121 | // Has a new event come in on the Sensor Hub Bus?
122 | if (myIMU.getSensorEvent() == true) {
123 |
124 | // is it the correct sensor data we want?
125 | if (myIMU.getSensorEventID() == SENSOR_REPORTID_ROTATION_VECTOR) {
126 |
127 | float quatI = myIMU.getQuatI();
128 | float quatJ = myIMU.getQuatJ();
129 | float quatK = myIMU.getQuatK();
130 | float quatReal = myIMU.getQuatReal();
131 | float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();
132 |
133 | Serial.print(quatI, 2);
134 | Serial.print(F(","));
135 | Serial.print(quatJ, 2);
136 | Serial.print(F(","));
137 | Serial.print(quatK, 2);
138 | Serial.print(F(","));
139 | Serial.print(quatReal, 2);
140 | Serial.print(F(","));
141 | Serial.print(quatRadianAccuracy, 2);
142 | Serial.print(F(","));
143 |
144 | Serial.println();
145 | }
146 | }
147 | }
148 |
149 | //Check if it is time to change the power state
150 | if (millis() > (lastMillis + 5000)) // Change state every 5 seconds
151 | {
152 | lastMillis = millis(); // Keep track of time
153 |
154 | if (lastPowerState) // Are we "On"?
155 | {
156 | Serial.println("Putting BNO08x to sleep...");
157 | myIMU.modeSleep(); // Put BNO to sleep
158 | } else {
159 | Serial.println("Waking up BNO08x");
160 | myIMU.modeOn(); // Turn BNO back on
161 | }
162 |
163 | lastPowerState ^= 1; // Invert lastPowerState (using ex-or)
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | BNO08x KEYWORD1
10 |
11 | #######################################
12 | # Methods and Functions (KEYWORD2)
13 | #######################################
14 |
15 | begin KEYWORD2
16 | beginSPI KEYWORD2
17 |
18 | enableDebugging KEYWORD2
19 |
20 | softReset KEYWORD2
21 | resetReason KEYWORD2
22 | wasReset KEYWORD2
23 | modeOn KEYWORD2
24 | modeSleep KEYWORD2
25 |
26 | qToFloat KEYWORD2
27 |
28 | enableRotationVector KEYWORD2
29 | enableGeomagneticRotationVector KEYWORD2
30 | enableGameRotationVector KEYWORD2
31 | enableARVRStabilizedRotationVector KEYWORD2
32 | enableARVRStabilizedGameRotationVector KEYWORD2
33 | enableAccelerometer KEYWORD2
34 | enableGyro KEYWORD2
35 | enableUncalibratedGyro KEYWORD2
36 | enableGravity KEYWORD2
37 | enableMagnetometer KEYWORD2
38 | enableTapDetector KEYWORD2
39 | enableStepCounter KEYWORD2
40 | enableStabilityClassifier KEYWORD2
41 | enableActivityClassifier KEYWORD2
42 | enableLinearAccelerometer KEYWORD2
43 | enableRawAccelerometer KEYWORD2
44 | enableRawGyro KEYWORD2
45 | enableRawMagnetometer KEYWORD2
46 | enableGyroIntegratedRotationVector KEYWORD2
47 |
48 | getQuat KEYWORD2
49 | getQuatI KEYWORD2
50 | getQuatJ KEYWORD2
51 | getQuatK KEYWORD2
52 | getQuatReal KEYWORD2
53 | getQuatRadianAccuracy KEYWORD2
54 | getQuatAccuracy KEYWORD2
55 |
56 | getAccel KEYWORD2
57 | getAccelX KEYWORD2
58 | getAccelY KEYWORD2
59 | getAccelZ KEYWORD2
60 | getAccelAccuracy KEYWORD2
61 |
62 | getGyro KEYWORD2
63 | getGyroX KEYWORD2
64 | getGyroY KEYWORD2
65 | getGyroZ KEYWORD2
66 | getGyroAccuracy KEYWORD2
67 |
68 | getUncalibratedGyro KEYWORD2
69 | getUncalibratedGyroX KEYWORD2
70 | getUncalibratedGyroY KEYWORD2
71 | getUncalibratedGyroZ KEYWORD2
72 | getUncalibratedGyroAccuracy KEYWORD2
73 | getUncalibratedGyroBiasX KEYWORD2
74 | getUncalibratedGyroBiasY KEYWORD2
75 | getUncalibratedGyroBiasZ KEYWORD2
76 |
77 | getGravity KEYWORD2
78 | getGravityX KEYWORD2
79 | getGravityY KEYWORD2
80 | getGravityZ KEYWORD2
81 | getGravityAccuracy KEYWORD2
82 |
83 | getGyroIntegratedRVI KEYWORD2
84 | getGyroIntegratedRVJ KEYWORD2
85 | getGyroIntegratedRVK KEYWORD2
86 | getGyroIntegratedRVReal KEYWORD2
87 | getGyroIntegratedRVangVelX KEYWORD2
88 | getGyroIntegratedRVangVelY KEYWORD2
89 | getGyroIntegratedRVangVelZ KEYWORD2
90 |
91 | getMag KEYWORD2
92 | getMagX KEYWORD2
93 | getMagY KEYWORD2
94 | getMagZ KEYWORD2
95 | getMagAccuracy KEYWORD2
96 |
97 | getLinAccel KEYWORD2
98 | getLinAccelX KEYWORD2
99 | getLinAccelY KEYWORD2
100 | getLinAccelZ KEYWORD2
101 | getLinAccelAccuracy KEYWORD2
102 |
103 | setCalibrationConfig KEYWORD2
104 | saveCalibration KEYWORD2
105 |
106 | tareNow KEYWORD2
107 | saveTare KEYWORD2
108 | clearTare KEYWORD2
109 | sendTareCommand KEYWORD2
110 |
111 | getTapDetector KEYWORD2
112 | getTimeStamp KEYWORD2
113 | getStepCount KEYWORD2
114 | getStabilityClassifier KEYWORD2
115 | getActivityClassifier KEYWORD2
116 |
117 | sendCommand KEYWORD2
118 | sendCalibrateCommand KEYWORD2
119 | calibrationComplete KEYWORD2
120 |
121 | getQ1 KEYWORD2
122 | getQ2 KEYWORD2
123 | getQ3 KEYWORD2
124 | getResolution KEYWORD2
125 | getRange KEYWORD2
126 | readFRSword KEYWORD2
127 | frsReadRequest KEYWORD2
128 | readFRSdata KEYWORD2
129 |
130 | getRawAccelX KEYWORD2
131 | getRawAccelY KEYWORD2
132 | getRawAccelZ KEYWORD2
133 |
134 | getRawGyroX KEYWORD2
135 | getRawGyroY KEYWORD2
136 | getRawGyroZ KEYWORD2
137 |
138 | getRawMagX KEYWORD2
139 | getRawMagY KEYWORD2
140 | getRawMagZ KEYWORD2
141 |
142 | getRoll KEYWORD2
143 | getPitch KEYWORD2
144 | getYaw KEYWORD2
145 |
146 | #######################################
147 | # Constants (LITERAL1)
148 | #######################################
149 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=SparkFun BNO08x Cortex Based IMU
2 | version=1.0.6
3 | author=SparkFun Electronics
4 | maintainer=SparkFun Electronics
5 | sentence=Library for the SparkFun Qwiic VR IMU - BNO080/BNO085/BNO086
6 | paragraph=An Arduino Library for the BNO08x IMU. The BNO08x IMU has a combination triple axis accelerometer/gyro/magnetometer packaged with an ARM Cortex M0+ running powerful algorithms. This enables the BNO08x Inertial Measurement Unit (IMU) to produce accurate rotation vector headings with an error of 5 degrees or less. It's what we've been waiting for: all the sensor data is combined into meaningful, accurate IMU information. Available at: https://www.sparkfun.com/products/22857
7 | category=Sensors
8 | url=https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/src/NOTICE.txt:
--------------------------------------------------------------------------------
1 | This software is licensed from Hillcrest Laboratories, Inc.
2 | Copyright (c) Hillcrest Laboratories, Inc. and its licensors.
3 | All rights reserved.
4 |
5 | Hillcrest Laboratories and the Hillcrest logo are trademarks of
6 | Hillcrest Laboratories, Inc.
7 |
8 | You can contact Hillcrest Laboratories on the web at
9 | http://hillcrestlabs.com/company/contact-us/ or at Hillcrest Laboratories,
10 | 15245 Shady Grove Road, Suite 400, Rockville, MD 20850 USA
11 |
12 | /**********************************************************/
13 |
14 | Some of this library was based off of the Adafruit BNO08x Arduino Library.
15 | More specifically, the code layers connecting to the HillCrest/Ceva Driver.
16 | Their original work can be found here:
17 | https://github.com/adafruit/Adafruit_BNO08x
18 |
19 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
20 | BusIO library found here:
21 | https://github.com/adafruit/Adafruit_BusIO
22 |
23 | Thank you Adafruit and your developers for all your hard work put into your Library!
24 | The following is the License text that they included on their code:
25 |
26 | Software License Agreement (BSD License)
27 |
28 | Copyright (c) 2019 Bryan Siepert for Adafruit Industries
29 | All rights reserved.
30 |
31 | Redistribution and use in source and binary forms, with or without
32 | modification, are permitted provided that the following conditions are met:
33 | 1. Redistributions of source code must retain the above copyright
34 | notice, this list of conditions and the following disclaimer.
35 | 2. Redistributions in binary form must reproduce the above copyright
36 | notice, this list of conditions and the following disclaimer in the
37 | documentation and/or other materials provided with the distribution.
38 | 3. Neither the name of the copyright holders nor the
39 | names of its contributors may be used to endorse or promote products
40 | derived from this software without specific prior written permission.
41 |
42 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
43 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
46 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 |
53 | /**********************************************************/
54 |
--------------------------------------------------------------------------------
/src/SparkFun_BNO08x_Arduino_Library.h:
--------------------------------------------------------------------------------
1 | /*
2 | This is a library written for the BNO08x
3 | SparkFun sells these at its website: www.sparkfun.com
4 | Do you like this library? Help support SparkFun. Buy a board!
5 | https://www.sparkfun.com/products/14686
6 |
7 | Originally written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017
8 |
9 | Adjusted by Pete Lewis @ SparkFun Electronics, June 2023 to incorporate the
10 | CEVA Sensor Hub Driver, found here:
11 | https://github.com/ceva-dsp/sh2
12 |
13 | Also, utilizing code from the Adafruit BNO08x Arduino Library by Bryan Siepert
14 | for Adafruit Industries. Found here:
15 | https://github.com/adafruit/Adafruit_BNO08x
16 |
17 | Also, utilizing I2C and SPI read/write functions and code from the Adafruit
18 | BusIO library found here:
19 | https://github.com/adafruit/Adafruit_BusIO
20 |
21 | The BNO08x IMU is a powerful triple axis gyro/accel/magnetometer coupled with an ARM processor
22 | to maintain and complete all the complex calculations for various VR, inertial, step counting,
23 | and movement operations.
24 |
25 | This library handles the initialization of the BNO08x and is able to query the sensor
26 | for different readings.
27 |
28 | https://github.com/sparkfun/SparkFun_BNO08x_Arduino_Library
29 |
30 | Development environment specifics:
31 | Arduino IDE 2.1.1
32 |
33 | SparkFun code, firmware, and software is released under the MIT License.
34 | Please see LICENSE.md for further details.
35 |
36 | Some of this library was based off of the Adafruit BNO08x Arduino Library.
37 | More specifically, the code layers connecting to the HillCrest/Ceva Driver.
38 | Their original work can be found here:
39 | https://github.com/adafruit/Adafruit_BNO08x
40 | Thank you Adafruit and your developers for all your hard work put into your Library!
41 | */
42 |
43 | #include "sh2.h"
44 | #include "sh2_SensorValue.h"
45 | #include "sh2_err.h"
46 |
47 | #pragma once
48 |
49 | #if (ARDUINO >= 100)
50 | #include "Arduino.h"
51 | #else
52 | #include "WProgram.h"
53 | #endif
54 |
55 | #include
56 | #include
57 |
58 | //The default I2C address for the BNO08x on the SparkFun breakout is 0x4B. 0x4A is also possible.
59 | #define BNO08x_DEFAULT_ADDRESS 0x4B
60 |
61 | //Platform specific configurations
62 |
63 | //Define the size of the I2C buffer based on the platform the user has
64 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
65 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
66 |
67 | //I2C_BUFFER_LENGTH is defined in Wire.H
68 | #define I2C_BUFFER_LENGTH 32
69 |
70 | //#else
71 |
72 | //The catch-all default is 32
73 | //#define I2C_BUFFER_LENGTH 32
74 |
75 | #endif
76 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
77 |
78 |
79 | //All the ways we can configure or talk to the BNO08x, figure 34, page 36 reference manual
80 | //These are used for low level communication with the sensor, on channel 2
81 | #define SHTP_REPORT_COMMAND_RESPONSE 0xF1
82 | #define SHTP_REPORT_COMMAND_REQUEST 0xF2
83 | #define SHTP_REPORT_FRS_READ_RESPONSE 0xF3
84 | #define SHTP_REPORT_FRS_READ_REQUEST 0xF4
85 | #define SHTP_REPORT_PRODUCT_ID_RESPONSE 0xF8
86 | #define SHTP_REPORT_PRODUCT_ID_REQUEST 0xF9
87 | #define SHTP_REPORT_BASE_TIMESTAMP 0xFB
88 | #define SHTP_REPORT_SET_FEATURE_COMMAND 0xFD
89 |
90 | //All the different sensors and features we can get reports from
91 | //These are used when enabling a given sensor
92 | #define SENSOR_REPORTID_ACCELEROMETER SH2_ACCELEROMETER
93 | #define SENSOR_REPORTID_GYROSCOPE_CALIBRATED SH2_GYROSCOPE_CALIBRATED
94 | #define SENSOR_REPORTID_MAGNETIC_FIELD SH2_MAGNETIC_FIELD_CALIBRATED
95 | #define SENSOR_REPORTID_LINEAR_ACCELERATION SH2_LINEAR_ACCELERATION
96 | #define SENSOR_REPORTID_ROTATION_VECTOR SH2_ROTATION_VECTOR
97 | #define SENSOR_REPORTID_GRAVITY SH2_GRAVITY
98 | #define SENSOR_REPORTID_UNCALIBRATED_GYRO SH2_GYROSCOPE_UNCALIBRATED
99 | #define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08
100 | #define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09
101 | #define SENSOR_REPORTID_GYRO_INTEGRATED_ROTATION_VECTOR SH2_GYRO_INTEGRATED_RV
102 | #define SENSOR_REPORTID_TAP_DETECTOR 0x10
103 | #define SENSOR_REPORTID_STEP_COUNTER SH2_STEP_COUNTER
104 | #define SENSOR_REPORTID_STABILITY_CLASSIFIER SH2_STABILITY_CLASSIFIER
105 | #define SENSOR_REPORTID_RAW_ACCELEROMETER 0x14
106 | #define SENSOR_REPORTID_RAW_GYROSCOPE 0x15
107 | #define SENSOR_REPORTID_RAW_MAGNETOMETER 0x16
108 | #define SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER SH2_PERSONAL_ACTIVITY_CLASSIFIER
109 | #define SENSOR_REPORTID_AR_VR_STABILIZED_ROTATION_VECTOR 0x28
110 | #define SENSOR_REPORTID_AR_VR_STABILIZED_GAME_ROTATION_VECTOR 0x29
111 |
112 | // Reset complete packet (BNO08X Datasheet p.24 Figure 1-27)
113 | #define EXECUTABLE_RESET_COMPLETE 0x1
114 |
115 | //Command IDs from section 6.4, page 42
116 | //These are used to calibrate, initialize, set orientation, tare etc the sensor
117 | #define COMMAND_ERRORS 1
118 | #define COMMAND_COUNTER 2
119 | #define COMMAND_TARE 3
120 | #define COMMAND_INITIALIZE 4
121 | #define COMMAND_DCD 6
122 | #define COMMAND_ME_CALIBRATE 7
123 | #define COMMAND_DCD_PERIOD_SAVE 9
124 | #define COMMAND_OSCILLATOR 10
125 | #define COMMAND_CLEAR_DCD 11
126 |
127 | #define CALIBRATE_ACCEL 0
128 | #define CALIBRATE_GYRO 1
129 | #define CALIBRATE_MAG 2
130 | #define CALIBRATE_PLANAR_ACCEL 3
131 | #define CALIBRATE_ACCEL_GYRO_MAG 4
132 | #define CALIBRATE_STOP 5
133 |
134 | #define TARE_AXIS_ALL 0x07
135 | #define TARE_AXIS_Z 0x04
136 |
137 | #define TARE_ROTATION_VECTOR 0
138 | #define TARE_GAME_ROTATION_VECTOR 1
139 | #define TARE_GEOMAGNETIC_ROTATION_VECTOR 2
140 | #define TARE_GYRO_INTEGRATED_ROTATION_VECTOR 3
141 | #define TARE_AR_VR_STABILIZED_ROTATION_VECTOR 4
142 | #define TARE_AR_VR_STABILIZED_GAME_ROTATION_VECTOR 5
143 |
144 | class BNO08x
145 | {
146 | public:
147 | boolean begin(uint8_t deviceAddress = BNO08x_DEFAULT_ADDRESS, TwoWire &wirePort = Wire, int8_t user_INTPin = -1, int8_t user_RSTPin = -1); //By default use the default I2C addres, and use Wire port
148 | boolean beginSPI(uint8_t user_CSPin, uint8_t user_INTPin, uint8_t user_RSTPin, uint32_t spiPortSpeed = 1000000, SPIClass &spiPort = SPI);
149 | boolean isConnected();
150 |
151 | sh2_ProductIds_t prodIds; ///< The product IDs returned by the sensor
152 | sh2_SensorValue_t sensorValue;
153 |
154 | void hardwareReset(void);
155 | bool wasReset(void); //Returns true if the sensor has reported a reset. Reading this will unflag the reset.
156 |
157 | uint8_t getResetReason(); // returns prodIds->resetCause
158 |
159 | bool enableReport(sh2_SensorId_t sensor, uint32_t interval_us = 10000, uint32_t sensorSpecific = 0);
160 | bool getSensorEvent();
161 | uint8_t getSensorEventID();
162 |
163 | void enableDebugging(Stream &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used.
164 |
165 | bool softReset(); //Try to reset the IMU via software
166 | bool serviceBus(void);
167 | uint8_t resetReason(); //Query the IMU for the reason it last reset
168 | bool modeOn(); //Use the executable channel to turn the BNO on
169 | bool modeSleep(); //Use the executable channel to put the BNO to sleep
170 |
171 | float qToFloat(int16_t fixedPointValue, uint8_t qPoint); //Given a Q value, converts fixed point floating to regular floating point number
172 |
173 | bool enableRotationVector(uint16_t timeBetweenReports = 10);
174 | bool enableGeomagneticRotationVector(uint16_t timeBetweenReports = 10);
175 | bool enableGameRotationVector(uint16_t timeBetweenReports = 10);
176 | bool enableARVRStabilizedRotationVector(uint16_t timeBetweenReports);
177 | bool enableARVRStabilizedGameRotationVector(uint16_t timeBetweenReports);
178 | bool enableAccelerometer(uint16_t timeBetweenReports = 10);
179 | bool enableLinearAccelerometer(uint16_t timeBetweenReports = 10);
180 | bool enableGravity(uint16_t timeBetweenReports = 10);
181 | bool enableGyro(uint16_t timeBetweenReports = 10);
182 | bool enableUncalibratedGyro(uint16_t timeBetweenReports = 10);
183 | bool enableMagnetometer(uint16_t timeBetweenReports = 10);
184 | bool enableTapDetector(uint16_t timeBetweenReports);
185 | bool enableStepCounter(uint16_t timeBetweenReports = 10);
186 | bool enableStabilityClassifier(uint16_t timeBetweenReports = 10);
187 | bool enableActivityClassifier(uint16_t timeBetweenReports, uint32_t activitiesToEnable);
188 | bool enableRawAccelerometer(uint16_t timeBetweenReports = 10);
189 | bool enableRawGyro(uint16_t timeBetweenReports = 10);
190 | bool enableRawMagnetometer(uint16_t timeBetweenReports = 10);
191 | bool enableGyroIntegratedRotationVector(uint16_t timeBetweenReports = 10);
192 |
193 | void getQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy);
194 | float getQuatI();
195 | float getQuatJ();
196 | float getQuatK();
197 | float getQuatReal();
198 | float getQuatRadianAccuracy();
199 | uint8_t getQuatAccuracy();
200 |
201 | float getGameQuatI();
202 | float getGameQuatJ();
203 | float getGameQuatK();
204 | float getGameQuatReal();
205 |
206 | void getAccel(float &x, float &y, float &z, uint8_t &accuracy);
207 | float getAccelX();
208 | float getAccelY();
209 | float getAccelZ();
210 | uint8_t getAccelAccuracy();
211 |
212 | void getLinAccel(float &x, float &y, float &z, uint8_t &accuracy);
213 | float getLinAccelX();
214 | float getLinAccelY();
215 | float getLinAccelZ();
216 | uint8_t getLinAccelAccuracy();
217 |
218 | void getGyro(float &x, float &y, float &z, uint8_t &accuracy);
219 | float getGyroX();
220 | float getGyroY();
221 | float getGyroZ();
222 | uint8_t getGyroAccuracy();
223 |
224 | void getUncalibratedGyro(float &x, float &y, float &z, float &bx, float &by, float &bz, uint8_t &accuracy);
225 | float getUncalibratedGyroX();
226 | float getUncalibratedGyroY();
227 | float getUncalibratedGyroZ();
228 | float getUncalibratedGyroBiasX();
229 | float getUncalibratedGyroBiasY();
230 | float getUncalibratedGyroBiasZ();
231 | uint8_t getUncalibratedGyroAccuracy();
232 |
233 | float getGyroIntegratedRVI();
234 | float getGyroIntegratedRVJ();
235 | float getGyroIntegratedRVK();
236 | float getGyroIntegratedRVReal();
237 | float getGyroIntegratedRVangVelX();
238 | float getGyroIntegratedRVangVelY();
239 | float getGyroIntegratedRVangVelZ();
240 |
241 | void getMag(float &x, float &y, float &z, uint8_t &accuracy);
242 | float getMagX();
243 | float getMagY();
244 | float getMagZ();
245 | uint8_t getMagAccuracy();
246 |
247 | void getGravity(float &x, float &y, float &z, uint8_t &accuracy);
248 | float getGravityX();
249 | float getGravityY();
250 | float getGravityZ();
251 | uint8_t getGravityAccuracy();
252 |
253 | bool setCalibrationConfig(uint8_t sensors);
254 | bool saveCalibration();
255 |
256 | bool tareNow(bool zAxis=false, sh2_TareBasis_t basis=SH2_TARE_BASIS_ROTATION_VECTOR);
257 | bool saveTare();
258 | bool clearTare();
259 |
260 | uint8_t getTapDetector();
261 | uint64_t getTimeStamp();
262 | uint16_t getStepCount();
263 | uint8_t getStabilityClassifier();
264 | uint8_t getActivityClassifier();
265 | uint8_t getActivityConfidence(uint8_t activity);
266 |
267 | int16_t getRawAccelX();
268 | int16_t getRawAccelY();
269 | int16_t getRawAccelZ();
270 |
271 | int16_t getRawGyroX();
272 | int16_t getRawGyroY();
273 | int16_t getRawGyroZ();
274 |
275 | int16_t getRawMagX();
276 | int16_t getRawMagY();
277 | int16_t getRawMagZ();
278 |
279 | float getRoll();
280 | float getPitch();
281 | float getYaw();
282 |
283 | // void sendCommand(uint8_t command);
284 | // void sendCalibrateCommand(uint8_t thingToCalibrate);
285 |
286 | //Metadata functions
287 | // int16_t getQ1(uint16_t recordID);
288 | // int16_t getQ2(uint16_t recordID);
289 | // int16_t getQ3(uint16_t recordID);
290 | // float getResolution(uint16_t recordID);
291 | // float getRange(uint16_t recordID);
292 | // uint32_t readFRSword(uint16_t recordID, uint8_t wordNumber);
293 | // void frsReadRequest(uint16_t recordID, uint16_t readOffset, uint16_t blockSize);
294 | // bool readFRSdata(uint16_t recordID, uint8_t startLocation, uint8_t wordsToRead);
295 |
296 | //Global Variables
297 | // uint8_t shtpHeader[4]; //Each packet has a header of 4 bytes
298 | // uint8_t shtpData[MAX_PACKET_SIZE];
299 | // uint8_t sequenceNumber[6] = {0, 0, 0, 0, 0, 0}; //There are 6 com channels. Each channel has its own seqnum
300 | // uint8_t commandSequenceNumber = 0; //Commands have a seqNum as well. These are inside command packet, the header uses its own seqNum per channel
301 | // uint32_t metaData[MAX_METADATA_SIZE]; //There is more than 10 words in a metadata record but we'll stop at Q point 3
302 |
303 | // unsigned long _spiPortSpeed; //Optional user defined port speed
304 | // uint8_t _cs; //Pins needed for SPI
305 |
306 | private:
307 |
308 | Stream *_debugPort; //The stream to send debug messages to if enabled. Usually Serial.
309 | boolean _printDebug = false; //Flag to print debugging variables
310 |
311 | //These are the raw sensor values (without Q applied) pulled from the user requested Input Report
312 | uint16_t rawAccelX, rawAccelY, rawAccelZ, accelAccuracy;
313 | uint16_t rawLinAccelX, rawLinAccelY, rawLinAccelZ, accelLinAccuracy;
314 | uint16_t rawGyroX, rawGyroY, rawGyroZ, gyroAccuracy;
315 | uint16_t rawUncalibGyroX, rawUncalibGyroY, rawUncalibGyroZ, rawBiasX, rawBiasY, rawBiasZ, UncalibGyroAccuracy;
316 | uint16_t rawMagX, rawMagY, rawMagZ, magAccuracy;
317 | uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy;
318 | uint16_t rawFastGyroX, rawFastGyroY, rawFastGyroZ;
319 | uint16_t gravityX, gravityY, gravityZ, gravityAccuracy;
320 | uint8_t tapDetector;
321 | uint16_t stepCount;
322 | uint32_t timeStamp;
323 | uint8_t stabilityClassifier;
324 | uint8_t activityClassifier;
325 | uint8_t calibrationStatus; //Byte R0 of ME Calibration Response
326 | uint16_t memsRawAccelX, memsRawAccelY, memsRawAccelZ; //Raw readings from MEMS sensor
327 | uint16_t memsRawGyroX, memsRawGyroY, memsRawGyroZ; //Raw readings from MEMS sensor
328 | uint16_t memsRawMagX, memsRawMagY, memsRawMagZ; //Raw readings from MEMS sensor
329 |
330 | //These Q values are defined in the datasheet but can also be obtained by querying the meta data records
331 | //See the read metadata example for more info
332 | int16_t rotationVector_Q1 = 14;
333 | int16_t rotationVectorAccuracy_Q1 = 12; //Heading accuracy estimate in radians. The Q point is 12.
334 | int16_t accelerometer_Q1 = 8;
335 | int16_t linear_accelerometer_Q1 = 8;
336 | int16_t gyro_Q1 = 9;
337 | int16_t magnetometer_Q1 = 4;
338 | int16_t angular_velocity_Q1 = 10;
339 | int16_t gravity_Q1 = 8;
340 |
341 | protected:
342 | virtual bool _init(int32_t sensor_id = 0);
343 | sh2_Hal_t _HAL; ///< The struct representing the SH2 Hardware Abstraction Layer
344 | };
--------------------------------------------------------------------------------
/src/sh2_SensorValue.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-16 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /*
19 | * BNO08x Sensor Event decoding
20 | */
21 |
22 | #include "sh2_SensorValue.h"
23 | #include "sh2_err.h"
24 | #include "sh2_util.h"
25 |
26 | #define SCALE_Q(n) (1.0f / (1 << n))
27 |
28 | const float scaleRadToDeg = 180.0 / 3.14159265358;
29 |
30 | // ------------------------------------------------------------------------
31 | // Forward declarations
32 |
33 | static int decodeRawAccelerometer(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
34 | static int decodeAccelerometer(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
35 | static int decodeLinearAcceleration(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
36 | static int decodeGravity(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
37 | static int decodeRawGyroscope(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
38 | static int decodeGyroscopeCalibrated(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
39 | static int decodeGyroscopeUncal(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
40 | static int decodeRawMagnetometer(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
41 | static int decodeMagneticFieldCalibrated(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
42 | static int decodeMagneticFieldUncal(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
43 | static int decodeRotationVector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
44 | static int decodeGameRotationVector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
45 | static int decodeGeomagneticRotationVector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
46 | static int decodePressure(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
47 | static int decodeAmbientLight(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
48 | static int decodeHumidity(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
49 | static int decodeProximity(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
50 | static int decodeTemperature(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
51 | static int decodeReserved(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
52 | static int decodeTapDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
53 | static int decodeStepDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
54 | static int decodeStepCounter(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
55 | static int decodeSignificantMotion(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
56 | static int decodeStabilityClassifier(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
57 | static int decodeShakeDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
58 | static int decodeFlipDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
59 | static int decodePickupDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
60 | static int decodeStabilityDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
61 | static int decodePersonalActivityClassifier(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
62 | static int decodeSleepDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
63 | static int decodeTiltDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
64 | static int decodePocketDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
65 | static int decodeCircleDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
66 | static int decodeHeartRateMonitor(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
67 | static int decodeArvrStabilizedRV(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
68 | static int decodeArvrStabilizedGRV(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
69 | static int decodeGyroIntegratedRV(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
70 | static int decodeIZroRequest(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
71 |
72 | // ------------------------------------------------------------------------
73 | // Public API
74 |
75 | int sh2_decodeSensorEvent(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
76 | {
77 | // Fill out fields of *value based on *event, converting data from message representation
78 | // to natural representation.
79 |
80 | int rc = SH2_OK;
81 |
82 | value->sensorId = event->reportId;
83 | value->timestamp = event->timestamp_uS;
84 |
85 | if (value->sensorId != SH2_GYRO_INTEGRATED_RV) {
86 | value->sequence = event->report[1];
87 | value->status = event->report[2] & 0x03;
88 | }
89 | else {
90 | value->sequence = 0;
91 | value->status = 0;
92 | }
93 |
94 | // extract delay field (100uS units)
95 |
96 |
97 | switch (value->sensorId) {
98 | case SH2_RAW_ACCELEROMETER:
99 | rc = decodeRawAccelerometer(value, event);
100 | break;
101 | case SH2_ACCELEROMETER:
102 | rc = decodeAccelerometer(value, event);
103 | break;
104 | case SH2_LINEAR_ACCELERATION:
105 | rc = decodeLinearAcceleration(value, event);
106 | break;
107 | case SH2_GRAVITY:
108 | rc = decodeGravity(value, event);
109 | break;
110 | case SH2_RAW_GYROSCOPE:
111 | rc = decodeRawGyroscope(value, event);
112 | break;
113 | case SH2_GYROSCOPE_CALIBRATED:
114 | rc = decodeGyroscopeCalibrated(value, event);
115 | break;
116 | case SH2_GYROSCOPE_UNCALIBRATED:
117 | rc = decodeGyroscopeUncal(value, event);
118 | break;
119 | case SH2_RAW_MAGNETOMETER:
120 | rc = decodeRawMagnetometer(value, event);
121 | break;
122 | case SH2_MAGNETIC_FIELD_CALIBRATED:
123 | rc = decodeMagneticFieldCalibrated(value, event);
124 | break;
125 | case SH2_MAGNETIC_FIELD_UNCALIBRATED:
126 | rc = decodeMagneticFieldUncal(value, event);
127 | break;
128 | case SH2_ROTATION_VECTOR:
129 | rc = decodeRotationVector(value, event);
130 | break;
131 | case SH2_GAME_ROTATION_VECTOR:
132 | rc = decodeGameRotationVector(value, event);
133 | break;
134 | case SH2_GEOMAGNETIC_ROTATION_VECTOR:
135 | rc = decodeGeomagneticRotationVector(value, event);
136 | break;
137 | case SH2_PRESSURE:
138 | rc = decodePressure(value, event);
139 | break;
140 | case SH2_AMBIENT_LIGHT:
141 | rc = decodeAmbientLight(value, event);
142 | break;
143 | case SH2_HUMIDITY:
144 | rc = decodeHumidity(value, event);
145 | break;
146 | case SH2_PROXIMITY:
147 | rc = decodeProximity(value, event);
148 | break;
149 | case SH2_TEMPERATURE:
150 | rc = decodeTemperature(value, event);
151 | break;
152 | case SH2_RESERVED:
153 | rc = decodeReserved(value, event);
154 | break;
155 | case SH2_TAP_DETECTOR:
156 | rc = decodeTapDetector(value, event);
157 | break;
158 | case SH2_STEP_DETECTOR:
159 | rc = decodeStepDetector(value, event);
160 | break;
161 | case SH2_STEP_COUNTER:
162 | rc = decodeStepCounter(value, event);
163 | break;
164 | case SH2_SIGNIFICANT_MOTION:
165 | rc = decodeSignificantMotion(value, event);
166 | break;
167 | case SH2_STABILITY_CLASSIFIER:
168 | rc = decodeStabilityClassifier(value, event);
169 | break;
170 | case SH2_SHAKE_DETECTOR:
171 | rc = decodeShakeDetector(value, event);
172 | break;
173 | case SH2_FLIP_DETECTOR:
174 | rc = decodeFlipDetector(value, event);
175 | break;
176 | case SH2_PICKUP_DETECTOR:
177 | rc = decodePickupDetector(value, event);
178 | break;
179 | case SH2_STABILITY_DETECTOR:
180 | rc = decodeStabilityDetector(value, event);
181 | break;
182 | case SH2_PERSONAL_ACTIVITY_CLASSIFIER:
183 | rc = decodePersonalActivityClassifier(value, event);
184 | break;
185 | case SH2_SLEEP_DETECTOR:
186 | rc = decodeSleepDetector(value, event);
187 | break;
188 | case SH2_TILT_DETECTOR:
189 | rc = decodeTiltDetector(value, event);
190 | break;
191 | case SH2_POCKET_DETECTOR:
192 | rc = decodePocketDetector(value, event);
193 | break;
194 | case SH2_CIRCLE_DETECTOR:
195 | rc = decodeCircleDetector(value, event);
196 | break;
197 | case SH2_HEART_RATE_MONITOR:
198 | rc = decodeHeartRateMonitor(value, event);
199 | break;
200 | case SH2_ARVR_STABILIZED_RV:
201 | rc = decodeArvrStabilizedRV(value, event);
202 | break;
203 | case SH2_ARVR_STABILIZED_GRV:
204 | rc = decodeArvrStabilizedGRV(value, event);
205 | break;
206 | case SH2_GYRO_INTEGRATED_RV:
207 | rc = decodeGyroIntegratedRV(value, event);
208 | break;
209 | case SH2_IZRO_MOTION_REQUEST:
210 | rc = decodeIZroRequest(value, event);
211 | break;
212 | default:
213 | // Unknown report id
214 | rc = SH2_ERR;
215 | break;
216 | }
217 |
218 | return rc;
219 | }
220 |
221 | // ------------------------------------------------------------------------
222 | // Private utility functions
223 |
224 | static int decodeRawAccelerometer(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
225 | {
226 | value->un.rawAccelerometer.x = read16(&event->report[4]);
227 | value->un.rawAccelerometer.y = read16(&event->report[6]);
228 | value->un.rawAccelerometer.z = read16(&event->report[8]);
229 | value->un.rawAccelerometer.timestamp = read32(&event->report[12]);
230 |
231 | return SH2_OK;
232 | }
233 |
234 | static int decodeAccelerometer(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
235 | {
236 | value->un.accelerometer.x = read16(&event->report[4]) * SCALE_Q(8);
237 | value->un.accelerometer.y = read16(&event->report[6]) * SCALE_Q(8);
238 | value->un.accelerometer.z = read16(&event->report[8]) * SCALE_Q(8);
239 |
240 | return SH2_OK;
241 | }
242 |
243 | static int decodeLinearAcceleration(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
244 | {
245 | value->un.linearAcceleration.x = read16(&event->report[4]) * SCALE_Q(8);
246 | value->un.linearAcceleration.y = read16(&event->report[6]) * SCALE_Q(8);
247 | value->un.linearAcceleration.z = read16(&event->report[8]) * SCALE_Q(8);
248 |
249 | return SH2_OK;
250 | }
251 |
252 | static int decodeGravity(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
253 | {
254 | value->un.gravity.x = read16(&event->report[4]) * SCALE_Q(8);
255 | value->un.gravity.y = read16(&event->report[6]) * SCALE_Q(8);
256 | value->un.gravity.z = read16(&event->report[8]) * SCALE_Q(8);
257 |
258 | return SH2_OK;
259 | }
260 |
261 | static int decodeRawGyroscope(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
262 | {
263 | value->un.rawGyroscope.x = read16(&event->report[4]);
264 | value->un.rawGyroscope.y = read16(&event->report[6]);
265 | value->un.rawGyroscope.z = read16(&event->report[8]);
266 | value->un.rawGyroscope.temperature = read16(&event->report[10]);
267 | value->un.rawGyroscope.timestamp = read32(&event->report[12]);
268 |
269 | return SH2_OK;
270 | }
271 |
272 | static int decodeGyroscopeCalibrated(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
273 | {
274 | value->un.gyroscope.x = read16(&event->report[4]) * SCALE_Q(9);
275 | value->un.gyroscope.y = read16(&event->report[6]) * SCALE_Q(9);
276 | value->un.gyroscope.z = read16(&event->report[8]) * SCALE_Q(9);
277 |
278 | return SH2_OK;
279 | }
280 |
281 | static int decodeGyroscopeUncal(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
282 | {
283 | value->un.gyroscopeUncal.x = read16(&event->report[4]) * SCALE_Q(9);
284 | value->un.gyroscopeUncal.y = read16(&event->report[6]) * SCALE_Q(9);
285 | value->un.gyroscopeUncal.z = read16(&event->report[8]) * SCALE_Q(9);
286 |
287 | value->un.gyroscopeUncal.biasX = read16(&event->report[10]) * SCALE_Q(9);
288 | value->un.gyroscopeUncal.biasY = read16(&event->report[12]) * SCALE_Q(9);
289 | value->un.gyroscopeUncal.biasZ = read16(&event->report[14]) * SCALE_Q(9);
290 |
291 | return SH2_OK;
292 | }
293 |
294 | static int decodeRawMagnetometer(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
295 | {
296 | value->un.rawMagnetometer.x = read16(&event->report[4]);
297 | value->un.rawMagnetometer.y = read16(&event->report[6]);
298 | value->un.rawMagnetometer.z = read16(&event->report[8]);
299 | value->un.rawMagnetometer.timestamp = read32(&event->report[12]);
300 |
301 | return SH2_OK;
302 | }
303 |
304 | static int decodeMagneticFieldCalibrated(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
305 | {
306 | value->un.magneticField.x = read16(&event->report[4]) * SCALE_Q(4);
307 | value->un.magneticField.y = read16(&event->report[6]) * SCALE_Q(4);
308 | value->un.magneticField.z = read16(&event->report[8]) * SCALE_Q(4);
309 |
310 | return SH2_OK;
311 | }
312 |
313 | static int decodeMagneticFieldUncal(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
314 | {
315 | value->un.magneticFieldUncal.x = read16(&event->report[4]) * SCALE_Q(4);
316 | value->un.magneticFieldUncal.y = read16(&event->report[6]) * SCALE_Q(4);
317 | value->un.magneticFieldUncal.z = read16(&event->report[8]) * SCALE_Q(4);
318 |
319 | value->un.magneticFieldUncal.biasX = read16(&event->report[10]) * SCALE_Q(4);
320 | value->un.magneticFieldUncal.biasY = read16(&event->report[12]) * SCALE_Q(4);
321 | value->un.magneticFieldUncal.biasZ = read16(&event->report[14]) * SCALE_Q(4);
322 |
323 | return SH2_OK;
324 | }
325 |
326 | static int decodeRotationVector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
327 | {
328 | value->un.rotationVector.i = read16(&event->report[4]) * SCALE_Q(14);
329 | value->un.rotationVector.j = read16(&event->report[6]) * SCALE_Q(14);
330 | value->un.rotationVector.k = read16(&event->report[8]) * SCALE_Q(14);
331 | value->un.rotationVector.real = read16(&event->report[10]) * SCALE_Q(14);
332 | value->un.rotationVector.accuracy = read16(&event->report[12]) * SCALE_Q(12);
333 |
334 | return SH2_OK;
335 | }
336 |
337 | static int decodeGameRotationVector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
338 | {
339 | value->un.gameRotationVector.i = read16(&event->report[4]) * SCALE_Q(14);
340 | value->un.gameRotationVector.j = read16(&event->report[6]) * SCALE_Q(14);
341 | value->un.gameRotationVector.k = read16(&event->report[8]) * SCALE_Q(14);
342 | value->un.gameRotationVector.real = read16(&event->report[10]) * SCALE_Q(14);
343 |
344 | return SH2_OK;
345 | }
346 |
347 | static int decodeGeomagneticRotationVector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
348 | {
349 | value->un.geoMagRotationVector.i = read16(&event->report[4]) * SCALE_Q(14);
350 | value->un.geoMagRotationVector.j = read16(&event->report[6]) * SCALE_Q(14);
351 | value->un.geoMagRotationVector.k = read16(&event->report[8]) * SCALE_Q(14);
352 | value->un.geoMagRotationVector.real = read16(&event->report[10]) * SCALE_Q(14);
353 | value->un.geoMagRotationVector.accuracy = read16(&event->report[12]) * SCALE_Q(12);
354 |
355 | return SH2_OK;
356 | }
357 |
358 | static int decodePressure(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
359 | {
360 | value->un.pressure.value = read32(&event->report[4]) * SCALE_Q(20);
361 |
362 | return SH2_OK;
363 | }
364 |
365 | static int decodeAmbientLight(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
366 | {
367 | value->un.ambientLight.value = read32(&event->report[4]) * SCALE_Q(8);
368 |
369 | return SH2_OK;
370 | }
371 |
372 | static int decodeHumidity(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
373 | {
374 | value->un.humidity.value = read16(&event->report[4]) * SCALE_Q(8);
375 |
376 | return SH2_OK;
377 | }
378 |
379 | static int decodeProximity(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
380 | {
381 | value->un.proximity.value = read16(&event->report[4]) * SCALE_Q(4);
382 |
383 | return SH2_OK;
384 | }
385 |
386 | static int decodeTemperature(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
387 | {
388 | value->un.temperature.value = read16(&event->report[4]) * SCALE_Q(7);
389 |
390 | return SH2_OK;
391 | }
392 |
393 | static int decodeReserved(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
394 | {
395 | value->un.reserved.tbd = read16(&event->report[4]) * SCALE_Q(7);
396 |
397 | return SH2_OK;
398 | }
399 |
400 | static int decodeTapDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
401 | {
402 | value->un.tapDetector.flags = event->report[4];
403 |
404 | return SH2_OK;
405 | }
406 |
407 | static int decodeStepDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
408 | {
409 | value->un.stepDetector.latency = readu32(&event->report[4]);
410 |
411 | return SH2_OK;
412 | }
413 |
414 | static int decodeStepCounter(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
415 | {
416 | value->un.stepCounter.latency = readu32(&event->report[4]);
417 | value->un.stepCounter.steps = readu32(&event->report[8]);
418 |
419 | return SH2_OK;
420 | }
421 |
422 | static int decodeSignificantMotion(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
423 | {
424 | value->un.sigMotion.motion = readu16(&event->report[4]);
425 |
426 | return SH2_OK;
427 | }
428 |
429 | static int decodeStabilityClassifier(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
430 | {
431 | value->un.stabilityClassifier.classification = event->report[4];
432 |
433 | return SH2_OK;
434 | }
435 |
436 | static int decodeShakeDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
437 | {
438 | value->un.shakeDetector.shake = readu16(&event->report[4]);
439 |
440 | return SH2_OK;
441 | }
442 |
443 | static int decodeFlipDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
444 | {
445 | value->un.flipDetector.flip = readu16(&event->report[4]);
446 |
447 | return SH2_OK;
448 | }
449 |
450 | static int decodePickupDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
451 | {
452 | value->un.pickupDetector.pickup = readu16(&event->report[4]);
453 |
454 | return SH2_OK;
455 | }
456 |
457 | static int decodeStabilityDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
458 | {
459 | value->un.stabilityDetector.stability = readu16(&event->report[4]);
460 |
461 | return SH2_OK;
462 | }
463 |
464 | static int decodePersonalActivityClassifier(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
465 | {
466 | value->un.personalActivityClassifier.page = event->report[4] & 0x7F;
467 | value->un.personalActivityClassifier.lastPage = ((event->report[4] & 0x80) != 0);
468 | value->un.personalActivityClassifier.mostLikelyState = event->report[5];
469 | for (int n = 0; n < 10; n++) {
470 | value->un.personalActivityClassifier.confidence[n] = event->report[6+n];
471 | }
472 |
473 | return SH2_OK;
474 | }
475 |
476 | static int decodeSleepDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
477 | {
478 | value->un.sleepDetector.sleepState = event->report[4];
479 |
480 | return SH2_OK;
481 | }
482 |
483 | static int decodeTiltDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
484 | {
485 | value->un.tiltDetector.tilt = readu16(&event->report[4]);
486 |
487 | return SH2_OK;
488 | }
489 |
490 | static int decodePocketDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
491 | {
492 | value->un.pocketDetector.pocket = readu16(&event->report[4]);
493 |
494 | return SH2_OK;
495 | }
496 |
497 | static int decodeCircleDetector(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
498 | {
499 | value->un.circleDetector.circle = readu16(&event->report[4]);
500 |
501 | return SH2_OK;
502 | }
503 |
504 | static int decodeHeartRateMonitor(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
505 | {
506 | value->un.heartRateMonitor.heartRate = readu16(&event->report[4]);
507 |
508 | return SH2_OK;
509 | }
510 |
511 | static int decodeArvrStabilizedRV(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
512 | {
513 | value->un.arvrStabilizedRV.i = read16(&event->report[4]) * SCALE_Q(14);
514 | value->un.arvrStabilizedRV.j = read16(&event->report[6]) * SCALE_Q(14);
515 | value->un.arvrStabilizedRV.k = read16(&event->report[8]) * SCALE_Q(14);
516 | value->un.arvrStabilizedRV.real = read16(&event->report[10]) * SCALE_Q(14);
517 | value->un.arvrStabilizedRV.accuracy = read16(&event->report[12]) * SCALE_Q(12);
518 |
519 | return SH2_OK;
520 | }
521 |
522 | static int decodeArvrStabilizedGRV(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
523 | {
524 | value->un.arvrStabilizedGRV.i = read16(&event->report[4]) * SCALE_Q(14);
525 | value->un.arvrStabilizedGRV.j = read16(&event->report[6]) * SCALE_Q(14);
526 | value->un.arvrStabilizedGRV.k = read16(&event->report[8]) * SCALE_Q(14);
527 | value->un.arvrStabilizedGRV.real = read16(&event->report[10]) * SCALE_Q(14);
528 |
529 | return SH2_OK;
530 | }
531 |
532 | static int decodeGyroIntegratedRV(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
533 | {
534 | value->un.gyroIntegratedRV.i = read16(&event->report[0]) * SCALE_Q(14);
535 | value->un.gyroIntegratedRV.j = read16(&event->report[2]) * SCALE_Q(14);
536 | value->un.gyroIntegratedRV.k = read16(&event->report[4]) * SCALE_Q(14);
537 | value->un.gyroIntegratedRV.real = read16(&event->report[6]) * SCALE_Q(14);
538 | value->un.gyroIntegratedRV.angVelX = read16(&event->report[8]) * SCALE_Q(10);
539 | value->un.gyroIntegratedRV.angVelY = read16(&event->report[10]) * SCALE_Q(10);
540 | value->un.gyroIntegratedRV.angVelZ = read16(&event->report[12]) * SCALE_Q(10);
541 |
542 | return SH2_OK;
543 | }
544 |
545 | static int decodeIZroRequest(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event)
546 | {
547 | value->un.izroRequest.intent = (sh2_IZroMotionIntent_t)event->report[4];
548 | value->un.izroRequest.request = (sh2_IZroMotionRequest_t)event->report[5];
549 |
550 | return SH2_OK;
551 | }
552 |
--------------------------------------------------------------------------------
/src/sh2_SensorValue.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-16 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /**
19 | * @file sh2_SensorValue.h
20 | * @author David Wheeler
21 | * @date 10 Nov 2015
22 | * @brief Support for converting sensor events (messages) into natural data structures.
23 | *
24 | */
25 |
26 | #ifndef SH2_SENSORVALUE_H
27 | #define SH2_SENSORVALUE_H
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | #include
34 |
35 | #include "sh2.h"
36 |
37 | /* Note on quaternion naming conventions:
38 | * Quaternions are values with four real components that are usually
39 | * interpreted as coefficients in the complex quantity, Q.
40 | *
41 | * As in, Q = W + Xi + Yj + Zk
42 | *
43 | * Where i, j and k represent the three imaginary dimensions.
44 | *
45 | * So W represents the Real components and X, Y and Z the Imaginary ones.
46 | *
47 | * In the Hillcrest datasheets and in this code, however, the four components
48 | * are named real, i, j and k, to make it explicit which is which. If you
49 | * need to translate these names into the "wxyz" or "xyzw" convention, then, the
50 | * appropriate mapping is this:
51 | * w = real
52 | * x = i
53 | * y = j
54 | * z = k
55 | */
56 |
57 | /**
58 | * @brief Raw Accelerometer
59 | *
60 | * See the SH-2 Reference Manual for more detail.
61 | */
62 | typedef struct sh2_RawAccelerometer {
63 | /* Units are ADC counts */
64 | int16_t x; /**< @brief [ADC counts] */
65 | int16_t y; /**< @brief [ADC counts] */
66 | int16_t z; /**< @brief [ADC counts] */
67 |
68 | /* Microseconds */
69 | uint32_t timestamp; /**< @brief [uS] */
70 | } sh2_RawAccelerometer_t;
71 |
72 | /**
73 | * @brief Accelerometer
74 | *
75 | * See the SH-2 Reference Manual for more detail.
76 | */
77 | typedef struct sh2_Accelerometer {
78 | float x;
79 | float y;
80 | float z;
81 | } sh2_Accelerometer_t;
82 |
83 | /**
84 | * @brief Raw gyroscope
85 | *
86 | * See the SH-2 Reference Manual for more detail.
87 | */
88 | typedef struct sh2_RawGyroscope {
89 | /* Units are ADC counts */
90 | int16_t x; /**< @brief [ADC Counts] */
91 | int16_t y; /**< @brief [ADC Counts] */
92 | int16_t z; /**< @brief [ADC Counts] */
93 | int16_t temperature; /**< @brief [ADC Counts] */
94 |
95 | /* Microseconds */
96 | uint32_t timestamp; /**< @brief [uS] */
97 | } sh2_RawGyroscope_t;
98 |
99 | /**
100 | * @brief Gyroscope
101 | *
102 | * See the SH-2 Reference Manual for more detail.
103 | */
104 | typedef struct sh2_Gyroscope {
105 | /* Units are rad/s */
106 | float x;
107 | float y;
108 | float z;
109 | } sh2_Gyroscope_t;
110 |
111 | /**
112 | * @brief Uncalibrated gyroscope
113 | *
114 | * See the SH-2 Reference Manual for more detail.
115 | */
116 | typedef struct sh2_GyroscopeUncalibrated {
117 | /* Units are rad/s */
118 | float x; /**< @brief [rad/s] */
119 | float y; /**< @brief [rad/s] */
120 | float z; /**< @brief [rad/s] */
121 | float biasX; /**< @brief [rad/s] */
122 | float biasY; /**< @brief [rad/s] */
123 | float biasZ; /**< @brief [rad/s] */
124 | } sh2_GyroscopeUncalibrated_t;
125 |
126 | /**
127 | * @brief Raw Magnetometer
128 | *
129 | * See the SH-2 Reference Manual for more detail.
130 | */
131 | typedef struct sh2_RawMagnetometer {
132 | /* Units are ADC counts */
133 | int16_t x; /**< @brief [ADC Counts] */
134 | int16_t y; /**< @brief [ADC Counts] */
135 | int16_t z; /**< @brief [ADC Counts] */
136 |
137 | /* Microseconds */
138 | uint32_t timestamp; /**< @brief [uS] */
139 | } sh2_RawMagnetometer_t;
140 |
141 | /**
142 | * @brief Magnetic field
143 | *
144 | * See the SH-2 Reference Manual for more detail.
145 | */
146 | typedef struct sh2_MagneticField {
147 | /* Units are uTesla */
148 | float x; /**< @brief [uTesla] */
149 | float y; /**< @brief [uTesla] */
150 | float z; /**< @brief [uTesla] */
151 | } sh2_MagneticField_t;
152 |
153 | /**
154 | * @brief Uncalibrated magnetic field
155 | *
156 | * See the SH-2 Reference Manual for more detail.
157 | */
158 | typedef struct sh2_MagneticFieldUncalibrated {
159 | /* Units are uTesla */
160 | float x; /**< @brief [uTesla] */
161 | float y; /**< @brief [uTesla] */
162 | float z; /**< @brief [uTesla] */
163 | float biasX; /**< @brief [uTesla] */
164 | float biasY; /**< @brief [uTesla] */
165 | float biasZ; /**< @brief [uTesla] */
166 | } sh2_MagneticFieldUncalibrated_t;
167 |
168 | /**
169 | * @brief Rotation Vector with Accuracy
170 | *
171 | * See the SH-2 Reference Manual for more detail.
172 | */
173 | typedef struct sh2_RotationVectorWAcc {
174 | float i; /**< @brief Quaternion component i */
175 | float j; /**< @brief Quaternion component j */
176 | float k; /**< @brief Quaternion component k */
177 | float real; /**< @brief Quaternion component, real */
178 | float accuracy; /**< @brief Accuracy estimate [radians] */
179 | } sh2_RotationVectorWAcc_t;
180 |
181 | /**
182 | * @brief Rotation Vector
183 | *
184 | * See the SH-2 Reference Manual for more detail.
185 | */
186 | typedef struct sh2_RotationVector {
187 | float i; /**< @brief Quaternion component i */
188 | float j; /**< @brief Quaternion component j */
189 | float k; /**< @brief Quaternion component k */
190 | float real; /**< @brief Quaternion component real */
191 | } sh2_RotationVector_t;
192 |
193 | /**
194 | * @brief Atmospheric Pressure
195 | *
196 | * See the SH-2 Reference Manual for more detail.
197 | */
198 | typedef struct sh2_Pressure {
199 | float value; /**< @brief Atmospheric Pressure. [hectopascals] */
200 | } sh2_Pressure_t;
201 |
202 | /**
203 | * @brief Ambient Light
204 | *
205 | * See the SH-2 Reference Manual for more detail.
206 | */
207 | typedef struct sh2_AmbientLight {
208 | float value; /**< @brief Ambient Light. [lux] */
209 | } sh2_AmbientLight_t;
210 |
211 | /**
212 | * @brief Humidity
213 | *
214 | * See the SH-2 Reference Manual for more detail.
215 | */
216 | typedef struct sh2_Humidity {
217 | float value; /**< @brief Relative Humidity. [percent] */
218 | } sh2_Humidity_t;
219 |
220 | /**
221 | * @brief Proximity
222 | *
223 | * See the SH-2 Reference Manual for more detail.
224 | */
225 | typedef struct sh2_Proximity {
226 | float value; /**< @brief Proximity. [cm] */
227 | } sh2_Proximity_t;
228 |
229 | /**
230 | * @brief Temperature
231 | *
232 | * See the SH-2 Reference Manual for more detail.
233 | */
234 | typedef struct sh2_Temperature {
235 | float value; /**< @brief Temperature. [C] */
236 | } sh2_Temperature_t;
237 |
238 | /**
239 | * @brief Reserved
240 | *
241 | * See the SH-2 Reference Manual for more detail.
242 | */
243 | typedef struct sh2_Reserved {
244 | float tbd; /**< @brief Reserved */
245 | } sh2_Reserved_t;
246 |
247 | /**
248 | * @brief TapDetector
249 | *
250 | * See the SH-2 Reference Manual for more detail.
251 | */
252 | #define TAPDET_X (1)
253 | #define TAPDET_X_POS (2)
254 | #define TAPDET_Y (4)
255 | #define TAPDET_Y_POS (8)
256 | #define TAPDET_Z (16)
257 | #define TAPDET_Z_POS (32)
258 | #define TAPDET_DOUBLE (64)
259 | typedef struct sh2_TapDetector {
260 | uint8_t flags; /**< @brief TapDetector. */
261 | } sh2_TapDetector_t;
262 |
263 | /**
264 | * @brief StepDetector
265 | *
266 | * See the SH-2 Reference Manual for more detail.
267 | */
268 | typedef struct sh2_StepDetector {
269 | uint32_t latency; /**< @brief Step detect latency [uS]. */
270 | } sh2_StepDetector_t;
271 |
272 | /**
273 | * @brief StepCounter
274 | *
275 | * See the SH-2 Reference Manual for more detail.
276 | */
277 | typedef struct sh2_StepCounter {
278 | uint32_t latency; /**< @brief Step counter latency [uS]. */
279 | uint16_t steps; /**< @brief Steps counted. */
280 | } sh2_StepCounter_t;
281 |
282 | /**
283 | * @brief SigMotion
284 | *
285 | * See the SH-2 Reference Manual for more detail.
286 | */
287 | typedef struct sh2_SigMotion {
288 | uint16_t motion;
289 | } sh2_SigMotion_t;
290 |
291 | /**
292 | * @brief StabilityClassifier
293 | *
294 | * See the SH-2 Reference Manual for more detail.
295 | */
296 | #define STABILITY_CLASSIFIER_UNKNOWN (0)
297 | #define STABILITY_CLASSIFIER_ON_TABLE (1)
298 | #define STABILITY_CLASSIFIER_STATIONARY (2)
299 | #define STABILITY_CLASSIFIER_STABLE (3)
300 | #define STABILITY_CLASSIFIER_MOTION (4)
301 | #define STABILITY_CLASSIFIER_RESERVED (5)
302 | typedef struct sh2_StabilityClassifier {
303 | uint8_t classification;
304 | } sh2_StabilityClassifier_t;
305 |
306 | /**
307 | * @brief ShakeDetector
308 | *
309 | * See the SH-2 Reference Manual for more detail.
310 | */
311 | #define SHAKE_X (1)
312 | #define SHAKE_Y (2)
313 | #define SHAKE_Z (4)
314 | typedef struct sh2_ShakeDetector {
315 | uint16_t shake;
316 | } sh2_ShakeDetector_t;
317 |
318 | /**
319 | * @brief flipDetector
320 | *
321 | * See the SH-2 Reference Manual for more detail.
322 | */
323 | typedef struct sh2_FlipDetector {
324 | uint16_t flip;
325 | } sh2_FlipDetector_t;
326 |
327 | /**
328 | * @brief pickupDetector
329 | *
330 | * See the SH-2 Reference Manual for more detail.
331 | */
332 | #define PICKUP_LEVEL_TO_NOT_LEVEL (1)
333 | #define PICKUP_STOP_WITHIN_REGION (2)
334 | typedef struct sh2_PickupDetector {
335 | uint16_t pickup; /**< flag field with bits defined above. */
336 | } sh2_PickupDetector_t;
337 |
338 | /**
339 | * @brief stabilityDetector
340 | *
341 | * See the SH-2 Reference Manual for more detail.
342 | */
343 | #define STABILITY_ENTERED (1)
344 | #define STABILITY_EXITED (2)
345 | typedef struct sh2_StabilityDetector {
346 | uint16_t stability; /**< flag field with bits defined above. */
347 | } sh2_StabilityDetector_t;
348 |
349 | /**
350 | * @brief Personal Activity Classifier
351 | *
352 | * See the SH-2 Reference Manual for more detail.
353 | */
354 | #define PAC_UNKNOWN (0)
355 | #define PAC_IN_VEHICLE (1)
356 | #define PAC_ON_BICYCLE (2)
357 | #define PAC_ON_FOOT (3)
358 | #define PAC_STILL (4)
359 | #define PAC_TILTING (5)
360 | #define PAC_WALKING (6)
361 | #define PAC_RUNNING (7)
362 | typedef struct sh2_PersonalActivityClassifier {
363 | uint8_t page;
364 | bool lastPage;
365 | uint8_t mostLikelyState;
366 | uint8_t confidence[10];
367 | } sh2_PersonalActivityClassifier_t;
368 |
369 | /**
370 | * @brief sleepDetector
371 | *
372 | * See the SH-2 Reference Manual for more detail.
373 | */
374 | typedef struct sh2_SleepDetector {
375 | uint8_t sleepState;
376 | } sh2_SleepDetector_t;
377 |
378 | /**
379 | * @brief tiltDetector
380 | *
381 | * See the SH-2 Reference Manual for more detail.
382 | */
383 | typedef struct sh2_TiltDetector {
384 | uint16_t tilt;
385 | } sh2_TiltDetector_t;
386 |
387 | /**
388 | * @brief pocketDetector
389 | *
390 | * See the SH-2 Reference Manual for more detail.
391 | */
392 | typedef struct sh2_PocketDetector {
393 | uint16_t pocket;
394 | } sh2_PocketDetector_t;
395 |
396 | /**
397 | * @brief circleDetector
398 | *
399 | * See the SH-2 Reference Manual for more detail.
400 | */
401 | typedef struct sh2_CircleDetector {
402 | uint16_t circle;
403 | } sh2_CircleDetector_t;
404 |
405 | /**
406 | * @brief heartRateMonitor
407 | *
408 | * See SH-2 Reference Manual for details.
409 | */
410 | typedef struct sh2_HeartRateMonitor {
411 | uint16_t heartRate; /**< heart rate in beats per minute. */
412 | } sh2_HeartRateMonitor_t;
413 |
414 | /**
415 | * @brief Gyro Integrated Rotation Vector
416 | *
417 | * See SH-2 Reference Manual for details.
418 | */
419 | typedef struct sh2_GyroIntegratedRV {
420 | float i; /**< @brief Quaternion component i */
421 | float j; /**< @brief Quaternion component j */
422 | float k; /**< @brief Quaternion component k */
423 | float real; /**< @brief Quaternion component real */
424 | float angVelX; /**< @brief Angular velocity about x [rad/s] */
425 | float angVelY; /**< @brief Angular velocity about y [rad/s] */
426 | float angVelZ; /**< @brief Angular velocity about z [rad/s] */
427 | } sh2_GyroIntegratedRV_t;
428 |
429 | typedef struct sh2_IZroRequest {
430 | sh2_IZroMotionIntent_t intent;
431 | sh2_IZroMotionRequest_t request;
432 | } sh2_IZroRequest_t;
433 |
434 | typedef struct sh2_SensorValue {
435 |
436 | /** Which sensor produced this event. */
437 | uint8_t sensorId;
438 |
439 | /** @brief 8-bit unsigned integer used to track reports.
440 | *
441 | * The sequence number increments once for each report sent. Gaps
442 | * in the sequence numbers indicate missing or dropped reports.
443 | */
444 | uint8_t sequence;
445 |
446 | /* Status of a sensor
447 | * 0 - Unreliable
448 | * 1 - Accuracy low
449 | * 2 - Accuracy medium
450 | * 3 - Accuracy high
451 | */
452 | uint8_t status; /**< @brief bits 7-5: reserved, 4-2: exponent delay, 1-0: Accuracy */
453 |
454 | uint64_t timestamp; /**< [uS] */
455 |
456 | uint32_t delay; /**< @brief [uS] value is delay * 2^exponent (see status) */
457 |
458 | /** @brief Sensor Data
459 | *
460 | * Use the structure based on the value of the sensor
461 | * field.
462 | */
463 | union {
464 | sh2_RawAccelerometer_t rawAccelerometer;
465 | sh2_Accelerometer_t accelerometer;
466 | sh2_Accelerometer_t linearAcceleration;
467 | sh2_Accelerometer_t gravity;
468 | sh2_RawGyroscope_t rawGyroscope;
469 | sh2_Gyroscope_t gyroscope;
470 | sh2_GyroscopeUncalibrated_t gyroscopeUncal;
471 | sh2_RawMagnetometer_t rawMagnetometer;
472 | sh2_MagneticField_t magneticField;
473 | sh2_MagneticFieldUncalibrated_t magneticFieldUncal;
474 | sh2_RotationVectorWAcc_t rotationVector;
475 | sh2_RotationVector_t gameRotationVector;
476 | sh2_RotationVectorWAcc_t geoMagRotationVector;
477 | sh2_Pressure_t pressure;
478 | sh2_AmbientLight_t ambientLight;
479 | sh2_Humidity_t humidity;
480 | sh2_Proximity_t proximity;
481 | sh2_Temperature_t temperature;
482 | sh2_Reserved_t reserved;
483 | sh2_TapDetector_t tapDetector;
484 | sh2_StepDetector_t stepDetector;
485 | sh2_StepCounter_t stepCounter;
486 | sh2_SigMotion_t sigMotion;
487 | sh2_StabilityClassifier_t stabilityClassifier;
488 | sh2_ShakeDetector_t shakeDetector;
489 | sh2_FlipDetector_t flipDetector;
490 | sh2_PickupDetector_t pickupDetector;
491 | sh2_StabilityDetector_t stabilityDetector;
492 | sh2_PersonalActivityClassifier_t personalActivityClassifier;
493 | sh2_SleepDetector_t sleepDetector;
494 | sh2_TiltDetector_t tiltDetector;
495 | sh2_PocketDetector_t pocketDetector;
496 | sh2_CircleDetector_t circleDetector;
497 | sh2_HeartRateMonitor_t heartRateMonitor;
498 | sh2_RotationVectorWAcc_t arvrStabilizedRV;
499 | sh2_RotationVector_t arvrStabilizedGRV;
500 | sh2_GyroIntegratedRV_t gyroIntegratedRV;
501 | sh2_IZroRequest_t izroRequest;
502 | } un;
503 | } sh2_SensorValue_t;
504 |
505 | int sh2_decodeSensorEvent(sh2_SensorValue_t *value, const sh2_SensorEvent_t *event);
506 |
507 |
508 | #ifdef __cplusplus
509 | } // extern "C"
510 | #endif
511 |
512 | #endif
513 |
--------------------------------------------------------------------------------
/src/sh2_err.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-16 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /**
19 | * @file sh2_err.h
20 | * @author David Wheeler
21 | * @date 22 May 2015
22 | * @brief Type definitions for Hillcrest SH-2 API.
23 | *
24 | * Struct and type definitions supporting the Hillcrest SH-2 SensorHub API.
25 | *
26 | */
27 |
28 |
29 | #ifndef SH2_ERR_H
30 | #define SH2_ERR_H
31 |
32 |
33 | #define SH2_OK (0) /**< Success */
34 | #define SH2_ERR (-1) /**< General Error */
35 | #define SH2_ERR_BAD_PARAM (-2) /**< Bad parameter to an API call */
36 | #define SH2_ERR_OP_IN_PROGRESS (-3) /**< Operation in progress */
37 | #define SH2_ERR_IO (-4) /**< Error communicating with hub */
38 | #define SH2_ERR_HUB (-5) /**< Error reported by hub */
39 | #define SH2_ERR_TIMEOUT (-6) /**< Operation timed out */
40 |
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/src/sh2_hal.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /*
19 | * SH2 HAL Interface for Non-RTOS Applications.
20 | */
21 |
22 | // Include guard
23 | #ifndef SH2_HAL_H
24 | #define SH2_HAL_H
25 |
26 | #include
27 |
28 | // SH2 Implementations generally have a max out transfer len of 256
29 | #define SH2_HAL_MAX_TRANSFER_OUT (256)
30 | #define SH2_HAL_MAX_PAYLOAD_OUT (256)
31 |
32 | // Although some implementations adversize a max in transfer of 32K,
33 | // in practice, the largest transfer performed is the advertisements
34 | // which is 272 bytes at time of writing.
35 | #define SH2_HAL_MAX_TRANSFER_IN (384)
36 | #define SH2_HAL_MAX_PAYLOAD_IN (384)
37 |
38 | // This needs to be a power of 2, greater than max of the above.
39 | #define SH2_HAL_DMA_SIZE (512)
40 |
41 | typedef struct sh2_Hal_s sh2_Hal_t;
42 |
43 | // The SH2 interface uses these functions to access the underlying
44 | // communications device, so the system integrator will need to
45 | // implement these. At system intialization time, an sh2_Hal_t
46 | // structure should be initialized with pointers to all the hardware
47 | // access layer functions. A pointer to this structure must then be
48 | // passed to sh2_open() to initialize the SH2 interface.
49 | //
50 | // If the DFU (download firmware update) capability is needed, the
51 | // example DFU code also uses this interface but each function has
52 | // somewhat different requirements. So a separate instance of an
53 | // sh2_Hal_t structure, pointing to different functions, is
54 | // recommended for supporting DFU.
55 |
56 | struct sh2_Hal_s {
57 | // This function initializes communications with the device. It
58 | // can initialize any GPIO pins and peripheral devices used to
59 | // interface with the sensor hub.
60 | // It should also perform a reset cycle on the sensor hub to
61 | // ensure communications start from a known state.
62 | int (*open)(sh2_Hal_t *self);
63 |
64 | // This function completes communications with the sensor hub.
65 | // It should put the device in reset then de-initialize any
66 | // peripherals or hardware resources that were used.
67 | void (*close)(sh2_Hal_t *self);
68 |
69 | // This function supports reading data from the sensor hub.
70 | // It will be called frequently to sevice the device.
71 | //
72 | // If the HAL has received a full SHTP transfer, this function
73 | // should load the data into pBuffer, set the timestamp to the
74 | // time the interrupt was detected and return the non-zero length
75 | // of data in this transfer.
76 | //
77 | // If the HAL has not recevied a full SHTP transfer, this function
78 | // should return 0.
79 | //
80 | // Because this function is called regularly, it can be used to
81 | // perform other housekeeping operations. (In the case of UART
82 | // interfacing, bytes transmitted are staggered in time and this
83 | // function can be used to keep the transmission flowing.)
84 | int (*read)(sh2_Hal_t *self, uint8_t *pBuffer, unsigned len, uint32_t *t_us);
85 |
86 | // This function supports writing data to the sensor hub.
87 | // It is called each time the application has a block of data to
88 | // transfer to the device.
89 | //
90 | // If the device isn't ready to receive data this function can
91 | // return 0 without performing the transmit function.
92 | //
93 | // If the transmission can be started, this function needs to
94 | // copy the data from pBuffer and return the number of bytes
95 | // accepted. It need not block. The actual transmission of
96 | // the data can continue after this function returns.
97 | int (*write)(sh2_Hal_t *self, uint8_t *pBuffer, unsigned len);
98 |
99 | // This function should return a 32-bit value representing a
100 | // microsecond counter. The count may roll over after 2^32
101 | // microseconds.
102 | uint32_t (*getTimeUs)(sh2_Hal_t *self);
103 | };
104 |
105 | // End of include guard
106 | #endif
107 |
--------------------------------------------------------------------------------
/src/sh2_util.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-16 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /*
19 | * Simple Utility functions common to several SH2 files.
20 | */
21 |
22 | #include "sh2_util.h"
23 |
24 | uint8_t readu8(const uint8_t *p)
25 | {
26 | uint8_t retval = p[0];
27 | return retval;
28 | }
29 |
30 | void writeu8(uint8_t * p, uint8_t value)
31 | {
32 | *p = (uint8_t)(value & 0xFF);
33 | }
34 |
35 | uint16_t readu16(const uint8_t *p)
36 | {
37 | uint16_t retval = p[0] | (p[1] << 8);
38 | return retval;
39 | }
40 |
41 | void writeu16(uint8_t * p, uint16_t value)
42 | {
43 | *p++ = (uint8_t)(value & 0xFF);
44 | value >>= 8;
45 | *p = (uint8_t)(value & 0xFF);
46 | }
47 |
48 | uint32_t readu32(const uint8_t *p)
49 | {
50 | uint32_t retval = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
51 | return retval;
52 | }
53 |
54 | void writeu32(uint8_t * p, uint32_t value)
55 | {
56 | *p++ = (uint8_t)(value & 0xFF);
57 | value >>= 8;
58 | *p++ = (uint8_t)(value & 0xFF);
59 | value >>= 8;
60 | *p++ = (uint8_t)(value & 0xFF);
61 | value >>= 8;
62 | *p = (uint8_t)(value & 0xFF);
63 | }
64 |
65 | int8_t read8(const uint8_t *p)
66 | {
67 | int8_t retval = p[0];
68 | return retval;
69 | }
70 |
71 | void write8(uint8_t * p, int8_t value)
72 | {
73 | *p = (uint8_t)(value & 0xFF);
74 | }
75 |
76 | int16_t read16(const uint8_t *p)
77 | {
78 | int16_t retval = p[0] | (p[1] << 8);
79 | return retval;
80 | }
81 |
82 | void write16(uint8_t * p, int16_t value)
83 | {
84 | *p++ = (uint8_t)(value & 0xFF);
85 | value >>= 8;
86 | *p = (uint8_t)(value & 0xFF);
87 | }
88 |
89 | int32_t read32(const uint8_t *p)
90 | {
91 | int32_t retval = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
92 | return retval;
93 | }
94 |
95 | void write32(uint8_t * p, int32_t value)
96 | {
97 | *p++ = (uint8_t)(value & 0xFF);
98 | value >>= 8;
99 | *p++ = (uint8_t)(value & 0xFF);
100 | value >>= 8;
101 | *p++ = (uint8_t)(value & 0xFF);
102 | value >>= 8;
103 | *p = (uint8_t)(value & 0xFF);
104 | }
105 |
--------------------------------------------------------------------------------
/src/sh2_util.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-16 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /*
19 | * Simple Utility functions common to several SH2 files.
20 | */
21 |
22 | #ifndef SH2_UTIL_H
23 | #define SH2_UTIL_H
24 |
25 | #include
26 |
27 | #ifndef ARRAY_LEN
28 | #define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
29 | #endif
30 |
31 | uint8_t readu8(const uint8_t * buffer);
32 | void writeu8(uint8_t * buffer, uint8_t value);
33 | uint16_t readu16(const uint8_t * buffer);
34 | void writeu16(uint8_t * buffer, uint16_t value);
35 | uint32_t readu32(const uint8_t * buffer);
36 | void writeu32(uint8_t * buffer, uint32_t value);
37 |
38 | int8_t read8(const uint8_t * buffer);
39 | void write8(uint8_t * buffer, int8_t value);
40 | int16_t read16(const uint8_t * buffer);
41 | void write16(uint8_t * buffer, int16_t value);
42 | int32_t read32(const uint8_t * buffer);
43 | void write32(uint8_t * buffer, int32_t value);
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/src/shtp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-18 Hillcrest Laboratories, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License and
6 | * any applicable agreements you may have with Hillcrest Laboratories, Inc.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /*
19 | * Hillcrest Sensor Hub Transport Protocol (SHTP) API
20 | */
21 |
22 | #ifndef SHTP_H
23 | #define SHTP_H
24 |
25 | #include
26 | #include
27 |
28 | #include "sh2_hal.h"
29 |
30 | // Advertisement TLV tags
31 | #define TAG_NULL 0
32 | #define TAG_GUID 1
33 | #define TAG_MAX_CARGO_PLUS_HEADER_WRITE 2
34 | #define TAG_MAX_CARGO_PLUS_HEADER_READ 3
35 | #define TAG_MAX_TRANSFER_WRITE 4
36 | #define TAG_MAX_TRANSFER_READ 5
37 | #define TAG_NORMAL_CHANNEL 6
38 | #define TAG_WAKE_CHANNEL 7
39 | #define TAG_APP_NAME 8
40 | #define TAG_CHANNEL_NAME 9
41 | #define TAG_ADV_COUNT 10
42 | #define TAG_APP_SPECIFIC 0x80
43 |
44 | typedef enum shtp_Event_e {
45 | SHTP_TX_DISCARD = 0,
46 | SHTP_SHORT_FRAGMENT = 1,
47 | SHTP_TOO_LARGE_PAYLOADS = 2,
48 | SHTP_BAD_RX_CHAN = 3,
49 | SHTP_BAD_TX_CHAN = 4,
50 | } shtp_Event_t;
51 |
52 | typedef void shtp_Callback_t(void * cookie, uint8_t *payload, uint16_t len, uint32_t timestamp);
53 | typedef void shtp_AdvertCallback_t(void * cookie, uint8_t tag, uint8_t len, uint8_t *value);
54 | typedef void shtp_SendCallback_t(void *cookie);
55 | typedef void shtp_EventCallback_t(void *cookie, shtp_Event_t shtpEvent);
56 |
57 | // Takes HAL pointer, returns shtp ID for use in future calls.
58 | // HAL will be opened by this call.
59 | void * shtp_open(sh2_Hal_t *pHal);
60 |
61 | // Releases resources associated with this SHTP instance.
62 | // HAL will not be closed.
63 | void shtp_close(void *pShtp);
64 |
65 | // Provide the point of the callback function for reporting SHTP asynchronous events
66 | void shtp_setEventCallback(void *pInstance,
67 | shtp_EventCallback_t * eventCallback,
68 | void *eventCookie);
69 |
70 | // Register a listener for an SHTP channel
71 | int shtp_listenChan(void *pShtp,
72 | uint16_t guid, const char * chan,
73 | shtp_Callback_t *callback, void * cookie);
74 |
75 | // Register a listener for SHTP advertisements
76 | int shtp_listenAdvert(void *pShtp,
77 | uint16_t guid,
78 | shtp_AdvertCallback_t *advertCallback, void * cookie);
79 |
80 | // Look up the channel number for a particular app, channel.
81 | uint8_t shtp_chanNo(void *pShtp,
82 | const char * appName, const char * chanName);
83 |
84 | // Send an SHTP payload on a particular channel
85 | int shtp_send(void *pShtp,
86 | uint8_t channel, const uint8_t *payload, uint16_t len);
87 |
88 | // Check for received data and process it.
89 | void shtp_service(void *pShtp);
90 |
91 | // #ifdef SHTP_H
92 | #endif
93 |
--------------------------------------------------------------------------------