老人用水监控报警

点击查看代码
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pwm.h"
#include "key.h"
#include "usart.h"
#include "string.h"
#include "exti.h"
#include "timer.h"

u8 printf_2(u8 *cmd,u8 *ack,u16 waittime);  //mqtt发送方式,需要通过规定时间内是否有需要的回传数据来判断是否发送成功
u8* check(u8 *str);
u32 flow=0;  //流量
u32 num=0;   //脉冲?
u8 time=0;   //时间
u32 water_flag=0;  //水标志
int water_time=0;  //水时间
float water=0;     //水
u8 limit[5];       //限制 数组
u32 limit_flag=5;  //限制标志

int main(void)
{
	u16 len,i=0;
	u8 FLOW_flag;
	
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	     //初始化与LED连接的硬件接口5
	EXTIX_Init();            //PB5
	
	uart_init(115200);       //TX:PA9,RX:PA10
	uart2_init(115200);      //TX:PA2,RX:PA3,接NB
	TIM3_Int_Init(49999,14399);    //10s 
	
	LED2=1;
	
	delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);//延迟15s,NB初始化?
	delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);
	delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);
	delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);
	delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);
	
	printf_2("AT+QMTCFG=\"will\",0,1,0,1,\"flow_will\",\"2\"","OK",20);  //配置 Will 信息,主题名称"flow_will"
	delay_ms(500);
	printf_2("AT+QMTCFG=\"KEEPALIVE\",0,2","OK",20);                     //配置 keep-alive 时间,2*1.5=3s
	//Keep-alive 时间,范围:0-3600,默认值:120,单位:秒。该参数定义从客户端接收消息的最大间隔时间,在 1.5 倍的设置时间内,若服务器未从客户端收到
	//消息,则默认客户端发送了断开连接消息,因此服务器会断开客户端连接。
	// 0 表示不断开客户端连接
	delay_ms(500);
	printf_2("AT+QMTOPEN=0,\"8.136.186.93\",1883","+QMTOPEN: 0,0",500);  //连接地址
	delay_ms(500);
	printf_2("AT+QMTCONN=0,\"flow\"","+QMTCONN: 0,0,0",500);             //以ID "flow" 登录
	delay_ms(500);
	printf_2("AT+QMTSUB=0,1,\"flow_r\",0","+QMTSUB: 0,1,0,0",500);       //订阅主题 "flow_r"
	delay_ms(500);
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
	LED2=0; //PB6
	
	while(1)
	{
		if(USART2_RX_STA&0X8000)//NB接收到网端下发的消息
		{
			if(strstr((const char*)USART2_RX_BUF,"+QMTSTAT: 0,2"))  //如果下发的消息中包含 "0,2",发送 PINGREQ 包超时或者失败
			{
				delay_ms(500);delay_ms(500);
				printf_2("AT+QMTCFG=\"will\",0,1,0,1,\"flow_will\",\"2\"","OK",20);
				delay_ms(500);
				printf_2("AT+QMTCFG=\"KEEPALIVE\",0,2","OK",20);
				delay_ms(500);
				printf_2("AT+QMTOPEN=0,\"8.136.186.93\",1883","+QMTOPEN: 0,0",500);
				delay_ms(500);
				printf_2("AT+QMTCONN=0,\"flow\"","+QMTCONN: 0,0,0",500);
				delay_ms(500);
				printf_2("AT+QMTSUB=0,1,\"flow_r\",0","+QMTSUB: 0,1,0,0",500);
				delay_ms(500);
			}
			if(strstr((const char*)USART2_RX_BUF,"+QMTSTAT: 0,1"))  //如果下发的消息中包含 "0,1",连接被服务器断开或者重置
			{
				delay_ms(500);delay_ms(500);
				printf_2("AT+QMTCFG=\"will\",0,1,0,1,\"flow_will\",\"2\"","OK",20);
				delay_ms(500);
				printf_2("AT+QMTCFG=\"KEEPALIVE\",0,2","OK",20);
				delay_ms(500);
				printf_2("AT+QMTOPEN=0,\"8.136.186.93\",1883","+QMTOPEN: 0,0",500);
				delay_ms(500);
				printf_2("AT+QMTCONN=0,\"flow\"","+QMTCONN: 0,0,0",500);
				delay_ms(500);
				printf_2("AT+QMTSUB=0,1,\"flow_r\",0","+QMTSUB: 0,1,0,0",500);
				delay_ms(500);
			}
			if(strstr((const char*)USART2_RX_BUF,"ERROR"))  //如果下发的消息中包含 "error",若有任何错误
			{
				delay_ms(500);delay_ms(500);
				printf_2("AT+QMTCFG=\"will\",0,1,0,1,\"flow_will\",\"2\"","OK",20);
				delay_ms(500);
				printf_2("AT+QMTCFG=\"KEEPALIVE\",0,2","OK",20);
				delay_ms(500);
				printf_2("AT+QMTOPEN=0,\"8.136.186.93\",1883","+QMTOPEN: 0,0",500);
				delay_ms(500);
				printf_2("AT+QMTCONN=0,\"flow\"","+QMTCONN: 0,0,0",500);
				delay_ms(500);
				printf_2("AT+QMTSUB=0,1,\"flow_r\",0","+QMTSUB: 0,1,0,0",500);
				delay_ms(500);
			}
			if(USART2_RX_BUF[31]=='*')  //如果下发的消息中第[31]是*
			{
				for(i=0;i<5;i++)
				limit[i]=USART2_RX_BUF[i+26]-'0';  //本地的第0、1、2、3、4位对应网端下发的26、27、28、29、30位的数字,所以需要-48
				limit_flag=limit[2]*100+limit[3]*10+limit[4];//第2、3、4位组成为一个三位数,水位限制?
				usart_flag=1;  //串口1发送
				printf("%d",limit_flag);
			}
			memset(USART2_RX_BUF,0,200*sizeof(char));
			USART2_RX_STA=0;
		} 
		delay_ms(10);   
	}
}		
//定时器中断
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 ,这个放在最后比较合适吧,否则下面程序的执行包含在10s内
		if(flow==0) water_flag=0;        //10s,如果没用水,用水时间置0
		else water_flag++;   //一个water_flag为10s,通过这种方法记录通水时间
		num+=flow;           //一分钟内,累加流量计给的脉冲数
		if(time!=5)  //每10秒
		{
			usart_flag=2;  //串口2发送
			printf("AT+QMTPUB=0,1,1,0,\"test_2\",\"2,%d,%d,%d\"\r\n",water_time,flow,limit_flag);//向主题"test_2"发送,水的时间、本次10s内的流量脉冲数、时间限制
		}
		if(time++==5)  //每一分钟
		{
			water=(float)num/660;  //计算累计用水量,660改300
			water_time=water_flag/6;  //换算成分钟,除非流量计为0或者超出用水时间限制,否则不清零
			usart_flag=2;  //串口2发送
			printf("AT+QMTPUB=0,1,1,0,\"flow_s_2\",\"2,time:%d,rate:%.3f\"\r\n",water_time,water);
			time=0;
			num=0;
		}
		if(water_time>=limit_flag)  //用水时间超过网端设置的用水时长
		{
			delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);
			usart_flag=2;  //串口2发送
			printf("AT+QMTPUB=0,1,1,0,\"flow_s_2\",\"2,wrong\"\r\n");
			flow_flag=1;delay_ms(100);   //复位键 
			SWITCH_3=0;delay_ms(100);  //关闭电磁阀1、2和水泵
			SWITCH_2=0;delay_ms(100);
			SWITCH_1=0;delay_ms(100);
			water_time=0;delay_ms(100);
			water_flag=0;delay_ms(100);
			LED2=1;delay_ms(100);
		}
		flow=0;  //脉冲数置0
	}
}

//外部中断
void EXTI9_5_IRQHandler(void)   //660脉冲1L水,新购买的流量计为300脉冲1L水
{						 
	flow++;
 	EXTI_ClearITPendingBit(EXTI_Line5);    //清除LINE5上的中断标志位  
}


u8 printf_2(u8 *cmd,u8 *ack,u16 waittime)
{
	u8 res=0; 
	USART2_RX_STA=0;
	usart_flag=2;
	printf("%s\r\n",cmd);	//发送命令
	if(ack&&waittime)		//需要等待应答
	{
		while(--waittime)	//等待倒计时
		{
			delay_ms(10);
			if(USART2_RX_STA&0X8000)//接收到期待的应答结果
			{
				if(check(ack))
				{
//					usart_flag=1;
//					printf("ack:%s\r\n",USART2_RX_BUF);
					break;//得到有效数据 
				}
//				usart_flag=1;
//				printf("%s",USART2_RX_BUF);
				memset(USART2_RX_BUF,0,200*sizeof(char));
				USART2_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
} 

u8* check(u8 *str)
{
	char *strx=0;
	if(USART2_RX_STA&0X8000)		//接收到一次数据了
	{ 
		USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
		strx=strstr((const char*)USART2_RX_BUF,(const char*)str);
	} 
	return (u8*)strx;
}		
		

posted @ 2023-02-23 21:35  hcnnnnnn  阅读(40)  评论(0)    收藏  举报