前述:
QQ:3177227373
V X:F9986858
主要内容
研究泳池水质监控系统的整体结构设计,包括总体方案设计、软硬件总体设计等,要求监控泳池水温度、PH值、浑浊度等。
以单片机为主要控制器件,主要包括硬件电路的设计和系统程序的设计。硬件电路主要包括传感器的选取,单片机的选取与应用,A/D转换的选用,电源设计,显示部分设计等;软件设计主要包括主程序设计和子程序设计,监测结果通过显示模块显示。
系统硬件结构设计
单片机的选择
泳池监控系统的核心是微处理器,对处理器的选型将直接决定系统的性能及总体开发方式。选型的主要标准有:
1、具有较高的计算能力;
2、具备与其他设备的通信接口;
3、整体功耗较低等。
根据获取和软件开发的难易程度,经过初步的筛选,基本在MSP430单片机,51单片机和其他PIC中进行选择。根据前文对低功耗要求,首先要选择的是具备低功耗模式且运算速度较快的芯片。
从供电电压上来看,MSP430的最低工作电压为3.3V,51单片机及其他PIC为5V,在工作电压的需求方面,与其他单片机相比,MSP430对电压的要求较低,可以更好的降低功率。另外,MSP430自身带有5种低功耗模式,可以根据不同的实际情况选择对应的低功耗模式,在程序设计上可以根据实际需要关闭闲置的模块,来达到低功耗的目的。在本次筛选对比MSP430系列的单片机低功耗以及运算能力方面有着相当的优势。
根据对比筛选得出,本设计选择MSP430芯片作为主控芯片。根据前人的设计证明,以及MSP430价格上的优势加上片内资源丰富,MSP 430能够很好的完成智能监控的主控功能。整个数据采集处理流程为,传感器模块将采集到的模拟信号经过A/D模块转化为数字信号传至MSP430芯片中,MSP430芯片对传来的信号进行分析和处理,实现对采集信息的显示以及对控制端的控制。
本设计主控芯片采用的是MSP430系列单片机中的f149型号。该单片机在程序设计、开发调试及实际应用上都具有明显的优点。具有方便、便宜、实用等优点,给用户提供了一个理想的样机开发方式。MSP430主控芯片特点:1、处理能力强;2、运算速度快;3、超低功耗;4、折叠片内资源丰富;5、开发环境简单。
传感器选择
温度传感器:
经常用到的温度传感器类型有、半导体、热电偶、热敏电阻等,其中半导体测温元件又分为电压型、电流型和数值型。DS18B20传感器为数值型温度传感器、其具备了导线少、体积小以及使用方便等特点。虽然它有0.5℃的固有测温误差为,但是考虑到作为泳池水质的温度采集,0.5℃的误差是可以接受的,其优点远大于缺点。因此本设计采用DS18B20数字温度传感器。
DS18B20温度传感器输出数字信号,通过程序编辑设置可选择数字值的位数(9-12位),本设计基于泳池水环境的实际使用情况,选择DS18B20的防水封装,该封装类型可以直接将传感器安装与水中,且体积小安装方便。
PH值传感器:
PH值的测量,主要由指示电极和参考电极构成。目前主要的指示电极有两大类,分别为金属电极和玻璃电极。在实际应用中由于各种原因,金属电极仅仅在工业测量中使用。而玻璃电极在实验测量和工业测量中都有比较广泛的应用。
在PH值测量中玻璃电极和金属电极都具有比较良好的复现性,都存在可以接受的测量误差,都能够较为准确的测量出被测溶液的PH值。经过各两类电极的比较,本设计采用玻璃电极传感器采集泳池水中的PH值。
水浊度传感器:
游泳池水质在正常营业过程中随着游泳人员越来越多加上所处的自然环境,水中出现越来越多的悬浮颗粒,从而导致水质被污染。对水浊度进行检测主要是检测水中悬浮颗粒的含量。
本设计选用的浊度传感器为红外传感器,内部有封装的红外对管。对管平行放置于泳池的水环境中,通过红外对管发射端发出光线,红外对管接收端把透过的光强度转化为电流。水中悬浮颗粒会挡住红外传感器发出的一部分光线,使光线的强度发生改变。水中的悬浮颗粒越多则水浊度越高,透过光线的强度则越弱,接收端转化出来的电流也越小。相反,水浊度越高,透光性越强则电流越大。所以可以通过对浊度传感器电流的检测,完成对泳池水浊度的监测。
系统软件结构设计
主程序是程序设计的主干,在主程序的调控下完成整体的工作。本设计实际流程为:打开开关,单片机通电,首先进行系统初始化,LCD显示屏进入欢迎界面,2秒钟后进入系统测量程序,屏幕实时显示测量的值,整个系统开始正常工作。主程序流程如图所示。
实物照片
仿真
PCB
部分代码
浑浊度计算
//浑浊度计算
void TURB_Date()
{
//浑浊度获取并计算
Dat1=ReadADC(1);
TU= 不展示核心代码;//计算电压
temp_data=shi*10+ge;//计算温度
TU_calibration=不展示核心代码;//温度补偿
TU_value=不展示核心代码;//转换公式
if(TU_value<=0){TU_value=0;}
if(TU_value>=3000){TU_value=3000;}
TU_Val=(int)TU_value/30;//计算为百分比
}
PH值计算
//PH值计算
void PH_Date()
{
//PH值获取并计算
Dat2=ReadADC(0);
ADC_Voltage_1=不展示核心代码;//转换为电压值
PH_Value=不展示核心代码;//转换公式
if(PH_Value<=0){PH_Value=0;}
if(PH_Value>=14){PH_Value=14;}
Disbuff_PH[0]=(int)(PH_Value*100)/1000;
Disbuff_PH[1]=(int)(PH_Value*100)%1000/100;
Disbuff_PH[2]=(int)(PH_Value*100)%100/10;
Disbuff_PH[3]=(int)(PH_Value*100)%10;
PH_DAT=Disbuff_PH[0]*1000+Disbuff_PH[1]*100+Disbuff_PH[2]*10+Disbuff_PH[3];
}
LCD1602显示
void LCD_Init()//液晶初始化
{
u8 i;
LCD_WR=0;
LCD_Write_Cmd(0x38);//设置16*2显示,5*7点阵,8位数据接口
LCD_Write_Cmd(0x0c);//设置开显示,0x0e显示光标 0x0c不显示光标
LCD_Write_Cmd(0x06);//写一个字符后地址指针自动加1,光标自动右移
LCD_Write_Cmd(0x01);//清屏
LCD_Write_Cmd(0x80);//数据指针定位到第一行第一个字处
for(i=0;i<16;i++)
LCD_Write_Data(str1[i]);//液晶显示第一行写数据
LCD_Write_Cmd(0xc0);//数据指针定位到第二行第一个字处
for(i=0;i<16;i++)
LCD_Write_Data(str2[i]);//液晶显示第二行写数据
}
//LCD1602显示函数
void LCD_Manifest(u8 row,u8 add,u8 date)
{
if(row==1) LCD_Write_Cmd(0x80+add);
if(row==2) LCD_Write_Cmd(0xc0+add);
LCD_Write_Data(0x30+date);
}
void LCD_Write_Cmd(u8 com)//液晶写命令
{
LCD_RS=0;//选择写命令模式
Date=com;//将要写的命令字送到数据总线上
delay_ms(1);
LCD_E=1;//使能端给一高脉冲,高脉冲有效
delay_ms(1);
LCD_E=0;
}
void LCD_Write_Data(u8 date)//数据写命令
{
LCD_RS=1;//选择写数据模式
Date=date;
delay_ms(1);
LCD_E=1;//使能端给一高脉冲,高脉冲有效
delay_ms(1);
LCD_E=0;
}
ADC采集
//读取AD模数转换的值,有返回值
unsigned char ReadADC(unsigned char Chl)
{
unsigned char Data;
Start(); //写入芯片地址
Send(0x90);
Ack();
Send(0x40|Chl);//写入选择的通道,Chl的值分别为0、1、2、3,分别代表1-4通道
Ack();
Start();
Send(0x91); //读入地址
Ack();
Data=Read(); //读数据
Scl=0;
NoAck();
Stop();
return Data; //返回值
}
DS18B20温度采集
void Tem_display(u16 temp)
{
float tp;
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=不展示核心代码;
//留一个小数点就*10,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
shi = temp % 1000 / 100; //显示温度十位数
ge = temp % 100 / 10; //显示温度个位数
xs = temp % 10; //显示小数一位
Temp_Now=(u16)temp%1000;
}
//读取温度
int Ds18b20ReadTemp()
{
int temp=0;
u8 tmh,tml;
Ds18b20ChangTemp(); //先写入转换命令
Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
tml=Ds18b20ReadByte(); //读取温度值共16位,先读低字节
tmh=Ds18b20ReadByte(); //再读高字节
不展示核心代码
return temp;
}