SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
bhi360_aux_bmm350_quaternion.ino
Go to the documentation of this file.
1
30#include <Wire.h>
31#include <SPI.h>
32#include <Arduino.h>
33#include <ImuDrv.hpp>
34
35
36// #define USE_I2C_INTERFACE true
37// #define USE_SPI_INTERFACE true
38
39#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
40#define USE_I2C_INTERFACE
41#warning "No interface type is selected, use I2C interface"
42#endif
43
44#if defined(USE_SPI_INTERFACE)
45#ifndef SPI_MOSI
46#define SPI_MOSI 33
47#endif
48
49#ifndef SPI_MISO
50#define SPI_MISO 34
51#endif
52
53#ifndef SPI_SCK
54#define SPI_SCK 35
55#endif
56
57// If BHI360_IRQ is set to -1, sensor interrupts are not used and the sensor polling method is used instead.
58#ifndef BHI360_IRQ
59#define BHI360_IRQ 37
60#endif
61
62#ifndef BHI360_CS
63#define BHI360_CS 36
64#endif
65
66#else //* I2C */
67
68#ifndef BHI360_SDA
69#define BHI360_SDA 2
70#endif
71
72#ifndef BHI360_SCL
73#define BHI360_SCL 3
74#endif
75
76// If BHI360_IRQ is set to -1, sensor interrupts are not used and the sensor polling method is used instead.
77#ifndef BHI360_IRQ
78#define BHI360_IRQ 8
79#endif
80#endif /*USE_SPI_INTERFACE*/
81
82#ifndef BHI360_RST
83#define BHI360_RST -1
84#endif
85
87
88/*
89* Define the USING_DATA_HELPER use of data assistants.
90* No callback function will be used. Data can be obtained directly through
91* the data assistant. Note that this method is not a thread-safe function.
92* Please pay attention to protecting data access security.
93* */
94// #define USING_DATA_HELPER
95
96#ifdef USING_DATA_HELPER
97SensorQuaternion quaternion(bhy);
98#endif
99
100// #define BOSCH_DATA_INJECT_BHI360
101// #define BOSCH_DATA_INJECT_BHI360_BMM150
102// #define BOSCH_DATA_INJECT_BHI360_BMM150_HEAD_ORIENTATION
103// #define BOSCH_DATA_INJECT_BHI360_BMM350
104// #define BOSCH_DATA_INJECT_BHI360_BMM350_HEAD_ORIENTATION
105// #define BOSCH_DATA_INJECT_BHI360_ENV
106// #define BOSCH_DATA_INJECT_BHI360_HEAD_ORIENTATION
107// #define BOSCH_DATA_INJECT_BHI360_MOTION_AI
108// #define BOSCH_SHUTTLE3_BHI360
109// #define BOSCH_SHUTTLE3_BHI360_AUX_BMM150
110// #define BOSCH_SHUTTLE3_BHI360_BMM150
111// #define BOSCH_SHUTTLE3_BHI360_BMM150_BMP580_BME688
112// #define BOSCH_SHUTTLE3_BHI360_BMM150_HEAD_ORIENTATION
113#define BOSCH_SHUTTLE3_BHI360_BMM350C
114// #define BOSCH_SHUTTLE3_BHI360_BMM350C_BME688_IAQ
115// #define BOSCH_SHUTTLE3_BHI360_BMM350C_BMP580
116// #define BOSCH_SHUTTLE3_BHI360_BMM350C_BMP580_BME688
117// #define BOSCH_SHUTTLE3_BHI360_BMM350C_HEAD_ORIENTATION
118// #define BOSCH_SHUTTLE3_BHI360_BMM350C_POLL
119// #define BOSCH_SHUTTLE3_BHI360_BMM350C_TURBO
120// #define BOSCH_SHUTTLE3_BHI360_BMP580_TEST_EXAMPLE
121// #define BOSCH_SHUTTLE3_BHI360_HW_ACTIVITY
122// #define BOSCH_SHUTTLE3_BHI360_HW_ACTIVITY_TURBO
123// #define BOSCH_SHUTTLE3_BHI360_IMU_HEAD_ORIENTATION
124// #define BOSCH_SHUTTLE3_BHI360_POLLING_STEP_COUNTER
125// #define BOSCH_SHUTTLE3_BHI360_TEMP
126// #define BOSCH_SHUTTLE3_BHI360_TEST_DATA_SOURCE
127// #define BOSCH_SHUTTLE3_BHI360_TURBO
128
129#include <BoschFirmware.h>
130
131// Force update of current firmware, whether it exists or not.
132// Only works when external SPI Flash is connected to BHI360.
133// After uploading firmware once, you can change this to false to speed up boot time.
135
136#if BHI360_IRQ > 0
137#define USING_SENSOR_IRQ_METHOD
138#endif
139
140#ifdef USING_SENSOR_IRQ_METHOD
141volatile bool isInterruptTriggered = false;
142
144{
146}
147#endif /*USING_SENSOR_IRQ_METHOD*/
148
149#ifndef USING_DATA_HELPER
150void parse_quaternion(uint8_t sensor_id, const uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
151{
152 struct bhy2_data_quaternion data;
153 uint32_t s, ns;
154 uint64_t tns;
155 // Function to parse FIFO frame data into orientation
156 bhy2_parse_quaternion(data_ptr, &data);
157 uint64_t _timestamp = *timestamp;
158 BoschSensorUtils::time_to_s_ns(_timestamp, &s, &ns, &tns);
159 Serial.print("SID:"); Serial.print(sensor_id);
160 Serial.print(" T:"); Serial.print(s);
161 Serial.print("."); Serial.print(ns);
162 Serial.print(" x:"); Serial.print(data.x / 16384.0f);
163 Serial.print(" y:"); Serial.print(data.y / 16384.0f);
164 Serial.print(" x:"); Serial.print(data.z / 16384.0f);
165 Serial.print(" w:"); Serial.print(data.w / 16384.0f);
166 Serial.print(" acc:"); Serial.println(((data.accuracy * 180.0f) / 16384.0f) / 3.141592653589793f);
167}
168#endif
169
170// Firmware update progress callback
171void progress_callback(uint32_t total, uint32_t transferred, void *user_data)
172{
173 float progress = (float)transferred / total * 100;
174 Serial.print("Upload progress: ");
175 Serial.print(progress);
176 Serial.println("%");
177}
178
179void setup()
180{
181 Serial.begin(115200);
182 while (!Serial);
183
184 // Set the reset pin
185 bhy.setPins(BHI360_RST);
186
187 Serial.println("Initializing Sensors...");
188
189 // Set the firmware array address and firmware size
190 bhy.setFirmware(bosch_firmware_image, bosch_firmware_size);
191
192 // Set the firmware update processing progress callback function
193 // bhy.setUpdateProcessCallback(progress_callback, NULL);
194
195 // Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
196 // bhy.setMaxiTransferSize(256);
197
198 // Set the processing fifo data buffer size,The default size is 512 bytes.
199 // bhy.setProcessBufferSize(1024);
200
201 Serial.println("Initializing Sensors...");
202
203#ifdef USE_I2C_INTERFACE
204 // Using I2C interface
205 // BHI360_SLAVE_ADDRESS_L = 0x28
206 // BHI360_SLAVE_ADDRESS_H = 0x29
207 if (!bhy.begin(Wire, BHI360_SLAVE_ADDRESS_L, BHI360_SDA, BHI360_SCL)) {
208 Serial.print("Failed to initialize sensor - error code:");
209 Serial.println(bhy.getError());
210 while (1) {
211 delay(1000);
212 }
213 }
214#endif
215
216#ifdef USE_SPI_INTERFACE
217 // Using SPI interface
218 if (!bhy.begin(SPI, BHI360_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
219 Serial.print("Failed to initialize sensor - error code:");
220 Serial.println(bhy.getError());
221 while (1) {
222 delay(1000);
223 }
224 }
225#endif
226
227 Serial.println("Initializing the sensor successfully!");
228
229 // Output all sensors info to Serial
230 BoschSensorInfo info = bhy.getSensorInfo();
231
232#ifdef ARDUINO
233 ArduinoStreamPrinter printer(Serial);
234 info.printInfo(printer);
235#else
236 info.printInfo([](const char *format, ...) -> int {
237 va_list args;
238 va_start(args, format);
239 int result = vprintf(format, args);
240 va_end(args);
241 return result;
242 });
243#endif
244
245 // The stepcount sensor will only report when it changes, so the value is 0 ~ 1
246 float sample_rate = 100.0;
247 uint32_t report_latency_ms = 0; /* Report immediately */
248
249#ifdef USING_DATA_HELPER
250 stepDetector.enable(sample_rate, report_latency_ms);
251 stepCounter.enable(sample_rate, report_latency_ms);
252#else
253 // Enable Step detector
254 bhy.configure(BoschSensorID::ROTATION_VECTOR, sample_rate, report_latency_ms);
255 bhy.onResultEvent(BoschSensorID::ROTATION_VECTOR, parse_quaternion);
256#endif
257
258#ifdef USING_SENSOR_IRQ_METHOD
259 // Set the specified pin (BHI360_IRQ) ​​to an input pin.
260 // This makes the pin ready to receive external signals.
261 // If the interrupt is already connected, if BHI360_IRQ is equal to -1 then the polling method will be used
262 pinMode(BHI360_IRQ, INPUT);
263
264 // Attach an interrupt service routine (ISR) to the specified pin (BHI360_IRQ).
265 // The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
266 attachInterrupt(BHI360_IRQ, dataReadyISR, RISING);
267#endif
268}
269
270
271void loop()
272{
273 uint32_t s;
274 uint32_t ns;
275
276#ifdef USING_SENSOR_IRQ_METHOD
278 isInterruptTriggered = false;
279#endif /*USING_SENSOR_IRQ_METHOD*/
280
281 /* If the interrupt is connected to the sensor and BHI360_IRQ is not equal to -1,
282 * the interrupt function will be enabled, otherwise the method of polling the sensor is used
283 */
284 bhy.update();
285
286#ifdef USING_SENSOR_IRQ_METHOD
287 }
288#endif /*USING_SENSOR_IRQ_METHOD*/
289
290#ifdef USING_DATA_HELPER
291 if (quaternion.hasUpdated()) {
292 uint32_t s;
293 uint32_t ns;
294 quaternion.getLastTime(s, ns);
295#ifdef PLATFORM_HAS_PRINTF
296 Serial.printf("[T: %" PRIu32 ".%09" PRIu32 "] QX:%+7.2f QY:%+7.2f QZ:%+7.2f QW:%+7.2f\n",
297 s, ns, quaternion.getX(), quaternion.getY(), quaternion.getZ(), quaternion.getW());
298#else
299 Serial.print("[T: ");
300 Serial.print(s);
301 Serial.print(".");
302 Serial.print(ns);
303 Serial.print("] ");
304 Serial.print("QX:");
305 Serial.print(quaternion.getX(), 2);
306 Serial.print(" QY:");
307 Serial.print(quaternion.getY(), 2);
308 Serial.print(" QZ:");
309 Serial.print(quaternion.getZ(), 2);
310 Serial.print(" QW:");
311 Serial.print(quaternion.getW(), 2);
312 Serial.println();
313#endif
314 }
315#endif
316 delay(50);
317}
318
319
@license MIT License
@license MIT License
SensorQuaternion quaternion(bhy)
SensorStepDetector stepDetector(bhy)
SensorStepCounter stepCounter(bhy)
SensorBHI360 bhy
volatile bool isInterruptTriggered
void parse_quaternion(uint8_t sensor_id, const uint8_t *data_ptr, uint32_t len, uint64_t *timestamp, void *user_data)
void progress_callback(uint32_t total, uint32_t transferred, void *user_data)
bool force_update_flash_firmware