在這里記錄一下我正在進行中的小項目,也可供大家參考(能力有限,大佬勿噴)
繼續(xù)之前的雛形,這次將它進行了完善,首先看一下設(shè)計的結(jié)構(gòu)圖
一、硬件的選用:
主控芯片:stm32F103zet6
1.png (99.67 KB, 下載次數(shù): 69)
下載附件
2019-12-8 01:53 上傳
傳感器部分:HX711與承重傳感器
99.jpg (8.39 KB, 下載次數(shù): 78)
下載附件
2019-12-8 01:54 上傳
2.png (72.35 KB, 下載次數(shù): 73)
下載附件
2019-12-8 01:53 上傳
顯示部分:HMI 串口屏
3.jpg (30.03 KB, 下載次數(shù): 78)
下載附件
2019-12-8 01:53 上傳
語音輔助:M6語音識別播報模塊
4.png (119.91 KB, 下載次數(shù): 66)
下載附件
2019-12-8 01:53 上傳
無線傳輸:nRF24L01轉(zhuǎn)ttl無線模塊
相較于雛形篇,這次的改進的重心在:主控芯片的修改(STM32)、整體程序邏輯的改善、系統(tǒng)整體延時和錯誤率降低、從而使得整體設(shè)計使用起來更加順暢,更貼近實用,下面是程序流程圖介紹:
5.png (64.58 KB, 下載次數(shù): 64)
下載附件
2019-12-8 01:53 上傳
二、核心邏輯為:
1、等待皮重輸入(因為在實際中藥液的容器分為很多規(guī)格,尤其是PVC型和玻璃型容器皮重差距太大,所以在監(jiān)測之前先進行皮重的輸入,本次程序預(yù)設(shè)了兩種皮重,并可以手動輸入皮重,用來后期進行消除)
2、開始藥液監(jiān)測(本次使用的稱重傳感器量程為1kg精度為1g,所以采用了每隔一秒采集一次,計算流速、進度、倒計時數(shù)據(jù)的方法進行監(jiān)測,雖采樣率不高,但是應(yīng)用于本設(shè)計,還是適用的)
3、數(shù)據(jù)的傳輸(本次采集到的流速、進度、倒計時等數(shù)據(jù)會實時體現(xiàn)在三個方面,第一是下位機串口屏幕上、第二是上位機的PC軟件中、第三是語音識別后的播報中)
三、重點問題與解決方案:
如何通過測量藥液重量來實現(xiàn):流速、進度、倒計時等信息的獲取?
1、手動輸入或選用預(yù)設(shè)的皮重為 Z,這一步是為了消除容器的質(zhì)量
2、測量初始藥液重量(已去皮)為A,進入while循環(huán),測 現(xiàn)一秒的重量為B,下一秒的重量為C,以此類推,從而實現(xiàn)每隔一秒測一次重量
3、流速 = B – C 得到一個單位為 g/s 的 流速數(shù)值
4、進度百分比 = C*100/A 得到一個單位為 % 的 進度數(shù)值
5、C / 流速 = 倒計時 得到一個單位為 s 的 倒計時數(shù)值
如何實現(xiàn)數(shù)據(jù)的無線傳輸與PC對多個下位機的數(shù)據(jù)接收?
首先是在硬件的選擇上,選用了nRF24L01無線傳輸模塊,只需單片機通過串口向其發(fā)送數(shù)據(jù),但是為了實現(xiàn)PC端對多個下位機的數(shù)據(jù)接收,我選擇每個下位機都以一個八位字符串來進行發(fā)送數(shù)據(jù):1、2位為設(shè)備號, 3、4位為流速信息,5、6位為進度信息, 7、8位為倒計時信息。并且上位機軟件利用LabVIEW進行編寫,上位機開啟后會依次按順序?qū)Ω鱾下位機發(fā)送啟動信號,當下位機接到此信號則進行數(shù)據(jù)發(fā)送,在上位機處對這個八位字符串進行采集,截取,分割,根據(jù)1、2位設(shè)備號的不同,送入不同的條件分支中,再進行判斷與報警
6.png (121.58 KB, 下載次數(shù): 61)
下載附件
2019-12-8 01:53 上傳
四、程序編寫時遇到的困難與解決方案: 如何使得一個發(fā)送來的兩位字符串轉(zhuǎn)換成數(shù)據(jù)變量形式參與運算? 首先,我們的Keil5編譯軟件在編寫stm32時無法調(diào)用string等相關(guān)語法和函數(shù),因為它是C++的內(nèi)容,這就使得我們在編寫時根本無法定義一個字符串,也就是無法很簡單的一次接收多位字符串,并且這個字符串如果想?yún)⑴c運算時,必須轉(zhuǎn)換成其他變量才可以,否則將會自動轉(zhuǎn)為ASCII碼,在這里我利用了switch-case很方便的解決了這個問題,部分程序如下 - void changeA(void);
- void changeB(void);
- while(1)
- {
- a=getchar();//接收第一個字符
- a=getchar();//確保接收成功
- b=getchar();//接收第二個字符
- changeA ();//通過子程序?qū)⑦@個字符轉(zhuǎn)換成整形數(shù)
- changeB ();//通過子程序?qū)⑦@個字符轉(zhuǎn)換成整形數(shù)
- z=x*10+y; //第一個整形數(shù)為十位,第二個為個位,組成這個兩位數(shù)
- }
- void changeA ()
- {
- switch(a)
- {
- case '0': x=0;
- break;
- case '1': x=1;
- break;
- case '2': x=2;
- break;
- case '3': x=3;
- break;
- case '4': x=4;
- break;
- case '5': x=5;
- break;
- case '6': x=6;
- break;
- case '7': x=7;
- break;
- case '8': x=8;
- break;
- case '9': x=9;
- break;
- }
- }
- void changeB ()
- {
- switch(b)
- {
- case '0': y=0;
- break;
- case '1': y=1;
- break;
- case '2': y=2;
- break;
- case '3': y=3;
- break;
- case '4': y=4;
- break;
- case '5': y=5;
- break;
- case '6': y=6;
- break;
- case '7': y=7;
- break;
- case '8': y=8;
- break;
- case '9': y=9;
- break;
- }
- }
復(fù)制代碼 如何使得字符串與整形變量一并發(fā)出去?
首先在編寫STM32時,printf函數(shù)只能定向在一個串口上,在調(diào)用其他串口發(fā)送數(shù)據(jù)時,我們又怎么才能將一個字符串與一個實時變化的變量一并發(fā)送呢,在這里選擇直接組成數(shù)組,將數(shù)組發(fā)送出去,如下:- void Sends(char *buf1);
- char A[10] = ""; //定義一個容量為10的數(shù)組
- while(1)
- {
- sprintf(A,"n1.val=%d",liusu); //發(fā)送格式化輸出到 str 所指向的字符串
- Sends(A); //發(fā)送數(shù)組
- }
-
- void Sends(char *buf1) //發(fā)送函數(shù)
- {
- u8 i=0;
- while(1)
- {
- if(buf1[i]!=0)
- {
- USART_SendData(USART3,buf1[i]); //發(fā)送一個字節(jié)
- while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET){};//等待發(fā)送結(jié)束
- i++;
- }
- else
- return ;
- }
- }
復(fù)制代碼 五、成果部分
實物主體部分
7.png (228.34 KB, 下載次數(shù): 84)
下載附件
2019-12-8 01:53 上傳
PC上位機界面
8.png (337.77 KB, 下載次數(shù): 69)
下載附件
2019-12-8 01:53 上傳
下位機串口屏界面
9.png (127.25 KB, 下載次數(shù): 71)
下載附件
2019-12-8 01:53 上傳
10.png (137.71 KB, 下載次數(shù): 70)
下載附件
2019-12-8 01:53 上傳
11.png (102.3 KB, 下載次數(shù): 63)
下載附件
2019-12-8 01:53 上傳
全部資料51hei下載地址:
輸液監(jiān)測裝置.zip
(13.05 MB, 下載次數(shù): 146)
2019-12-8 01:24 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|