SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
bhi260ap_klio_self_learning.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#if BHI260_IRQ > 0
104#define USING_SENSOR_IRQ_METHOD
105#endif
106
107#ifdef USING_SENSOR_IRQ_METHOD
108volatile bool isInterruptTriggered = false;
109
111{
113}
114#endif /*USING_SENSOR_IRQ_METHOD*/
115
116// Firmware update progress callback
117void progress_callback(uint32_t total, uint32_t transferred, void *user_data)
118{
119 float progress = (float)transferred / total * 100;
120 Serial.print("Upload progress: ");
121 Serial.print(progress);
122 Serial.println("%");
123}
124
144void recognition_event_callback(uint8_t pattern_id, float count, void *user_data)
145{
146 Serial.print("<-Recognition[Id:");
147 Serial.print(pattern_id);
148 Serial.print(" Count:");
149 Serial.print(count);
150 Serial.print("]");
151}
152
169void learning_event_callback(SensorBHI260AP_Klio::LearningChangeReason reason, uint32_t progress, int learn_index, void *user_data)
170{
171 // Print the learning event details to the serial monitor, including the progress, reason, and learned pattern index.
172 Serial.print("->Learning [Progress:");
173 Serial.print(progress);
174 Serial.print(" Reason:");
175 Serial.print(static_cast<uint8_t>(reason));
176 Serial.print(" ID:");
177 Serial.print(learn_index);
178 Serial.println("]");
179
180 // Check if the learning index is valid (not equal to INVALID_LEARNING_INDEX).
182 // Create a buffer to store the learned pattern data. The buffer size is 252 bytes.
183 uint8_t tmp_buf[252];
184 // Store the size of the buffer. This variable will be updated with the actual size of the learned pattern.
185 uint16_t bufsize = sizeof(tmp_buf);
186
187 // Try to retrieve the learned pattern from the sensor using the getLearnPattern function.
188 // The result indicates whether the retrieval is successful.
189 bool learn_success = klio.getLearnPattern(tmp_buf, &bufsize);
190 if (!learn_success) {
191 // If the retrieval fails, print an error message and the specific error reason.
192 Serial.print("Read learnt failed. Reason:");
193 Serial.println(klio.errorToString());
194 } else {
195 // If the retrieval is successful, print a success message and the details of the learned pattern.
196 Serial.println("Learning the action successfully");
197 Serial.println("PATTERN LEARNT: ");
198 Serial.print("const uint8_t * learn_pattern = { ");
199 // Iterate through the buffer and print the pattern data in hexadecimal format.
200 for (uint16_t i = 0; i < bufsize; i++) {
201 if (i > 0 && i % 8 == 0) {
202 // Print a new line every 8 bytes for better readability.
203 Serial.println();
204 }
205 Serial.print("0x"); Serial.print(tmp_buf[i], HEX);
206 if (i < bufsize - 1) {
207 // Add a comma and a space after each byte except the last one.
208 Serial.print(", ");
209 }
210 }
211 Serial.println(" \n};\n");
212 }
213 // Print a message indicating that the learned pattern will be written.
214 Serial.println("Write the learning pattern.");
215 // Define an example pattern ID.
216 uint8_t examples_id = 1;
217 // Try to write the learned pattern to the sensor using the writePattern function.
218 if (!klio.writePattern(examples_id, tmp_buf, bufsize)) {
219 // If the write operation fails, print an error message.
220 Serial.println("Klio write pattern failed!");
221 }
222 // Print messages indicating that the action recognition will start.
223 Serial.println("Start recognizing actions");
224 Serial.println("Please perform the learned action instructions and the sensor will start to recognize the number of actions.");
225 // Start the recognition process for the specified pattern ID.
226 klio.recognition(&examples_id, 1);
227 }
228}
229
230void setup()
231{
232 Serial.begin(115200);
233 while (!Serial);
234
235 // Set the reset pin
236 bhy.setPins(BHI260_RST);
237
238 // Set the firmware array address and firmware size
239 bhy.setFirmware(bosch_firmware_image, bosch_firmware_size, bosch_firmware_type, force_update_flash_firmware);
240
241 // Set the firmware update processing progress callback function
242 // bhy.setUpdateProcessCallback(progress_callback, NULL);
243
244 // Set the maximum transfer bytes of I2C/SPI,The default size is I2C 32 bytes, SPI 256 bytes.
245 // bhy.setMaxiTransferSize(256);
246
247 // Set the processing fifo data buffer size,The default size is 512 bytes.
248 // bhy.setProcessBufferSize(1024);
249
250 // Set to load firmware from flash
251 bhy.setBootFromFlash(bosch_firmware_type);
252
253 Serial.println("Initializing Sensors...");
254
255#ifdef USE_I2C_INTERFACE
256 // Using I2C interface
257 // BHI260AP_SLAVE_ADDRESS_L = 0x28
258 // BHI260AP_SLAVE_ADDRESS_H = 0x29
259 if (!bhy.begin(Wire, BHI260AP_SLAVE_ADDRESS_L, BHI260_SDA, BHI260_SCL)) {
260 Serial.print("Failed to initialize sensor - error code:");
261 Serial.println(bhy.getError());
262 while (1) {
263 delay(1000);
264 }
265 }
266#endif
267
268#ifdef USE_SPI_INTERFACE
269 // Using SPI interface
270 if (!bhy.begin(SPI, BHI260_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
271 Serial.print("Failed to initialize sensor - error code:");
272 Serial.println(bhy.getError());
273 while (1) {
274 delay(1000);
275 }
276 }
277#endif
278
279 Serial.println("Initializing the sensor successfully!");
280
281 // Output all sensors info to Serial
282 BoschSensorInfo info = bhy.getSensorInfo();
283
284#ifdef ARDUINO
285 ArduinoStreamPrinter printer(Serial);
286 info.printInfo(printer);
287#else
288 info.printInfo([](const char *format, ...) -> int {
289 va_list args;
290 va_start(args, format);
291 int result = vprintf(format, args);
292 va_end(args);
293 return result;
294 });
295#endif
296
297 // Try to initialize the KLIO sensor.
298 // The begin() method is called on the 'klio' object to set up the sensor.
299 if (!klio.begin()) {
300 while (1) {
301 Serial.println("Failed to initialize Klio sensor. Are you currently using a firmware that includes Klio sensor functionality?");
302 delay(1000);
303 }
304 }
305
306 // Call the getMaxPatterns() method of the klio object to get the maximum number of patterns allowed by the KLIO sensor.
307 // This method returns a value of type uint8_t representing the maximum number of patterns and stores it in the variable max_patterns.
308 uint8_t max_patterns = klio.getMaxPatterns();
309 Serial.print("Klio sensor max patterns:");
310 Serial.println(max_patterns);
311
312 // Set the callback function for learning events.
313 // The setLearningCallback() method is used to register a function that will be called
314 // whenever a learning - related event occurs in the KLIO sensor.
315 // 'learning_event_callback' is the name of the callback function,
316 // and 'nullptr' is passed as the user data pointer, meaning no additional user - specific data is provided.
318
319 // Set the callback function for recognition events.
320 // Similar to the learning callback, the setRecognitionCallback() method registers a function
321 // that will be invoked when a recognition - related event happens in the KLIO sensor.
322 // 'recognition_event_callback' is the callback function, and 'nullptr' is used as the user data pointer.
324
325 // Start the learning process of the KLIO sensor.
326 // The learning() method initiates the sensor's functionality to start learning patterns or behaviors.
327 klio.learning();
328
329 // Define the sample rate for data reading.
330 // The variable'sample_rate' is set to 25.0, which means the sensor will read out data
331 // at a frequency of 25 Hertz (25 times per second).
332 float sample_rate = 25.0;
333
334 // Define the report latency in milliseconds.
335 // The variable'report_latency_ms' is set to 0, indicating that the sensor should report
336 // the measured data immediately without any delay.
337 uint32_t report_latency_ms = 0;
338
339 // Enable the KLIO sensor with he specified sample rate and report latency.
340 // The enable() method activates the sensor and configures it to operate at the given sample rate
341 // and report latency. This allows the sensor to start collecting and reporting data according to the settings.
342 klio.enable(sample_rate, report_latency_ms);
343
344#ifdef USING_SENSOR_IRQ_METHOD
345 // Set the specified pin (BHI260_IRQ) ​​to an input pin.
346 // This makes the pin ready to receive external signals.
347 // If the interrupt is already connected, if BHI260_IRQ is equal to -1 then the polling method will be used
348 pinMode(BHI260_IRQ, INPUT);
349
350 // Attach an interrupt service routine (ISR) to the specified pin (BHI260_IRQ).
351 // The ISR 'dataReadyISR' will be called whenever a rising edge is detected on the pin.
352 attachInterrupt(BHI260_IRQ, dataReadyISR, RISING);
353#endif
354
355 Serial.println("Please repeat the movements you want to learn and the sensor will start recording.");
356}
357
358
359void loop()
360{
361#ifdef USING_SENSOR_IRQ_METHOD
363 isInterruptTriggered = false;
364#endif /*USING_SENSOR_IRQ_METHOD*/
365
366 /* If the interrupt is connected to the sensor and BHI260_IRQ is not equal to -1,
367 * the interrupt function will be enabled, otherwise the method of polling the sensor is used
368 */
369 bhy.update();
370
371#ifdef USING_SENSOR_IRQ_METHOD
372 }
373#endif /*USING_SENSOR_IRQ_METHOD*/
374
375 delay(50);
376}
@license MIT License
@license MIT License
SensorBHI260AP bhy
volatile bool isInterruptTriggered
SensorBHI260AP_Klio klio(bhy)
void recognition_event_callback(uint8_t pattern_id, float count, void *user_data)
Callback function for handling KLIO sensor recognition events.
void progress_callback(uint32_t total, uint32_t transferred, void *user_data)
bool force_update_flash_firmware
void learning_event_callback(SensorBHI260AP_Klio::LearningChangeReason reason, uint32_t progress, int learn_index, void *user_data)
Callback function for KLIO sensor learning events.
bool getLearnPattern(uint8_t *pattern, uint16_t *size)
Retrieve the learned pattern from the sensor.
void setLearningCallback(LearningCallback cb, void *user_data)
Set the callback function for the learning event.
bool writePattern(uint8_t idx, const uint8_t *parameter_data, uint16_t size)
Write a pattern to 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 learning()
Start the learning function of the KLIO sensor.
uint8_t getMaxPatterns()
Retrieve the maximum number of recognition patterns allowed.
const char * errorToString() const
Convert the error information to a string.
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
uint8_t i