wifi模块基于AT指令集实现收发功能(笔记记录)
几个我参考的链接:
1、ESP8266笔记 ---- 常用AT指令_esp8266 at-优快云博客
2、esp8266WIFI模块教程:正点原子ATK-ESP8266进行网络通信,单片机与电脑,单片机与手机发送数据_正点原子esp8266-优快云博客
3、【常用模块】ESP8266 WIFI串口通信模块使用详解(实例:附STM32详细代码)_正点原子wifiesp8266提供代码-优快云博客
最有用的是乐鑫官方给的AT指令操作示例:
4、TCP-IP AT 示例 - ESP32 - — ESP-AT 用户指南 latest 文档 (espressif.com)
主要参考esp32做tcp客户端,建立单连接,实现uart wifi透传
注意:
1、模块可能没有下载AT指令集的固件,可能需要烧录一下对应的固件,参考链接在这里:
ESP开发(一)ESP8266-01烧录AT固件_esp 01固件-优快云博客
2、B站有一个视频教程:
快速了解wifi模块 这个视频就够了 ESP8266_哔哩哔哩_bilibili
看完这个视频就可以上手wifi模块了,30分钟可以两倍速看。
AT固件下载
首先是ESP32引脚分布(这里要注意烧录模式的时候和正常工作模式GPIO0的接线不同,还有一个注意点就是GPIO15必须接到低),有关ESP32的详细引脚定义可以参照下面这个链接:esp-12f_product_specification_zh_v1.0.pdf (ai-thinker.com)
模组启动模式说明
推荐的电路连接方式(正常工作模式)
如何下载?
下载模式需要把只需要把GPIO0接到地,rst先浮空,配置好flash下载软件之后,先点击擦除,之后会等待上电复位,将rst用杜邦线触碰一下地,即可开始烧录,此时等待烧录完毕,将GPIO接到高电平,重新上电即可正常使用AT指令集。
1、使用ESP12F飞线图
2、Flash下载软件参数配置
注意:目前只测试了安信可的固件可以下载成功,并且这个使用起来功能一切正常,固件存放位置在目录固件下载下面。偏移地址一定是0x0000,先选erase,上电复位之后自动开始烧录程序。
判断是否烧录成功?
使用串口助手调试(波特率是115200,具体参数配置见下图),上电之后会有复位信息输出,并且返回会有个ready字符串,同时发送AT\r\n(使用串口助手发送新行可以不用\r\n)会自动返回AT OK,表示烧录成功,之后可以正常使用了。
AT指令简单使用
就是在用单片机操作之前会先用串口调试助手,测试一下这个wifi芯片是不是好的,同时也可以熟悉一下,at常用的几条指令的返回值是什么。同样这里也有一个链接:
简单记录ESP8266WIFI模块网络调试过程,测试通过。_esp8266 ch340 联网测试-优快云博客
使用战舰V3实现wifi连接的收发
收发演示视频
wifi模块演示
程序实现
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "mywifi.h"
// 全局变量定义
u8 receive_number = 0; // 记录接收长度
u8 temp_rec_num = 0;
u8 rev_finish_flag = 0; // 接收完成标志
u8 wifi_connect_flag = 0; // 1表示wifi连接成功
char mywifi_recv_buf[MAX_LENGTH] = {0}; // 接收数组
/**
* @description: 功能描述
* 1、初始化延时函数 led灯
* 2、wifi芯片自检
* 3、自检成功之后会软件复位一下wifi芯片,之后关闭指令回环显示
* 4、设置wifi芯片为站点模式,按照定义好的wifi账号的密码连接热点,这个热点可以是电脑也可以时候,只要电脑和手机连上一个wifi就可以,注意频段是2.4G
* 5、查看一下wifi芯片分配到ip地址,可能每次分配的地址不一样,这样要配置的上位机服务器的ip就要随之改变一下,这个到时候我教你嘿嘿
* 6、根据上位机服务器ip地址,连接上服务器
* 7、开启wifi芯片透传 和透输模式,这个时候它就和一个串口无差异了,可以把之前的485写的协议往上套了
* 8、在透传模式下给服务器发送20次你好之后,推出透传模式,断开和服务器的连接
* 9、结束
* @return {*}
*/
int main(void)
{
delay_init(); // 延时函数初始化
LED_Init(); // 初始化与LED连接的硬件接口
uart_init(115200);
mywifi_uart_init();
int rec = 0;
int num = 0;
u8 test[] = {"hello!\r\n"}; // 打印测试数据
delay_ms(5000);
if (mywifi_self_test())
{
mywifi_soft_rst();
delay_ms(500);
mywifi_polldispaly(0);
delay_ms(20);
mywifi_set_mode(1); // 设置站点模式
mywifi_connect_host(); // 连接之后需要判断是否连接成功,由于连接需要一定时间
mywifi_get_ip(); // 获取站点动态分配地址,注意在合理只进行了打印,没有存储,带busy等待。
mywifi_connect_sever(); // 连接服务器
mywifi_set_transparent(1); // 开启透传模式
LED1 = 0; // wifi芯片自检成功会亮灯,但是不一定会连上wifi,wifi是否连上通过串口1打印结果
}
while (1)
{
LED0 = 0; // 0表示灯亮
delay_ms(300); // 延时300ms
LED0 = 1;
delay_ms(300); // 延时300ms
u8 nums[10] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 2}; // 自定义数据
// mywifi_data_send(nums, sizeof(nums) / sizeof(nums[0]));//数据发送测试
mywifi_data_send(test, sizeof(test) / sizeof(test[0])); // 字符发送测试
num++;
if (num > 20)
{
delay_ms(2000); // 需要等待一秒,结束透传
mywifi_set_transparent(0); // 透传关闭测试成功
break;
}
#if 0
// 前期搭建测试用
// rec = USART_ReceiveData(USART2); // 接收也没问题
// USART_SendData(USART2, rec); // 发送测试
// printf("test ok");
// mywifi_send_nbytes("nihaoya\n\r",10);
// mywifi_send_at_cmd(test, "nihaone", 30,sizeof(test)/sizeof(test[0]));//sizeof不能对传入的参数进行求长度
// int flag=mywifi_send_at_cmd(test, "AT\r\nOK", 20, sizeof(test) / sizeof(test[0]));// 发送AT测试成功,第一次可能会失败,需要多测试几次、
// // 测试成功之后给这个东东软件复位一下,复位之后不用接收这个里面的数据了
#endif
}
while (1)
{
LED0 = 0; // 0表示灯亮
delay_ms(300); // 延时300ms
LED0 = 1;
delay_ms(300);
}
}
mywifi.h
/*
* @Author: <lan> <1791060296@qq.com>
* @Date: 2024-01-04 20:23:27
* @LastEditors: <lan> <1791060296@qq.com>
* @LastEditTime: 2024-01-05 16:03:18
* @FilePath: \实验1 跑马灯实验\HARDWARE\MYWIFI\mywifi.h
* @Description:
*
* Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
*/
#ifndef __MYWIFI_H
#define __MYWIFI_H
#include "sys.h"
#include "stdbool.h"
// 使用AT指令连接电脑热点,wifi模块作为客户端,电脑作为服务器
// 实现两边数据收发
// AT指令定义,注意这里发送的时候是asiic码发送,结束要以换行结束
// 从wifi芯片的接收还是用到空闲中断,判断空闲之后开始处理数据
// 这里要做wifi初始化(正式传输数据前)和数据传输两个区分(后续通透模式传输数据),设置两个标志位
// 上电之后发送一个AT测试wifi芯片是否正常
// 存在一个问题,就是进入透传模式之后没有推出,之后的指令都没用了,需要给wifi芯片重启
// 所以需要手动断开透传模式,断开和服务器的连接
// 注意这里介个宏定义目前没有用到,热点名称,密码等是在函数定义上方,需要按照你电脑分配的自行修改
#define DEMO_WIFI_SSID "ALIENTEK-YF" // 热点名称,注意这里频段要设置在2.4G
#define DEMO_WIFI_PWD "15902020353" // 热点密码
#define DEMO_TCP_SERVER_IP "192.168.1.3" // 服务器IP地址,TCP协议
#define DEMO_TCP_SERVER_PORT "8080" // 主机访问端口号
// MyWIFI 状态
#define MYWIFI_OK 1
#define MYWIFI_ERROR 0
#define MAX_LENGTH 200
extern u8 receive_number; // 记录接收长度
extern u8 temp_rec_num; // 用于测试的临时长度记录
extern u8 rev_finish_flag; // 接收完成标志
extern u8 wifi_connect_flag; // 1表示连接成功
extern char mywifi_recv_buf[MAX_LENGTH]; // 接收数组
void mywifi_uart_init(void); // 默认波特率为115200
void mywifi_send_nbytes(char *data, u8 len);
u8 mywifi_send_at_cmd(char *cmd, char *ack, u32 timeout, u8 len); // 发送指令,期待应答指令,等待时间
u8 mywifi_recv_data(char *data); // 接收数据函数
u8 mywifi_self_test(void); // wifi芯片自动检测
void mywifi_soft_rst(void); // wifi软件复位
void mywifi_polldispaly(u8 flag); // wifi回显开关
void mywifi_set_mode(u8 mode); // wifi设置工作模式,站点模式 Or AP模式
bool mywifi_connect_host(void); // 芯片连接到热点,这里我默认是我电脑的热点
void mywifi_get_ip(void); // 获取wifi连接分配的ip地址
void mywifi_set_one_node(void); // 设置单路连接
bool mywifi_judge_host_connect(void); // 判断热点是否连接
void mywifi_connect_sever(void); // 连接到服务器
void mywifi_set_transparent(u8 flag); // 设置透传模式
void mywifi_data_send(u8 *data, u8 len); // wifi数据传输
void mywifi_close_tcp_connection(void); // 关闭tcp连接
void mywifi_judge_tranfer_end(void); // 判断是否结束透传
void mywifi_char_printf(char *fmt, ...); // 用于打印+++,退出透传模式
#endif
mywifi.c
#include "mywifi.h"
#include <string.h>
#include <stdio.h>
#include "delay.h"
#include "usart.h"
#include <stdarg.h> // 用来重定向
/**
* @description: wifi用到串口初始化
* @return {*}
*/
void mywifi_uart_init(void)
{
// GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能USART2,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
// USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA.2
// USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA.3
// Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器
// USART 初始化设置
USART_InitStructure.USART_BaudRate = 115200; // 串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
USART_Init(USART2, &USART_InitStructure); // 初始化串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启串口接受中断
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // 开启串口空闲中断
USART_Cmd(USART2, ENABLE); // 使能串口1
}
/**
* @description: 给wifi芯片传输指定长度数据
* @param {char} *data 传输数据
* @param {u8} len 传输数据长度
* @return {*}
*/
void mywifi_send_nbytes(char *data, u8 len)
{
for (int i = 0; i < len; i++)
{
USART_SendData(USART2, data[i]); // 发送测试
while (!USART_GetFlagStatus(USART2, USART_FLAG_TC))
; // 等待发送完成
}
}
/**
* @description: wifi发送数据
* @param {char} *cmd数据
* @param {char} *ack期待的应答
* @param {u32} timeout超时
* @param {u8} len数据长度
* @return {*}
*/
u8 mywifi_send_at_cmd(char *cmd, char *ack, u32 timeout, u8 len)
{
char *ret = NULL; // 用于接收数据
// atk_mw8266d_uart_rx_restart();
// 正点原子有一个硬件复位的过程,这里没设置了,
mywifi_send_nbytes(cmd, len);
if ((ack == NULL) || (timeout == 0))
{
return MYWIFI_OK;
}
else
{
while (timeout > 0)
{
if (mywifi_recv_data(ret))
{
if (strstr((const char *)mywifi_recv_buf, ack) != NULL) // ack 作为子串去查询
{
// mywifi_send_nbytes(mywifi_recv_buf, sizeof(mywifi_recv_buf));
return MYWIFI_OK;
}
else
{
// 不同则复位
// atk_mw8266d_uart_rx_restart();
}
}
timeout--;
delay_ms(1);
}
return MYWIFI_ERROR; // 这里代表超时
}
}
/**
* @description: 接收数据
* @param {char} *data
* @return {*} 返回当前是否完成了数据接收
*/
u8 mywifi_recv_data(char *data)
{
char temp[MAX_LENGTH] = {0}; // 测试使用
if (rev_finish_flag == 1)
{
// 当前接收完成
data = mywifi_recv_buf; // 先预留的,目前我没有用到
strncpy(temp, mywifi_recv_buf, receive_number);
rev_finish_flag = 0;
receive_number = 0;
// printf("the rec data : \r\n");
// printf("%s", temp);
return 1;
}
else
return 0;
}
/**
* @description: wifi自检测
* @return {*} 自检成功返回1
*/
u8 mywifi_self_test(void)
{
char test[] = {"AT\r\n"};
char ack[] = {"OK"};
u8 flag = 0;
for (u8 i = 0; i < 50; i++)
{
flag = mywifi_send_at_cmd(test, (char *)ack, 20, sizeof(test) / sizeof(test[0]));
char temp[MAX_LENGTH] = {0};
while (strstr((const char *)temp, "busy") != NULL) // 等待忙完成
{
// 等待不忙,才执行后面的,这里写的有点问题,没有达到预期的效果
memset(temp, 0, MAX_LENGTH);
strncpy(temp, mywifi_recv_buf, temp_rec_num);
flag = mywifi_send_at_cmd(test, (char *)ack, 20, sizeof(test) / sizeof(test[0]));
rev_finish_flag = 0;
temp_rec_num = 0;
// 开机都忙等待的话直接给它硬件复位
}
if (flag)
return flag;
}
return flag; // 自检测5次,最后一次成功表示成功
}
/**
* @description: wifi软件重启,这个操作在自检测成功之后
* @return {*}
*/
char soft_rst[] = {"AT+RST\r\n"};
void mywifi_soft_rst(void)
{
mywifi_send_at_cmd(soft_rst, NULL, 20, sizeof(soft_rst) / sizeof(soft_rst[0]));
}
/**
* @description: WiFi回显开关
* @param {u8} flag
* @return {*}
*/
char polldispaly0[] = {"ATE0\r\n"};
char polldispaly1[] = {"ATE1\r\n"};
void mywifi_polldispaly(u8 flag)
{
mywifi_send_at_cmd(flag ? polldispaly0 : polldispaly1, "OK", 20, sizeof(polldispaly0) / sizeof(polldispaly0[0]));
}
/**
* @description: wifi设置工作模式,站点模式 Or AP模式
* @param {u8} mode 1表示设置为站点模式
* @return {*}
*/
char set_mode0[] = {"AT+CWMODE=0\r\n"};
char set_mode1[] = {"AT+CWMODE=1\r\n"};
void mywifi_set_mode(u8 mode)
{
mywifi_send_at_cmd(mode ? set_mode1 : set_mode0, "OK", 20, sizeof(set_mode0) / sizeof(set_mode0[0]));
}
/**
* @description: 芯片连接到热点,这里我默认是我电脑的热点
* @return {*}
*/
char connecet_host[] = {"AT+CWJAP=\"mldesk\",\"12345671\"\r\n"};
bool mywifi_connect_host(void)
{
mywifi_send_at_cmd(connecet_host, "OK", 4000, sizeof(connecet_host) / sizeof(connecet_host[0]));
delay_ms(4000);
return true;
}
/**
* @description: 获取wifi连接获取的ip地址
* @return {*}
*/
char get_ip[] = {"AT+CIPSTA?\r\n"};
void mywifi_get_ip(void)
{
char temp[MAX_LENGTH] = {0};
while (strstr((const char *)temp, "OK") == NULL)
{
// 等待不忙,才执行后面的
memset(temp, 0, MAX_LENGTH);
strncpy(temp, mywifi_recv_buf, temp_rec_num);
rev_finish_flag = 0;
temp_rec_num = 0;
}
mywifi_send_at_cmd(get_ip, NULL, 2000, sizeof(get_ip) / sizeof(get_ip[0]));
delay_ms(1000);
// 获取ip号先保存起来之后使用,这个打来之后是会调硬件错误的,可能是数组超了
// if (rev_finish_flag == 1)
// {
// // 当前接收完成
// u8 i = 0;
// rev_finish_flag = 0;
// for (; i < temp_rec_num; i++)
// {
// if ((mywifi_recv_buf[i] == 0x69) && (mywifi_recv_buf[i + 1] == 0x70))
// break;
// }
// // 找到了ip地址的位置
// memset(temp, 0, MAX_LENGTH);
// strncpy(temp, mywifi_recv_buf + i + 4, 15);
// temp_rec_num = 0;
// //printf("%s",temp);
// }
}
/**
* @description: 判断热点是否连接
* @return {*}
*/
bool mywifi_judge_host_connect(void)
{
if ((strstr((const char *)mywifi_recv_buf, "CONNCETED") != NULL) ||
(strstr((const char *)mywifi_recv_buf, "GOT") != NULL))
{
printf("\r\nconnecet_host ok\r\n");
// 成功之后设置相应的标志位,比如可以用来连接tcp服务器
wifi_connect_flag = 1; // wifi 连接成功
return true;
}
else if ((strstr((const char *)mywifi_recv_buf, "DISCONNECT") != NULL))
{
printf("\r\nconnecet_host error\r\n");
// 失败时候需要将相应标志位清除,显示连接丢失
wifi_connect_flag = 0; // wifi 连接失败
return false;
}
return false;
}
/**
* @description: wifi芯片作为client 连接到服务器
* @return {*}
*/
char connecet_sever[] = {"AT+CIPSTART=\"TCP\",\"192.168.137.1\",8080\r\n"};
void mywifi_connect_sever(void)
{
if (wifi_connect_flag) // 需要保证wifi连接成功之后设置tcpip单路连接
{
char temp[MAX_LENGTH] = {0};
while (strstr((const char *)temp, "OK") == NULL)
{
// 等待上一次指令完成,才执行后面的
memset(temp, 0, MAX_LENGTH);
strncpy(temp, mywifi_recv_buf, temp_rec_num);
rev_finish_flag = 0;
temp_rec_num = 0;
}
mywifi_send_at_cmd(connecet_sever, "OK", 2000, sizeof(connecet_sever) / sizeof(connecet_sever[0]));
delay_ms(1000);
}
}
/**
* @description: 设置透传模式
* @param {u8} flag 1 表示透传 0 表示关闭透传发送+++
* @return {*}
*/
char open_transparent[] = {"AT+CIPMODE=1\r\n"};
char close_transparent[] = {"AT+CIPMODE=0\r\n"};
char send_data_cmd[] = {"AT+CIPSEND\r\n"};
char fade_transparent[] = {"+++"};
void mywifi_set_transparent(u8 flag)
{
if (flag)
{
mywifi_send_at_cmd(open_transparent, "OK", 200, sizeof(open_transparent) / sizeof(open_transparent[0]));
delay_ms(1000);
mywifi_send_at_cmd(send_data_cmd, ">", 200, sizeof(send_data_cmd) / sizeof(send_data_cmd[0]));
}
else
{
delay_ms(2000); // 需要等待一秒,结束透传
mywifi_char_printf("+++"); // 发送结束标志
delay_ms(4000); // 需要等待一秒,结束透传
mywifi_send_at_cmd("\r\n", NULL, 200, 0);
mywifi_send_at_cmd(close_transparent, "OK", 200, sizeof(close_transparent) / sizeof(close_transparent[0]));
mywifi_close_tcp_connection(); // 断开tcp连接
}
}
/**
* @description: 通过透传模式进行输出传输
* @param {u8} *data
* @param {u8} len
* @return {*}
*/
void mywifi_data_send(u8 *data, u8 len)
{
if (wifi_connect_flag) // 需要保证wifi连接成功,服务器连接成功,才能进行输出传输
{
mywifi_send_at_cmd(data, NULL, 0, len); // 数据发送,需要等待
}
}
/**
* @description: 断开tcp连接
* @return {*}
*/
char close_tcp[] = {"AT+CIPCLOSE\r\n"};
void mywifi_close_tcp_connection(void)
{
mywifi_send_at_cmd(close_tcp, "OK", 200, sizeof(close_tcp) / sizeof(close_tcp[0]));
}
/**
* @description: 判断是否结束透传,需要通过服务器发送+++,判断
* @return {*}
*/
void mywifi_judge_tranfer_end(void)
{
}
/**
* @description: 用于打印+++,推出透传模式
* @param {char} *fmt
* @return {*}
*/
void mywifi_char_printf(char *fmt, ...)
{
va_list ap;
uint16_t len;
char cmd[MAX_LENGTH] = {0};
va_start(ap, fmt);
vsprintf((char *)cmd, fmt, ap);
va_end(ap);
len = strlen((const char *)cmd);
mywifi_send_nbytes(cmd, len);
}
/**
* @description: 串口2中断回调函数
* @return {*}
*/
void USART2_IRQHandler()
{
static char res; // 静态变量防止堆栈溢出
static u32 temp;
char temp1[MAX_LENGTH] = {0}; // 静态变量防止堆栈溢出
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
res = USART_ReceiveData(USART2); // 读取接收到的数据
if (receive_number >= MAX_LENGTH) // 防止刷爆
receive_number = MAX_LENGTH - 1;
mywifi_recv_buf[receive_number] = res;
receive_number++;
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
if (USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET) // 命中空闲中断
{
/*---------------使用串口1打印从wifi芯片接收到的数据--------*/
strncpy(temp1, mywifi_recv_buf, receive_number);
temp_rec_num = receive_number;
printf("%s", temp1);
/*----------------end-------------------------------------*/
rev_finish_flag = 1;
// 判断wifi是否断开连接
mywifi_judge_host_connect();
// 判断服务器是否断开连接
// ------还没实现,可以通过各个指令不同的返回值去判定
// 下面这个操作是必要的,清除空闲中断标志位
temp = USART2->SR;
temp = USART2->DR;
USART_ClearITPendingBit(USART2, USART_IT_IDLE); // 清除空闲中断标志位
receive_number = 0;
}
}
标记一下这里要注意的几个点
1、 当前程序可实现收发,具体看wifi演示视频
(我的编程习惯不是很好,可能写的有点乱)
2、 程序参考了正点原子的,所以把它的程序也丢到压缩包了
3、 使用串口助手调试的时候,所有的指令都是要加上换行符的,这个是AT指令集规定的,不加就会返回error
4、 网络调试助手要选择TCP 服务器模式,它的IP号的选择,要通过wifi芯片所被分配的ip地址选择,比如下面这种张图片,通过查询ip地址,返回的IP地址是192.168.137.89,掩码是255.255.255.0,那么服务器的ip地址的前三个数据也应该是192.168.137,那么就可在网络调试助手里面选择对应的IP号了,然后使用默认的通道号就可以。
插播一点点TCP\IP的知识,但是只要了解就可以
5、 有一点没有做好的就是,wifi芯片连接热点是有时间要求的,而且每次不一样,我做了一个等待上一次指令完成的操作,就是如果上一次是指令传输,那么成功的话就会返回OK,在执行当前指令前,先判断接收buffer里面是不是存在OK这个字符,如果是则表示上一次传输完成,但其实如果是出错的话会有个ERROR返回,这个没有加上去。需要你自己加上去了。
6、 还有一点是每次关机之后,好像这个芯片内部电容还有电一样,会保持几秒钟的连接时间。如果掉电立马复位,发送指令它会一直显示正忙,这里我没有找到解决办法,现象如下
7、 我测试的条件