博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于电应普超声波液位传感器的液位控制系统
阅读量:3950 次
发布时间:2019-05-24

本文共 3147 字,大约阅读时间需要 10 分钟。

项目目的

本项目是水藻过滤自动填装原液装置,通过对水箱内的液位进行探测,满足条件时输出一个水泵驱动信号,添加过滤后的水,进一步进行处理提高过滤纯度,由于过滤后的藻类留存在水箱中,水箱内的液位不断上升,所以没有固定的液位作为阈值启停水泵。

实现方案

本项目使用超声波传感器作为液位测量的工具,读取到距离信息后通过串口回传数据,STM32将距离信息显示在OLED屏幕上,当测得的距离高于80cm即液位过深,此时水箱中的水位过低,达到启动水泵加水的条件,输出启动信号。当测得的距离低于30cm,水位过高,达到水箱上限,关闭水泵。当液位在一个大于50cm的值保持过久,系统判定此时为藻类留存抬高水位,满足启动水泵加水。

问题与复盘

本项目实现顺序为点亮OLED-串口通信实现-数据转码-控制算法

OLED的点亮

本次项目使用了IIC ,SPI 两种OLED屏幕进行测试,并更换STM32与C51平台进行测试,测试结果都无法驱动OLED,检查电源SCL,SDA都有信号,难以排查问题。但基本确认硬件平台出现问题的可能性很低,在更换一块新的OLED后,开始对软件代码进行排查,发现中景园提供的部分代码的时序与STM32提供例程中的IIC有几个延时的误差,中景园没有提供延时,有两种方案,一、确保32例程IIC的可靠性后对相关时序代码进行移植,二、重新找一个OLED程序,在此基础上开始后续工作的开展。出于方便考虑我选择了第二种,重新在51黑上下载了项目工程之后,发现成功驱动了OLED屏幕。

 

在调节UI的过程中,发现输入其他中文后(此项目原本就有中文显示)屏幕不再点亮,应该是其字库中未包括输入的汉字,使用英文正常,便使用英文作为UI的界面

 

目前需要在此工程上开展后续的工作,有两个方案,一、在此工程上添加串口,按键等代码,二、将IIC部分转移至原有的一个工程,其中有调试完毕的串口起始帧处理。最终选择方案二,将OLEDiic和OLEDh文件转移至原工程,至此OLED显示工作已完毕,可以正常显示项目UI界面。

 

串口调试

超声波传感器传输的数据为4个八位数据,第一位为0xff 起始帧,数据高八位,数据低八位,校验位,波特率为9600。因此在串口接收中断处理函数中需要对起始帧进行判断,由于没有结束帧,但由于每一组数据为固定长度,所以可以在起始帧后计数的方式完成一组数据的读取存放。

具体代码为:

  1. 1	void UART4_IRQHandler(void)			2	{3	u8 r;4	5		if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) 6		{7			r =USART_ReceiveData(UART4);//(USART1->DR);	8			if((USART4_RX_STA&0x8000)==0)9			{10				if(USART4_RX_STA&0x4000)//如果第七位被置高说明此时已检测到起始帧11				{12					if(t<=3)	//检测到起始帧且位数不到三个13					{	14						t++;			15						USART4_RX_BUF[t&0X3FFF]=r;//自加并存入数组16	17					}18					else 19					{20						USART4_RX_STA|=0x8000;	//读取位数到三个之后将第八位置高作为                 21	                                      //一组数据接收完成的标志22						t=0;23					}24				}25				else26				{	27					if(r==0xFF)//检测起始帧28						USART4_RX_STA|=0x4000;//检测到之后将计数的第七位置高29					else30					{31						USART4_RX_STA++;32						if(USART4_RX_STA>(USART4_REC_LEN-1))//过长时间没检测到 接收错误清零33						USART4_RX_STA=0; 34					}		 35				}36			}37			else38				USART4_RX_STA=0;//数据接收完成后清零39		} 40	}

     

以上程序完成对起始帧为0xff,后有连续三帧的数据的收取。

值得注意的是 t计数起始帧后收取的帧数和USART4_RX_STA 一样需要进行全局变量的定义 extern u8 t;这样避免了每次出中断处理函数之后会被清零的问题,这个问题导致只能计数到1便被清零。

串口调试推荐在debug模式下进行调试,可以逐行运行查看计数逻辑和条件进入是否有问题,但逐行调试会无法抓取连续的帧,将待观察的量添加到watch。

小插曲部分:在想要Debug时出现一个小问题,尝试debug时,出现flash download的报错,option-debug-setting-flash download没有单片机对应flash下载算法,这个是报错的直接原因。点击ADD也找不到STM32F103ZET对应的算法。推测可能是芯片包的问题,进行了重新的下载安装,甚至将keil5重新下载后安装原始的stm32F1系统的支持包,打开原工程在option-device中任未找到对应的芯片型号,但在芯片包中已经安装芯片。如果重新建立工程可以选择STM32F1的芯片,在原工程中却无法更换此芯片。

至此我意识到问题的根源和我想象的不一样,一番搜索中找到了类似的情况,推测应该是keil4和keil5的问题,这个工程一打开就有版本不对应的报错,如果此时选择上面的按钮,就能升级到kei5就可以使用keil5的芯片包,之前没找到是因为没有对keil4进行对应芯片包的下载。更新完工程后成功实现代码的debug。

数据转码

接收到的数据为16进制,要使其在OLED屏幕上进行十进制数据的显示,需要进行处理,此处用到了一个很巧妙的方式进行处理。

u16 hex2uint(void *a) //16进制转10进制{	return *(u16 *)a;}

此处用了强制类型转换,对四位16进制数据进行拼接,使其显示时为十进制,输出至OLED屏。

因为这是传感器传回的数据,是直接的二进制数据,所以使用强制类型转换和字符拼接的方式是可行的。有的时候,输入的数据为ASCII码,此时需要进行的处理不能使用此方式,如在另一个单片机系统或者操作系统上位机传回的数据,很可能是字符串或ASCII码,此时需要使用其他方式先取出各位的数值,再进行转换。

控制算法

到此系统已实现,实时显示串口传回的数据在OLED屏上,目前需要根据数据确定水泵的启停,很简单的直接的方式为用define设定最大值和最小值。在达到最大值时启动,最小值时暂停。

至于变化过小的停止检测使用以下的平均值求差的策略。

if(dis>=waterM)//waterM的值为500介于H=800和L=300之间	{		sum=sum+dis;		countime++;		avg=sum/countime;//计算每一时刻的平均值		delta=dis-avg;		if(delta<=10)//变化小于1cm时进行计数		holdtime++;		if(holdtime>=300)//持续时长可以通过修改holdtime来改变		{			enginON();			holdtime=0;		}	}

持续时长过长便会判定为水位不变,需要重新加水。

转载地址:http://fduzi.baihongyu.com/

你可能感兴趣的文章
快收藏! 30 分钟包你学会 AWK
查看>>
各平台的推荐算法,太贴切了!
查看>>
一张图学会Python3
查看>>
500款各领域机器学习数据集,总有一个是你要找的
查看>>
2017年终奖调查出炉 程序员年终奖多少你绝对猜不到
查看>>
使用 Charles 抓取 app 数据包
查看>>
未来,改变世界的将是这些......
查看>>
2018年大数据趋势
查看>>
大数据揭示年度学霸画像:大家都在学什么?
查看>>
各领域机器学习数据集汇总(附下载地址)
查看>>
如何运用Python建一个聊天机器人?
查看>>
人民日报:让中国大数据跑起来!
查看>>
百度地图大数据告诉你一线城市真相
查看>>
大数据 勾勒中国人“的亲情地图”!
查看>>
500款各领域机器学习数据集,总有一个是你要找的
查看>>
大数据读心术丨这15条数据统计准爆了!
查看>>
大数据预测报告:2018年春节长假居民最喜欢去这些地方
查看>>
趣图:有时候我写的代码,就是这样子的
查看>>
大数据读心术丨这15条数据统计准爆了!
查看>>
500款各领域机器学习数据集,总有一个是你要找的
查看>>