秋名山最速传说
除了该搞的啥都搞 邮箱:li_yi_liang@qq.com
文号937379
2558
1
收藏(3)

STM32MCU边缘AI部署之再探NanoEdge AI Studio(二)

前言:

原文再续,书接上一回。上一回讲到如何使用NanoEdge AI Studio训练出用于部署的模型,下面我将继续讲解如何部署模型到STM32的MCU。这里我使用的MCU是STM32F103,软件是CubeIDE。训练使用的数据集是上文正态分布生成的数据集。分别为3-1-200-16.csv,4-1-200-16.csv,5-1-200-16.csv,命名格式为:期望-标准差-矩阵的行数-矩阵的列数。

本系列第一篇文章:STM32MCU边缘AI部署之初探NanoEdge AI Studio - 科创网 (XXXXXXXXXXXX)


正文:

1、把.h .a文件移动到要部署的工程中,我的路径如下

image.png

2、我们打开NanoEdgeAI.h看看里面有什么好东西,注释看着挺详细的。

image.png

3、NanoEdgeAI.h的接近末尾下面有写道“Here some sample declaration added in your main program for the use of the NanoEdge AI library.”开启CV大法,如下图二。

image.png

image.png

4、在main里面初始化neai

enum neai_state error_code = neai_classification_init(knowledge);

image.png

5、如果你这时候编译,你就会发现,沃日?怎么undefined reference to neai_classification_init',点击转跳是能转跳进NanoEdgeAI.h的......还记得我们前面添加进来的libneai.a吗,要把静态编译库添加进GCC链路。如下图,注意要去掉lib和后缀.a,实际上键入的是neai,路径也要添加。

image.png

如果你使用的是Keil5,先添加文件到工程目录,如下图

image.png

右键.a文件,点击OptionXXXX如下图一,然后更改文件类型如下图二

image.png

image.png

编译如果如下图一报错--wchar32什么的,在C/C++中添加如下图二的

--wchar32

静态库分 wc16 和 wc32 库,keil5默认的是 wc16 的,这里我们需要修改为wc32库,此时编译应该是没问题了(处理这个问题的时候,真的感慨AI知识污染的严重性,搜索出来的第一页完全是乱来的,一眼AI生成,还霸占CSDN之类的简中网站,这类回答对解决问题毫无用处,还误导学习者)。

image.png

image.png


6、我们来看看main里面的代码,主要逻辑是初始化neai,然后进入neai_classification函数(这个函数无法查看内部实现,我们只能使用接口)

int main(void)
{
  /* USER CODE BEGIN 1 */

    uint16_t id_class = 0;
    uint16_t newClass = 0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
    enum neai_state error_code = neai_classification_init(knowledge);//初始化

    if (error_code != NEAI_OK) 
    {
		/* This happens if the knowledge does not correspond to the library or if the library works into a not supported board. */
    }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	char uart_buffer[100];//存放要发送的数据,不使用printf偷个懒
	
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);//查看代码有没有运行
	HAL_Delay(100);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
	HAL_Delay(100);

	neai_classification(input_user_buffer, output_class_buffer, &id_class);//跑数据

	// 逐个类发送置信度
	for (uint16_t class_cpt = 0; class_cpt < CLASS_NUMBER; class_cpt++) {
	    // 使用 sprintf 格式化字符串,存储到 uart_buffer 中
	    int len = sprintf(uart_buffer, "%d: %.3f ", class_cpt, output_class_buffer[class_cpt]);
	    // 通过 UART 发送字符串,等待发送完成
	    HAL_UART_Transmit(&huart1, (uint8_t*)uart_buffer, len, HAL_MAX_DELAY);
	}

	// 发送换行符
	sprintf(uart_buffer, "\n");
	HAL_UART_Transmit(&huart1, (uint8_t*)uart_buffer, 1, HAL_MAX_DELAY);

	// 发送 "Class found" 信息
	sprintf(uart_buffer, "Class found: %s.\n\n", id2class[id_class]);
	HAL_UART_Transmit(&huart1, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

7、使用虚拟数据进行预测,使用的数据如下,期望是5附近。

float input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER]={5.1,4.8,4.8,4.6,4.5,5,4.6,4.6,5.5,4.9,4.4,4.6,4.9,4.9,5.6,4.9}; // Buffer of input values

8、烧录然后RUN查看串口结果,实测单次运算时间小于0.01ms,BINGO,运行结果符合预期,输出每个类的置信度和最终结果。

image.png

9、余下的交由各位自行发挥了......电流、加速度、电压、温度、湿度等数据都可以进行训练,甚至你不在乎延迟,低算力MCU跑个图像也可以。


PS:写到这里,想起长者的“闷声发大财,这是坠吼滴。”不经感慨,本系列的文章没有意外应该是简中互联网关于这个工具的首篇详细教程,从训练部署到应用,希望有受益的朋友水个回复也好吧^_^

PPS:浅浅数了一下,本文似乎是我发的第25篇文章。

[修改于 1 个月前 - 2024/11/22 17:09:10]

1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
zRed洲虹
3个月8天前 IP:中国
937443

感谢分享,感觉电炮自动调整时序要来哩 sticker

主体信息
主体类型:个人
所属领域:无
认证方式:身份证号
IP归属地:广东
 内容统计
2024年12月
1 篇
2024年09月
2 篇
2024年08月
3 篇
2024年07月
2 篇
2024年03月
4 篇
2024年01月
8 篇
ID: {{user.uid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
回复
设为精选取消精选
评学术分
鼓励
编辑
查看历史
通过审核
移动文章
加入收藏取消收藏
退修或删除
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
回复
加入收藏取消收藏