基于单片机的智能水质监测系统设计

收藏和点赞,您的关注是我创作的动力

概要

  水资源一直以来都是人类最重要的财富之一,由于工农业的发展人
们对水资源的污染变得越来越严重,保护水资源应势在必行。在这个科学技术日新月异的时代,嵌入式技术和物联网技术一直在发展未曾被淘汰便足以证明这些技术的优秀,结合现在的时代背景对水质检测的需求,水质检测对世界各国家的发展以及人们的生活至关重要。本文在以上基础上本文利用嵌入式技术和物联网技术设计一款基于 STM32F103C8T6单片机实现水质检测的功能,单片机外接 E-201 系列的 PH 传感器和TSW-30 浑浊度传感器采集数据然后通过单片机计算具体水质数据,再将水质数据显示到 LCD1602 液晶显示器上,并外接 ESP8266WIFI 模块通过单片机将水质数据实时传输到手机应用上显示,该设计与传统的水质检测相比有着采集效率高,实时性好,成本低等优点。同时,水资检测是保护水资源的重要手段之一,对人们的身体健康有着良好的保障,对国家的发展有着重要意义。

一、系统总体设计

1功能需求分析

本设计以单片机为基础对水质进行检测,需要实现显示功能、水质数据采集功能、无线通信功能,实现一个自动采集水质数据并显示出来的系统。
显示需求分析:
单片机较为常用的液晶显示屏主流有 LCD1602 和 LCD12864,这两款液晶显示器区别不大,显示内容上 LCD12864 比 LCD1602 能够呈现的信息更多,LCD12864能够显示中文,LCD1602 显示数字和英文更为方便,后者比前者相对便宜,且本设计用于显示大小对 LCD1602 已经足够,所以显示方面选择性价比更高的 LCD1602。
水质传感器需求分析:
水质可以检测的常见参数有 COD、氨氮、色度、浑浊度、PH 值等,但由于成本和技术上的问题,只能选取少量参数进行检测。
(1)COD 是水中的还原物被氧化需要的量,是一种化学检测方法,但一般用在工业级别的检测上,且会因使用的氧化剂会导致结果有所区别,故不选取。
(2)氨氮是检测由 NH3 和 NH4+ 在水中结合而成的化合物含量,这中化合物会导致水富营养化,这种检测仪器较为昂贵,设计成本太高所以不适用于本设计。
(3)色度是天然水或者对水中的悬浮物进行处理,然后进行检测其颜色的一种检测方式,但由于检测原理较为复杂,应用于单片机检测上难度较大,故也不选用
(4)PH 是指水中氢离子浓度,这种检测方式虽然也在工业上使用,且市面上的 PH 检测仪器无法进行二次开发,但却有成熟的 PH 检测模块可以配合 ph 测量电极使用,价格便宜,使用起来简单方便,可采用。
(5)浑浊度指水中悬浮物质的含量,检测原理是根据水对光线的穿透量的大小,虽然工业级的检测仪器价格高昂,但可采用洗衣机、洗碗机所使用的浑浊度传感器,这种传感器价格低廉,适合用于开发,可采用。
无线通信需求分析:
目前嵌入式使用比较多的无线通信技术有红外遥控、蓝牙、WIFI。红外遥控技术需要端口对接,受障碍物影响较大,而且传输距离较短;而蓝牙技术虽然没有了障碍物的影响,能够全方位地传输信息,但缺点是传输距离仍然较短,传输速率较慢;WIFI 相对以上两者,没有了那些缺点,传输距离和传输速率都有了明显的提升,以上三种技术中显然 WIFI是最适用的。

2原理图设计

STM32 最小系统由 STM32 芯片、晶振电路和复位电路组成,如图 3.5 所示。晶振电路的作用是为单片机提供合适的时钟信号流,就像人的心脏提供心跳,单片机才能运行,电路中两个电容是为了满足谐振要求,要想晶振电路能够工作正常,需要接上适当大小的电容。复位电路是上电复位电路,为低电平复位,电压升高,让系统恢复到初始状态。具体原理图如图 3.9 所示。
在这里插入图片描述

图3-4 STM32 最小系统
图 3.7 为稳压电路,AMS1117 是一款稳压芯片,用于转换电压。由于 USB 供电通常为 5V,而 STM32 需要 3.3V 供电,所以需要通过稳压电路将 5V 转换为 3.3V 给单片机提供电源,D3 二极管是肖特基二极管,它的主要作用是让电流只能从一个方向通过,保障电路正常工作。

二、程序流程图

本设计以 STM32 为核心,外接液晶显示模块、PH 传感器、浑浊度传感器、WIFI模块实现检测水质 PH 值和浑浊度,STM32 单片机通过 PH 传感器以及浑浊度传感器获取电压信号,然后单片机获取信号再将具体数据计算结果,将结果通过程序显示在 LCD1602,同时单片机利用 WIFI 模块发送水质的 PH 值和浑浊度数据,手机应用获取到具体数据并显示出来,具体程序流程图如图 4.1。开始时需要时钟初始化、IO 口初始化、串口初始化、液晶初始化等。其中获取 PH 值和浑浊度参数是通过单片机的采集电压而来的,然后算出实际数据

在这里插入图片描述

图4-1 程序流程图
图4.1为液晶显示的部分程序内容,其中调用函数 LCD_DisStr(0,0,“”)表示从第一行第一列开始显示数据,LCDW_Dat()显示水质数据的各位(个位、十位等)数据。
在这里插入图片描述

图4-2 液晶显示
STM32 单片机通过 WIFI 模块发送数据方式如图 4.3 所示,sendchar()为发送一段字符串,字符串中 S 表示发送起点,009 表示九个字节的数据,后面跟着的即为发送的数据,E 表示发送结束。
在这里插入图片描述

图4-3WIFI 发送

仿真电路图

如图5.1所示。
在这里插入图片描述

图5-1仿真电路图

三、 主要代码

主程序:
源代码:
#include "sys.h"
#include "delay.h"
#include "gpio.h"
#include "OLED_I2C.h"
#include "ds18b20.h"
#include "usart1.h"
#include "esp8266.h"
#include "adc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STM32_RX1_BUF       Usart1RecBuf 
#define STM32_Rx1Counter    RxCounter
#define STM32_RX1BUFF_SIZE  USART1_RXBUFF_SIZE

#define Offset 0.00	//deviation compensate
#define RATIO  4.51/4.08
short temperature=0;  //温度
u8    tempSetVal=40;  //温度上限
u8 shuaxin = 0;  //刷新标志
u8 setFlag = 0;  //设置标志
float PH  = 0.0;
u16 Ph_min = 300,Ph_max = 900;   //PH下限上限
u16 Turbidity=0;
u16 TurSetMax=1000;  //浊度上限
unsigned long int avgValue;	//Store the average value of the sensor feedback 

char display[16];

void Usart1RxBufClear(void) //清除串口接收缓存
{
	  memset(STM32_RX1_BUF, 0, STM32_RX1BUFF_SIZE);//清除缓存
		STM32_Rx1Counter = 0; 
}

void InitDisplay(void)   //初始化显示
{
	  unsigned char i=0;
	  
	  OLED_ShowStr(0, 2, "PH:", 2,0);
	  for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+0,0);//显示中文:温度
	  for(i=0;i<2;i++)OLED_ShowCN(i*16,6,i+2,0);//显示中文:浊度
	  OLED_ShowChar(32,4,':',2,0);
	  OLED_ShowChar(32,6,':',2,0);
}

void displaySetValue(void)  //显示设置的值
{
	  if(setFlag == 1 ||setFlag == 2)
		{
				sprintf(display,"%5.2f",(float)Ph_min/100); 
				OLED_ShowStr(40, 4,(u8 *)display, 2,setFlag+1-1);
			
				sprintf(display,"%5.2f",(float)Ph_max/100); 
				OLED_ShowStr(40, 6,(u8 *)display, 2,setFlag+1-2);
		}
		if(setFlag == 3)
		{
				sprintf(display,"%02d",tempSetVal); 
				OLED_ShowStr(40, 4,(u8 *)display, 2,setFlag+1-3);
		}
		if(setFlag == 4)
		{
				sprintf(display,"%04d",TurSetMax); 
				OLED_ShowStr(40, 4,(u8 *)display, 2,setFlag+1-4);
		}
}

void keyscan(void)   //按键扫描
{
	 unsigned char i=0;
	
	 if(KEY1 == 0) //设置键
	 {
			delay_ms(20);
		  if(KEY1 == 0)
			{
					while(KEY1 == 0);
				  BEEP=0;
				  setFlag ++;
				  if(setFlag == 1)
					{
							OLED_CLS();    //清屏
						  for(i=0;i<2;i++)OLED_ShowCN(i*16+32,0,i+8,0);//显示中文:设置
						  OLED_ShowStr(62, 0, " PH", 2,0);
						  for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+4,0);//显示中文:下限
							for(i=0;i<2;i++)OLED_ShowCN(i*16,6,i+6,0);//显示中文:上限
						  OLED_ShowChar(32,4,':',2,0);
						  OLED_ShowChar(32,6,':',2,0);
					}
					if(setFlag == 3)
					{
							for(i=0;i<2;i++)OLED_ShowCN(i*16+64,0,i+0,0);//显示中文:温度
						  OLED_ShowStr(56, 4, "    ", 2,0);
						  OLED_ShowCentigrade(56, 4);    //℃
						  OLED_ShowStr(0, 6, "                ", 2,0);
					}
					if(setFlag == 4)
					{
							for(i=0;i<2;i++)OLED_ShowCN(i*16+64,0,i+2,0);//显示中文:浊度
						  OLED_ShowStr(72, 4, "NTU", 2,0);
					}
					if(setFlag >= 5)
					{
						  setFlag = 0;
							OLED_CLS();    //清屏
						  InitDisplay();
						  
					}
					displaySetValue();
			}
	 }
	 if(KEY2 == 0) //加键
	 {
			delay_ms(100);
		  if(KEY2 == 0)
			{
					if(setFlag == 1)
					{
						  if(Ph_max-Ph_min > 10)Ph_min+=10;
					}
					if(setFlag == 2)
					{
							if(Ph_max < 1400)Ph_max+=10;
					}
					if(setFlag == 3)
					{
							if(tempSetVal<99)tempSetVal++;
					}
					if(setFlag == 4)
					{
						  if(TurSetMax<3000)TurSetMax+=10;
					}
					displaySetValue();   //显示没有设置值
			}
	 }
	 if(KEY3 == 0) //减键
	 {
			delay_ms(100);
		  if(KEY3 == 0)
			{
					if(setFlag == 1)
					{
						  if(Ph_min >= 10)Ph_min-=10;
					}
					if(setFlag == 2)
					{
							if(Ph_max-Ph_min > 10)Ph_max-=10;
					}
					if(setFlag == 3)
					{
							if(tempSetVal>0)tempSetVal--;
					}
					if(setFlag == 4)
					{
						  if(TurSetMax>=10)TurSetMax-=10;
					}
					displaySetValue();   //显示没有设置值
			}
	 }
}

void Get_PH(void)    //获取PH
{
	  u16 buf[10];//buffer for read analog
	  u8 i,j;	
	  float phValue=0.0;
	
		for(i=0;i<10;i++)	//Get 10 sample value from the sensor for smooth the value
		{
			buf[i]=Get_Adc_Average(ADC_Channel_8,10); 
		}
		for(i=0;i<9;i++)	//sort the analog from small to large
		{
				for(j=i+1;j<10;j++)
				{
						if(buf[i]>buf[j])
						{
							int temp=buf[i];
							buf[i]=buf[j]; 
							buf[j]=temp;
						}
				}
		}
		avgValue=0;
		for(i=2;i<8;i++)	//take the average value of 6 center sample 
		avgValue+=buf[i];
    phValue=((float)avgValue*5.0/4095/6)*RATIO; //convert the analog into millivolt
		PH=(phValue*(-5.290))+23.053;	//convert the millivolt into pH value 
		if(PH<0)PH=0;
		if(PH>14.0)PH=14.0;
}

void Get_Turbidity(void)   //获取浑浊度
{
		float T;
	  u16 adcx = 0;
	
	  adcx = Get_Adc_Average(ADC_Channel_9,20);//读取AD值
		T = adcx;
		T = T*(3.3/4096)+1.72;
		if(T < 2.5)
		{
				T = 3000;	
		}
		else 
		{
				T = (-1120.4*T*T+5742.3*T-4352.9);	//Tul是AD值
		}
		if(T < 0)
		{
			T = 0;
		}
		Turbidity = (u16)T;
		
		if(Turbidity > 3000)Turbidity = 3000;
}

void UsartSendData(void)    //串口发送数据
{
	  char SEND_BUF[100];
	  char BUF[50];
	 
	  memset(SEND_BUF,0,sizeof(SEND_BUF));      //清空缓冲区
	  sprintf(SEND_BUF,"PH:%5.2f\r\n",PH); 
	
	  memset(BUF,0,sizeof(BUF));      //清空缓冲区	
	  sprintf(BUF,"温度:%d℃\r\n",temperature);
    strcat(SEND_BUF,BUF);	
	
	  memset(BUF,0,sizeof(BUF));      //清空缓冲区	
	  sprintf(BUF,"浊度:%dNTU\r\n",Turbidity);
    strcat(SEND_BUF,BUF);	
	
	  strcat(SEND_BUF,"\r\n");
	  
	  ESP8266_SendData((u8 *)SEND_BUF, strlen(SEND_BUF));   //ESP8266发送数据
}

int main(void)
{
	  u16 timeCount1 = 300;
	  u16 timeCount2 = 10;
	  u8 shanshuo=0;
	
		delay_init();	           //延时函数初始化	 
    NVIC_Configuration();	   //中断优先级配置
	  I2C_Configuration();     //IIC初始化
	  delay_ms(200); 
	  Adc_Init();		  	      	//ADC初始化	
	  OLED_Init();             //OLED液晶初始化
	  OLED_CLS();              //清屏
	  OLED_ShowStr(0, 2,"   Loading...   ", 2,0);
	  ESP8266_Init();
	  OLED_CLS();              //清屏
	  InitDisplay();
		KEY_GPIO_Init();        //按键引脚初始化
	  DS18B20_GPIO_Init();
	  DS18B20_Init();         //初始化显示
	  uart1_Init(9600);
		while(1)
		{ 
			   keyscan();  //按键扫描
         timeCount1 ++;
			   if(timeCount1 >= 300 && !setFlag)   //延时一段时间读取
				 {
						timeCount1 = 0;
					 
					  shanshuo=!shanshuo;
					 
					  Get_PH() ;      //获取PH
					  /*超限的时候闪烁显示*/
					  if(((PH*100)<=Ph_min || (PH*100)>=Ph_max) && shanshuo)
						{
								OLED_ShowStr(32, 2,"     ", 2,0);
						}
						else
						{
								sprintf(display,"%5.2f ",(float)PH); 
								OLED_ShowStr(32, 2,(u8 *)display, 2,0);
						}
					 
					 
					  temperature = ReadTemperature();//读取温度
						/*超限的时候闪烁显示*/
						if((temperature>=tempSetVal) && shanshuo)
						{
								OLED_ShowStr(40, 4,"    ", 2,0);
						}
						else
						{
								sprintf(display,"%02d",temperature); 
								OLED_ShowStr(40, 4,(u8 *)display, 2,0);
							  OLED_ShowCentigrade(56, 4);    //℃
						}
					 
					  Get_Turbidity() ;
						/*超限的时候闪烁显示*/
						if((Turbidity>=TurSetMax) && shanshuo)
						{
								OLED_ShowStr(40, 6,"       ", 2,0);
						}
						else
						{
								sprintf(display,"%dNTU   ",Turbidity); 
								OLED_ShowStr(40, 6,(u8 *)display, 2,0);
						}
						
						if(((PH*100)<=Ph_min || (PH*100)>=Ph_max)||(temperature>=tempSetVal)||(Turbidity>=TurSetMax))BEEP= 1;else BEEP=0;  //超限蜂鸣器报警 
						timeCount2 ++;
						if(timeCount2 >= 3)
						{
								timeCount2 = 0;
							  UsartSendData();     //串口发送数据
						}
				 }
			   delay_ms(1);
		}
}





四、 内容截图

在这里插入图片描述
在这里插入图片描述

请添加图片描述
请添加图片描述
在这里插入图片描述

五、 文章目录

目 录

1 绪论………………………………………………………………………………1
1.1 研究背景…………………………………………………………………Y
1.2 国内外研究现状………………………………………………………………Y
1.3选题背景和研究内容……………………………………………………………Y
1.4本章小结………………………………………………………………Y
2 方案论证……………………………………………………………………Y
2.1 功能需求分析…………………………………………………………………Y
2.2技术应用概况…………………………………………………………………Y
2.3本章小结…………………………………………………………………Y
3 硬件设计………………………………………………………………………Y
3.1 芯片选型及系统框架……………………………………………………………Y
3.2原理图设计…………………………………………………………………Y
4 软件开发………………………………………………………………………Y
4.1 开发软件应用……………………………………………………………Y
4.2程序流程图…………………………………………………………………Y
5 综合测试………………………………………………………………………Y
5.1硬件测试……………………………………………………………Y
5.2功能测试…………………………………………………………………Y
6总结与展望………………………………………………………………………Y
致谢 …………………………………………………………………………………Y
参考文献……………………………………………………………………………Y
附录…………………………………………………………………………………Y

  • 12
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
无需任何TDS/pH计,即可构建自己的基于IoT的水质监测系统! 硬件部件: Arduino UNO×1个 公/母跳线×1个 HC-05蓝牙模块×1个 RGB扩散普通阴极×1个 电阻330欧姆×3 旋转电位器(通用)×1个 RGB LCD屏蔽套件,16x2字符显示×1个 电阻1k欧姆×1个 软件应用程序和在线服务:ArduinoIDEArdutooth 手动工具和制造机: 剥线钳和切割器,26-14 AWG单芯和绞线 什么是TDS? TDS代表总溶解固体。顾名思义,它可以使我们溶解在一定量的水中的固体数量,以ppm(百万分之一)为单位。TDS是根据电导率[S / m]计算的。电导率越高,TDS值越高。以下是不同类型的水的TDS值的列表: 纯净水:80-150 自来水:250-350 地下水:500-1000 海水:约30000 根据世界卫生组织(世界卫生组织)的建议,饮用水的TDS低于300。但是,TDS低于100的水不能食用,因为它缺乏必需的矿物质。高于300的水被认为过于“坚硬”,因为其中所含的矿物质过多。 通常,我们使用TDS笔来测量水的TDS。但是,我们无法将笔与Arduino集成在一起。因此,有可以与Arduino集成的特殊TDS仪表。但是,我决定在不使用TDS笔的情况下进行此项目。 Arduino的电路 将Arduino的5V连接到面包板的一个电源轨 将Arduino的地面连接到面包板的另一个电源导轨 将1k欧姆电阻的一端连接到地面,另一端连接到面包板。将Arduino上的模拟引脚A0连接到电阻器。最后,将一根线连接到电阻器,将另一根线连接到5V。将这些电线的自由端连接到鳄鱼夹。 液晶显示 将VSS引脚连接到接地轨 将VDD引脚连接到5V电源轨 将V0连接到电位计的中心引脚 将电位计的两端连接到5V并接地 将RS引脚连接到Arduino引脚7 将R / W引脚连接到Arduino引脚8 将D4连接到Arduino引脚10 将D5连接到Arduino引脚11 将D6连接到Arduino引脚12 将D7连接到Arduino引脚13 HC-05蓝牙模块 将VCC引脚连接到5V电源轨 将GND引脚接地 将TX引脚连接到Arduino引脚3(用作RX) 将RX引脚连接到Arduino引脚2(用作TX) RGB LED 将公共阴极(最长的引脚)接地 通过330欧姆电阻将红色引脚(阴极引脚的右侧)连接到Arduino的PWM引脚9 通过330欧姆电阻将绿色引脚(阴极引脚的左侧)连接到Arduino上的PWM引脚6 通过330欧姆电阻将蓝色引脚(最左侧)连接到Arduino上的PWM引脚5
### 回答1: 基于STM32单片机水质检测系统使用了先进的传感技术和智能算法,通过对水质参数进行采集和处理,能够准确地评估水质的好坏。 首先,STM32单片机作为微控制器,具有高性能和低功耗的特点,能够满足复杂的水质检测需求。它可以连接各种传感器,如PH传感器、溶解氧传感器、浊度传感器等,实时采集水质参数。 其次,通过STM32单片机的AD转换功能,可以将传感器采集到的模拟信号转换为数字信号,提高了数据的准确性和精度。 然后,STM32单片机搭载了先进的智能算法,可以对采集到的数据进行分析和处理。它能够判断水质是否符合标准,比如判断PH值是否在合适范围内、溶解氧浓度是否达到要求等。 此外,STM32单片机可以通过与外部设备的通信接口,如UART、SPI、I2C等,将检测结果实时传输到显示屏上或者通过无线通信发送到云端,实现远程监测和数据共享。 总的来说,基于STM32单片机水质检测系统具有高性能、低功耗、准确度高和智能化等特点,能够满足水质检测的要求,有助于保障水质安全和环境保护。 ### 回答2: 基于STM32单片机水质检测系统可以通过检测、分析和监控水质指标来评估水的质量。该系统可以使用多种传感器来检测水中的各种参数,例如pH值、溶解氧浓度、温度、浊度和电导率等。采集到的数据可以通过STM32单片机进行处理和分析,并利用LCD显示屏或者其他输出设备将结果展示出来。 在STM32单片机水质检测系统中,传感器是关键的部件之一。它们能够实时监测水质指标,并将数据传送给STM32单片机进行处理。通过使用合适的模拟和数字转换技术,传感器可以将实际的物理量转换为数字信号,方便STM32单片机进行处理。 STM32单片机可以通过使用合适的算法和数据处理技术,对采集到的水质数据进行分析。例如,可以使用滤波算法来去除噪声,使用校准曲线来将传感器输出转换为实际测量值,并使用数据处理算法来判断水质是否符合标准。 此外,STM32单片机还可以通过和其他外部设备进行通信,实现水质参数的即时监控和远程控制。例如,可以通过无线通信方式将数据发送到上位机进行保存和分析,或者通过网络通信方式实现远程监控和控制。 基于STM32单片机水质检测系统具有灵活性和可扩展性,可以根据实际需求进行定制和扩展。同时,STM32单片机具有低功耗、高性能和丰富的外设接口等特点,适合于工业应用和物联网应用场景。 ### 回答3: 基于STM32单片机水质检测系统是一种可以实时监测和分析水质状况的设备。它主要通过测量水体中的各种指标来评估水质,包括pH值、溶解氧、浊度、电导率等。 该系统使用STM32单片机作为核心控制器,通过采集外部传感器的数据来实现水质指标的测量。传感器测量到的数据通过STM32单片机进行处理和分析,然后通过显示屏或者无线通信模块将结果显示出来。 具体来说,STM32单片机从传感器获取各项数据,并进行数据处理和校准,例如利用pH标定溶液校准pH传感器。然后,单片机会根据预设的阈值和标准对测量数据进行比较和评估,判断水质是否达到标准要求。 基于STM32单片机水质检测系统具有快速、准确和可靠的特点。它可以广泛应用于水质监测领域,包括水处理厂、饮用水供应、农田灌溉等。同时,该系统在实时性上也具有优势,可以及时监测水质异常情况,并采取相应的措施,以保障水质安全。 总之,基于STM32单片机水质检测系统是一种高效、稳定的设备,它能够帮助我们实时了解和监测水质,并采取相应措施,从而保护我们的健康和环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值