【Follow me第二季第4期】-选做任务四-通过IMU数据结合机器学习算法,识别运动状态...
[复制链接]
选做任务四:通过IMU数据结合机器学习算法,识别运动状态,并通过串口打印。
按照惯例,我们来看看arduino官方是怎么实现这个功能的
LSM6DSOXTR传感器是内置了深度学习的功能的,所以大家请不要看上去这个功能很难就没用去测试,咱们跟则官方教程来,还是能轻易实现的
这里跟大家道个歉,我由于回家了,板子忘在公司没用带回来,在这里先跟大家分享一下功能实现的思路以及中文翻译,下周去公司了再补上演示视频,示例代码我放在下面了,附上了中文注释,现在有条件的兄弟可以先试试效果
代码:
/**
******************************************************************************
* [url=home.php?mod=space&uid=1307177]@File[/url] X_NUCLEO_IKS01A3_LSM6DSOX_MLC.ino
* [url=home.php?mod=space&uid=1315547]@author[/url] SRA
* [url=home.php?mod=space&uid=252314]@version[/url] V1.1.0
* [url=home.php?mod=space&uid=311857]@date[/url] 2020年3月
* [url=home.php?mod=space&uid=159083]@brief[/url] 这是用于STMicrolectronics X-NUCLEO-IKS01A3 MEMS 惯性和环境传感器扩展板的Arduino测试应用程序。
* 该应用程序使用从C组件驱动程序获得的C++类。
******************************************************************************
* [url=home.php?mod=space&uid=1020061]@attention[/url] *
* <h2><center>© COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
*
* 允许在源代码和二进制形式下,无论是否修改,重新分发和使用,
* 只要满足以下条件:
* 1. 源代码的再分发必须保留上述版权声明、此条件列表以及以下免责声明。
* 2. 二进制形式的再分发必须在随软件提供的文档和/或其他材料中复制上述版权声明、此条件列表以及以下免责声明。
* 3. 未经特定事先书面许可,不得使用STMicroelectronics或其贡献者的名字支持或推广衍生自本软件的产品。
*
* 本软件由版权持有者和贡献者“按原样”提供,
* 任何明示或暗示的保证,包括但不限于对适销性和特定用途适用性的暗示保证均被排除。
* 在任何情况下,即使被告知可能发生此类损害的可能性,版权持有者或贡献者也不对任何直接的、间接的、偶然的、特殊的、惩罚性的或间接损害负责(包括但不限于替代商品或服务的采购、使用、数据或利润的损失,或业务中断)。
* 无论责任理论是合同责任、严格责任还是侵权行为(包括疏忽或其他原因)引起的,无论是因使用本软件还是其他方式引起的。
*
******************************************************************************
*/
// 注意:此示例与Arduino Uno不兼容。
// 注意:对于此示例,您需要将STEVAL-MKI197V1开发板连接到X-NUCLEO-IKS01A3的DIL24连接器。
// 包含头文件
#include "LSM6DSOXSensor.h"
#include "lsm6dsox_activity_recognition_for_mobile.h"
#ifdef ARDUINO_SAM_DUE
#define DEV_I2C Wire1
#elif defined(ARDUINO_ARCH_STM32)
#define DEV_I2C Wire
#elif defined(ARDUINO_ARCH_AVR)
#define DEV_I2C Wire
#else
#define DEV_I2C Wire
#endif
#define SerialPort Serial
#define INT_1 INT_IMU //已针对Nano RP2040 Connect做了修改,中断引脚位于 GPIO 引脚 21 上,可以称为INT_IMU.
// 中断。
volatile int mems_event = 0;
// 组件
LSM6DSOXSensor AccGyr(&DEV_I2C, LSM6DSOX_I2C_ADD_L);
// MLC
ucf_line_t *ProgramPointer;
int32_t LineCounter;
int32_t TotalNumberOfLine;
// 中断回调函数
void INT1Event_cb();
// 打印MLC状态函数
void printMLCStatus(uint8_t status);
void setup() {
uint8_t mlc_out[8];
// LED。
pinMode(LED_BUILTIN, OUTPUT);
// 将LSM6DSOX的INT1强制为低电平以启用I2C
pinMode(INT_1, OUTPUT);
digitalWrite(INT_1, LOW);
delay(200);
// 初始化串口输出。
SerialPort.begin(115200);
// 初始化I2C总线。
DEV_I2C.begin();
AccGyr.begin();
AccGyr.Enable_X();
AccGyr.Enable_G();
/* 将程序输入到机器学习核心 */
/* 活动识别默认程序 */
ProgramPointer = (ucf_line_t *)lsm6dsox_activity_recognition_for_mobile;
TotalNumberOfLine = sizeof(lsm6dsox_activity_recognition_for_mobile) / sizeof(ucf_line_t);
SerialPort.println("LSM6DSOX MLC的活动识别");
SerialPort.print("UCF行数=");
SerialPort.println(TotalNumberOfLine);
for (LineCounter=0; LineCounter<TotalNumberOfLine; LineCounter++) {
if(AccGyr.Write_Reg(ProgramPointer[LineCounter].address, ProgramPointer[LineCounter].data)) {
SerialPort.print("在第 ");
SerialPort.print(LineCounter);
SerialPort.println(" 行将程序加载到LSM6DSOX时出错");
while(1) {
// LED闪烁。
digitalWrite(LED_BUILTIN, HIGH);
delay(250);
digitalWrite(LED_BUILTIN, LOW);
delay(250);
}
}
}
SerialPort.println("程序已加载到LSM6DSOX MLC");
// 中断。
pinMode(INT_1, INPUT);
attachInterrupt(INT_1, INT1Event_cb, RISING);
/* 我们需要等待一个时间窗口才能获得第一个MLC状态 */
delay(3000);
AccGyr.Get_MLC_Output(mlc_out);
printMLCStatus(mlc_out[0]);
}
void loop() {
if (mems_event) {
mems_event=0;
LSM6DSOX_MLC_Status_t status;
AccGyr.Get_MLC_Status(&status);
if (status.is_mlc1) {
uint8_t mlc_out[8];
AccGyr.Get_MLC_Output(mlc_out);
printMLCStatus(mlc_out[0]);
}
}
}
void INT1Event_cb() {
mems_event = 1;
}
void printMLCStatus(uint8_t status) {
switch(status) {
case 0:
SerialPort.println("活动:静止");
break;
case 1:
SerialPort.println("活动:步行");
break;
case 4:
SerialPort.println("活动:慢跑");
break;
case 8:
SerialPort.println("活动:骑自行车");
break;
case 12:
SerialPort.println("活动:驾驶");
break;
default:
SerialPort.println("活动:未知");
break;
}
}
|