文章目录
- 前言
- 一、连接TCP服务器
- 1.1 配置Wifi模式
- 1.2 连接路由器
- 1.3 查询ESP8266设备IP地址
- 1.4 连接TCP服务器
- 二、向服务器接收数据和发送数据
- 2.1 发送数据
- 2.2 接收数据
- 总结
前言
随着物联网(IoT)技术的迅速发展,越来越多的设备和系统开始连接到互联网,实现远程监控、数据采集和远程控制等功能。在物联网应用中,STM32微控制器以其强大的性能和丰富的外设功能成为了重要的选择之一。而在STM32与互联网通信中,AT指令与TCP/IP协议成为了两个重要的技术手段。
一、连接TCP服务器
1.1 配置Wifi模式
我们可以使用下面这个AT指令进行WIFI模式的设置:AT+CWMODE=3 // softAP+station mode
。3的意思为softAP+station一起,即可以开热点也可以连接路由器,一般我们都是使用这个
1.2 连接路由器
我们可以使用下面这个AT指令连接我们的路由器或者热点:AT+CWJAP="SSID","password"
我们的名称和密码都需要双引号,所以我们发送cmd时,字符串里面的名称和密码需要转义字符的帮助
1.3 查询ESP8266设备IP地址
我们可以使用下面这个AT指令来查询ESP8266的设置IP地址:AT+CIFSR
1.4 连接TCP服务器
我们可以使用下面这个AT指令来连接我们的TCP服务器:
AT+CIPSTART="TCP","TCPServerIP",8080
,注意,前两个参数是需要加双引号的,后面的端口8080不需要
二、向服务器接收数据和发送数据
2.1 发送数据
首先我们需要发送AT指令告诉ESP8266说我等下要发数据了
AT+CIPSEND=你要发送的字节大小 // set date length which will be sent
然后我们等待一会:我们直接发送我们的需要发送的数据即可,这个可以不需要使用\r\n
作为最后,如果你想换行也是可以使用的
2.2 接收数据
对于我们的接收数据,当我们服务端发送数据之后,esp8266会马上发给我们stm32的串口,然后我们的串口就会进入回调函数打印接收到的数据,但是这样我们就不能知道他什么时候发给我们数据了,那发送还有什么意义呢,所以我们需要自己实现函数,对esp8266的数据进行实时解析成tcp服务器发送的数据。
每次TCP服务端发送给ESP8266,ESP8266会这样显示出数据:+IPC,数据个数:数据
我们可以根据前面的+IPC
来判断,这次的数据不是我们发送AT指令返回的数据,而是我们的服务端给我们发送的数据
所以我们可以写一个函数进行解析:
int checkADDIPD(void)
{
int ret = 0;
char temp[5] = {"+IPD"};
int index = 0;
for(int i = 0;i<strlen((char*)esp8266_rxbuf);i++)
{
if(esp8266_rxbuf[i] == temp[index])
{
ret++;
index++;
if(ret == 4)
{
break;
}
}
}
return ret == 4;
}
在我们的回调函数中就可以每次去check一下数据了。
由于这是串口接收,每次buf并不会被清空,这样会影响我们的判断,再每次执行完回调之后,我们应该清空buf,但是由于回调函数清空了的话,我们实际需要的也会被清空啊(因为回调函数高于任何普通的函数,所以我们无法及时拿到数据,导致数据的丢失),所以需要变量先记录buf,然后再清空buf。
uint8_t esp8266_rxbuf[1000] = {0};
uint8_t recvfrom[1000] = {0};
memcpy(recvfrom,esp8266_rxbuf,sizeof(esp8266_rxbuf));
memset(esp8266_rxbuf,0,sizeof(esp8266_rxbuf));
从我们的网络知识知道,recv他是一个阻塞的函数,所以我们也需要实现阻塞,我们只需要加一个变量即可,当没数据时,while循环,有数据时,读取到具体的数据,然后进行下面的其他代码。
那么何时有数据呢?当我们的回调函数执行checkADDIPD
为1时,为有数据发过来了。所以在判断if checkADDIPD
时,把变量标记一下即可
if(checkADDIPD() == 1) RxData=1;
//read函数
while(RxData == 0)
{
HAL_Delay(10);
}
不要忘记在while循环结束后标记变量为0
过了while循环,我们应该去解析+IPC,数据个数:数据
他了。在这里,我并没有去进一步解析他的数据个数,这里仅仅是一个简单的演示。我们可以写一个函数去解析他,并且把解析之后的内容通过返回值返回给我们。
// 函数定义
char* parseStringAfterColon(const char* input) {
// 查找冒号的位置
const char* colonPtr = strchr(input, ':');
// 如果找到了冒号
if (colonPtr != NULL) {
// 返回冒号后面的字符串(不包括冒号本身)
size_t length = strlen(colonPtr + 1);
char* result = (char*)malloc(length + 1); // 分配足够的内存来存储结果
if (result != NULL) {
strcpy(result, colonPtr + 1); // 复制字符串
return result;
} else {
printf("内存分配失败\n");
return NULL;
}
} else {
printf("未找到冒号\n");
return NULL;
}
}
然后我们把我们存储到的数据recvData作为参数给这个函数:
char *data = parseStringAfterColon(recvfrom);
这个data就是我们解析出来服务端发给我们的数据了。
最后,我们不要忘记释放data
总结
AT指令是一种简单的命令集,常用于与通信设备进行串口通信。在STM32物联网应用中,通过串口与无线模块(如SIM800、SIM900等)通信时,常常使用AT指令来控制模块实现TCP/IP连接、数据传输等功能。AT指令的简洁易用使得STM32与无线模块之间的通信变得更加简单可靠。
与此同时,TCP/IP协议作为互联网通信的基础协议,也在STM32物联网应用中发挥着重要作用。通过TCP/IP协议,STM32可以与远程服务器建立稳定的连接,实现数据的可靠传输。TCP/IP协议提供了可靠的数据传输机制,保证了数据的完整性和可靠性,使得STM32在物联网应用中能够更好地与互联网进行通信。
综上所述,AT指令与TCP/IP协议在STM32物联网应用中发挥着重要的作用。通过使用AT指令控制无线模块,以及通过TCP/IP协议与远程服务器通信,STM32可以实现丰富的物联网功能,为各种物联网应用提供了强大的支持和保障。