之前我們有介紹過如何利用STM32F103使用NanoEdge AI訓(xùn)練MPU6050的數(shù)據(jù)實現(xiàn)靜止和振動判斷。
不過這是一個非常簡單的Demo測試,本期我們在此基礎(chǔ)上,使用MPU6050實現(xiàn)小風(fēng)扇的運行模式檢測。
文末有部署到STM32F103并串口輸出的視頻!
準(zhǔn)備工作
本期依舊是一個MPU6050用來檢測震動數(shù)據(jù),STM32利用USB實現(xiàn)和上位機(jī)通訊。
因此CubeMX只需要一組I2C和USB充當(dāng)虛擬串口即可。
將MPU6050用膠帶粘貼到小風(fēng)扇上,這個風(fēng)扇總共有三檔風(fēng)速調(diào)節(jié)。
因此我們打算訓(xùn)練一個多分類識別網(wǎng)絡(luò),可以判斷出風(fēng)扇是靜止、低風(fēng)速、中風(fēng)速、高風(fēng)速狀態(tài)。
數(shù)據(jù)上傳
? ??for(int?i =?0;i<128-1;i++)
? ? ? {
? ? ? ? MPU6050_Read_All(&hi2c2, &mpu_data);
? ? ? ? memset(s,0,sizeof(s));
? ? ? ??sprintf(s,"%f %f %f ",mpu_data.Ax,mpu_data.Ay,mpu_data.Az);
? ? ? ? CDC_Transmit_FS(s,strlen(s));
? ? ? ? Data[i*3+0] = mpu_data.Ax;
? ? ? ? Data[i*3+1] = mpu_data.Ay;
? ? ? ? Data[i*3+2] = mpu_data.Az;
? ? ? ? HAL_Delay(1);
? ? ? }
? ? ??sprintf(s,"%f %f %frn",mpu_data.Ax,mpu_data.Ay,mpu_data.Az);
? ? ? Data[127*3+0] = mpu_data.Ax;
? ? ? Data[127*3+1] = mpu_data.Ay;
? ? ? Data[127*3+2] = mpu_data.Az;
? ? ? CDC_Transmit_FS(s,strlen(s));
數(shù)據(jù)上傳部分非常簡單,將XYZ軸的數(shù)據(jù)格式化為字符串,每組數(shù)據(jù)之間用空格隔開,最后一組數(shù)據(jù)發(fā)送完后添加換行符號。(最后一組數(shù)據(jù)的最后不需要空格)
打開NanoEdge AI,選擇多分類模型。
設(shè)置Flash和RAM大小,選擇我們的芯片系列(F103),選擇傳感器類型,這里我們選用三軸加速度傳感器。
添加數(shù)據(jù),并選用USB輸入,然后開始上傳每一組別的數(shù)據(jù)。
依次獲取了四組數(shù)據(jù),分別是對應(yīng)了四個工作模式。
模型訓(xùn)練和驗證
選擇這四組數(shù)據(jù)開始訓(xùn)練,這里需要等待一段時間等待訓(xùn)練結(jié)束。
訓(xùn)練完可以查看我們的模型指標(biāo),例如準(zhǔn)確率,RAM和Flash大小。
選擇模型進(jìn)行驗證。
獲取并保存我們的模型到工作目錄。
這里主要就是需要這三個文件。
CubeIDE中添加.a文件和它的路徑(不需要lib和后綴)
接著我們看一下NanoEdgeAI.h的內(nèi)容。
包含了初始化和調(diào)用NanoEdgeAI進(jìn)行預(yù)測的函數(shù)。下面我們將介紹如何在main.c中使用。
#include?"NanoEdgeAI.h"
#include?"knowledge.h"
//需要包含兩個頭文件
float?Data[3*128];
float?output_class_buffer[CLASS_NUMBER];?// Buffer of class probabilities
const?char?*id2class[CLASS_NUMBER?+?1] = {?// Buffer for mapping class id to class name
??"unknown",
??"高風(fēng)速",
??"中風(fēng)速",
??"低風(fēng)速",
??"靜止",
};
int?Index;
main.c內(nèi)容
首先需要包含頭文件的內(nèi)容,存放輸入數(shù)組,輸出數(shù)組(各個分類的預(yù)測值),分類名以及最大預(yù)測值的索引值。
??MPU6050_Init(&hi2c2);
? neai_classification_init(knowledge);
初始化
調(diào)用MPU6050和NanoEdgeAI的初始化函數(shù),Knowledge這個數(shù)組的定義在knowledge.h中。
? ??for(int?i =?0;i<128-1;i++)
? ? ? {
? ? ? ? MPU6050_Read_All(&hi2c2, &mpu_data);
? ? ? ? memset(s,0,sizeof(s));
? ? ? ??sprintf(s,"%f %f %f ",mpu_data.Ax,mpu_data.Ay,mpu_data.Az);
? ? ? ??//CDC_Transmit_FS(s,strlen(s));
? ? ? ? Data[i*3+0] = mpu_data.Ax;
? ? ? ? Data[i*3+1] = mpu_data.Ay;
? ? ? ? Data[i*3+2] = mpu_data.Az;
? ? ? ? HAL_Delay(1);
? ? ? }
? ? ??sprintf(s,"%f %f %frn",mpu_data.Ax,mpu_data.Ay,mpu_data.Az);
? ? ? Data[127*3+0] = mpu_data.Ax;
? ? ? Data[127*3+1] = mpu_data.Ay;
? ? ? Data[127*3+2] = mpu_data.Az;
? ? ??//CDC_Transmit_FS(s,strlen(s));
? ? ? neai_classification(Data,output_class_buffer,&Index);
? ? ? CDC_Transmit_FS(id2class[Index], strlen(id2class[Index]));
? ? ? HAL_Delay(1);
? ? ? CDC_Transmit_FS("rn",?2);
接著采集我們的數(shù)據(jù),調(diào)用預(yù)測函數(shù)并利用串口輸出。