基于STM32部署卷积神经网络控制设备方案-AI项目-STM32部署卷积神经网络方案-红外信号复制方案-轨迹识别
项目包含下述内容
- 硬件部分、PCB制板、BOM表文件等等 (Hardware)
- 外壳、3D打印文件 (3D_print)
- 软件程序、用于电子法棒的软件程序 AI + Keil等等(Software)
- QT上位机动作识别模型训练脚本 (用于训练模型等功能)(Upper_computer)
- 图示、Demo中的13个动作轨迹图例(Model_trajectories)
- 环境安装包、工具包(Install_package) + 嵌入式神经网络部署源码(NNOM_Demo)
- 二次开发方案
1.项目简介
功能:(通俗易懂)
设备会根据你的手势轨迹动作,去发出指令,控制设备。你可以理解是一个哈利波特魔法棒。
1.设备的手势可以自行添加,目前13个手势,你可以任意添加你想要的手势轨迹,配备QT上位机给你添加(还可以学到QT)
2.设备会根据你做的动作判断是否正确,是否是动作集里面的动作,去发出控制设备的信号,比如空调的开关,温度的升降,任何牌子的都可以(格力美的等等都可以 本质是复制红外信号)
2.系统架构
硬件架构:STM32F103、MPU6050、红外传感器、电池降压电路、电源管理IC、电源选择电路、充电管理电路、充电管理IC等等
软件架构:QT、ARM、Tensorflow、Keras、实战算法、nnom(嵌入式AI推理库)等等
3.开发环境配置说明
Keil环境配置:
-
Keil 版本:请使用 Keil 5,建议从 Keil 官网下载最新版,避免遇到兼容性问题。
-
编译器版本:请选择 Arm Compiler 6.22 作为编译器,确保项目能够顺利编译。
-
调试器设置:根据您的设备选择合适的调试器,例如 ST-Link 或其他兼容设备,以进行程序调试。
-
库文件安装:首次打开项目时,Keil 可能提示需要安装缺失的库,请根据提示进行安装,以确保项目能够正常运行。
代码如下所示:
#include "CyberryPotter.h"
#include "weights.h"
#include "nnom.h"#define QUANTIFICATION_SCALE (pow(2, INPUT_1_OUTPUT_DEC))
#define OUTPUT_THRESHOLD 63void model_feed_data(void);
Model_Output_t model_get_output(void);#ifdef NNOM_USING_STATIC_MEMORYuint8_t static_buf[1024 * 10];
#endif nnom_model_t* model;
volatile Model_Output_t model_output = -1;int main(void) {System_Init();LED.Operate(BLINK_10HZ);#ifdef NNOM_USING_STATIC_MEMORYnnom_set_static_buf(static_buf, sizeof(static_buf)); #endif model = nnom_model_create();while (1) {if (Button.status == BUTTON_HOLD && IMU.status == IMU_Idle) {IMU.Sample_Start();EXTI_Stop();LED.Operate(OFF);while (IMU.status != IMU_Sampled);LED.Operate(ON);#ifndef SYSTEM_MODE_DATA_COLLECTmodel_output = model_get_output();if (model_output != Unrecognized) {switch (Cyberry_Potter.System_Mode) {case SYSTEM_MODE_0:Module.Mode0_Handler();break;case SYSTEM_MODE_1:Module.Mode1_Handler();break;default:break;}}#endifIMU.status = IMU_Idle;Button.status_clear();EXTI_Restore();} else if (Button.status == BUTTON_HOLD_LONG) {printf("BUTTON_HOLD_LONG\n");LED.Operate(BLINK_5HZ);Cyberry_Potter_System_Status_Update();Button.status_clear();}}
}void model_feed_data(void) {const double scale = QUANTIFICATION_SCALE;for (uint16_t i = 0; i < IMU_SEQUENCE_LENGTH_MAX; i++) {nnom_input_data[i * 3] = (int8_t)round(IMU.gyro[i][Roll] * scale);nnom_input_data[i * 3 + 1] = (int8_t)round(IMU.gyro[i][Pitch] * scale);nnom_input_data[i * 3 + 2] = (int8_t)round(IMU.gyro[i][Yaw] * scale);}
}Model_Output_t model_get_output(void) {model_feed_data();model_run(model);int8_t max_output = -128;Model_Output_t ret = Unrecognized;for (uint8_t i = 0; i < 13; i++) {#ifdef SERIAL_DEBUGprintf("Output[%d] = %.2f %%\n", i, (nnom_output_data[i] / 127.0) * 100);#endifif (nnom_output_data[i] > max_output) {max_output = nnom_output_data[i];ret = i;}}if (max_output < OUTPUT_THRESHOLD) {ret = Unrecognized;}#ifdef SERIAL_DEBUGconst char* gesture_names[] = {"Unrecognized", "RightAngle", "SharpAngle", "Lightning", "Triangle", "Letter_h", "Letter_R", "Letter_W", "Letter_phi", "Circle", "UpAndDown", "Horn", "Wave", "NoMotion"};printf("%s\n", gesture_names[ret]);#endifreturn ret;
}