基于STM32的水质检测系统设计与实现

基于STM32的水质检测系统设计

最近参加校赛做的基于STM32的水质检测系统设计,进行一些简单记录吧

一、题目要求

说明:(溶解氧浓度的硬件太贵就没做这个)
功能如下:
1.通过TFT屏实现实时各数据,可进行多级菜单切换
2.可以通过按键进行温度、PH、采集频率调节
3.可以通过语音控制温度、PH、采集频率的调节(SU-03T语音模块)
4.通过ESP8266将采取的数据上传到Onenet云端
5.采取的数据超过设置阈值会进行报警提示
6.大气压采取BMP180模块
成品展示

二、硬件材料

STM32F103C8T6最小系统一块 x1
语音模块(SU-03T) x1
ESP8266wifi模块 x1
BMP180大气压模块 x1
DS18B20温度传感器带探针 x1
蜂鸣器 x1
TFT3.5显示屏 x1
TDS传感器水电导率 x1
不可充式电极探头PH传感器 x1
杜邦线 若干
按键 x4
STM32F103C9T6最小系统

SU-03T语音模块

PH传感器模块(这个相对来说比较贵60几吧)

ESP8266模块

TDS传感器

BMP180大气压传感器

DS18B20温度传感器

TFT显示屏

蜂鸣器

三、部分代码

/*-----------------------main.c------------------*/
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "lcd_init.h"
#include "beep.h"
#include "time.h"
#include "ds18b20.h"
#include "adc.h"
#include "bmp180.h"
#include "iic.h"

//外设层
#include "oled.h"
#include "usart.h"
#include "esp8266.h"
//网络协议层
#include "onenet.h"

//网络设备
#include "esp8266.h"
//c库
#include "string.h"

/*---------------------------------水质检测系统-----------------------------------*
Author:slow-walker
Date:2022-10-26
功能:
1.实时数据显示TFT屏 2.OneNet云平台数据显示(ESP8266远端传输) 3.ST-03T语音控制  4.按键调节

----------------------------------------------------------------------------------*/

/*--------------------------------------全局变量定义--------------------------------*/
unsigned int set_time = 1;                 //设置刷新数据的频率默认500ms 1s 2s
unsigned char time_flag = 0;                //定时器开始标志
unsigned char display_flag = 0;                    //刷新标志
float temper = 15.0;                       //温度数据变量
float max_temper = 40.0,min_temper = 0.0,PH_Set = 7.0;										//温度设置阀值 0-50 默认为最大值
unsigned char key_value = 0,key = 0;
unsigned char Index = 0,flag_function = 0;                    //界面索引
float ph, tds,p;         //ph 浊度 大气压
unsigned char buzzer_flag = 0;//警报标志
/*-------------------------------------界面显示函数---------------------------------*/

/*-------------------------------功能操作界面--------------------------*/

void Init_Interface(void)
{  
		static unsigned int i = 0;
		LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);
		LCD_ShowString(90,40,(unsigned char *)"Author:Slow-Walker",RED,GREEN,32,0);
		LCD_ShowString(110,80,(unsigned char *)"Date:2022-10-26",RED,GREEN,32,0);
		LCD_ShowString(140,240,(unsigned char *)"WIFI",RED,GREEN,32,0);
		LCD_ShowChinese(220,240,(unsigned char *)"加载中",RED,GREEN,32,0);
	 while(i*8 < 472)
		{
			 LCD_ShowString(i*8,280,(unsigned char *)".",RED,	WHITE,32,0);
				delay_ms(50);	
				i++;
		}
		delay_ms(500);
		//LCD_ShowChinese(140,240,(unsigned char *)"加载成功",RED,GREEN,32,0);		
		//LCD_Init();
}

void Interface1(void)
{
	LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);
	LCD_ShowChinese(150,120,(unsigned char *)"参数查看",RED,GREEN,32,0);
	LCD_ShowChinese(150,160,(unsigned char *)"参数设置",RED,GREEN,32,0);
}


void Interface2(void)
{

	LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);
	LCD_ShowChinese(120,80,(unsigned char *)"温度阈值:",RED,GREEN,32,0);
  	LCD_ShowFloatNum1(320,80,max_temper,4,RED,GREEN,32);								 
  	LCD_ShowChinese(120,120,(unsigned char *)"当前温度:",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,120,temper,4,RED,GREEN,32);			
	LCD_ShowChinese(120,160,(unsigned char *)"当前",RED,GREEN,32,0);
	LCD_ShowString(200,160,(unsigned char *)"PH",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,160,ph,4,RED,GREEN,32);	
	LCD_ShowChinese(120,200,(unsigned char *)"大气压值:",RED,GREEN,32,0);
	LCD_ShowIntNum(320,200,bmp180.p,6,RED,GREEN,32);	
	LCD_ShowChinese(120,240,(unsigned char *)"水电导率:",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,240,tds,6,RED,GREEN,32);		
}

void Interface3(void)
{
	
	LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);
	LCD_ShowChinese(120,80,(unsigned char *)"温度阈值",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,80,max_temper,4,RED,GREEN,32);	
	LCD_ShowString(120,120,(unsigned char *)"PH",RED,GREEN,32,0);	
	LCD_ShowChinese(200,120,(unsigned char *)"阈值",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,120,PH_Set,4,RED,GREEN,32);
	LCD_ShowChinese(120,160,(unsigned char *)"刷新频率:",RED,GREEN,32,0);
	LCD_ShowIntNum(320,160,set_time,1,RED,GREEN,32);	
}

void Interface4(void)
{
	
	LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);
	LCD_ShowChinese(120,120,(unsigned char *)"温度阈值",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,120,max_temper,4,RED,GREEN,32);	
}
void Interface5(void)
{
	
	LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);	
	LCD_ShowString(120,120,(unsigned char *)"PH",RED,GREEN,32,0);	
	LCD_ShowChinese(200,120,(unsigned char *)"阈值",RED,GREEN,32,0);
	LCD_ShowFloatNum1(320,120,PH_Set,4,RED,GREEN,32);
}
void Interface6(void)
{
	
	LCD_ShowChinese(80,0,(unsigned char *)"欢迎使用水质监测系统",RED,Q_BLUE,32,0);
	LCD_ShowChinese(120,120,(unsigned char *)"刷新频率:",RED,GREEN,32,0);
	LCD_ShowIntNum(320,120,set_time,1,RED,GREEN,32);	
}

/*----------------------------------按键操作函数--------------------------------------*/
unsigned char Key_Mode(void)
{
	key_value = KEY_Scan(); //按键1来进行模式的切换
	//按键每按一下蜂鸣器响200ms然后关掉 按键提示音
	if(key_value)
	{
		LCD_Init(); 
	}
	if(key_value == 1) //判断按键1是否被按下
	{ 
		Index++;
		BEEP_ON();
		delay_ms(200);
		BEEP_OFF();
		delay_ms(200);
	}	
	if(key_value == 2) //判断按键1是否被按下
	{
		Index--;
		BEEP_ON();
		delay_ms(200);
		BEEP_OFF();
		delay_ms(200);
	}
		switch(Index)
		{	
			case 1:	Interface1();break;
			case 2:	Interface2();break;
			case 3:	Interface3();break;
			case 4:	Interface4();flag_function = 3;break;
			case 5:	Interface5();flag_function = 4;break;
			case 6:	Interface6();flag_function = 5;break;		
			default:break;
		}
		key_value = 0;
	return flag_function; //返回功能函数的标志位
}

void Param_Set(void)
{
	 unsigned char keyvalue = 0;
	 keyvalue = KEY_Scan(); //按键1来进行模式的切换
		//按键每按一下蜂鸣器响200ms然后关掉 按键提示音
	if(flag_function == 3)
	{
	 if(keyvalue == 3)
	 {
		 	BEEP_ON();
			delay_ms(200);
			BEEP_OFF();
	
		 max_temper += 2;
		 if(max_temper >= 50)
		 {
				max_temper = 50;
		 }
	 }
	 if(keyvalue == 4)
	 {
		 	BEEP_ON();
			delay_ms(200);
			BEEP_OFF();
		 max_temper -= 2;
		 if(max_temper == 0)
		 {
				max_temper = 0;
		 }		 
	 }
 }
	else if(flag_function == 4)
	{
		if(keyvalue == 3)
	 {
			BEEP_ON();
			delay_ms(200);
			BEEP_OFF();
		 PH_Set += 1;
	 }
	 if(keyvalue == 4)
	 {
		 	BEEP_ON();
			delay_ms(200);
			BEEP_OFF();
		 PH_Set -= 1;
		 	 
	 }
	}
	else if(flag_function == 5)
	{
	if(keyvalue == 3)
	 {
			BEEP_ON();
			delay_ms(200);
			BEEP_OFF();
		 	set_time += 1;
		  if(set_time > 3)
			{
				set_time = 3;
			}
	 }
	 if(keyvalue == 4)
	 {
		 	BEEP_ON();
			delay_ms(200);
			BEEP_OFF();
		 set_time -= 1;
		 if(set_time == 1)
		 {
			 set_time = 1;
		 } 	 
	 }
	}
	flag_function = 0;
	keyvalue = 0;
}




/*-------------------------------------主函数-----------------------------------------*/
int main(void)
 {	

	unsigned char *dataPtr = NULL;
	 
	unsigned short timeCount = 0;	//发送间隔变量
	 
	delay_init();	    	   //延时函数初始化	  
	NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
 	Led_Init();			      //LED端口初始化
	Adc_Init();           //adc初始化
	KEY_Init();           //按键初始化
	Beep_Init();          //蜂鸣器初始化
	Time_Init();          //定时器2初始化
	DS18B20_Init();
	BMP_Init();
	BMP_ReadCalibrationData();	
  	delay_ms(50);
	uart_init(9600);//串口1初始化
	uart3_init(115200); //串口3初始化
	 
	LCD_Init();            //LCD初始化
	LCD_Fill(0,0,LCD_W,LCD_H,GREEN);             //LCD屏颜色初始化  
  	Init_Interface();       //初始界面显示


	ESP8266_Init();					//初始化ESP8266
	printf("8266_INIT_END\n");	 
	while(OneNet_DevLink())			//接入OneNET
	delay_ms(500);
	printf("接入onenet成功");
	LCD_ShowString(140,240,(unsigned char *)"WIFI",RED,GREEN,32,0);
	LCD_ShowChinese(220,240,(unsigned char *)"加载成功",RED,GREEN,32,0);	
	delay_ms(500);	
	while(1) 
	{		
	
		if(display_flag)
		{
			display_flag = 0;	
			temper = DS18B20_GetTemperture();             //读取温度
			Get_PH_and_TUR();                             //获取PH这里没有读取浊度
			Get_TDS();                                    //TDS 水电导率
			BMP_UncompemstatedToTrue();	                  //大气压
		}	
		//测量的温度不在温度范围内进行蜂鸣器报警
		if( temper > max_temper)
		{
			buzzer_flag = 1;
			BEEP_ON();
			delay_ms(300);
			BEEP_OFF();
			delay_ms(300);
		}
		else
		{
			buzzer_flag = 0;
			BEEP_OFF();	
		}
		//PH超出阈值后报警
		if( ph > PH_Set)
		{
			buzzer_flag = 1;
			BEEP_ON();
			delay_ms(300);
			BEEP_OFF();
			delay_ms(300);
		}
		else
		{
			buzzer_flag = 0;
			BEEP_OFF();	
		}
//	
		//printf("PH = %.1f TDS = %.2f Temper = %.2f Press:%ld\r\n",ph,tds,temper,bmp180.p);
		//delay_ms(200);
		//key = Key_Mode();
	//	printf( "OneNet_SendData\r\n");//通过串           口1发送提示信息(要开始发送数据了)				
		OneNet_SendData();//发送数据给onenet			
	//	printf("send_data_end\n");
		delay_ms(100); 		
		ESP8266_Clear();		
		dataPtr = ESP8266_GetIPD(0);//获取平台返回的数据
		if(dataPtr != NULL)//如果返回数据不为空
		OneNet_RevPro(dataPtr);//平台返回数据检测		
		delay_ms(100); 		
	}
}


/*-----------------------100ms定时器中断处理---------------------*/
void TIM2_IRQHandler(void) //TIM2 中断
{
	static unsigned char count = 0,t = 0;
		if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查 TIM2 更新中断发生与否
		{
			count++;
			t++;
			if(count >= set_time)   //set_time 通过按键来改变
			{
				display_flag = 1;
				count = 0;           //计数清零
			}
  		if(t == 10)
			{
				Key_Mode();
				Param_Set();
				t = 0;
			}
		
			TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除 TIM2 更新中断标志
		}
}


/*-------------------------------串口中断服务函数-------------------------*/
void USART1_IRQHandler(void)
{
	char cmd = 0,Alarm = 0;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
	{
		cmd = USART_ReceiveData(USART1);
		//printf("%c",cmd);
		if(cmd == 0xAA)
		{
				max_temper++;
		}
		else if(cmd == 0xBB)
		{
			max_temper--;
		}
		else if(cmd == 0xCC)
		{
			PH_Set++;
		}
		else if(cmd == 0xDD)
		{
			PH_Set--;
		}
		else if(cmd == 0xEE)
		{
			for(Alarm =0;Alarm<8;Alarm++)
			{
				BEEP_ON();
				delay_ms(300);
				BEEP_OFF();
				delay_ms(300);
			}
		}
		else if(cmd == 0xFF)
		{
			//Alarm = 0;
			BEEP_OFF();
		}		
		else if(cmd == 0xCD)
		{
			set_time = 1; //500ms
		}	
		
		else if(cmd == 0xDE)
		{
			set_time = 2;//2s
		}	
		
		else if(cmd == 0xEF)
		{
			set_time = 3; //3.5s
		}	
		USART_ClearFlag(USART1, USART_FLAG_RXNE);
	}
}

四、工程链接

链接: https://pan.baidu.com/s/1EGRi3mnxnXVd18pKNUYZJA?pwd=bqqg 提取码: bqqg 复制这段内容后打开百度网盘手机App,操作更方便哦 
--来自百度网盘超级会员v5的分享

现在不开源了哦,有需要完整资料可私,创作不易拒绝白嫖

物联沃分享整理
物联沃-IOTWORD物联网 » 基于STM32的水质检测系统设计与实现

发表评论