基于WIFI模块(ESP8266)与非同一个局域网内服务器建立连接(转)
Posted PacexDong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于WIFI模块(ESP8266)与非同一个局域网内服务器建立连接(转)相关的知识,希望对你有一定的参考价值。
案例简述:
以WIFI模块(ESP8266)为开发对象,处在局域内网中的WIFI模块,连接到另外一个局域内网的TCP服务器,形成WIFI模块和服务器之间通信。本文先以电脑控制WIFI模块的连接,熟悉AT指令的使用,再通过编程手段,由单片机去控制WIFI模块,深入学习。
一.电脑端调试,控制WIFI模块的连接
说明:将WIFI模块通过串口与电脑连接,电脑通过串口调试软件给模块发送AT指令,控制WIFI模块与其他局域网内的服务器建立连接。
步骤:
1. 所需条件:
1)两台PC机,一个路由器,确保有台电脑可联网,并且路由器也联网,并分别连接在不同的局域网内,(支招:没有路由器的可以通过一台电脑开WIFI作为路由器,但确保是两个局域网内。没有两个局域网的,可以用手机开wifi热点给电脑提供网络,本实验不怎么费手机流量,勿担心)
2)联网的电脑(B电脑)安装花生壳软件(注意用的是穿透版),登入保持在线。
3)在有花生壳的电脑(B电脑)开启网络调试助手软件,另一台电脑(A电脑)开启串口调试软件。
4)有串口调试软件的电脑(A电脑),通过USB转TTL线与WIFI模块相连接。
前期准备工作如下图:
花生壳软件:
网络调试助手:
串口调试助手:
wifi模块与电脑串口连接(只需要TX,RX,VCC,GND引脚)
2. WIFI 模块连接到路由器
通过串口调试助手给wifi模块发送AT指令,控制模块。
1)复位WIFI模块,指令:AT+RST(注意发送指令后必须加换行,下面同理)
指令说明:
指令实现:
1)选择模式,指令:AT+CWMODE=3
指令说明:
指令实现:
1)连接到路由器,指令:AT+ CWJAP =”ldy”,”99999999”(路由器名称和密码,只能是非中文名称)
指令说明:
指令实现:
3. 模块与其他局域网服务器建立TCP连接
1)在B电脑上开启花生壳和网络调试助手,其中花生壳被映射的地址应为电脑本机IP地址,端口任意。网络调试助手上的IP和端口应该设置为被花生壳所映射的IP和端口。IP被花生壳映射到外网域名和端口号,是将要被WIFI模块连接的外网地址。如图:
2)启动单连接,指令:AT+ CIPMUX =0
指令说明:
指令实现:
3)连接到TCP服务器,
AT+CIPSTART=”TCP”,”14z95r6389.iask.in”,35447(改指令可以通过域名和端口号去连接,也可以通过IP和端口号连接,由于被穿透后是域名,故采用域名形式连接)
指令描述:
指令实现:
4)发送消息 AT+CIPSEND=5(5指的要发送消息的长度)
指令说明:
指令描述:
WIF模块端发送:
服务器端接收:
5)接收服务器(接收到消息会有“+IPD”的数据头)
说明:
接收实现:(接收到服务器端发的”zzz”字符)
二.单片机实现控制WIFI模块与服务器连接
从上面电脑端实现了,对WIFI模块连接到路由器后,再与服务器建立连接的过程,都是通过AT指令实现的,目的是为了熟悉AT指令的使用和调试。接下来就可以比较容易的通过单片机来控制WIFI模块,将需要发送的AT指令写入程序中。
实验内容:单片机控制WIFI模块,给服务器端发送长度为7位的字符串”abcdefg”
1.硬件条件
基于STM32单片机,通过USART3与WiFi模块相连接。
2.程序核心代码
本人已经写好了发送AT指令的封装函数,可灵活实现每个指令的定时等待和多次重发功能。可大大提高模块使用的稳定性,现在附上主要代码供参考。
主函数如下:
int main(void)
{ //通过域名形式连接到服务器
char *string
="AT+CIPSTART="TCP","14z95r6389.iask.in",35447";
char *Seddstr = "abcdefg"; //被发送的字符串
ALL_init();//初始化各种外设
LED_ALL2_ON;
delay_ms(1000);
WIFI_AT_Command( "AT+RST","ready",5,2,ENABLE);
delay_ms(1000);
if(Send_wifiAT("AT+CWSAP?")==0)//判断是否连接上路由器
{
WIFI_AT_Command("AT+CWMODE=3","OK",3,2,DISABLE); //STATION兼AP模式
WIFI_AT_Command("AT+CWJAP="ldy","99999999"","CONNECTED",10,3,DISABLE); //连接的到路由器,需要等待较长时间
}
WIFI_AT_Command("AT+CIPMUX=0","OK",3,2,DISABLE); //单连接
WIFI_AT_Command((char*)string,"OK",5,3,ENABLE);
//连接到服务器
SendDATA_wifi(Seddstr,strlen(Seddstr));
//发送数据
while(1)
{
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
发送AT指令封装函数如下:(自写的封装函数,可供网友移植)
/*
函数:WIFI_AT_Command
功能:(智能化发送指令)在规定时间内,可多次重发某个指令,多次发送失败可复位
参数:b:发送内容,a:等待接收内容,timeout_S:发单次内最多允许等待 的时间,ReSendcount:最多可以重复发几次(失败情况),EN_Reset:如果失败是否复位机器。
返回: 成功回1 失败回0
*/
char WIFI_AT_Command(char *b,char *a,u8 timeout_S , char ReSendcount,FunctionalState EN_Reset)
{
u16 count =0;
u8 i = 0;
WaitACKflag = 1; //WaitACKflag用于防止重入函数 strstr
CLR_Buf3();
ACK_Command = a;
for(i =1 ; (i<= ReSendcount && WaitACKflag); i++) //若失败 ,重复发送ReSendcount次
{
CLR_Buf3();
USART_Puts(USART3 ,b);
USART_Puts(USART3 ,"
");
while(WaitACKflag) //判断在中断里,等待变成0
{
count ++;
delay_ms(5);
if(count >200*timeout_S) //最多允许等待timeout_S S
{
count=0;
break;
}
}
}
ACK_Command="";
WaitACKflag =0;
if(count == 0 && i == ReSendcount) //重复发送ReSendcount次,还没接收到响应指令(都失败)
{
if(EN_Reset == ENABLE)//如果使能了复位模式
{
__set_FAULTMASK(1); // 关闭所有中端
NVIC_SystemReset(); //软件直接复位(重来)
}
return 0;
}
return 1;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
给服务器发送数据封装函数:
/**
函数:SendDATA_wifi
功能:给服务器发送数据
参数:a:发送的数据 length:发送的长度
返回:
**/
void SendDATA_wifi(char *a ,u16 length)
{
char Buf[30] = "";
sprintf(Buf,"AT+CIPSEND=%d",length);
WIFI_AT_Command(Buf,">",3,2,ENABLE);
WIFI_AT_Command(a,"SEND OK",4,2,ENABLE);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
串口USART3接收中断函数:
/**
函数名 : USART3_IRQHandler
描述 : 串口3中断服务程序
输入 : 无
返回 : 无
说明 :
**/
void USART3_IRQHandler(void)
{
u8 ch=0;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
ch = USART_ReceiveData(USART3);
Wifi_RXbuf[Wificount++] =(char)ch;
if(ch == ‘
‘ || Wificount>=Uart3bufMAX)//防止超限
{
Wificount =0;
}
if(WaitACKflag ==1) //将判断strstr函数写在中断里,WaitACKflag用于防止重入函数
{
if(strstr(Wifi_RXbuf,ACK_Command)!=NULL)
{
WaitACKflag=0;
}
}
else
{
Judge_UART3_box();//对接收服务器接收消息的处理
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
接收服务器消息函数:
/**
函数:Judge_UART3_box
功能:接收服务器消息判断
参数:
返回:
**/
void Judge_UART3_box()
{
if(strstr(Wifi_RXbuf,"+IPD")!=NULL)
{
//用户自行定义
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3.实验现象
服务器端可以接收到WIFI模块的数据如图:(服务器端也可以给WIFI模块发数据来控制单片机执行,接收函数也封装好在上面的代码中,感兴趣的可以做些相关实验)
以上是关于基于WIFI模块(ESP8266)与非同一个局域网内服务器建立连接(转)的主要内容,如果未能解决你的问题,请参考以下文章
基于MicroPython结合ESP8266模块实现TCP通信(AT指令版)