本文前言
NanoEdge ai Studio是ST提供的免费软件,可以轻松地将ai添加到任何Arm@ Cortex®-M MCU上运行的任何嵌入式项目中。官网首页:NanoEdge AI Studio,官方文档:AI:NanoEdge AI Studio。官方文档写的很详细,建议观看。
原本是基于keil5来体验的,但是keil5的默认编译器找不到添加链接.a文件的地方,虽然说也能切换成GCC,但是看着网上的资料和自己的尝试,感觉问题不少,还是直接换STM32CubeIDE了。
验证目标:基于STM32F407VGT6+附着在杯子上的六轴传感器(MPU6050)+NanoEdge AI Studio训练的异常状态模型。其它材料:STLINK-V2,USB转串口模块,若干杜邦线。当然文章末尾,我也会提供项目工程,和使用到的正常异常信号的CSV文件和导出的模型。
前置准备
安装NanoEdge AI Studio
去官网注册下载安装包,填好自己的邮箱,会收到账号激活邮件,和进入NanoEdge AI Studio时所需的序列号,就不演示了,相信大家都会注册安装的,前言处有官网链接。
安装STM32CubeIDE
如果,你也和我一样之前只用Keil5,那么就需要去这里,意法官网STM32CubeMX:图形化工具下个STM32CubeIDE了。
- 为什么在下图实物中插了两个模块,因为STM32CubeIDE默认不支持DAP的,我也鼓捣过下,但是问题不少,所以还是老老实实用STLINK-V2了,不然有1个模块都同时支持串口和DAP了。
体验流程
下述流程,将安装前言的目标进行异常状态项目所配置训练,不会去扩展讲解其它的东西,读者在基本了解流程和软件的使用的流程后,在自行探索,如探寻其它的项目类型,1 类分类,N 级分类*,外推法的训练之类的。
项目设置
在项目配置这里,设置个项目名称,写个描述,选择目标芯片就可以,下滑在选择轴数就可以了。像RAM和Flash都是用默认配置。完成后点击下一步即可。
信号采集
信号采集,或者是数据采集。在项目中是步骤2采集正常信号,步骤3采集异常信号。
输入文件格式的一般注意事项:
.txt / .csv 文件。仅数值,无标题。统一分隔符(单字节、制表符、逗号或分号)。使用句点 (.) 格式化的十进制值。每行少于 16,384 个值。每行的数值数量一致。每个传感器轴至少 20 条线。总行数少于 ~100,000 行。文件大小小于 ~1 Gbit。
三个导入信号方式:
- 从文件(.txt / .csv 格式)
- 从实时数据记录器的串行端口 (USB)
- 来自 FP-SNS-Datalog
上面说的都是官方的规则格式,我的是通过配置好的串口接收信号。关于数据分割可以看到步骤2界面中讲解了。其实就是数据分割符,行与行之间的分割符,上传就看了,可能描述的比较迷糊,可以看代码表述。
int LineNum = 0;
while (1)
{
while(MPU6050_DMP_Get_Date(&x,&y,&z)!=0){}
// 学习时,获取数据用
printf("%.2f,%.2f,%.2f,",x,y,z);
LineNum++;
HAL_Delay(10);
if(LineNum>=100)
{
printf("\r\n");
LineNum = 0;
}
}
点击ADD SIGNAL
添加信号
NormalSignal1信号是之前采集的,刚开始都是空的。选择了串口采集后,就跟常见的串口监视器的操作差不多的,圈出来的两个是开始监听/暂停
,和清除所有
,相信大家都能看得懂的的。还有两个要注意的地方是:
- 采集行数不等于最终的信号数,在下一步中是可以删除选择的,假如采集了100行,可以只选择20行。
- 串口采集完后,一定要暂停,且有数据后才能点击
CONTINUE
继续到下一步数据处理
当信号采集好后,会有图框分析这段数据。我这里就是采集了20行的数据量,每行300个值,因为设置的是三轴,所以每行每轴是100个值。大概是这么个表达,[x1 y1 z1 … x100 y100 z100 ] * 20行。
因为步骤3的异常信号采集,与这个正常信号采集流程一样,就不再赘述。所以说我的验证数据分别是,1个正常信号,1个异常信号,就简单的体验体验先。
基准训练
到基准这里后,点击RUN NEW BENCHMARK
,选择信号开始即可。我之前训练过一个了,就不重新训练了,在下面看可以看到它的数据,而且是只训练到了,预计验证模型数的百分之十多,我就停止了,可能全部验证完要1个多小时,我觉得太久了。所以说模型可能不是最优。
验证信息
会列出指定基准的,所有验证过的模型列出来和各种基本参数,且把最优标上皇冠。没有要操作的,进行到下一步模型部署。
模型部署
看下面的模型部署块,还是不理解的话可以看看官方关于部署的介绍,AI:NanoEdge 异常检测 (AD) AI 库—部署。按官方文档中描述,可以在Arduino
(基于Cortex-M的板子)下或有GCC编译器
的环境下部署的。
在NanoEdge AI Studio上的部署界面
有5个单选框,有跟内存与效率有关的,有是否包括来自基准的知识(否的话,则不包含训练过的知识,在嵌入式上使用时必需调用学习后才能用),这里暂时先按默认配置里。点击COMPILE LIBRARY
导出zip即可。
至于官方右侧的开始代码,下面我就去掉注释简单的描述下。
![部署-进入配置2](部署-进入配置2.png)#include "NanoEdgeAI.h"
// 学习样本数量:由用户设置
#define LEARNING_ITERATIONS 10
// 输入值缓冲区
float input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER];
// 私有函数:用于填充数据,来进行学习或验证
void fill_buffer(float input_buffer[])
{
/* USER BEGIN */
/* USER END */
}
// 主函数
int main(void)
{
// 初始化
enum neai_state error_code = neai_anomalydetection_init();
uint8_t similarity = 0;
if (error_code != NEAI_OK) {
// 初始化失败后操作
}
// 学习过程
for (uint16_t iteration = 0 ; iteration < LEARNING_ITERATIONS ; iteration++) {
fill_buffer(input_user_buffer);
neai_anomalydetection_learn(input_user_buffer);
}
// 检测过程
while (1) {
fill_buffer(input_user_buffer);
neai_anomalydetection_detect(input_user_buffer, &similarity);
}
}
在STM32CubeIDE上需要进行的配置。
项目中添加libneai.a的编译链接
添加右键项目,点击属性。然后在属性框下,C/C++构建
->设置
->MCU/MPU GCC Linker的Libraries下
,在 Libraries 部分添加 “neai”,在 Library search path 部分添加 libneai.a 路径。单击 Apply and Close (应用并关闭)
项目中添加NanoEdgeAI.h的引入路径
也是在属性框下的配置,大家就按照自己的存放库的路径自行添加。
至此,文件配置也算是完成了,接下来就是在main.h中编写用户代码了。不过其实在在上面的解析官方的开始文件中,该说的都说了,所以还是,直接把我的main.h用户代码全贴了出来,大家可以自行比对(为了减少行数,已删去HAL库的注释)。
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
#include "MPU6050.h"
#include "stdio.h"
#include "MPU6050_DMP.h"
#include "NanoEdgeAI.h"
#define LEARNING_ITERATIONS 10
float input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER]; // Buffer of input values
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch,1,HAL_MAX_DELAY);
return ch;
}
void SystemClock_Config(void);
float x = 0;
float y = 0;
float z = 0;
int ret = 0;
void fill_buffer(float input_buffer[])
{
/* USER BEGIN */
char count = 0;
// 达到数组即可退出
while(count < DATA_INPUT_USER)
{
// 单轮学习配置
MPU6050_DMP_Get_Date(&x,&y,&z);
while(MPU6050_DMP_Get_Date(&x,&y,&z)!=0){}
// 一次三轴
input_buffer[count*3] = x;
input_buffer[count*3+1] = y;
input_buffer[count*3+2] = z;
// 递增
count++;
}
/* USER END */
}
int main(void)
{
enum neai_state error_code;
uint8_t similarity = 0;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
printf("Hello World\r\n");
do
{
ret = MPU6050_DMP_init();
printf("MPU6050 init, ret = %d\r\n", ret);
HAL_Delay(100);
} while(ret);
printf("address:%x\r\n",MPU6050_ReadID());
// Ai初始化
error_code = neai_anomalydetection_init();
similarity = 0;
if (error_code == NEAI_OK)
{
printf("Ai_InitOK\r\n");
}
else
{
printf("Ai_InitErr:%d\r\n",error_code);
}
// Ai前置学习
for (uint16_t iteration = 0 ; iteration < LEARNING_ITERATIONS ; iteration++) {
fill_buffer(input_user_buffer);
neai_anomalydetection_learn(input_user_buffer);
printf("LearnNum:%d\r\n",iteration+1);
}
while (1)
{
// 验证数据采集
// 达到数组即可退出
fill_buffer(input_user_buffer);
// 进入验证
neai_anomalydetection_detect(input_user_buffer, &similarity);
printf("%d\r\n",similarity);
}
}
演示验证
实物材料以及烧录到开发板中,测试验证图。相似度从0~100,下述串口输出相似率,降到90以下时,是对杯子进行倾倒了。还就是,因为我的模型没有勾选,利用基准时的数据,所以在10次学习时,还需要让杯子传入10次正常信号,进行学习。
资料链接
STM32CubeIDE项目工程,1个正常信号,1个异常信号的CSV文件,libneai_cupcondition_2.zip
为上述项目部署导出的模型。
链接:https://pan.baidu.com/s/1p9s-AsT9HGWFgRYQo-VVyQ 提取码:pdhs