SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
bhi260ap_klio_recognize_multiple.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 BHI260_IRQ is set to -1, sensor interrupts are not used and the sensor polling method is used instead.
58#ifndef BHI260_IRQ
59#define BHI260_IRQ 37
60#endif
61
62#ifndef BHI260_CS
63#define BHI260_CS 36
64#endif
65
66#else //* I2C */
67
68#ifndef BHI260_SDA
69#define BHI260_SDA 2
70#endif
71
72#ifndef BHI260_SCL
73#define BHI260_SCL 3
74#endif
75
76// If BHI260_IRQ is set to -1, sensor interrupts are not used and the sensor polling method is used instead.
77#ifndef BHI260_IRQ
78#define BHI260_IRQ 8
79#endif
80#endif /*USE_SPI_INTERFACE*/
81
82#ifndef BHI260_RST
83#define BHI260_RST -1
84#endif
85
88
89// The firmware runs in RAM and will be lost if the power is off. The firmware will be loaded from RAM each time it is run.
90#define BOSCH_BHI260_KLIO
91
92// Firmware is stored in flash and booted from flash,Depends on BHI260 hardware connected to SPI Flash
93// #define BOSCH_BHI260_KLIO_FLASH
94// #define BOSCH_BHI260_KLIO_TURBO_FLASH
95
96#include <BoschFirmware.h>
97
98// Force update of current firmware, whether it exists or not.
99// Only works when external SPI Flash is connected to BHI260.
100// After uploading firmware once, you can change this to false to speed up boot time.
102
103/* Action 1 mode, BHI260 should point upwards, for action instructions,
104see action1.gif in the example directory */
106uint8_t action1_pattern[] = {
107 0x52, 0x42, 0x31, 0x06, 0x03, 0xfd, 0xad, 0x80,
108 0x40, 0x0a, 0xd7, 0x23, 0x3c, 0x78, 0xe2, 0x44,
109 0xbf, 0x63, 0xe1, 0x0d, 0xc0, 0x19, 0x39, 0x97,
110 0xbf, 0xdb, 0x93, 0x04, 0x3f, 0xce, 0x07, 0xb7,
111 0x3e, 0x5e, 0xda, 0xf0, 0x3d, 0xe3, 0x6f, 0x8f,
112 0x3e, 0x65, 0x7c, 0x4f, 0x40, 0x46, 0x3f, 0xb4,
113 0x3f, 0xdf, 0xd1, 0x3d, 0xbf, 0xfa, 0x5a, 0x82,
114 0xbf, 0x35, 0xf6, 0x16, 0x3e, 0xbe, 0x70, 0x82,
115 0x40, 0xaa, 0x21, 0x70, 0x41, 0xcb, 0x27, 0xf0,
116 0x40, 0x19, 0x06, 0xd9, 0xbf, 0x3a, 0x10, 0xa7,
117 0xbf, 0x27, 0x07, 0x31, 0x3f, 0x27, 0x23, 0xc9,
118 0xbd, 0x44, 0x29, 0x2f, 0x40, 0xa6, 0x61, 0x97,
119 0xc0, 0x29, 0x5d, 0x21, 0xbe, 0x82, 0xd4, 0x0d,
120 0x3e, 0xc0, 0xf0, 0x15, 0x3d, 0x00, 0xbc, 0xda,
121 0x3d, 0x14, 0x0c, 0xc5, 0xbd, 0x46, 0xa0, 0x03,
122 0x3e, 0xca, 0x5c, 0x95, 0x3d, 0x24, 0xe5, 0x13,
123 0x3c, 0x70, 0x0a, 0x81, 0x3c, 0x69, 0x22, 0xd6,
124 0x3c, 0x51, 0xa4, 0xdf, 0x3e, 0x4c, 0xa8, 0x55,
125 0xbf, 0xe1, 0xe8, 0xc7, 0xbd, 0xe8, 0x7c, 0xbe,
126 0x3d, 0xf7, 0x5b, 0x21, 0x3c
127};
128
129/* Action 2 mode, BHI260 should point to the right,
130for action instructions, see action2.gif in the example directory*/
132const uint8_t action2_pattern[] = {
133 0x52, 0x42, 0x31, 0x06, 0x03, 0xfd, 0xad, 0x80,
134 0x40, 0x0a, 0xd7, 0x23, 0x3c, 0x38, 0xf3, 0x08,
135 0x40, 0x1a, 0x9e, 0x06, 0xbf, 0xde, 0xcd, 0xca,
136 0x3d, 0x88, 0xb3, 0x9b, 0x3e, 0x01, 0x26, 0xb9,
137 0x3d, 0x8f, 0xe9, 0x88, 0x3d, 0x6e, 0xc3, 0x13,
138 0xc1, 0x4f, 0x1e, 0x09, 0x40, 0x75, 0x7a, 0x2d,
139 0xc0, 0x80, 0x31, 0xdb, 0xbd, 0x2f, 0x1e, 0x83,
140 0x3f, 0xc0, 0x6f, 0x10, 0x3d, 0xf7, 0xc1, 0x26,
141 0xbf, 0x5a, 0x36, 0x00, 0x3f, 0x8b, 0x31, 0x77,
142 0xbe, 0x51, 0x09, 0x3b, 0xbf, 0x16, 0xa9, 0xa0,
143 0xbf, 0x6d, 0x90, 0x89, 0x3d, 0x39, 0x79, 0xb3,
144 0x3d, 0x39, 0x0e, 0x9f, 0xbd, 0xfc, 0x77, 0x55,
145 0xbd, 0x69, 0x44, 0x13, 0xbf, 0x02, 0x31, 0x14,
146 0x3e, 0x60, 0xe6, 0x75, 0x3b, 0xd2, 0x69, 0x19,
147 0xbc, 0xa8, 0x41, 0x46, 0x3d, 0x87, 0x45, 0x88,
148 0x3e, 0x70, 0xf7, 0x87, 0x3d, 0x81, 0x8a, 0xe2,
149 0x3d, 0xea, 0x15, 0x8d, 0x3b, 0xf5, 0x2e, 0xc1,
150 0x3c, 0x1e, 0xcc, 0x05, 0x3e, 0x00, 0x70, 0x16,
151 0x3c, 0x41, 0x8b, 0x07, 0xbe, 0x4e, 0xd8, 0xb0,
152 0x3d, 0x94, 0xd9, 0x40, 0x3b
153};
154
155#if BHI260_IRQ > 0
156#define USING_SENSOR_IRQ_METHOD
157#endif
158
159#ifdef USING_SENSOR_IRQ_METHOD
160volatile bool isInterruptTriggered = false;
161
163{
165}
166#endif /*USING_SENSOR_IRQ_METHOD*/
167
168// Firmware update progress callback
169void progress_callback(uint32_t total, uint32_t transferred, void *user_data)
170{
171 float progress = (float)transferred / total * 100;
172 Serial.print("Upload progress: ");
173 Serial.print(progress);
174 Serial.println("%");
175}
176
194void recognition_event_callback(uint8_t pattern_id, float count, void *user_data)
195{
196 Serial.print("<-Recognition[Id:");
197 Serial.print(pattern_id);
198 Serial.print(" Count:");
199 Serial.print(count);
200 Serial.print("]");
201
202 // When the recognition counter is greater than 10 times, reset the recognition counter
203 if (count > 10) {
204
205 Serial.println("Reset recognition counter!");
206
207 // Disable Klio
208 klio.disable();
209
210 // Restart Recognition
212 }
213
214}
215
217{
218 // Define an array to hold the IDs of the patterns to be written to the KLIO sensor.
219 // 'action1_pattern_id' and 'action2_pattern_id' are predefined pattern IDs.
220 uint8_t patterns_ids[] = {action1_pattern_id, action2_pattern_id};
221
222 // Define an array of pointers to the actual pattern data.
223 // 'action1_pattern' and 'action2_pattern' are arrays containing the pattern data.
224 const uint8_t *patterns[] = {action1_pattern, action2_pattern};
225
226 // Define an array to hold the sizes of each pattern.
227 // Use the sizeof operator to determine the size of each pattern array.
228 uint16_t patterns_sizes[] = {sizeof(action1_pattern), sizeof(action2_pattern)};
229
230 // Calculate the number of patterns in the 'patterns_ids' array.
231 // This is done by dividing the total size of the array by the size of a single element.
232 uint8_t patterns_count = sizeof(patterns_ids) / sizeof(patterns_ids[0]);
233
234 // Try to write multiple patterns to the KLIO sensor.
235 // Call the writeMultiplePatterns() method with the arrays of pattern IDs, pattern data pointers,
236 // pattern sizes, and the number of patterns. If the write operation fails, print an error message.
237 if (!klio.writeMultiplePatterns(patterns_ids, patterns, patterns_sizes, patterns_count)) {
238 Serial.println("Klio write multiple patterns failed!");
239 }
240
241 // Start the recognition process for the specified patterns.
242 // Call the recognition() method with the array of pattern IDs and the number of patterns.
243 klio.recognition(patterns_ids, patterns_count);
244
245 // Define the sample rate for data reading.
246 // The sample rate is set to 25.0 Hz, meaning data will be read 25 times per second.
247 float sample_rate = 25.0; /* Read out data measured at 25Hz */
248
249 // Define the report latency in milliseconds.
250 // A value of 0 means that the sensor will report data immediately as it is measured.
251 uint32_t report_latency_ms = 0; /* Report immediately */
252
253 // Enable the KLIO sensor with the specified sample rate and report latency.
254 // Call the enable() method to activate the sensor and configure it according to the settings.
255 klio.enable(sample_rate, report_latency_ms);
256}
257
258void setup()
259{
260 Serial.begin(115200);
261 while (!Serial);
262
263 // Set the reset pin
264 bhy.setPins(BHI260_RST);
265
266 // Set the firmware array address and firmware size
267 bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
268
269 // Set the firmware update processing progress callback function
270 // bhy.setUpdateProcessCallback(progress_callback, NULL);
271
272 // Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
273 // bhy.setMaxiTransferSize(256);
274
275 // Set the processing fifo data buffer size,The default size is 512 bytes.
276 // bhy.setProcessBufferSize(1024);
277
278 // Set to load firmware from flash
279 bhy.setBootFromFlash(bosch_firmware_type);
280
281 Serial.println("Initializing Sensors...");
282
283#ifdef USE_I2C_INTERFACE
284 // Using I2C interface
285 // BHI260AP_SLAVE_ADDRESS_L = 0x28
286 // BHI260AP_SLAVE_ADDRESS_H = 0x29
287 if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
288 Serial.print("Failed to initialize sensor - error code:");
289 Serial.println(bhy.getError());
290 while (1) {
291 delay(1000);
292 }
293 }
294#endif
295
296#ifdef USE_SPI_INTERFACE
297 // Using SPI interface
298 if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
299 Serial.print("Failed to initialize sensor - error code:");
300 Serial.println(bhy.getError());
301 while (1) {
302 delay(1000);
303 }
304 }
305#endif
306
307 Serial.println("Initializing the sensor successfully!");
308
309 // Output all sensors info to Serial
310 BoschSensorInfo info = bhy.getSensorInfo();
311
312#ifdef ARDUINO
313 ArduinoStreamPrinter printer(Serial);
314 info.printInfo(printer);
315#else
316 info.printInfo([](const char *format, ...) -> int {
317 va_list args;
318 va_start(args, format);
319 int result = vprintf(format, args);
320 va_end(args);
321 return result;
322 });
323#endif
324
325 // Try to initialize the KLIO sensor.
326 if (!klio.begin()) {
327 while (1) {
328 Serial.println("Failed to initialize Klio sensor. Are you currently using a firmware that includes Klio sensor functionality?");
329 delay(1000);
330 }
331 }
332
333 // Set the callback function for recognition events.
334 // Similar to the learning callback, the setRecognitionCallback() method registers a function
335 // that will be invoked when a recognition - related event happens in the KLIO sensor.
336 // 'recognition_event_callback' is the callback function, and 'nullptr' is used as the user data pointer.
338
339 // Start Recognition
341
342#ifdef USING_SENSOR_IRQ_METHOD
343 // Set the specified pin (BHI260_IRQ) ​​to an input pin.
344 // This makes the pin ready to receive external signals.
345 // If the interrupt is already connected, if BHI260_IRQ is equal to -1 then the polling method will be used
346 pinMode(BHI260_IRQ, INPUT);
347
348 // Attach an interrupt service routine (ISR) to the specified pin (BHI260_IRQ).
349 // The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
350 attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
351#endif
352
353 Serial.println("Please check the gif(atcion1.gif,action2.gif) image in the example directory to see the action instructions."
354 "If the action meets the record value, the action record counter will be triggered.");
355}
356
357void loop()
358{
359#ifdef USING_SENSOR_IRQ_METHOD
361 isInterruptTriggered = false;
362#endif /*USING_SENSOR_IRQ_METHOD*/
363
364 /* If the interrupt is connected to the sensor and BHI260_IRQ is not equal to -1,
365 * the interrupt function will be enabled, otherwise the method of polling the sensor is used
366 */
367 bhy.update();
368
369#ifdef USING_SENSOR_IRQ_METHOD
370 }
371#endif /*USING_SENSOR_IRQ_METHOD*/
372
373 delay(50);
374}
@license MIT License
@license MIT License
SensorBHI260AP bhy
const uint8_t action2_pattern[]
volatile bool isInterruptTriggered
SensorBHI260AP_Klio klio(bhy)
void recognition_event_callback(uint8_t pattern_id, float count, void *user_data)
Callback function for KLIO sensor recognition events.
void progress_callback(uint32_t total, uint32_t transferred, void *user_data)
bool writeMultiplePatterns(const uint8_t *ids, const uint8_t **parameter_data_array, const uint16_t *sizes, uint8_t count)
Write multiple patterns to the KLIO sensor.
void disable()
Disable the KLIO sensor.
bool begin()
Initialize the interaction with the KLIO functionality of the BHI260AP sensor.
bool enable(float sample_rate, uint32_t report_latency_ms)
Enable the KLIO sensor with specified sample rate and report latency.
bool recognition(const uint8_t *pattern_ids, size_t size)
Start the recognition function of the KLIO sensor for the specified pattern IDs.
void setRecognitionCallback(RecognitionCallback cb, void *user_data)
Set the callback function for the recognition event.
void setBootFromFlash(bool boot_from_flash)
setBootFromFlash