基于51单片机的管道压力检测及泄露检测无线WiFi传输系统proteus仿真原理图PCB

编程入门 行业动态 更新时间:2024-10-27 16:37:29

基于51<a href=https://www.elefans.com/category/jswz/34/1769836.html style=单片机的管道压力检测及泄露检测无线WiFi传输系统proteus仿真原理图PCB"/>

基于51单片机的管道压力检测及泄露检测无线WiFi传输系统proteus仿真原理图PCB

功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前始端和末端压力,压力阈值
2.按键启动/停止管道压力和泄漏检测
3.按键可更改压力阈值
4.管道压力超过报警阈值时将声光报警,并在液晶上显示OVER
5.管道发生泄漏时将声光报警,并在液晶上显示距离上游多少米
6.每隔2秒向WIFI串口发送当前检测信息
7.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:

PCB :

主程序:

#include <reg52.h>
#include "main.h"#define LENGTH 100 //管道长度m
#define RATE 100 //负压波传播速度m/s
#define FLUCTUATE 10 //0.01paunsigned char isNew;
unsigned int alarmWeight = 2000; //单位g
long initialWeight[2] = 0; //单位g
float objectWeight[2] = 0; //单位g //最大5
float lastObjectWeight[2] = 0; //单位g //最大5
float location = 0; //定位泄漏点位置
unsigned char timeCnt = 0; //10msj计数
bit dispFlag = 0; //液晶刷新标志
bit checkFlag = 0; //开启检测标志
bit sendDataFlag = 0; //无线发送数据标志
bit atFlag = 0; //命令/数据标志enum {IDLE, WAITING, UPFIRST, DOWNFIRST}timeFlag; //空闲,等待,上游开始,下游开始
enum {NONE, LEAK, OVER}errorFlag; //无,泄漏,过压//函数声明
void Timer0_Init(void); //定时器0初始化
void Timer1_Init(void); //定时器1初始化
void SendData(void); //串口发送数据
void Display(void); //显示函数
void KeyProcess(void); //按键处理
void RfreshData(void); //刷新数据
void Check(void); //检测管道泄漏
void Alarm(void); //报警
void UART_Init(void); //串口初始化
void UART_SendByte(unsigned char dat); //串口发送单字节数据
void UART_SendStr(unsigned char *s, unsigned char length); //发送定长度字符串void main()
{// 初始化DelayS(1);DelayMs(20);//EEPROM52_Init();// 定时器初始化Timer0_Init();Timer1_Init();UART_Init();#ifndef _SIMULATION_ //仿真时无需发送命令UART_SendStr("AT+CIPMUX=1\r\n", 13); //打开多连接DelayS(1);UART_SendStr("AT+CIPSERVER=1,8080\r\n", 21); //建立服务 端口号为8080DelayS(1);#endif// 开机显示LCD_Init();LCD_DispStr(0, 0, "    Welcome!    ");initialWeight[0] = HX711_GetInitialWeight();initialWeight[1] = HX711_1_GetInitialWeight();LCD_Clear();while(1){        RfreshData(); //刷新数据if (sendDataFlag == 1){sendDataFlag = 0;SendData(); //发送数据}if (checkFlag == 1){Check(); //检测}if (dispFlag == 1){Display(); //显示}   KeyProcess(); //按键处理}
}void RfreshData(void)
{EA = 0;objectWeight[0] = HX711_Read();objectWeight[1] = HX711_1_Read();EA = 1;objectWeight[0] = objectWeight[0] - initialWeight[0];objectWeight[1] = objectWeight[1] - initialWeight[1];objectWeight[0] = (objectWeight[0] * 10 / GAPVALUE); //计算真实值objectWeight[1] = (objectWeight[1] * 10 / GAPVALUE_1); //计算真实值}void Check(void)
{if (objectWeight[0] > alarmWeight || objectWeight[1] > alarmWeight) //检测到压力过高{errorFlag = OVER;Alarm();}if (timeFlag == WAITING) {if (objectWeight[0] > (lastObjectWeight[0] + FLUCTUATE) || objectWeight[0] < (lastObjectWeight[0] - FLUCTUATE)) //检测到上游压力波动大于FLUCTUATE{timeFlag = UPFIRST;timeCnt = 0;TH1 = 0xDC; //10msTL1 = 0x00;TR1 = 1; //开启计时}if (objectWeight[1] > (lastObjectWeight[1] + FLUCTUATE) || objectWeight[1] < (lastObjectWeight[1] - FLUCTUATE)) //检测到下游压力波动大于FLUCTUATE{timeFlag = DOWNFIRST;timeCnt = 0;TH1 = 0xDC; //10msTL1 = 0x00;TR1 = 1; //开启计时}}if (timeFlag == UPFIRST) //上游已检测到压力波动{if (objectWeight[1] > (lastObjectWeight[1] + FLUCTUATE) || objectWeight[1] < (lastObjectWeight[1] - FLUCTUATE)) //检测到下游压力波动大于FLUCTUATE{timeFlag = IDLE;TR1 = 0; //停止计时if (timeCnt >= 100) //大于100ms则为误判{timeFlag = 0;timeCnt = 0;}else{errorFlag = LEAK;location = LENGTH / 2 - (RATE * (timeCnt * 10 + ((unsigned int)(TH1 - 0xDC) << 8 + TL1) / 1000) / 1000) / 2;Alarm();}}}if (timeFlag == DOWNFIRST) //下游已检测到压力波动{if (objectWeight[0] > (lastObjectWeight[0] + FLUCTUATE) || objectWeight[0] < (lastObjectWeight[0] - FLUCTUATE)) //检测到上游压力波动大于FLUCTUATE{timeFlag = IDLE;TR1 = 0; //停止计时if (timeCnt >= 100) //大于100ms则为误判{timeFlag = WAITING;timeCnt = 0;}else{errorFlag = LEAK;location = LENGTH / 2 + (RATE * (timeCnt * 10 + ((unsigned int)(TH1 - 0xDC) << 8 + TL1) / 1000) / 1000) / 2;Alarm();}}}lastObjectWeight[0] = objectWeight[0]; //保留前一次测试值lastObjectWeight[1] = objectWeight[1]; //保留前一次测试值
}void Display(void)
{unsigned char dispRow[16];sprintf(dispRow, "A:%5.2f B:%5.2f", objectWeight[0] / 1000, objectWeight[1] / 1000);LCD_DispStr(0, 0, dispRow);sprintf(dispRow, "S:%5.2fPa", (float)alarmWeight / 1000);LCD_DispStr(0, 1, dispRow);if (errorFlag == OVER){LCD_DispStr(10, 1, " OVER!");}else if (errorFlag == LEAK){sprintf(dispRow, "%5.2fm", (float)location);LCD_DispStr(10, 1, dispRow);}else{if (checkFlag == 1){LCD_DispStr(10, 1, "Check!");}else{LCD_DispStr(10, 1, " IDLE ");}}}void SendData(void)
{unsigned char dispRow[16];if (atFlag == 1){#ifndef _SIMULATION_ //仿真时无需发送命令UART_SendStr("AT+CIPSEND=0,36\r\n", 18); //命令#endifatFlag = 0;}else{sprintf(dispRow, "A:%5.2f B:%5.2f", objectWeight[0] / 1000, objectWeight[1] / 1000);UART_SendStr(dispRow, 16); //发送内容UART_SendStr("\r\n", 2);if (errorFlag == OVER){sprintf(dispRow, "S:%5.2fPa  OVER!", (float)alarmWeight / 1000);UART_SendStr(dispRow, 16); //发送内容}else if (errorFlag == LEAK){sprintf(dispRow, "S:%5.2fPa %5.2fm", (float)alarmWeight / 1000, (float)location);UART_SendStr(dispRow, 16); //发送内容}else{if (checkFlag == 0){sprintf(dispRow, "S:%5.2fPa  IDLE ", (float)alarmWeight / 1000);}else{sprintf(dispRow, "S:%5.2fPa Check!", (float)alarmWeight / 1000);}UART_SendStr(dispRow, 16); //发送内容}UART_SendStr("\r\n", 2);atFlag = 1;}
}void Alarm(void)
{checkFlag = 0;timeFlag = IDLE;LED_GREEN = 1;LED_RED = 0;BUZZER = 0;
}void KeyProcess(void)
{if (!KEY_RIGHT) //开启检查{DelayMs(100);if (!KEY_RIGHT){checkFlag = ~checkFlag;if (checkFlag == 1){timeFlag = WAITING;errorFlag = NONE;lastObjectWeight[0] = objectWeight[0]; //保留前一次测试值lastObjectWeight[1] = objectWeight[1]; //保留前一次测试值TH1 = 0xDC;                            //10msTL1 = 0x00;timeCnt = 0;location = 0;LED_GREEN = 0;LED_RED = 1;BUZZER = 1; //关闭报警}else{timeFlag = IDLE;errorFlag = NONE;BUZZER = 1; //关闭报警LED_RED = 1;LED_GREEN = 1;}}while(!KEY_RIGHT);}if (!KEY_UP) //按键加{DelayMs(160);if (!KEY_UP){alarmWeight = alarmWeight + 10;if (alarmWeight > 5000){alarmWeight = 5000;}// EEPROM52_Write();}}if (!KEY_DOWN) //按键减{DelayMs(160);if (!KEY_DOWN){alarmWeight = alarmWeight - 10;if (alarmWeight <= 0){alarmWeight = 0;}// EEPROM52_Write();}}}void Timer0_Init(void)
{TMOD &= 0xF0; //Timer0 16位装载TMOD |= 0x01;TH0 = RH_10MS(5); //50msTL0 = RL_10MS(5);TR0 = 1; //启动T0计时ET0 = 1; //打开T0中断EA = 1;  //打开总中断
}void Timer0_Intterupt(void) interrupt 1
{static unsigned int cnt=0;TH0 = RH_10MS(5); //50msTL0 = RL_10MS(5);cnt++;if (cnt % 2 == 0) //100ms{dispFlag = ~dispFlag; //每100ms刷新一次屏幕}if (cnt >= 20){sendDataFlag = 1; //每1s发送一次数据cnt = 0;}
}void Timer1_Init(void)
{TMOD &= 0x0F; //Timer1 16位装载TMOD |= 0x10;TH1 = 0xDC; //10msTL1 = 0x00;TR1 = 0; //停止T1计时ET1 = 1; //打开T1中断EA = 1;  //打开总中断
}void Timer1_Intterupt(void) interrupt 3
{TH1 = 0xDC; //10msTL1 = 0x00;if (timeCnt<100){timeCnt++;}
}void UART_Init(void)
{SCON = 0x50;TH2 = 0xFF;TL2 = 0xFD;RCAP2H = 0xFF; //(65536-(FOSC/32/BAUD))   BAUD = 115200 FOSC = 11059200RCAP2L = 0xFD;/*****************/TCLK = 1;RCLK = 1;C_T2 = 0;EXEN2 = 0;/*****************/TR2 = 1;ES = 1; //打开串口中断EA = 1; //打开总中断
}void UART_SendByte(unsigned char dat) //串口发送单字节数据
{unsigned char time_out;time_out = 0x00;SBUF = dat;						  //将数据放入SBUF中while ((!TI) && (time_out < 100)) //检测是否发送出去{time_out++;DelayUs10x(2);}		//未发送出去 进行短暂延时TI = 0; //清除ti标志
}void UART_SendStr(unsigned char *s, unsigned char length) //发送定长度字符串
{unsigned char num;num = 0x00;while (num < length) //发送长度对比{UART_SendByte(*s); //放松单字节数据s++;			  //指针++num++;			  //下一个++}
}void UART_Interrupt(void) interrupt 4 //串行中断服务程序
{if (RI) //判断是接收中断产生{RI = 0; //标志位清零}
}

仿真演示视频:
/

实物演示视频:
/

更多推荐

基于51单片机的管道压力检测及泄露检测无线WiFi传输系统proteus仿真原理图PCB

本文发布于:2024-03-12 12:17:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1731490.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:单片机   管道   原理图   压力   系统

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!