在这里记录一下我正在进行中的小项目,也可供大家参考(能力有限,大佬勿喷)
继续之前的雏形,这次将它进行了完善,首先看一下设计的结构图
一、硬件的选用:
主控芯片:stm32F103zet6
传感器部分:HX711与承重传感器
显示部分:HMI 串口屏
语音辅助:M6语音识别播报模块
无线传输:nRF24L01转ttl无线模块
相较于雏形篇,这次的改进的重心在:主控芯片的修改(STM32)、整体程序逻辑的改善、系统整体延时和错误率降低、从而使得整体设计使用起来更加顺畅,更贴近实用,下面是程序流程图介绍:
二、核心逻辑为:
1、等待皮重输入(因为在实际中药液的容器分为很多规格,尤其是PVC型和玻璃型容器皮重差距太大,所以在监测之前先进行皮重的输入,本次程序预设了两种皮重,并可以手动输入皮重,用来后期进行消除)
2、开始药液监测(本次使用的称重传感器量程为1kg精度为1g,所以采用了每隔一秒采集一次,计算流速、进度、倒计时数据的方法进行监测,虽采样率不高,但是应用于本设计,还是适用的)
3、数据的传输(本次采集到的流速、进度、倒计时等数据会实时体现在三个方面,第一是下位机串口屏幕上、第二是上位机的PC软件中、第三是语音识别后的播报中)
三、重点问题与解决方案:
如何通过测量药液重量来实现:流速、进度、倒计时等信息的获取?
1、手动输入或选用预设的皮重为 Z,这一步是为了消除容器的质量
2、测量初始药液重量(已去皮)为A,进入while循环,测 现一秒的重量为B,下一秒的重量为C,以此类推,从而实现每隔一秒测一次重量
3、流速 = B – C 得到一个单位为 g/s 的 流速数值
4、进度百分比 = C*100/A 得到一个单位为 % 的 进度数值
5、C / 流速 = 倒计时 得到一个单位为 s 的 倒计时数值
如何实现数据的无线传输与PC对多个下位机的数据接收?
首先是在硬件的选择上,选用了nRF24L01无线传输模块,只需单片机通过串口向其发送数据,但是为了实现PC端对多个下位机的数据接收,我选择每个下位机都以一个八位字符串来进行发送数据:1、2位为设备号, 3、4位为流速信息,5、6位为进度信息, 7、8位为倒计时信息。并且上位机软件利用LabVIEW进行编写,上位机开启后会依次按顺序对各个下位机发送启动信号,当下位机接到此信号则进行数据发送,在上位机处对这个八位字符串进行采集,截取,分割,根据1、2位设备号的不同,送入不同的条件分支中,再进行判断与报警
四、程序编写时遇到的困难与解决方案: 如何使得一个发送来的两位字符串转换成数据变量形式参与运算? 首先,我们的Keil5编译软件在编写stm32时无法调用string等相关语法和函数,因为它是C++的内容,这就使得我们在编写时根本无法定义一个字符串,也就是无法很简单的一次接收多位字符串,并且这个字符串如果想参与运算时,必须转换成其他变量才可以,否则将会自动转为ASCII码,在这里我利用了switch-case很方便的解决了这个问题,部分程序如下 - void changeA(void);
- void changeB(void);
- while(1)
- {
- a=getchar();//接收第一个字符
- a=getchar();//确保接收成功
- b=getchar();//接收第二个字符
- changeA ();//通过子程序将这个字符转换成整形数
- changeB ();//通过子程序将这个字符转换成整形数
- z=x*10+y; //第一个整形数为十位,第二个为个位,组成这个两位数
- }
- 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;
- }
- }
复制代码 如何使得字符串与整形变量一并发出去?
首先在编写STM32时,printf函数只能定向在一个串口上,在调用其他串口发送数据时,我们又怎么才能将一个字符串与一个实时变化的变量一并发送呢,在这里选择直接组成数组,将数组发送出去,如下:- void Sends(char *buf1);
- char A[10] = ""; //定义一个容量为10的数组
- while(1)
- {
- sprintf(A,"n1.val=%d",liusu); //发送格式化输出到 str 所指向的字符串
- Sends(A); //发送数组
- }
-
- void Sends(char *buf1) //发送函数
- {
- u8 i=0;
- while(1)
- {
- if(buf1[i]!=0)
- {
- USART_SendData(USART3,buf1[i]); //发送一个字节
- while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET){};//等待发送结束
- i++;
- }
- else
- return ;
- }
- }
复制代码 五、成果部分
实物主体部分 PC上位机界面 下位机串口屏界面
全部资料51hei下载地址:
输液监测装置.zip
(13.05 MB, 下载次数: 146)
|