HTTP-AT 介绍
HTTP-AT 是利用 AT 实现的一种类似于“路由器配置页面”功能的应用, 利用手机或电脑访问 URL 即可以控制 ESP32 的各种特性。
本应用单纯依靠 ESP32,只需通过网页,即可配置 ESP32 各项功能。主要包含以下两个部分:
- HTTP-AT 基本架构
- HTTP-AT 解析框架
其中:
HTTP-AT 基本架构
主要包括 http server libesphttpd
和 ESP32 文件系统
。
libesphttpd 使用 ESP32 作为 HTTP server 实现 HTTP 请求、解析和响应。
ESP32 文件系统 是小型 ESP32 FAT 文件系统。
这两者既相互独立,又紧密联系。
一. HTTP-AT 基本架构
HTTP-AT 基本架构
将 AT 命令打包和解析封装成不同 API,用户可直接调用这些 API 来实现 ESP32 上各项功能,而无需关心底层 AT 接口。如图一:
图一: HTTP-AT 基本架构
二. AT 解析框架
2.1 框架简介
HTTP-AT 解析框架
作为一个整体模块将 AT 命令进行封装,并对结果进行解析,以 API 形式提供给用户,使得用户只需根据接口即可得到想要结果。相对于 AT 来说,提供了更加方便和灵活的方式,用户无需使用 UART 或者 SPI 等外设去连接调用命令,也无需关心各个 AT 命令实现。
HTTP-AT 解析框架
主要分为两层:
- AT 命令打包和解析
- 解析结果处理再组装
如图二:
图二: HTTP-AT 解析框架
2.2 以连接 AP 为例
- 在
esp_at_join_ap()
函数,用户需在函数参数中输入ssid
和pwd
等信息,esp_at_join_ap()
内部会对参数合法性判断,将参数信息传递到at_add_cmd()
- 在
at_add_cmd()
函数中,会将传递参数进行拼装,组成AT+CWJAP=<ssid>,<pwd>[,<bssid>]
命令形式发送给AT core
进行处理 AT core
返回结果给at_add_cmd()
,esp_at_join_ap()
函数检测at_add_cmd()
函数返回值, 返回给cgiShowApInfo()
cgiShowApInfo()
组装好JSON
字符串,通过http server
返回给用户
读者可参考如下 test.c 代码来测试 esp_at_join_ap
等接口是否有效:
void app_main()
{
esp_err_t ret;
esp_at_arg at_arg;
nvs_flash_init();
/****** Init parse frame, it must call before using other API ******/
ESP_ERROR_CHECK(esp_at_init_parse());
/****** got free ram size ******/
int32_t ram_size = esp_at_getramsize();
ESP_LOGI(TAG, "ramsiz:%d",ram_size);
/****** Connect WiFi ******/
memset(&at_arg, '\0', sizeof(at_arg));
strcpy(at_arg.cwjap.ssid, "HUAWEI001");
strcpy(at_arg.cwjap.pwd, "12345678");
ret = esp_at_join_ap(SET, &at_arg);
if(ret == ESP_ERR_INVALID_STATE){
ESP_LOGE(TAG, "Error pwd or ssid");
}
/****** Get connected WiFi info ******/
memset(&at_arg, '\0', sizeof(at_arg));
ret = esp_at_join_ap(QUERY, &at_arg);
if(ret == ESP_ERR_INVALID_STATE){
ESP_LOGE(TAG, "Error");
}
ESP_LOGI(TAG, "SSID:%s, bssid:%s",at_arg.queryjap.ssid, at_arg.queryjap.bssid);
}
2.3 添加自己的 HTTP-AT 命令
目前 HTTP-AT
中已支持大部分常见 AT 命令解析,可满足基本需求,如需要较复杂功能,可通过 AT 组合来实现相关功能,也可以自行开发相关接口。一般开发步骤如下:
2.3.1 命令注册
- 在
atparse.h
中的at_command_list
中增加需添加命令 - 在
at_cmd_arg
中增加此命令的参数信息 - 在
cmdparse.c
中的cmd_func_list
中 添加此命令的拼装和解析回调函数。
注意:以上三步添加需要在对应同一位置,即都添加在 at_command_list
,at_cmd_arg
,cmd_func_list
第 n 位, 如都添加在最后,系统是通过对应位置去执行相应回调
2.3.2 拼装和解析实现
拼装和解析实现是将cmd_func_list
中两个函数实现。
- 在实现这两个函数之前,建议使用
uart
对HTTP-AT
命令进行测试,确定相应返回值顺序 - 拼装实现需按照 AT 文档说明将此命令参数进行传递,注意其中有些参数是可选参数,使用中需根据参数状态进行判断
解析的实现主要对返回值解析,以及初步判断 AT 命令执行的正确性
当 AT 命令执行完成后,如果成功,会返回相应的结果,并返回”OK”,而错误的话会直接返回”ERROR” 所以我们需要做的就是将结果保存下来,并通过一个状态来标识执行正确或者错误。在已有的框架中,结构体 rsp_msg 用来标识 AT 返回信息,其中 rsp_msg.rsp_flag 为返回状态标志位,rsp_msg.data 为返回数据,一般如果 rsp_msg.rsp_flag 为 AT_CMD_RETURN_FAIL,即 AT 执行错误,则 rsp_msg.data 为 NULL。
如 AT 命令只关心是否返回正确,则可以直接使用at_comm_rsp()
,不需要自己写解析回调函数在 AT 返回多组信息时,如
AT + CIFSR
命令返回:
AT+CIFSR
+CIFSR:APIP,<SoftAP IP address>
+CIFSR:APMAC,<SoftAP MAC address>
+CIFSR:STAIP,<Station IP address>
+CIFSR::STAMAC,<Station MAC address>
OK
一般我们有两种方式:
- 将这些结果拼接起来拷贝到
rsp_msg.data
- 声明一个结构体,然后将这些结果赋值到结构体中拷贝到
rsp_msg.data
推荐使用第一种方式,这样可以使得代码风格统一,拼接结果在上层调用接口处理。
注意:
- BLE 命令与其他命令略有不同,BLE 命令执行和返回是异步的,所以会先打印 OK,然后才会返回结果
2.3.3 ESP32-AT 返回结果再处理
在完成上述结果后,可以在上层对 HTTP-AT
结果再次加工,以满足特殊需求。如对于 WiFi 扫描结果,返回后还需要对于结果进行打包,将有用信息以 callback
方式提供给用户,参考 wifiscanresult_cb
使用。
三. HTTP-AT Demo 使用
HTTP-AT demo 编译和使用方法如下:
make menuconfig
配置,默认配置即可运行make flash
编译并烧写到 flash- 手机连接到 ESP32, ESP32 的 AP SSID 为 AP MAC 地址的后六位
- 手机浏览器访问
192.168.4.1
即可连接到 ESP32 - 配置和操作 ESP32
四. 参考项目
- HTTP SERVER 要参考 : https://github.com/Spritetm/libesphttpd
- FAT image 制作工具参考: https://github.com/jkearins/ESP32_mkfatfs