您的位置:首页 > 其它

基于WIFI模块(ESP8266)与非同一个局域网内服务器建立连接

2017-08-03 15:21 429 查看
前一篇文章讲述的是两个局域网间应该如何搭建连接的方法,这篇文章将讲述,这种方法的具体实施过程。

案例简述:

以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


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
[/code]

发送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 ,"\r\n");

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


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
[/code]

给服务器发送数据封装函数:

/**
函数: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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]

串口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 == '\n' || 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


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
[/code]

接收服务器消息函数:

/**
函数: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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]

3.实验现象

服务器端可以接收到WIFI模块的数据如图:(服务器端也可以给WIFI模块发数据来控制单片机执行,接收函数也封装好在上面的代码中,感兴趣的可以做些相关实验)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐