看到网上用遥控器控制小车的视频感觉非常酷,刚好对ESP8266_01s这款mini的无线模块情有独钟(性价比非常高),之前一直使用arduino对这块板子进行物联网的设计,可以说是物联网的yyds了。除此之外还可以用AT指令对其进行配置,让两块板子进行通信。
做什么:单片机 控制 ESP8266_01s。
怎么做:a.STM32核心板提供ESP8266_01s所需要的硬件环境;
b.程序中写好特定格式的命令,通过串口发送给ESP8266_01s。
stm32f103c8t6
esp8266_01s
双轴按键摇杆
先利用电脑通过串口发送信息给 ESP8266_01s模块,熟悉一下流程。
选择正确的 COM 号(WIFI与你电脑相连的串口),然后设置波特率为 115200,勾选发送新行 (必选!即自动添加回车换行功能)然后发送 AT指令 到 ESP8266_01s模块。
然后理清楚一下服务器(主机)和客户端(从机)分别需要执行什么AT指令。
服务器(主机) |
AT指令 |
客户端(从机) |
AT指令 |
检测模块是否在线 |
AT |
检测模块是否在线 |
AT |
修改服务器WIFI名和密码 |
AT+CWSAP=“esp8266_01s”,“a1234567”,11,3 |
设置 WIFI 模式1 |
AT+CWMODE=1 |
设置 WIFI 模式2 |
AT+CWMODE=2 |
重启生效 |
AT+RST |
重启生效 |
AT+RST |
连接服务器的WIFI |
AT+CWJAP=“esp8266_01s”,“a1234567” |
建立服务器指令 |
AT+CIPSERVER=1,8089 |
连接服务器 |
AT+CIPSTART=“TCP”,“你的服务器 IP 地址”,8089 |
获取服务器IP地址 |
AT+CIFSR |
开启透传模式 |
AT+CIPMODE=1 |
开始透传 |
AT+CIPSEND |
利用串口调试助手发送'AT'指令给它,它会返回'OK'的响应。如果没有响应有可能是固件的问题,需要重新刷一下原厂的固件,原厂默认是'AT'指令固件一般可以直接用。如果要开启透传模式需要刷入透传模式的固件才可以使用,固件包可以到安可信官网进行下载。
关于AT指令的使用细则网上已经有很多资料,我不再赘述,可以参考这篇文章 (2条消息) 两个ESP8266相互通信_点灯大师~的博客-CSDN博客
在我进行‘AT’指令进行数据传输时只有客户端可以开启透传模式,服务端怎么也开不起来,有懂的大佬可以在评论区指点一下
完成了esp8266与电脑的串口通信我们就可以尝试用单片机与它进行通信
服务端代码
//ESP8266服务端
void esp8266_server(void)
{
//设置工作模式 1: station模式 2:AP模式 3:兼容AP+station模式
esp8266_send_cmd("AT+CWMODE=3","OK",50);
//让WiFi模块重启
esp8266_send_cmd("AT+RST","ready",20);
delay_ms(1000); //延时等待重启
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
//0:单路连接模式 1:多路连接模式
esp8266_send_cmd("AT+CIPMUX=1","OK",20);
//建立服务器server指令
esp8266_send_cmd("AT+CIPSERVER=1,8089","OK",20);
/修改无线名字和密码指令
esp8266_send_cmd("AT+CWSAP=\"ONE-ETA\",\"a1234567\",11,3","OK",20);
}
//向esp8266发送命令
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%s\r\n",cmd); //发送命令
if(ack&&waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收期待应答结果
{
if(esp8266_check_cmd(ack))
{
printf("ack:%s\r\n",(u8*)ack);
break;//得到有效数据
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
//ESP8266发送命令后,检测收到的应答
u8* esp8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //接收的第一次数据
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
//向esp8266发送数据
u8* esp8266_send_data(u8 *cmd,u16 waittime)
{
char temp[5];
char *ack=temp;
USART3_RX_STA=0;
u3_printf("%s",cmd); //发送命令
if(waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收期待的应答结果
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
ack=(char*)USART3_RX_BUF;
printf("ack:%s\r\n",(u8*)ack);
USART3_RX_STA=0;
break;//得到有效数据
}
}
}
return (u8*)ack;
}
客户端代码
//ESP8266模块和PC进入透传模式
void esp8266_start_trans(void)
{
//设置工作模式 1: station模式 2:AP模式 3:兼容AP+station模式
esp8266_send_cmd("AT+CWMODE=1","OK",50);
//让WiFi模块重启
esp8266_send_cmd("AT+RST","ready",20);
Delay_ms(1000); //ÑÓʱ3SµÈ´ýÖØÆô³É¹¦
Delay_ms(1000);
Delay_ms(1000);
Delay_ms(1000);
//让模块连接上自己的路由器
(esp8266_send_cmd("AT+CWJAP=\"hao\",\"h123456.\"","WIFI GOT IP",600));
//0:单路连接模式 1:多路连接模式
esp8266_send_cmd("AT+CIPMUX=0","OK",20);
//建立TCP连接
(esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"192.168.4.1\",8080","CONNECT",200));
//是否开启透传模式 0:关闭 1:开启
esp8266_send_cmd("AT+CIPMODE=1","OK",200);
//透传模式下开始发送数据指令
esp8266_send_cmd("AT+CIPSEND","OK",50);
}
//ESP8266退出透传指令
//返回值 0:退出成功;1:退出失败
u8 esp8266_quit_trans(void)
{
u8 result=1;
u3_printf("+++");
Delay_ms(1000);
result=esp8266_send_cmd("AT","OK",20);//退出透传判断
return result;
}
//向esp8266发送命令
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%s\r\n",cmd); //发送命令
if(ack&&waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收期待应答结果
{
if(esp8266_check_cmd(ack))
{
printf("ack:%s\r\n",(u8*)ack);
break;//得到有效数据
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
//ESP8266发送命令后,检测收到的应答
u8* esp8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //接收的第一次数据
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
//向esp8266发送数据
u8* esp8266_send_data(u8 *cmd,u16 waittime)
{
char temp[5];
char *ack=temp;
USART3_RX_STA=0;
u3_printf("%s",cmd); //发送命令
if(waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收期待的应答结果
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
ack=(char*)USART3_RX_BUF;
printf("ack:%s\r\n",(u8*)ack);
USART3_RX_STA=0;
break;//得到有效数据
}
}
}
return (u8*)ack;
}
在进行服务端串口进行数据接收的时候,智能出现数据的前两位,后来发现是我将printf放入了中断服务函数当中去了,可能printf会占用你的时间,最好将printf放入while循环当中打印接收到的数据。接收到的数据最好存入数组当中,方便我们对接收的数据进行判断。
附:我们的模块是基于TCP通信的,我们也可以在手机上下载一个TCP调试助手,方便我们去调试小车
这是我的第一篇博客,主要就是记录自己在做的过程当中遇到的一些问题,之前都是看别人的博客来解决自己的问题,现在也希望自己的东西可以帮助到别人。