STM32之 ESP8266 WIFI 模块驱动代码-可以通过互联网实现数据远程传输(程序稳定,清晰明了非常容易移植到51单片机上)

成品展示部分 :(ESP8266只是其中一个小部分而已

实物图:

基于互联网的农业大棚环境监控系统设计
基于互联网的农业大棚环境监控系统设计

电路图:

农业大棚环境监控设计电路图(彩色)
农业大棚环境监控设计电路图(彩色)

 调试部分:ESP8266 WIFI 模块串口调试过程-实现通过互联网实现数据远程传输(结尾含驱动代码链接)_xiaohai@Linux的博客-CSDN博客_esp8266串口调试

(在看代码之前务必先串口调试ESP8266,否则难以用单片机控制ESP8266通过互联网实现数据远程传输!!!)

 ESP8266程序流程部分:

ESP8266程序流程图
ESP8266驱动程序流程图

ESP8266 代码部分:

第一部分:ESP8266模块头文件(wifi_esp8266.h)

#ifndef WIFI_ESP8266_H
#define WIFI_ESP8266_H
#include <stdio.h>
#include "usart.h"
#include "string.h"
#include "sys.h"
#include "delay.h"
#include "SHT30.h"

#define ESP8266_CHECK_CNT 5
//#define AZE
#define TP_LINK

struct  ESP8266_WIFI_INFO
{
	u32 ID1;
	u32 ID2;
	u32 ID3;
	u8 ESP8266_ERROR;
	u8 WIFI_Connect_State;
	u8 Server_Connect_State;
	u8 Server_Connect_Cnt;
	u8 ESP8266_State;
	u8 ConnectState;  //保存WIFI连接状态。0表示连接成功 1表示未连接 
	u32 SeverPort;
	char MAC[20];     //保存mac地址
	char IPAddr[20];  //保存IP地址
	char Password[20];  //保存密码
	char SSID[20];     //SSID
	char SeverIP[20];
};

#pragma pack(1) //以下结构体以一个字节对齐
/*--------------------------------*/
//定义socket数据传输的结构体
struct SocketPackageData
{
	u8 FrameHead[4];   //存放帧头数据, 固定为: 0xA1 0xA2 0xA3 0xA4
	u8 SrcDataBuffer[30]; //存放传输的字符串源数据
	u32 id[3]; 		  //存放 96 位 ID 号
	u32 CheckSum; 		  //存放数据位的校验和
};

extern struct ESP8266_WIFI_INFO ESP8266WIFI_Info; 
extern struct SocketPackageData RxTxDataPackage;
extern struct ESP8266_WIFI_INFO ESP8266WIFI_Info;

void ESP8266_Data_Handler(void);
u8 ESP8266_TCP_ClientModeInit(char *ssid ,char * password ,char * sever_ip ,u32 sever_port);
u8 ESP8266_ResponseData(char * string);
u8 ESP8266_CheckDevice(void);
u8 ESP8266_ATE0(void);
u8 ESP8266_SetWorkMode(u8 mode);
u8 ESP8266_RsetDevice(void);
u8 Get_Connect_WIFI_State(void);
u8 ESP8266_SetConnectWIFI(char * ssid ,char * password);
u8 ESP8266_STAModeGetIpAddr(void);
u8 ESP8266_ConnectServer(char * server_ip,u32 server_port);
u8 ESP8266_SetTransferMode(u8 mode);
u8 ESP8266_StartTransfer(void);
u8 ESP8266_StoptTransfer(void);
u8 ESP8266_TransferDataHander(void);
u8 SetDataPackage(struct SocketPackageData *data_pack,u8 *SendBuff,u32 id1,u32 id2,u32 id3);
u8 CheckDataPackage(struct SocketPackageData data);
void ESP8266_STA_ErrorInfo(u8 value);
u8 Restart_ConnectServer(void);
#endif

 第二部分:ESP8266驱动代码文件(wifi_esp8266.c)

#include "wifi_esp8266.h"
#include "led.h"
#include "oled.h"

struct  ESP8266_WIFI_INFO ESP8266WIFI_Info; //保存ESP8266的各项数据
struct SocketPackageData RxTxDataPackage; //保存接收和发送的数据

/*
函数功能: 等待并查找ESP8266的响应数据中是否有指定的字符串(判断响应是否正常)
函数参数:要指定查找的字符串
函数返回值: 0 表示设备响应正常  1 表示设备响应不正常(没有收到ESP8266的数据或者数据里面没有指定的字符串)
*/
u8 ESP8266_ResponseData(char *string)
{
	u8 cnt=0;
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		if(USART3_RX_State)
		{
			USART3_RX_Data[USART3_RX_Count]='\0';
			if(strstr((char*)USART3_RX_Data,string))
			{ 
				USART3_RX_State=0;
				USART3_RX_Count=0;
				return 0;
			}
			else 
			{
				USART3_RX_State=0;
				USART3_RX_Count=0;
				memset(USART3_RX_Data,0,1024);
				printf("ESP8266无回应!!!\n");
			}
		}
		DelayMs(50);
	}	
	return 1;
}
/*1.*/

/*
函数功能: 检查ESP8266设备是否存在
函数返回值: 0 表示设备正常  1 表示设备不正常
*/
u8 ESP8266_CheckDevice(void)
{
	u8 cnt=0;
	
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		ESP8266_StoptTransfer();//退出透传模式
		ESP8266_SetTransferMode(0);//关闭透传功能
		USARTx_SendString(USART3,"AT\r\n"); 
		if(ESP8266_ResponseData("OK")==0) 
		{
			ESP8266WIFI_Info.ESP8266_State=1;
			printf("ESP8266设备正常!重发次数:%d次\n",cnt);
			DelayMs(200);
			return 0;
		}
	}
	ESP8266WIFI_Info.ESP8266_ERROR=1;
	ESP8266WIFI_Info.ESP8266_State=0;
	return 1;
	
}

/*
函数功能: 关闭 ESP8266 回显
函数返回值: 0 表示成功  2 表示关闭回显失败
*/
u8 ESP8266_ATE0(void)
{
	u8 cnt=0;
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		USARTx_SendString(USART3,"ATE0\r\n"); //关闭回显
		if(ESP8266_ResponseData("OK")==0) 
		{
			printf("关闭回显成功!重发次数:%d次\n",cnt);
			DelayMs(200);
			return 0;
		}
	}
	return 2;
}

/*
函数功能: 设置 ESP8266 的工作模式 
函数参数:工作模式 
函数返回值: 0 表示成功  3 表示设置模式失败
*/
u8 ESP8266_SetWorkMode(u8 mode) //设置模式
{
	u8 cnt=0;
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		if(mode==1) USARTx_SendString(USART3,"AT+CWMODE=1\r\n"); //设置为 AP 模式
		else if(mode==2) USARTx_SendString(USART3,"AT+CWMODE=2\r\n"); //设置为 STA 模式
		else if(mode==3) USARTx_SendString(USART3,"AT+CWMODE=3\r\n"); //设置为 AP+STA 模式
		else return 3;
		if(ESP8266_ResponseData("OK")==0) 
		{
			if(mode==1)	printf("设置 AP 模式成功!重发次数:%d次\n",cnt);
			if(mode==2)	printf("设置 STA 模式成功!重发次数:%d次\n",cnt);
			if(mode==3)	printf("设置 AP+STA 模式成功!重发次数:%d次\n",cnt);
			return 0;
		}
	}
	return 3;
}

/*
函数功能: 复位重启 ESP8266
函数返回值: 0 表示成功  4 表示复位重启失败
*/
u8 ESP8266_RsetDevice(void)
{
	u8 cnt=0;
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		USARTx_SendString(USART3,"AT+RST\r\n"); //重启生效
		if(ESP8266_ResponseData("OK")==0) 
		{
			printf("重启成功!重发次数:%d次\n",cnt);
			DelayMs(2000);
			return 0;
		}
	}
	return 4;
}
/*
函数功能: STA模式下设置ESP8266将要连接的路由器名称和密码
函数参数: char *ssid  : WIFI名称
				  char *password :WIFI密码
返回值  : 0 表示正常   5 表示连接失败  
*/
u8 ESP8266_SetConnectWIFI(char * ssid ,char * password)
{
	char SendBuffer[100];
	u8 cnt=0,j=0,state=0;
	sprintf(SendBuffer,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,password);	
	strcpy((char *)ESP8266WIFI_Info.Password,password);
	strcpy((char *)ESP8266WIFI_Info.SSID,ssid);
//printf("SetConnectWIFI_Info : %s \n",SendBuffer);
	printf("正在努力连接 %s WIFI......!\n",ssid);
	OLED_Clear();
	OLED_DisplayString(0,0,16,16,"连接WIFI......");
	state=Get_Connect_WIFI_State();
	if(state==2||state==3)
	{
		OLED_Clear();
		OLED_DisplayString(0,0,16,16,"Connect WIFI OK");
		ESP8266WIFI_Info.WIFI_Connect_State=1;
		DelayMs(1000);
		return 0;
	}
	else
	{
		ESP8266WIFI_Info.WIFI_Connect_State=0;
	}
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		memset(USART3_RX_Data,0,1024);
		USART3_RX_State=0;
		USART3_RX_Count=0;
		USARTx_SendString(USART3,SendBuffer);  //连接对象路由器的 ssid 和 password
		for(j=0;j<ESP8266_CHECK_CNT;j++) 
		{
			if(USART3_RX_State)
			{
				USART3_RX_Data[USART3_RX_Count]='\0';  
				USART3_RX_State=0;
				USART3_RX_Count=0;
				if(strstr((const char*)USART3_RX_Data,"WIFI GOT IP"))  //判断WIFI的返回状态值
				{
					OLED_Clear();
					OLED_DisplayString(0,0,16,16,"成功连接WIFI!");
					ESP8266WIFI_Info.WIFI_Connect_State=1;
					DeviceInfo.Menu_Page=0;
					DeviceInfo.Display_Fleg=1;
					//DelayMs(1000);//等待时间 
					printf("成功连接到WIFI:%s !重连 %s 次数:%d次\n",ssid,ssid,cnt);
					return 0;
				}
			}
			DelayMs(1000);//等待时间
		}
	}
	ESP8266WIFI_Info.WIFI_Connect_State=0;
	OLED_Clear();
	printf("设备连接 %s WIFI失败!\n",ssid);
	OLED_DisplayString(0,0,16,16,"连接WIFI失败!");
	return 5;
}

u8 Get_Connect_WIFI_State()
{
	char SendBuffer[100];
	u8 cnt=0,j=0;
	sprintf(SendBuffer,"AT+CIPSTATUS\r\n");	
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		memset(USART3_RX_Data,0,1024);
		USART3_RX_State=0;
		USART3_RX_Count=0;
		USARTx_SendString(USART3,SendBuffer);  
		for(j=0;j<ESP8266_CHECK_CNT;j++) 
		{
			if(USART3_RX_State)
			{
				USART3_RX_Data[USART3_RX_Count]='\0';  
				USART3_RX_State=0;
				USART3_RX_Count=0;
				printf("\n连接wifi状态:%s \n",USART3_RX_Data);
				if(strstr((const char*)USART3_RX_Data,"STATUS:2"))  //获得 IP
				{
					printf("ESP8266 已经获得 IP\n");
					return 2;
				}
				if(strstr((const char*)USART3_RX_Data,"STATUS:3"))  //已连接
				{
					printf("ESP8266 已连接到WIFI\n");
					return 3;
				}
				if(strstr((const char*)USART3_RX_Data,"STATUS:4"))  //断开连接
				{
					printf("ESP8266 断开连接状态 IP\n");
					return 4;
				}
				if(strstr((const char*)USART3_RX_Data,"STATUS:5"))  //未连接到 WiFi
				{
					printf("ESP8266 未连接到 WiFi\n");
					return 5;
				}
			}
			DelayMs(1000);//等待时间
		}
	}
	return 1;
	

}

/*
函数功能: 查询 ESP8266 STA 模式下 IP 地址
函数返回值: 0 表示成功  6 表示查询STA模式下IP失败
*/
u8 ESP8266_STAModeGetIpAddr(void)
{
	u8 cnt=0,i=0,j=0;
	
  char *tmp_p1=NULL,*tmp_p2=NULL;
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		memset(USART3_RX_Data,0,1024);
		USARTx_SendString(USART3,"AT+CIFSR\r\n"); //查询STA模式下 模块 IP
		if(ESP8266_ResponseData("OK")==0) 
		{
			tmp_p1=strstr((const char*)USART3_RX_Data,"STAIP");
			if(tmp_p1==NULL) break;
			tmp_p2=strstr(tmp_p1+10,"\"");
			if(tmp_p2==NULL) break;
			snprintf(ESP8266WIFI_Info.IPAddr,tmp_p2-(tmp_p1+6),"%s",tmp_p1+7);
			
			tmp_p1=strstr((const char*)USART3_RX_Data,"STAMAC");
			if(tmp_p1==NULL) break;
			tmp_p2=strstr(tmp_p1+10,"\"");
			if(tmp_p2==NULL) break;
			snprintf(ESP8266WIFI_Info.MAC,tmp_p2-(tmp_p1+7),"%s",tmp_p1+8);
			for(i=0;i<17;i++)
			{
				if(ESP8266WIFI_Info.MAC[i]!=':') 
				{
					DeviceInfo.Device_MAC[j++]=ESP8266WIFI_Info.MAC[i];			
				}
			}
			memset(ESP8266WIFI_Info.MAC,0,20);
			strcpy(ESP8266WIFI_Info.MAC,DeviceInfo.Device_MAC);
			printf("DeviceInfo.Device_MAC:%s\n",ESP8266WIFI_Info.MAC);
//			printf("%s \n",(char *)USART3_RX_Data);
			printf("SAT_IP : %s 重发次数:%d 次\n",USART3_RX_Data,cnt);
			USART3_RX_State=0;
			USART3_RX_Count=0;
			DelayMs(200);
			return 0;
		}
	}
	return 6;
}
/*
ESP8266_ResponseData:+CIFSR:STAIP,"192.168.43.199"
+CIFSR:STAMAC,"84:f3:eb:17:e7:f1"

OK

SAT_IP : 
*/

/*
函数功能: 设置 ESP8266 模块连接到指定服务器
函数返回值: 0 表示成功  7 表示连接到服务器失败
*/
u8 ESP8266_ConnectServer(char *server_ip,u32 server_port)
{
	char SendBuffer[100];
	u8 cnt=0;
	OLED_Clear();
	printf("设备正在连接服务器......\n");
	OLED_DisplayString(0,0,16,16,"连接服务器......");
	sprintf(SendBuffer,"AT+CIPSTART=\"%s\",\"%s\",%d\r\n","TCP",server_ip,server_port);
	strcpy((char *)ESP8266WIFI_Info.SeverIP,server_ip);
	ESP8266WIFI_Info.SeverPort=server_port;
	printf("ConnectSever_Info : %s \n",SendBuffer);
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		USARTx_SendString(USART3,SendBuffer);  //模块连接到 server
		if(ESP8266_ResponseData("OK")==0) 
		{
			printf("连模块成功连接到服务器(%s:%d )!重发次数:%d次\n",server_ip,server_port,cnt);	
			OLED_Clear();
			OLED_DisplayString(0,0,16,16,"成功连接服务器!");
			DelayMs(1000);
			ESP8266WIFI_Info.WIFI_Connect_State=1;
			ESP8266WIFI_Info.Server_Connect_State=1;
			DeviceInfo.Menu_Page=0;
			DeviceInfo.Display_Fleg=1;
			return 0;
		}
		DelayMs(500);
	}
	ESP8266WIFI_Info.Server_Connect_State=0;
	OLED_Clear();
	OLED_DisplayString(0,0,16,16,"连接服务器失败!");
	if(ESP8266WIFI_Info.Server_Connect_Cnt++>ESP8266_CHECK_CNT) ESP8266WIFI_Info.ESP8266_ERROR=2;
	printf("服务器错误连接次数:Server_Connect_Cnt=%d \n",ESP8266WIFI_Info.Server_Connect_Cnt);
	DelayMs(1000);
	return 7;
}

/*
函数功能: 把ESP8266 设置为开启/关闭透传模式 )
函数返回值: 0 表示成功  8 表示开启/关闭透传模式失败
*/

u8 ESP8266_SetTransferMode(u8 mode)
{
	u8 cnt=0;
	while(cnt++<=ESP8266_CHECK_CNT)
	{	
		if(mode) USARTx_SendString(USART3,"AT+CIPMODE=1\r\n");  //开启透传模式
		else USARTx_SendString(USART3,"AT+CIPMODE=0\r\n");  //关闭透传模式
		if(ESP8266_ResponseData("OK")==0) 
		{
			printf("开启透传模式成功!重发次数:%d次\n",cnt);
			return 0;
		}
	}
	return 8;
}

/*
函数功能: 把ESP8266 设置为开始透传模式 )
函数返回值: 0表示成功  9 表示开始透传模式失败
*/
u8 ESP8266_StartTransfer(void)
{
	u8 cnt=0;
	while(cnt++<=ESP8266_CHECK_CNT)
	{
		USARTx_SendString(USART3,"AT+CIPSEND\r\n");  //开始透传
		if(ESP8266_ResponseData(">")==0) 
		{
			printf("开始透传模式成功!重发次数:%d次\n",cnt);
			return 0;
		}
	}
	return 9;
}

/*
函数功能: 把ESP8266 退出透传模式
函数返回值: 0表示成功  
*/
u8 ESP8266_StoptTransfer(void)
{
	USARTx_SendString(USART3,"+++");  //退出透传
	printf("已成功退出透传模式!\n");
	DelayMs(2000);
	return 0;
}

/*
函数功能: 把ESP8266 设置为 STA 的模式 (TCP Client 透传模式 )
函数形参:   ssid :要连接到的WIFI名称   password:要连接到的WIFI密码   sever_ip:服务器的IP   sever_port: 服务器的端口号
函数返回值: 0表示成功  其他见注释
例如:ESP8266_TCP_ClientModeInit("xiaohai","123456788","193.112.82.114",8080)
*/
u8 ESP8266_TCP_ClientModeInit(char *ssid ,char * password ,char * sever_ip ,u32 sever_port)
{
	char buff[16];
	OLED_DisplayString(0,0,16,16,"ESP8266 Init... ");
	printf("\n正在设置ESP8266 为 TCP Client 透传模式中.......\n");
	if(ESP8266_CheckDevice()) return 1; /*1.检查设备是否存在*/	
	if(ESP8266_ATE0()) return 2; /*2.关闭回显*/	
	if(ESP8266_SetWorkMode(1)) return 3; /*3.设置为 STA 模式*/		 
	if(ESP8266_RsetDevice()) return 4; /*4.复位设备*/	
	if(ESP8266_ATE0()) return 2; 	/*5.关闭回显*/	
	if(ESP8266_SetConnectWIFI(ssid,password)) return 5;  /*6.设置将要连接的WIFI名称和密码*/	
	if(ESP8266_STAModeGetIpAddr()) return 6; 	/*7.查询模块STA 模式下的 IP地址*/
	if(ESP8266_ConnectServer(sever_ip,sever_port)) return 8; 	/*8.模块连接到 server*/
	if(ESP8266_SetTransferMode(1)) return 7; /*9.开启透传模式*/	
	if(ESP8266_StartTransfer()) return 8; /*10.开始透传模式*/	
//	SetDataPackage(&RxTxDataPackage,"Send_Info",ID1,ID2,ID3); /*封包数据*/
//	USARTx_SendStructPackage(USART3,(u8 *)&RxTxDataPackage,sizeof(struct SocketPackageData));
//	printf("结构体大小=%d\n",sizeof(struct SocketPackageData));
	printf("成功连接服务器!\nWIFI:%s\nIP:%s\nMAC:%s\nSeverIP:%s\nSeverPort:%d\n",ESP8266WIFI_Info.SSID,ESP8266WIFI_Info.IPAddr,ESP8266WIFI_Info.MAC,ESP8266WIFI_Info.SeverIP,ESP8266WIFI_Info.SeverPort);
	OLED_DisplayString(0,0,16,16,"成功连接服务器!");
	sprintf(buff,"WIFI:%s",ESP8266WIFI_Info.SSID);
	OLED_DisplayString(0,2,16,16,buff);
	if(strlen(ESP8266WIFI_Info.IPAddr)>13) 
	{
		sprintf(buff,"%s",ESP8266WIFI_Info.IPAddr);
	}
	else
	{
		sprintf(buff,"IP:%s",ESP8266WIFI_Info.IPAddr);
	}
	OLED_DisplayString(0,4,16,16,buff);
	sprintf(buff,"MAC:%s",ESP8266WIFI_Info.MAC);
	OLED_DisplayString(0,6,16,16,buff);
	DelayMs(2000);
	OLED_Clear();
	return 0;
}

void ESP8266_Data_Handler(void)
{
	if(USART3_RX_State)
	{
		 USART3_RX_Data[USART3_RX_Count]='\0';
		 printf("USART3_RX_Data=%s\n",USART3_RX_Data);
		 printf("USART3_RX_Count=%d\n",USART3_RX_Count);
		 USART3_RX_State=0;
		 USART3_RX_Count=0;
	}
}
/*
函数功能: 对接收的数据进行解包处理
函数返回值: 0 表示数据校验成功  1 数据包校验错误   2 数据包大小接收错误
*/
u8 ESP8266_TransferDataHander(void)
{
	if(USART3_RX_State)//表示收到服务器数据包
	{
		USART3_RX_State=0;
		/*1. 读取服务器数据包*/
		memcpy(&RxTxDataPackage,USART3_RX_Data,sizeof(struct SocketPackageData));	
		printf("rx_cnt= %d   package=%d ",USART3_RX_Count,sizeof(struct SocketPackageData));
		if(USART3_RX_Count==sizeof(struct SocketPackageData))
		{
			if(CheckDataPackage(RxTxDataPackage)==0)
			{
				if(RxTxDataPackage.id[0]==ESP8266WIFI_Info.ID1 && RxTxDataPackage.id[1]==ESP8266WIFI_Info.ID2 && RxTxDataPackage.id[2]==ESP8266WIFI_Info.ID3)
				{
					printf("rx=%s,%d,%d,%d\n",RxTxDataPackage.SrcDataBuffer,RxTxDataPackage.id[0],RxTxDataPackage.id[1],RxTxDataPackage.id[2]);
//				USART_Handler(RxTxDataPackage.SrcDataBuffer);
				}
			}
			else
			{
				USART3_RX_Count=0;
				return 1;//数据包校验错误
			}
		}
		else
		{
			USART3_RX_Count=0;
			return 2;//数据包大小接收错误
		}
	}
	USART3_RX_Count=0;
	return 0;
}
/*
函数功能: 对要发送的数据进行封包处理
函数形参:   data_pack :要封包的结构体  SendBuff:要封包的结构体  id:设备的96位ID
函数返回值: 0表示成功
*/
u8 SetDataPackage(struct SocketPackageData *data_pack,u8 *SendBuff,u32 id1,u32 id2,u32 id3)
{
	u8 i;
	/*1. 封装帧头*/
	data_pack->FrameHead[0]=0xA1;
	data_pack->FrameHead[1]=0xA2;
	data_pack->FrameHead[2]=0xA3;
	data_pack->FrameHead[3]=0xA4;
	/*2. 赋值数据*/
	memcpy(data_pack->SrcDataBuffer,SendBuff,30);
	data_pack->id[0] = id1;
	data_pack->id[1] = id2;
	data_pack->id[2] = id3;
	data_pack->CheckSum=0;
	/*3. 计算校验和*/
	data_pack->CheckSum=0;
	for(i=0;i<sizeof(data_pack->SrcDataBuffer)/sizeof(data_pack->SrcDataBuffer[0]);i++)
	{
		data_pack->CheckSum+=data_pack->SrcDataBuffer[i];
	}
	return 0;
}

/*
函数功能: 校验数据包是否正确
函数形参:   data :校验的数据包结构
函数返回值: 0表示成功 其他值表示失败
*/
u8 CheckDataPackage(struct SocketPackageData data)
{
	unsigned int checksum=0;
	int i;
	if(data.FrameHead[0]!=0xA1||data.FrameHead[1]!=0xA2||data.FrameHead[2]!=0xA3||data.FrameHead[3]!=0xA4)
	{
		printf("帧头校验错误!\n");
		return 1;
	}
	for(i=0;i<30;i++)//这样到好处是当buff的大小变化不会影响校验循环次数
	{
		checksum+=data.SrcDataBuffer[i];
	}
	if(checksum!=data.CheckSum)
	{
		printf("校验和错误!\n");
		return 1;
	}
	return 0;
}

/*
函数功能: 打印ESP8266设置STA模式的错误信息
*/
void ESP8266_STA_ErrorInfo(u8 value)
{
	switch(value)
		{
			case 0:	printf("ESP8266成功进入STA透传模式!\n");OLED_DisplayString(0,0,16,16,"Transfer Mode OK");break;
			case 1:	printf("ESP8266设备不存在.....\n");OLED_DisplayString(0,0,16,16,"No ESP Device!!!");DelayMs(1000);break;
			case 2: printf("关闭回显失败.....\n");OLED_DisplayString(0,0,16,16,"Set ATE0 failure");DelayMs(1000);break;
			case 3: printf("设置模式失败.....\n");OLED_DisplayString(0,0,16,16,"Set mode failure");DelayMs(1000);break;
			case 4:	printf("重启失败.....\n");OLED_DisplayString(0,0,16,16,"Restart failure!");DelayMs(1000);break;
			case 5:	printf("连接对象路由器失败.....\n");OLED_DisplayString(0,0,16,16,"连接WIFI失败!!! ");DelayMs(1000);break;
			case 6:	printf("查询STA模式下IP失败.....\n");OLED_DisplayString(0,0,16,16,"Fail to get IP!");DelayMs(1000);break;
			case 7:	printf("连模块连接到 server失败.....\n");OLED_DisplayString(0,0,16,16,"连接服务器失败! ");DelayMs(1000);break;
			case 8:	printf("开启透传模式失败.....\n");OLED_DisplayString(0,0,16,16,"Fail to transfer");DelayMs(1000);break;
			case 9:	printf("开始透传失败.....\n");OLED_DisplayString(0,0,16,16,"Fail to transfer");DelayMs(1000);break;
			default : break;
		}

}

u8 Restart_ConnectServer(void)
{
	static	u8 SetTransferMode_Fleg=0;
	static	u8 StartTransfer_Fleg=0;
	static	u8 Connect_wifi_Fleg=0;
//	connect_server:	
	if(ESP8266_ConnectServer("xiaohai-linux.cn",80)==0)//连接服务器
	{
		
		SetTransferMode:
		if(ESP8266_SetTransferMode(1)==0)//设置透传模式
		{
			StartTransfer:
			if(ESP8266_StartTransfer()==0)//开始透传
			{
				printf("重发温湿度数据....\n");
				return 0;
			}
			else //重新设置透传模式失败,就重新设置
			{
				printf("\n StartTransfer Mode ..........\n");
				if(StartTransfer_Fleg++ == ESP8266_CHECK_CNT) goto connect_wifi;
				else 	goto StartTransfer;
			}
		}
		else //重新设置STA 模式失败,就重新设置
		{
			printf("\n Set Esp8266 STA Mode ..........\n");
			if(SetTransferMode_Fleg++ == ESP8266_CHECK_CNT) goto connect_wifi;
			else goto SetTransferMode;
		}
	}
	else //重新连接服务器失败,就重新连接wifi
	{
		printf("\n reconect wifi..........\n");
		connect_wifi:
#ifdef AZE
		ESP8266_STA_ErrorInfo(ESP8266_TCP_ClientModeInit("AZE","88888888","xiaohai-linux.cn",80));
#endif 
#ifdef TP_LINK
		ESP8266_STA_ErrorInfo(ESP8266_TCP_ClientModeInit("TP-LINK","fuxibuyaowanshouji.666","xiaohai-linux.cn",80));
#endif
		if(Connect_wifi_Fleg++ == ESP8266_CHECK_CNT) 
		{
			SetTransferMode_Fleg=0;
			StartTransfer_Fleg=0;
			Connect_wifi_Fleg=0;
			return 1;
		}
		else 
		{
			printf("Connect_wifi_Fleg= %d \n",Connect_wifi_Fleg);
			return 0;
		}
	}
}



/*
snprintf(output, 256, "{\"mac_address\":\"%x%x%x%x%x%x\",\"temperature_1\":%f,\"temperature_2\":%f,\"humidity_1\":%f,\"humidity_2\":%f}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], temperature_1, temperature_2, humidity_1, humidity_2);
"mac_address":"84f3eba9c8df","temperature_1":25,"temperature_2":555.55,"humidity_1":66,"humidity_2":5555.55
POST //upload HTTP/1.1
Host: 111.230.199.63
Content-Type: application/json
Content-Length: 215
{"mac_address":"aabbccddeeff","temperature_1":33.3,"temperature_2":666,"humidity_1":77.77,"humidity_2":111.11}


ESP8266_WIFI AT指令说明:
(以下所有指令没有特殊说明都需要加  \r\n  为结束)
AT					    		测试指令
AT+RST			    		重启模块
AT+GMR			  			查看版本信息
ATE* 								ATE0 : 关闭回显   ATE1 : 开启回显
AT+RESTORE 					恢复出厂设置
AT+UART         		设置串口配置

AT+CWMODE=<mode>    选择 WIFI 应用模式      参数<mode>说明: 1 Station 模式		2 AP 模式    3 AP+Station 模式

AT+CWMODE=?  				测试指令		响应:+CWMODE(1-3)   OK							
AT+CWMODE?      		查询指令    响应返回当前模块的模式 :+CWMODE:<mode>   OK

AT+CWJAP?						查询指令    响应返回当前选择的 AP: + CWJAP:<ssid>(没加入 AP,则返回 No AP)  OK
AT+CWJAP =<ssid>,< password>    设置指令    响应 :  OK    连接不成功,则返回 ERROR     例如:AT+ CWJAP =“xiaohai”,“123456788”
															  参数说明:<ssid>字符串参数,接入点名称    <pwd>字符串参数,密码最长 64 字节 ASCII 参数
															  设置需要开启Station 模式 , 若 SSID 或 者password 中含 有’,’、 ’“’和’\’时,需要进行转义,其它字符转义无效
																
AT+CWQAP 						退出与 AP 的连接			响应 : OK
AT+CWSAP?						查询指令		响应 :返回当前 AP 的参数   + CWSAP:<ssid>,<pwd>,<ch>,<ecn>
AT+CWSAP=<ssid>,<pwd>,<ch>,<ecn>       
										设置指令    响应:OK     设置失败,则返回 ERROR
										参数说明:指令只有在 AP 模式 开启后有效  (本设置掉电重启设置仍保留。)
															<ssid>字符串参数,接入点名称
															<pwd>字符串参数,密码最长 64 字节 ASCII
															<ch>通道号
															<ecn>0 OPEN  1 WEP   2 WPA_PSK   3 WPA2_PSK   	4 WPA_WPA2_PSK
										例如:AT+CWSAP="ATK_ESP8266","12345678",6,4
														
AT+CWLIF 											查看已接入设备的 IP				响应:<ip addr>, <mac>   OK		

AT+CWDHCP= <mode>,<en>				设置 DHCP 开关						响应:OK		  (本设置掉电重启设置仍保留。)
															参数说明<mode>   0:设置AP     1:设置STA     2:设置AP和STA
																			<en>     0:去能 DHCP  1:使能 DHCP			
AT+CWAUTOCONN=<enable>				设置 STA 开机自动连接   	响应:OK		   (本设置掉电重启设置仍保留。)
															参数说明<enable>  0:开机禁能 STA 自动连接    1:开机使能 STA 自动连接
									
AT+CIPSTAMAC?									查询STA模式的MAC地址		响应:+CIPSTAMAC:<mac>  OK     
AT+CIPSTAMAC=<mac> 						设置STA模式的MAC地址    响应:OK           (本设置掉电重启设置仍保留。)
															举例 : AT+CIPSTAMAC="18:fe:35:98:d3:7b"

AT+CIPSTA?										查询模块 STA 模式的 IP 地址    响应:+CIPSTA:<ip>   OK
AT+CIPSTA=<ip> 								设置模块 STA 模式的 IP 地址    例如:AT+CIPSTA="192.168.1.100"

AT+CIPAP?											查询模块 AP 模式的 IP 地址     响应:+CIPAP:<ip>   OK
AT+CIPAP=<ip> 								设置模块 AP 模式的 IP 地址    例如:AT+CIPAP="192.168.5.1"

AT+SAVETRANSLINK=<mode>,<remote IP>,<remoteport>,<type>    保存透传连接到 Falsh   	举例 AT+SAVETRANSLINK=1,”192.168.1.110”,8086,”TCP”
参数说明:<mode>										<remote IP>    <remote port>    <type>                             
					0 取消上电透传						远端 IP					远端端口号       TCP 或者 UDP,缺省默认为 TCP  
					1 保存上电进入透传模式
AT+CIPMUX?										查询多连接模式    响应:OK   如果已经处于连接状态,则返回:Link is builded
															参数说明<mode> : 0 单路连接模式   1 多路连接模式  (只有当连接都断开后才能更改,如果开启过serve需要重启模块)
AT+CIPSERVER=<mode>,<port>    配置为服务器      响应: OK    ( AT+ CIPMUX=1 时才能开启服务器 )
															参数说明<mode> :  0 关闭 server 模式   1 开启 server 模式
																			<port> :  端口号,缺省值为 333

AT+CIPMODE=?									查询模块传输模式   响应:OK 
AT+CIPMODE=<mode>							设置模块传输模式   响应:OK   如果已经处于连接状态,则返回 :Link is builded
															参数说明<mode>:0 非透传模式   1 透传模式
															
AT+CIPSTO=?										查询服务器超时时间    响应:+ CIPSTO:<time>   OK    
AT+CIPSTO=<time>							设置服务器超时时间    响应:OK 
															参数说明<time> :0~28800 服务器超时时间,单位为 s
															
AT+PING=<ip>   								响应:+<time>  OK     若能 ping 通则返回 OK,否则返回 ERROR
**********************************/

实物工程源码下载:

农业大棚环境监测(温湿度+二氧化碳浓度+光照强度+时间+OLED显示+ESP8266连网+EEPROM)-C文档类资源-CSDN下载

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值