当前位置:网站首页>Esp32 experiment - self built web server distribution network 02
Esp32 experiment - self built web server distribution network 02
2022-06-27 00:56:00 【NULL_ one thousand nine hundred and sixty-nine】
Preface
The previous article mentioned the simple way of distribution network , Adopted json Format transfer wifi Account and password . The advantage of this method is that it can be used in esp32 Use it directly cjson Library parse out json data . But the bad thing is ,html Web pages will be a little more complicated , You need to convert the data in the input box into json Format and then send . Send by post request . Is there any way to directly analyze post Default format data . This point will be discussed in this paper .
Another point , Last one wifi from ap Mode switch to station The mode uses delay . This way is not very reasonable , It is optimized here .
The whole process of distribution network
Here, the whole process of distribution network is sorted out .
Access to electricity ->wifi Initialize to ap Pattern -> Turn on http The server -> The user is connected to esp32wifi-> Browser input esp The gateway address defaults to 192.168.1.4-> On the page, enter the... To be connected wifi Name and password -> Click the send button on the page -> Browser pass post The request will be wifi The name and password are sent to esp32->esp32 It is concluded that wifi Name and password -> sign out wifiap Pattern , close http The server -> take wifi Name and password as parameters , take wifi Initialize to station Pattern . The distribution network is completed .
The embedded html Web page method
The content of a web page file is essentially a very long string . The simplest way is to define an array of strings . Fill the contents of the array with the contents of the web page .
const char index_string[] =
"<!DOCTYPE html> \ <head> \ <meta charset=\"utf-8\"> \ <title>wifi config</title> \ </head>";
For example, use this definition , This method is generally used to give feedback to web pages , such as 404 Information, etc . But for more complex web pages , This is obviously not very convenient . If you can directly use html Generated by tool design .htm It's not better to compile files in the format of . This is another recommended way .

This time, we directly borrowed a semi open source esp32 The distribution Web page of desktop TV . As shown in the figure above . Direct compilation requires two steps .
1、 modify CMakeList.txt file
idf_component_register(SRCS ${main_src}
INCLUDE_DIRS "."
EMBED_FILES "upload_script.html" "wifi.html"
)
add to EMBED_FILES
2、 Call the compiled file .
This wifi.html How to use the compiled text file .wifi.html Compiled generic names are default _binary_ name _ type _start. This pointer represents the starting address of the compiled file ._binary_ name _ type _end, Represents the end address .wifi.html Is quoted as follows .
extern const unsigned char script_start[] asm("_binary_wifi_html_start");
extern const unsigned char script_end[] asm("_binary_wifi_html_end");
const size_t script_size = (script_end - script_start);
By , You can get wifi.html This large array .
http Server configuration
There is a quote above wifi.html Methods , But how can it be displayed in the browser ? That's what we need http The server .
Enter the address in the browser , The browser will default to GET Method direction http The server requests data .http Server received GET After the command , Send the data to be displayed in the browser to the browser , So the browser can display the web page .
In distribution network , At least two pages need to be defined , One is the root page , One is that clicking the button of the distribution network on the web page will trigger the page you enter . The root page is to visit 192.168.4.1 Web page to go to . The specific definitions are as follows :
Define the page structure :
httpd_uri_t index_page = {
.uri = "/", //192.168.1.4
.method = HTTP_GET,
.handler = index_get_handler,
/* Let's pass response string in user * context to demonstrate it's usage */
.user_ctx = NULL,
};
among uri For root , Namely 192.168.4.1 This page .method Define the trigger method of this page , by GET Method .handler Define the function to be run after entering this page . When the browser accesses 192.168.4.1 When index_get_handler The function will run .
Definition index_get_handler
static esp_err_t index_get_handler(httpd_req_t *req)
{
extern const unsigned char upload_script_start[] asm("_binary_wifi_html_start");
extern const unsigned char upload_script_end[] asm("_binary_wifi_html_end");
const size_t upload_script_size = (upload_script_end - upload_script_start);
/* Add file upload form and script which on execution sends a POST request to /upload */
httpd_resp_set_type(req,HTTPD_TYPE_TEXT);
httpd_resp_send(req, (const char *)upload_script_start, upload_script_size);
return ESP_OK;
}
This function is what I mentioned earlier wifi.html The contents of this file are returned to the browser for display .
The actual page display effect is as follows :
Now let's talk about what you need to do when you click save and connect . After clicking this button , The browser will call get Method , Send the data to http The server . So click save and connect to display the following page definitions and processing methods :
static const httpd_uri_t echo = {
.uri = "/",
.method = HTTP_POST,
.handler = echo_post_handler,
.user_ctx = NULL
};
static esp_err_t echo_post_handler(httpd_req_t *req)
{
char buf[100];
// char ssid[10];
// char pswd[10];
int ret, remaining = req->content_len;
while (remaining > 0) {
/* Read the data for the request */
if ((ret = httpd_req_recv(req, buf,
MIN(remaining, sizeof(buf)))) <= 0) {
if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
/* Retry receiving if timeout occurred */
continue;
}
return ESP_FAIL;
}
/* Send back the same data */
httpd_resp_send_chunk(req, buf, ret);
remaining -= ret;
esp_err_t e = httpd_query_key_value(buf,"ssid",wifi_name,sizeof(wifi_name));
if(e == ESP_OK) {
printf("ssid = %s\r\n",wifi_name);
}
else {
printf("error = %d\r\n",e);
}
e = httpd_query_key_value(buf,"password",wifi_password,sizeof(wifi_password));
if(e == ESP_OK) {
printf("pswd = %s\r\n",wifi_password);
}
else {
printf("error = %d\r\n",e);
}
/* Log data received */
ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
ESP_LOGI(TAG, "%.*s", ret, buf);
ESP_LOGI(TAG, "====================================");
}
// End response
httpd_resp_send_chunk(req, NULL, 0);
if(strcmp(wifi_name ,"\0")!=0 && strcmp(wifi_password,"\0")!=0)
{
xSemaphoreGive(ap_sem);
ESP_LOGI(TAG, "set wifi name and password successfully! goto station mode");
}
return ESP_OK;
}
When you click the save and connect button ,echo_post_handler The function will run . The main function of this function is , Return the received data to the browser for display , And will post In the string wifi The name and password are resolved separately , Assign a value to
char wifi_name[30]={0};
char wifi_password[30]={0};
These two string arrays . The maximum name and password length is 29 byte .
When parsed wifi_name and wifi_password None of the values are empty , Then release the semaphore , to wifi_station The task of , Get into station Pattern .
When entering a name abc password 123456 when , The string received by the server is
ssid=abc&password=123456&citycode=
This is a kind of post Method through a formatted string .esp32 The corresponding parsing method is provided . I didn't know this parsing method at first , That's why we use json Format send wifi Name and password . The parsed functions are as follows :
esp_err_t e = httpd_query_key_value(buf,“ssid”,wifi_name,sizeof(wifi_name));
The first parameter is to be parsed post character string .
The second parameter is the parameter that needs to be parsed “ Key value pair ” The key .
The third parameter is the array of parsed data storage .
The last parameter is the length of the storage array
After successful parsing .e The value of is ESP_OK, Use this to determine whether the parsing is successful .
start-up http The server
Start the service , Register the above two pages to the server . This is simpler .
httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.lru_purge_enable = true;
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK) {
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &echo);
httpd_register_uri_handler(server, &index_page);
#if CONFIG_EXAMPLE_BASIC_AUTH
httpd_register_basic_auth(server);
#endif
return server;
}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
wifistation
When you receive the correct wifi After the name and password ,esp32 To put wifi Turn into station Pattern , And networking . How to implement this part ? A separate task is used here .
Get into station Before mode , Need to put http Server down , also wifi Reinitialize .** Note that none of the following functions can be omitted . otherwise station The mode will not work properly .** This is the result of a long experiment .
void wifi_station_task(void * pvParameters)
{
uint32_t result =0;
while(1)
{
result = xSemaphoreTake(ap_sem,portMAX_DELAY);
if(result == pdPASS)
{
esp_wifi_stop();
esp_event_handler_unregister(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler
);
esp_netif_destroy_default_wifi(ap_netif);
esp_event_loop_delete_default();
esp_wifi_deinit();
esp_netif_deinit();
httpd_stop(server);
printf("hello \r\n");
ESP_LOGI(TAG,"led on");
wifi_init_sta(wifi_name,wifi_password);
}
printf("hello1 \r\n");
// vTaskDelay(pdMS_TO_TICKS(1000));
}
}
Code link
The specific code link is as follows , The development environment is official esp-idf.https://download.csdn.net/download/sinat_36568888/85750520
边栏推荐
- 滑环安装有哪些技巧和方法
- How to convert an old keyboard into a USB keyboard and program it yourself?
- [vscode] setting sync, a plug-in for synchronizing extensions and settings
- 简单快速的数网络(网络中的网络套娃)
- CEC-I 中华学习机使用说明与问答
- 网上开通证券账户安全吗 手机炒股靠谱吗
- Special topic II on mathematical physics of the sprint strong foundation program
- One click acceleration of Sony camera SD card file copy operation, file operation batch processing tutorial
- Moher College -x-forwarded-for injection vulnerability practice
- Hid device descriptor and keyboard key value corresponding coding table in USB protocol
猜你喜欢

Kubernetes visual interface dashboard

Lambda expression

當Transformer遇見偏微分方程求解

What is the difference between the working principle of gas-liquid slip ring and other slip rings

buuctf-pwn write-ups (6)

Deep learning method for solving mean field game theory problems

Lwip之ARP模块实现

Implementation of ARP module in LwIP

解决STC8G1K08程序不能运行的问题和端口配置

One click acceleration of Sony camera SD card file copy operation, file operation batch processing tutorial
随机推荐
Moher College - SQL injection vulnerability test (error reporting and blind note)
ESP32-添加多目录的自定义组件
matlab数据类型 —— 字符型
Live review | Ziya &ccf TF: Discussion on software supply chain risk management technology under cloud native scenario
ESP32-SOLO开发教程,解决CONFIG_FREERTOS_UNICORE问题
统计无向图中无法互相到达点对数[经典建邻接表+DFS统计 -> 并查集优化][并查集手册/写的详细]
【UVM实战 ===> Episode_3 】~ Assertion、Sequence、Property
Redis detailed tutorial
墨者学院-SQL注入漏洞测试(报错盲注)
论文解读(LG2AR)《Learning Graph Augmentations to Learn Graph Representations》
Processing of slice loss in ArcGIS mosaic dataset
Solve the problem that stc8g1k08 program cannot run and port configuration
[vscode] setting sync, a plug-in for synchronizing extensions and settings
find_circ详细使用指南
Oracle database basics concepts
2022年地理信息系统与遥感专业就业前景与升学高校排名选择
3 - wire SPI Screen Drive
Is it safe to open a compass account?
用代码生成流程图,Markdown的使用方法
如何把老式键盘转换成USB键盘并且自己编程?