0
演示
本帖最后由 HonestQiao 于 2021-8-1 08:33 编辑
今天要给大家演示的,通过浏览器访问网页进行IoT控制。
需要完成的工作包括:
1. 开发板连接WiFi
2. 开发板连接WiFi后,提供web服务
3. 电脑或者手机通过浏览器访问开发板提供的web服务
4. 在网页界面上,控制开发板上LED等的点亮和关闭
先来一段演示视频:
再来完整代码:
讲解如下:
1. 拷贝examples中的http_server/simple,以此为基础进行:
- cp -r $IDF_PATH/examples/protocols/http_server/simple web_server_iot
复制代码
2. 修改配置:
- 文件Makefile:
- EXTRA_COMPONENT_DIRS := $(IDF_PATH)/examples/common_components/led_strip
- EXTRA_COMPONENT_DIRS += $(IDF_PATH)/examples/common_components/protocol_examples_common
复制代码
- 文件CMakeLists.txt:
- set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/common_components/led_strip $ENV{IDF_PATH}/examples/common_components/protocol_examples_common")
复制代码
因为本实例参考了blink例子,进行板载LED的控制,所以EXTRA_COMPONENT_DIRS中需要添加examples/common_components/led_strip
3. 主代码:具体代码,请查看完整代码包中的main.c文件
- /*
- 简单web server控制IoT
- */
- #include
- #include
- #include
- #include
- #include
- #include
- #include "nvs_flash.h"
- #include "esp_netif.h"
- #include "protocol_examples_common.h"
- #include
- #include "driver/gpio.h"
- #include "led_strip.h"
- /*
- 通过提供web server服务,来提供http接口,实现IoT控制
- */
- static const char *TAG = "webserver_iot";
- #define IOT_GPIO_RMT_CHANNEL 0
- #define IOT_GPIO 8
- static const char *CTRL_OPEN = "open";
- static const char *CTRL_CLOSE = "close";
- static led_strip_t *pStrip_a;
- static uint8_t s_led_state = 0;
- ......
- /* 主程序 */
- void app_main(void)
- {
- static httpd_handle_t server = NULL;
- /* 初始化LED */
- configure_led();
- /* 网络初始化 */
- ESP_ERROR_CHECK(nvs_flash_init());
- ESP_ERROR_CHECK(esp_netif_init());
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- /* 使用默认演示例子中的example_connect连接wifi,具体见examples/protocols/README.md */
- ESP_ERROR_CHECK(example_connect());
- /* 设置wifi事件回调 */
- ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
- ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
- /* 首次主动启动web server */
- server = start_webserver();
- }
复制代码
4. 逻辑讲解:
- configure_led():初始化led,参考blink
- 连接wifi:example_connect(),演示组件中提供的方法,对应的wifi连接信息,在menuconfig中设置,后续有说明
- 注册wifi事件回调:
- esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server);
- esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server);
复制代码
- 启动web服务:start_webserver()
- 接受用户请求,进行状态返回,或者LED控制
在wifi事件IP_EVENT_STA_GOT_IP(成功连接并获得ip地址)的回调中,有两个关键的httpd_register_uri_handler注册:
- httpd_register_uri_handler(server, &index_config);
- httpd_register_uri_handler(server, &ctrl_config);
复制代码
通过index_config、ctrl_config的设置:
- static const httpd_uri_t index_config = {
- .uri = "/",
- .method = HTTP_GET,
- .handler = index_get_handler,
- .user_ctx = "..."
- };
- static const httpd_uri_t ctrl_config = {
- .uri = "/ctrl",
- .method = HTTP_POST,
- .handler = ctrl_post_handler,
- .user_ctx = NULL
- };
复制代码
我们可以看到,分别注册了两个网址回调,一个是/,用来访问默认的网页界面,一个是/ctrl,用来提供控制指令的发送。
两者对应的回调函数,分别为:
- index_get_handler:表示处理直接访问/的请求,如果为/?status=时间戳,就会返回当前的LED状态,否则,显示一个控制界面。
- ctrl_post_handler:表示接受POST /ctrl的请求,收到open则点亮LED,收到close,则关闭LED
而控制led,则由两个函数完成:
- configure_led:初始化LED
- ctrl_led:点亮或者关闭LED
注意,代码中定义了#define IOT_GPIO 8,板载的LED为GPIO8,可以根据自己的实际需要进行设置
上述控制界面网页,由index_config.user_ctx来提供:
这里引用了bootstrap,用于界面样式的控制,引用jquery用于ajax请求的控制。
该界面上,有两个按钮,以及一个状态显示,具体如下:
其处理逻辑如下:
- 浏览器访问 http://ip/,返回上述控制界面
- 页面发送ajax请求 /?status=1234567890,返回当前LED的状态open 或者 close
- 点击Open按钮后,发送ajax post请求到/ctrl,数据为open,web server收到后,点亮LED,并返回open
- 点击Close按钮后,发送ajax post请求到/ctrl,数据为close,web server收到后,关闭LED,并返回close
- 页面收到web server返回后,会在状态区块中,显示:Status: [状态]
5. 具体操作:
- idf set-target esp32c3设置target
- idf menuconfig配置:
该处默认为512,浏览器访问时,可能会出现错误:
Header fields are too long for the server to interpret
- 配置完成后,执行idf build进行编译
- 刷机:idf flash
- 监控:idf monitor
- wifi配置错误时,会如下显示:
- 正常连接wifi,并开启web server,其中显示的ip地址,即为网页控制要访问的地址
|
|