物联网loT开发——ESP8666 ESP-01SWiFi模块使用
1. 引言:物联网与ESP01S的简介
物联网:就是把各种日常物品(如家电、汽车、传感器等)通过互联网与计算设备连接,使它们能够相互沟通并进行智能化处理和控制。比如单片机从传感器获取的温湿度信息,通过无线网络传输到平台,经过平台算法处理再反馈给单片机进行温度或湿度控制
esp01s:它能当作这其中传输数据的中间桥梁。连接上WiFi和目标端口,单片机发送给esp01s的信息就能传输到目标端口上
2. ESP01S硬件概述


3.ESP01S配置:通过USB转TTL-CH340模块连接AT指令配置





4.ESP01S使用:stm32f103C8T6做主控连接WIFI
uint8_t esp8266_Init(void) //ESP01s初始化,printf函数以及重定义到串口1作为调试信息
{
//状态检测
printf("准备配置模块\r\n");
printf("准备退出透传模式\n");
if(esp8266_quit_trans())
{
printf("退出透传模式失败,准备重启\r\n");
return 6;
}else printf("退出透传模式成功\r\n");
printf("查询模块是否在线\r\n");
if(esp8266_send_cmd("AT","OK",100))
{
printf("模块不在线准备重启\r\n");
return 1;
}else printf("设置查询在线成功\r\n");
//设置
printf("准备设置STA模式\r\n");
if(esp8266_send_cmd("AT+CWMODE=1","OK",50))
{
printf("设置STA模式失败准备重启\r\n");
return 1;
}else printf("设置STA模式成功\r\n");
printf("准备重启\r\n");
if(esp8266_send_cmd("AT+RST","OK",50))
{
printf("重启失败,准备重启\r\n");
return 2;
}else printf("重启成功,等待三秒\r\n");
printf("准备设置自动连接\r\n");
if(esp8266_send_cmd("AT+CWAUTOCONN=1","OK",50))
{
printf("设置连接失败,准备重启\r\n");
return 3;
}else printf("设置连接成功\r\n");
printf("准备链接路由器\r\n");
if(esp8266_Connect_AP())
{
printf("连接路由器失败,等待重启\r\n");
return 4;
}else printf("连接路由器成功\r\n");
HAL_Delay(3000);//延时等待WIFI模块就绪
//TCP连接
printf("设置为单路连接\r\n");
if(esp8266_send_cmd("AT+CIPMUX=0","OK",100))
{
printf("关闭多路连接失败,准备重启\r\n");
return 7;
}else printf("设置关闭多路连接成功\r\n");
printf("准备链接服务器\r\n");
if(esp8266_Connect_Server())
{
printf("连接服务器失败,等待重启\r\n");
return 8;
}else printf("连接服务器成功\r\n");
printf("设置为透传模式\r\n");
if(esp8266_send_cmd("AT+CIPMODE=1","OK",50))
{
printf("设置透传失败,准备重启\r\n");
return 6;
}else printf("设置透传成功\r\n");
//发送数据
printf("设置开启透传模式\r\n");
if(esp8266_send_cmd("AT+CIPSEND","OK",1000))
{
printf("开启透传失败,准备重启\r\n");
return 9;
}else printf("开启透传成功\r\n");
USART2_RX_STA = 0;//清除串口2的RX获取标志位
memset(USART2_RX_BUF,0,USART2_REC_LEN);//清空串口2的缓冲区
return 0; //一切顺利返回0
}
uint8_t esp8266_send_cmd(char *cmd, char *ack, uint16_t waittime) //ESP8266发送指令(底层函数)
{
uint8_t res = 0;
USART2_RX_STA = 0;
memset(USART2_RX_BUF,0,USART2_REC_LEN); //将串口2的缓存空间清0
WIFI_printf("%s\r\n", cmd); //这里实际是通过串口2发送给WiFi模块
if(waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
HAL_Delay(10);//HAL库延时函数
if(USART2_RX_STA&0x8000) //接收到期待的应答结果,STA的最高位为标志位
{
if(esp8266_check_cmd((uint8_t *)ack))
{
HAL_Delay(10);
break; //得到有效数据
}
USART2_RX_STA=0; //串口3标志位清0
}
}
if(waittime==0)res=1;
}
return res;
}
//命令检查函数
uint8_t* esp8266_check_cmd(uint8_t *str) //ESP8266检查指令(底层函数)
{
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 (uint8_t*)strx;
}
//WIFI发送函数
void WIFI_printf (char *fmt, ...)
{
char buff[USART2_REC_LEN+1]; //用于存放转换后的数据 [长度]
uint16_t i=0;
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsnprintf(buff, USART2_REC_LEN+1, fmt, arg_ptr);//数据转换
i=strlen(buff);//得出数据长度
if(strlen(buff)>USART2_REC_LEN)i=USART2_REC_LEN;//如果长度大于最大值,则长度等于最大值(多出部分忽略)
HAL_UART_Transmit(&huart2,(uint8_t *)buff,i,0xffff);//串口发送函数(串口号,内容,数量,溢出时间)
va_end(arg_ptr);
}
//ESP8266退出判断(底层函数)
uint8_t esp8266_quit_trans(void)
{
while((USART2->SR&0X40)==0); //等待发送空
USART2->DR='+';
HAL_Delay(15); //大于串口组帧时间(10ms)
while((USART2->SR&0X40)==0); //等待发送空
USART2->DR='+';
HAL_Delay(15); //大于串口组帧时间(10ms)
while((USART2->SR&0X40)==0); //等待发送空
USART2->DR='+';
HAL_Delay(500); //等待500ms
return esp8266_send_cmd("AT","OK",20); //退出透传判断
}
//连接WiFi的底层函数
uint8_t esp8266_Connect_AP()
{
uint8_t i=10;
char *p = (char*)malloc(50);//分配存储空间的指针
//SSID与PASS为WiFi账号与密码
sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",SSID,PASS);//发送连接AT指令
while(esp8266_send_cmd(p,"WIFI GOT IP",1000) && i)//循环判断等待连接AP的结果
{
printf("链接AP失败,尝试重新连接\r\n"); //连接失败的反馈信息
i--;
}
free(p);//释放分配的空间和指针
if(i) return 0;//执行成功返回0
else return 1;//执行失败返回1
}
//ESP8266连接到服务器
uint8_t esp8266_Connect_Server()
{
uint8_t i=10;
char *p = (char*)malloc(70);//分配存储空间的指针
//IOT_DOMAIN_NAME为IP地址,IOT_PORTNUM为端口号。配置AT指令时有提到
sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",IOT_DOMAIN_NAME,IOT_PORTNUM);
while(esp8266_send_cmd(p,"CONNECT",1000) && i)
{
printf("链接服务器失败,尝试重新连接\r\n");
i--;
}
free(p);//释放分配的空间和指针
if(i)return 0;//执行成功返回0
else return 1;//执行失败返回1
}
主函数里面调用:while(esp8266_Init());//连接服务器。
一切正常之后。代表服务器以及连接成功。之后所有通过串口2给WiFi模块发送的消息都将传给服务器。到此我们物联网就实现了第一步。
6.常见问题与解决方法
7.建议
如果想要深入了解物联网的底层,可以看看其他的文章。本文只为后面物联网的连接、数据上传、下发操作做准备,不会过多的讲解原理。
新人写手,有什么问题、错误可以随时交流,
作者:嵌入式硬件探索