物联网项目-温湿度stm32 发送短信打电话
  CLYEAq02EKEQ 2023年11月02日 35 0

物联网项目-温湿度表结构

物联网项目-温湿度-Web后台

物联网项目-服务端TCP Server

物联网项目-订阅者Subscribe

物联网项目-温湿度之 TCP 协议包C#版

物联网项目-通讯协议之 C语言版 STM32

物联网项目-通讯协议之 Java版

物联网项目-温湿度之 nodemcu esp8266 刷机

物联网项目-温湿度stm32 发送短信打电话


0、背景

朋友企业机房空调容易跳闸,给他做了个温湿度异常报警,发短信打电话。

1、环境配置

开发环境uVersion5,c库,硬件 stm32 f105 开发板,温湿度传感器 dht22,GSM模块.

2、代码

#include "main.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "timer.h"
#include "string.h"
#include "rt_heap.h"
#include "stdlib.h"
//#include "DB18B20ForStm32.h" 
#include "GSM.h"
#include "AT_Cmd.h"

/**********************************************************************
实例温湿度监控发送短信实验		   
实验现象:D2,D3闪烁,时间间隔为300ms.
***********************************************************************/

/*#define Buf2_Max 200 					  //串口2缓存长度*/
/*************	本地常量声明	**************/
const char *string = "AT+CIPSTART=\"TCP\",\"xxiems.wicp.vip\",26476";	//IP登录服务器

u8 Times=0,First_Int = 0,shijian=0;
u16 Heartbeat=0, NetState =0, RegNetWork = 0, RegNetWorkTime = 0, ReSetSIM = 0, ReSetSIMCount = 0;

vu8 Timer0_start;	//定时器0延时启动计数器
vu8 Uart2_Start;	//串口2开始接收数据
vu8 Uart2_End;	  //串口2接收数据结束
vu8 Heart_beat;		//发送心跳帧标志位

vu32 DHT11Time = 0; //温湿度计定时计数器
vu8  DHT11State = 0;

vu32 SMSNoticeTime = 0;//短信提醒间隔 600s
vu8  SMSNoticeClockState = 0;//短信提醒计时标记
vu8  SMSFirstNoticeFlag = 1;//开机后首次温度异常第一次提醒

char result[60];
char * phoneNumberUnicode = "0031003800390031003400370036003400000380000";//陶XX的手机号
char * phoneNumber = "18914760000";//脱敏
//char * phoneNumberUnicode = "00310033003600310036003200390035000000320000";//爱友晴天的手机号
//char * phoneNumber = "13616290000";//ken_ji_ji的手机号
char * messageHead = "673A623F60000EA662A58B66";//机房温度报警
char * messageLoginHead = "673A623F73AF588376D00007542F52A8";//机房环境监控启动
/*************	本地函数声明	**************/

void Rec_Server_Data(void);

void getTempAndHum(int flag);

void ByteToHexStr01(const unsigned char* source, char* dest, int sourceLen);
int HexStrToByteBCC(const  char* source/*, unsigned char* dest*/, int sourceLen);
char * postpack(float temper, float humidity);
char * loginpack(void);
void CL_Result(void);
char *del_char(char *str, char ch);
void rep_char(char *str, char * out, char oldch, char newch);



int main(void)
 {
		char clientidArr[50];
		int bcc_count;
		char * login;
		u8 res;
	  u8 len;
	  u8 t;
	  u16 times=0;
		SystemInit(); 			 //系统时钟初始化默认为72M,SYSCLK_FREQ_72MHz
		delay_init(72);	    	 //延时函数初始化	  
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
		LED_Init();			     //LED端口初始化
		/*串口1初始化*/
		usart_config(115200);
	 /*串口2初始化*/
		USART2_Init_Config(115200);
		Timer2_Init_Config();
	 

		NetState = 0;//网络连接状态 0 未连接 1 连接 
	 
		//res = AT_Test();
	  //usart_printf("\r\n...AT_Test:%d...\r\n", res);
		
		//GSM初始化
		LED0=1;
		res=1;
		while(res)
		{
			LED0=0;
			res= GSM_Dect();
			delay_ms(1000);
			delay_ms(1000);
		}
		/*中英文短信模式初始化*/
		//GSM_InitCN();
		LED0=1;

		res=1;
		
		NetState = 1;//网络连接状态 0 未连接 1 连接
		Heart_beat = 0;
		Heartbeat = 0;
		
		CL_Result();
		delay_ms(100);
		getTempAndHum(1);
		
		delay_ms(1000);
		//res = AT_Test();
		//usart_printf("\r\n...AT_Test:%d...\r\n", res);
		UART1_SendString("\r\nBegin Main Loop\r\n");
		while(1)
		{
				//网络状态心跳和发数据 AT超时次数大于5重连
				if(RegNetWorkTime > 5)
				{
						usart_printf("\r\n网络状态AT超时次数大于5 重连 {%d}", RegNetWorkTime);
						NetState = 0;
						
						res=1;
						LED0=1;//D2灯灭
						while(res)
						{
							LED0=0;
							UART1_SendString("\r\nMain Loop Reg GSM...");
							RegNetWorkTime = 0;//如果模块死机这里就是死循环
							res=GSM_Dect();
							delay_ms(1000);
							delay_ms(1000);
						}
						LED0=1;
						Set_ATE0();
						delay_ms(1000);
						/*中英文短信模式初始化*/
						//GSM_InitCN();
						res=1;
						

						UART1_SendString("\r\nGSM模块在主循环中初始化成功\r\n");
						delay_ms(1000);
						
						
						NetState = 1;//网络连接状态 0 未连接 1 连接
						Heart_beat = 0;
						Heartbeat = 0;
						
						RegNetWorkTime = 0;
			}
				
        LED1=0;//D3灯亮
				
				if(DHT11State && NetState)
				{
					LED0=0;//D2灯亮
					UART1_SendString("\r\nDHT11State && NetState\r\n");
					getTempAndHum(0);
					LED0=1;
					
					DHT11State = 0;
					Heart_beat=0;
					Heartbeat = 0;
				}
				delay_ms(1800);
        
				
				LED1=1;//D3灯灭
				//LED0=1;
				delay_ms(1000);		 
				//UART1_SendString("\r\nDHT11State && NetState...\r\n");
				//usart_printf("\r\n...DHT11State:%d, NetState:%d...\r\n", DHT11State, NetState);
		}
 }
 
/*******温湿度*******/
void getTempAndHum(int flag){
				u8 ret = 1;
				char * post;
				float t;//ds18b20 温度
				u8 buffer[5];
        float hum;
        float temp;
				u8 testNum = 3;
				char tempStr[140];
				
				char msg[100];
				//UART1_SendString("\r\n *******dht11_read_data(buffer) == 0 里面有死循环******");//2020-09-24 注释
        if (dht11_read_data(buffer) == 0)
        {
            hum = ((buffer[0]<<8)+buffer[1])/10.0;
            temp = ((buffer[2]<<8)+buffer[3])/10.0;
        }
				CL_Result();
				
				usart_printf("\r\nT:%.2f, H:%.2f\r\n", temp, hum);
				
				sprintf(result, "%.2fC", temp);
				
				
				ByteToHexStr01(result, tempStr, strlen(result));
				UART1_SendString("\r\ntempStr:");
				UART1_SendString(tempStr);
				UART1_SendString("\r\n");
				if(flag == 1){
					sprintf(msg, "%s%s", messageLoginHead, tempStr);
					}else{
					sprintf(msg, "%s%s", messageHead, tempStr);
				}
				UART1_SendString("\r\nmsg:\r\n");
				UART1_SendString(msg);
				UART1_SendString("\r\n");
				Heart_beat = 0;//心跳计数器置0 否则发送数据时冲突。
				Heartbeat = 0;
				
				if(temp <= 27){
						SMSNoticeClockState = 0;
						SMSFirstNoticeFlag =  1;
						SMSNoticeTime = 0;
					}else{
						SMSNoticeClockState = 1;
					}
				/*测试AT指令最多3次*/	
				ret = AT_Test();
				if(ret && testNum){
					ret = AT_Test();
					testNum--;
					delay_ms(300);
				}
				testNum = 3;
				
				usart_printf("\r\nAT_Test in getTemp:ret= %d \r\n", ret);
				//delay_ms(300);
				usart_printf("\r\n End Post RealData****AT_Test -> ret=%d ,RegNetWorkTime=%d", ret,RegNetWorkTime);
				
				if(ret != 0){
					RegNetWorkTime++;
				}else{
					RegNetWorkTime = 0;
					
					if(flag){
						UART1_SendString("\r\n发送启动短信:\r\n");
						GSM_SendMessageCN((char*)phoneNumberUnicode, (char*)msg);
						
						delay_s(5);//延时5秒
						return;
					}
					usart_printf("\r\n ****SMSNoticeClockState=%d ,SMSFirstNoticeFlag=%d", SMSNoticeClockState, SMSFirstNoticeFlag);
					if(temp > 27 && SMSFirstNoticeFlag)
					{//温度大于27度或者开机时发送短信通知
						usart_printf("\r\n ****temp > 27 && SMSFirstNoticeFlag=%d 发送报警短信", SMSFirstNoticeFlag);
						SMSFirstNoticeFlag = 0;
						GSM_SendMessageCN((char*)phoneNumberUnicode, (char*)msg);
						delay_s(5);//延时5秒
						
						if(temp > 29){//温度大于29度时拨打电话
							usart_printf("\r\n ****temp > 29 && SMSFirstNoticeFlag=%d 拨打报警电话", SMSFirstNoticeFlag);
							
							GSM_CallPhone((char *)phoneNumber);
							delay_s(20);//延时20秒
							GSM_EndPhone();
						}
					}
			}
}


char * del_char(char *str, char ch)
{
    unsigned char i=0,j=0;
    while(str[i] != '\0')
    {
        if(str[i] != ch)  //只有在不是空格的情况下才会移动赋值
        {
            str[j++] = str[i];
        }
        i++;  //源一直移动
    }
    str[j] = '\0';
		UART1_SendString(str);
    return str;
}

void rep_char(char *str, char * out, char oldch, char newch)
{
    int i=0;
		for(i = 0; i < strlen(str); i++)
		{
			if(str[i] == oldch){
				str[i] = newch;
			}
		}
		strcpy(out, str);
}
 
/*双字节字符转化为16进制字符串发中文短信使用*/
void ByteToHexStr01(const unsigned char* source, char* dest, int sourceLen)
{
	short i;
	unsigned char highByte, lowByte;

	for (i = 0; i < sourceLen; i++)
	{
		highByte = source[i] >> 4;
		lowByte = source[i] & 0x0f;

		highByte += 0x30;
		dest[i * 4] = '0';
		if (highByte > 0x39)
			dest[i * 4 + 2] = highByte + 0x07;
		else
			dest[i * 4 + 2] = highByte;

		lowByte += 0x30;
		dest[i* 4+ 1] = '0';
		if (lowByte > 0x39)
			dest[i * 4 + 3] = lowByte + 0x07;
		else
			dest[i * 4 + 3] = lowByte;
	}
	//usart_printf("out = %s\n", dest);

}
/*16进制字符串BCC校验*/
int HexStrToByteBCC(const  char* source, int sourceLen)
{
	unsigned char * dest = (unsigned char*)malloc((sourceLen + 1) / 2);
	short i;
	unsigned char highByte, lowByte;
	int aubChecksum = 0;
	for (i = 0; i < sourceLen; i += 2)
	{
		highByte = toupper(source[i]);
		lowByte = toupper(source[i + 1]);

		if (highByte > 0x39)
			highByte -= 0x37;
		else
			highByte -= 0x30;

		if (lowByte > 0x39)
			lowByte -= 0x37;
		else
			lowByte -= 0x30;

		dest[i / 2] = (highByte << 4) | lowByte;
		aubChecksum ^= dest[i / 2];
		//printf("%d\n", dest[i / 2]);
	}
	free(dest);
	dest = NULL;
	//printf("aubChecksum:%d\n", aubChecksum);
	return aubChecksum;
}

void CL_Result(void)
{
	u16 k;
	for(k = 0; k < strlen(result); k++)
	{
		result[k] = 0x00;
	}
}
/*******************************************************************************
* 函数名 : Rec_Server_Data
* 描述   : 接收服务器数据函数
* 输入   : 
* 输出   : 
* 返回   : 
* 注意   : 
*******************************************************************************/
void Rec_Server_Data(void)
{
	//UART1_SendString("\r\nRec_Server_Data");
	//UART1_SendString(AT_RecvBuffer);
	if(strstr(AT_RecvBuffer,"+IPD")!=NULL)   		//若缓存字符串中含有^SISR
	{	
		Heartbeat=0;	//清除心跳帧计数器
		Heart_beat=0;
		delay_ms(100);
		if(strstr(AT_RecvBuffer,"onled")!=NULL)
		{
			//LED1_ON();
		}
		else if(strstr(AT_RecvBuffer,"offled")!=NULL)
		{
			//LED1_OFF();
		}
		UART1_SendString("收到新信息:\r\n");
		UART1_SendString(AT_RecvBuffer);
		//CLR_Buf2();
		//AT_DataInit();
		Heart_beat=1;//发送应答数据,告诉服务器收到数据		
	}
}
/*******************************************************************************
* 函数名  : TIM2_IRQHandler
* 描述    : 定时器2中断服务函数
* 输入    : 无
* 输出    : 无
* 返回    : 无 
* 说明    : 无
*******************************************************************************/
void TIM2_IRQHandler(void)   //TIM2中断
{
	static u8 flag =1;

	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM2更新中断发生与否
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除TIMx更新中断标志 
		//AT指令延时判断
		if(Timer0_start)
			Times++;
		if(Times > shijian)
		{
			Timer0_start = 2;
			Times = 0;
		}
		//UART1_SendString("中断执行\r\n");
		//End AT指令延时判断
		
		//TCP心跳 20秒钟
		Heartbeat++;
		if(Heartbeat > 20)//每20秒发送心跳帧
		{
			Heartbeat=0;
			Heart_beat=1;
			//UART1_SendString("\r\n *******H B T N(IRQ)******");//2020-09-24 注释
		}
		//End TCP心跳 20秒钟
		
				
		//DHT22 10分钟测温湿度
		DHT11Time++;
		if(DHT11Time > 119)
		{
			DHT11Time = 0;
			DHT11State = 1;
			UART1_SendString("\r\n *******S D T N(IRQ)******");//2020-09-24 注释
		}
		//End DHT2 10分钟测温度
		
		//vu32 SMSNoticeTime = 0;//短信提醒间隔 600s
		//vu8  SMSNoticeClockState = 1;//短信提醒计时标记
		//vu8  SMSFirstNoticeFlag = 1;//开机后首次温度异常第一次提醒
		if(SMSNoticeClockState){
			SMSNoticeTime++;
			if(SMSNoticeTime > 599){
				SMSNoticeTime = 0;
				SMSFirstNoticeFlag = 1;
			}
			//usart_printf("\r\nSMSNoticeTime=>%d, SMSFirstNoticeFlag=>%d\r\n",SMSNoticeTime, SMSFirstNoticeFlag);
		}
		
	}
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  k5GskpyrCqoj   2023年11月13日   31   0   0 单片机sdcc编译器
  fLutY3C6VwgE   2023年11月19日   37   0   0 stm32SD卡
CLYEAq02EKEQ