ESP-idf框架下的HTTP服务器\HTML 485温湿度采集并长传

项目描述:

本项目采用485采集温湿度以及电压电流等,485模块分别为下图,串口转485模块采用自动收发模块,ESP32工作在AP热点模式,通过手机连接esp32的热点来和esp进行数据通讯,

使用esp32作为HTTP服务器

缺陷:

项目的最终HTML页面

代码

可发给AI让其写注释

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include <string.h>
#include "lwip/err.h"
#include "lwip/sys.h"
#include <esp_http_server.h>
#include <stdio.h>
#include <string.h>
#include "freertos/queue.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "cJSON.h"
#include <time.h>/* 配置参数 */
#define EXAMPLE_ESP_WIFI_SSID      "laotie666"
#define EXAMPLE_ESP_WIFI_PASS      "12345678"
#define EXAMPLE_ESP_WIFI_CHANNEL   1
#define EXAMPLE_MAX_STA_CONN       4
#define EXAMPLE_HTTP_QUERY_KEY_MAX_LEN  (64)#define EX_UART_NUM UART_NUM_1
#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)/* 全局变量 */
uint8_t get_jsy_value[8] = {0x02, 0x03, 0x00, 0x48, 0x00, 0x05, 0x05, 0xEC};
uint8_t get_val[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
uint16_t Hum = 255;   // 湿度值 Hum = 实际值 * 10
int16_t Tem = 232;    // 温度值 Tem = 实际值 * 10
uint16_t Voltage=24, Current=2;
float Power=2.3;          // 功率static QueueHandle_t uart0_queue;
static const char *TAG = "wifi softAP";/* 美观的HTML页面模板 */
static const char *HTML_PAGE = R"rawliteral(
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ESP32 环境监测</title><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);min-height: 100vh;display: flex;justify-content: center;align-items: center;padding: 20px;}.container {background: rgba(255, 255, 255, 0.15);backdrop-filter: blur(10px);border-radius: 20px;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);width: 100%;max-width: 500px;padding: 30px;color: white;}header {text-align: center;margin-bottom: 30px;}h1 {font-size: 28px;margin-bottom: 10px;text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);}.status {display: flex;align-items: center;justify-content: center;gap: 10px;font-size: 16px;}.status-indicator {width: 12px;height: 12px;border-radius: 50%;background-color: #4CAF50;box-shadow: 0 0 10px #4CAF50;}.sensors-grid {display: grid;grid-template-columns: 1fr 1fr;gap: 20px;margin-bottom: 30px;}.sensor-card {background: rgba(255, 255, 255, 0.1);border-radius: 15px;padding: 20px;text-align: center;transition: transform 0.3s ease, box-shadow 0.3s ease;cursor: pointer;}.sensor-card:hover {transform: translateY(-5px);box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);background: rgba(255, 255, 255, 0.2);}.sensor-icon {font-size: 40px;margin-bottom: 15px;}.sensor-value {font-size: 32px;font-weight: bold;margin: 10px 0;}.sensor-unit {font-size: 16px;opacity: 0.8;}.sensor-title {font-size: 18px;margin-bottom: 10px;color: #FFD700;}.power-section {background: rgba(0, 0, 0, 0.2);border-radius: 15px;padding: 20px;margin-bottom: 25px;}.power-title {text-align: center;font-size: 20px;margin-bottom: 15px;color: #FFD700;}.power-grid {display: grid;grid-template-columns: repeat(3, 1fr);gap: 15px;}.power-card {background: rgba(255, 255, 255, 0.1);border-radius: 10px;padding: 15px;text-align: center;}.power-value {font-size: 24px;font-weight: bold;margin: 5px 0;}.power-label {font-size: 14px;opacity: 0.8;}.last-update {text-align: center;font-size: 14px;opacity: 0.7;margin-top: 20px;}.refresh-info {text-align: center;font-size: 14px;margin-top: 10px;opacity: 0.7;}footer {text-align: center;margin-top: 30px;font-size: 14px;opacity: 0.8;}</style>
</head>
<body><div class="container"><header><h1>ESP32 环境监测</h1><div class="status"><div class="status-indicator"></div><span>设备在线</span></div></header><div class="sensors-grid"><div class="sensor-card" style="border: 2px solid #FF5252;"><div class="sensor-icon">🌡️</div><div class="sensor-title">温度</div><div class="sensor-value">%.1f</div><div class="sensor-unit">°C</div></div><div class="sensor-card" style="border: 2px solid #29B6F6;"><div class="sensor-icon">💧</div><div class="sensor-title">湿度</div><div class="sensor-value">%.1f</div><div class="sensor-unit">%</div></div></div><div class="power-section"><div class="power-title">电能参数</div><div class="power-grid"><div class="power-card"><div class="power-label">电压</div><div class="power-value">%d</div><div class="power-unit">V</div></div><div class="power-card"><div class="power-label">电流</div><div class="power-value">%.1f</div><div class="power-unit">A</div></div><div class="power-card"><div class="power-label">功率</div><div class="power-value">%.1f</div><div class="power-unit">W</div></div></div></div><div class="last-update">最后更新: %s</div><div class="refresh-info">页面每2秒自动刷新</div><footer>ESP32 环境监测系统 | © 2025</footer></div><script>// 每2秒自动刷新页面setTimeout(function() {location.reload();}, 2000);</script>
</body>
</html>
)rawliteral";/* 获取当前时间字符串 */
static const char *get_current_time() {static char time_str[20];time_t now = time(NULL);struct tm *timeinfo = localtime(&now);strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", timeinfo);return time_str;
}/* UART事件处理任务 */
static void uart_event_task(void *pvParameters) {uart_event_t event;size_t buffered_size;uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);for (;;) {if (xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY)) {bzero(dtmp, RD_BUF_SIZE);switch (event.type) {case UART_DATA:uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);if (event.size == 15) {Voltage = dtmp[3];Voltage = Voltage << 8;Voltage |= dtmp[4];Current = dtmp[5];Current = Current << 8;Current |= dtmp[6];Power = (Voltage * Current) / 10.0f;ESP_LOGI(TAG, "电能数据: %dV, %.1fA, %.1fW", Voltage, Current / 10.0f, Power);} else if (event.size == 9) {Hum = dtmp[3];Hum = Hum << 8;Hum |= dtmp[4];Tem = dtmp[5];Tem = Tem << 8;Tem |= dtmp[6];ESP_LOGI(TAG, "温湿度数据: %.1f°C, %.1f%%", Tem / 10.0f, Hum / 10.0f);}break;case UART_FIFO_OVF:ESP_LOGW(TAG, "UART FIFO溢出");uart_flush_input(EX_UART_NUM);xQueueReset(uart0_queue);break;case UART_BUFFER_FULL:ESP_LOGW(TAG, "UART缓冲区满");uart_flush_input(EX_UART_NUM);xQueueReset(uart0_queue);break;case UART_BREAK:ESP_LOGW(TAG, "UART线路断开");break;case UART_FRAME_ERR:ESP_LOGW(TAG, "UART帧错误");break;default:ESP_LOGW(TAG, "未知UART事件: %d", event.type);break;}}}free(dtmp);vTaskDelete(NULL);
}/* 串口发送任务 */
void uart_T_task(void *p) {while (1) {uart_write_bytes(EX_UART_NUM, get_jsy_value, 8);vTaskDelay(pdMS_TO_TICKS(300));uart_write_bytes(EX_UART_NUM, get_val, 8);vTaskDelay(pdMS_TO_TICKS(300));}
}/* WiFi事件处理 */
static void wifi_event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data) {if (event_id == WIFI_EVENT_AP_STACONNECTED) {wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;ESP_LOGI(TAG, "设备连接: "MACSTR", AID=%d", MAC2STR(event->mac), event->aid);} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;ESP_LOGI(TAG, "设备断开: "MACSTR", AID=%d, 原因=%d", MAC2STR(event->mac), event->aid, event->reason);}
}/* 初始化WiFi AP */
void wifi_init_softap(void) {ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_ap();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL));wifi_config_t wifi_config = {.ap = {.ssid = EXAMPLE_ESP_WIFI_SSID,.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),.channel = EXAMPLE_ESP_WIFI_CHANNEL,.password = EXAMPLE_ESP_WIFI_PASS,.max_connection = EXAMPLE_MAX_STA_CONN,.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg = {.required = true,},},};if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {wifi_config.ap.authmode = WIFI_AUTH_OPEN;}ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "WiFi AP启动完成. SSID:%s 密码:%s 信道:%d",EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
}/* HTTP请求处理函数:处理根路径"/"的GET请求,返回带实时数据的HTML页面 */
static esp_err_t root_get_handler(httpd_req_t *req) {// 分配内存存储HTML内容(长度为模板长度+200,预留数据填充空间)char *html_content = (char *)malloc(strlen(HTML_PAGE) + 200);if (!html_content) {// 若内存分配失败httpd_resp_send_500(req);// 发送500(服务器内部错误)响应return ESP_FAIL; // 返回失败}// 格式化HTML内容,将实时数据填充到HTML代码模板的占位符中snprintf(html_content, strlen(HTML_PAGE) + 200, HTML_PAGE, Tem / 10.0f, // 温度(实际值 = 存储值/10)Hum / 10.0f,// 湿度(实际值 = 存储值/10)Voltage,// 电压Current / 10.0f, // 电流(实际值 = 存储值/10)Power,// 功率get_current_time());// 返回最后更新时间(字符串)// 发送HTTP响应httpd_resp_set_type(req, "text/html");httpd_resp_send(req, html_content, strlen(html_content));free(html_content); // 释放内存return ESP_OK;
}/* HTTP服务器URI配置:定义根路径"/"的处理规则 */
static httpd_uri_t root = {.uri       = "/",// 匹配的URI路径.method    = HTTP_GET,// 支持的HTTP方法(GET).handler   = root_get_handler,//GET方法的 处理函数.user_ctx  = NULL           // 用户上下文数据(无)
};/* 启动HTTP服务器 */
static httpd_handle_t start_webserver(void) {httpd_handle_t server = NULL;       // 服务器句柄httpd_config_t config = HTTPD_DEFAULT_CONFIG();// 默认服务器配置config.lru_purge_enable = true; // 启用LRU(最近最少使用)缓存清理// 启动HTTP服务器if (httpd_start(&server, &config) == ESP_OK) {// 注册根路径"/"的处理函数httpd_register_uri_handler(server, &root);ESP_LOGI(TAG, "HTTP服务器已启动,端口: %d", config.server_port);return server;}ESP_LOGE(TAG, "HTTP服务器启动失败!");return NULL;
}void app_main(void) {// 初始化NVSesp_err_t ret = nvs_flash_init();if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK(nvs_flash_erase());ret = nvs_flash_init();}ESP_ERROR_CHECK(ret);// 初始化UARTuart_config_t uart_config = {.baud_rate = 9600,.data_bits = UART_DATA_8_BITS,.parity = UART_PARITY_DISABLE,.stop_bits = UART_STOP_BITS_1,.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,.source_clk = UART_SCLK_DEFAULT,};uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);uart_param_config(EX_UART_NUM, &uart_config);uart_set_pin(EX_UART_NUM, GPIO_NUM_4, GPIO_NUM_5, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);// 创建任务xTaskCreate(uart_event_task, "uart_event_task", 4046, NULL, 12, NULL);xTaskCreate(uart_T_task, "uart_T_task", 4046, NULL, 10, NULL);// 初始化时间setenv("TZ", "CST-8", 1);tzset();// 初始化WiFi和HTTP服务器ESP_LOGI(TAG, "初始化WiFi AP...");wifi_init_softap();ESP_LOGI(TAG, "启动HTTP服务器...");httpd_handle_t server = start_webserver();ESP_LOGI(TAG, "系统已启动完成");ESP_LOGI(TAG, "请连接热点: %s", EXAMPLE_ESP_WIFI_SSID);ESP_LOGI(TAG, "然后在浏览器访问: http://192.168.4.1");
}

上述代码时间显示有问题,下面是优化后的代码 显示时间为手机的时间与esp32无关


#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include <string.h>
#include "lwip/err.h"
#include "lwip/sys.h"
#include <esp_http_server.h>
#include <stdio.h>
#include <string.h>
#include "freertos/queue.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "cJSON.h"
#include <time.h>
#include "esp_sntp.h"/* 配置参数 */
#define EXAMPLE_ESP_WIFI_SSID "laotie666"
#define EXAMPLE_ESP_WIFI_PASS "12345678"
#define EXAMPLE_ESP_WIFI_CHANNEL 1
#define EXAMPLE_MAX_STA_CONN 4
#define EXAMPLE_HTTP_QUERY_KEY_MAX_LEN (64)#define EX_UART_NUM UART_NUM_1
#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)/* 全局变量 */
uint8_t get_jsy_value[8] = {0x02, 0x03, 0x00, 0x48, 0x00, 0x05, 0x05, 0xEC};
uint8_t get_val[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
uint16_t Hum = 255; // 湿度值 Hum = 实际值 * 10
int16_t Tem = 232;  // 温度值 Tem = 实际值 * 10
uint16_t Voltage = 24, Current = 2;
float Power = 2.3; // 功率static QueueHandle_t uart0_queue;
static const char *TAG = "wifi softAP";/* 美观的HTML页面模板 */
static const char *HTML_PAGE = R"rawliteral(
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ESP32 环境监测</title><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);min-height: 100vh;display: flex;justify-content: center;align-items: center;padding: 20px;}.container {background: rgba(255, 255, 255, 0.15);backdrop-filter: blur(10px);border-radius: 20px;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);width: 100%;max-width: 500px;padding: 30px;color: white;}header {text-align: center;margin-bottom: 30px;}h1 {font-size: 28px;margin-bottom: 10px;text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);}.status {display: flex;align-items: center;justify-content: center;gap: 10px;font-size: 16px;}.status-indicator {width: 12px;height: 12px;border-radius: 50%;background-color: #4CAF50;box-shadow: 0 0 10px #4CAF50;}.sensors-grid {display: grid;grid-template-columns: 1fr 1fr;gap: 20px;margin-bottom: 30px;}.sensor-card {background: rgba(255, 255, 255, 0.1);border-radius: 15px;padding: 20px;text-align: center;transition: transform 0.3s ease, box-shadow 0.3s ease;cursor: pointer;}.sensor-card:hover {transform: translateY(-5px);box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);background: rgba(255, 255, 255, 0.2);}.sensor-icon {font-size: 40px;margin-bottom: 15px;}.sensor-value {font-size: 32px;font-weight: bold;margin: 10px 0;}.sensor-unit {font-size: 16px;opacity: 0.8;}.sensor-title {font-size: 18px;margin-bottom: 10px;color: #FFD700;}.power-section {background: rgba(0, 0, 0, 0.2);border-radius: 15px;padding: 20px;margin-bottom: 25px;}.power-title {text-align: center;font-size: 20px;margin-bottom: 15px;color: #FFD700;}.power-grid {display: grid;grid-template-columns: repeat(3, 1fr);gap: 15px;}.power-card {background: rgba(255, 255, 255, 0.1);border-radius: 10px;padding: 15px;text-align: center;}.power-value {font-size: 24px;font-weight: bold;margin: 5px 0;}.power-label {font-size: 14px;opacity: 0.8;}.last-update {font-size: 16px;margin-bottom: 8px;color: #FFD700;}#current-time {text-align: center;font-size: 14px;margin-top: 10px;opacity: 0.7;}.refresh-info {text-align: center;font-size: 14px;margin-top: 10px;opacity: 0.7;}footer {text-align: center;margin-top: 30px;font-size: 14px;opacity: 0.8;}</style>
</head>
<body><div class="container"><header><h1>ESP32 环境监测</h1><div class="status"><div class="status-indicator"></div><span>设备在线</span></div></header><div class="sensors-grid"><div class="sensor-card" style="border: 2px solid #FF5252;"><div class="sensor-icon">🌡️</div><div class="sensor-title">温度</div><div class="sensor-value">%.1f</div><div class="sensor-unit">°C</div></div><div class="sensor-card" style="border: 2px solid #29B6F6;"><div class="sensor-icon">💧</div><div class="sensor-title">湿度</div><div class="sensor-value">%.1f</div><div class="sensor-unit">%%</div></div></div><div class="power-section"><div class="power-title">电能参数</div><div class="power-grid"><div class="power-card"><div class="power-label">电压</div><div class="power-value">%d</div><div class="power-unit">V</div></div><div class="power-card"><div class="power-label">电流</div><div class="power-value">%.1f</div><div class="power-unit">A</div></div><div class="power-card"><div class="power-label">功率</div><div class="power-value">%.1f</div><div class="power-unit">W</div></div></div></div><div class="refresh-info">数据更新时间: <span id="current-time">正在获取...</span></div><div class="refresh-info">页面每秒自动刷新</div><footer>ESP32 环境监测系统 | © 2025</footer></div><script>
function updateSystemTime() {const now = new Date();const timeString = now.toLocaleString('zh-CN', {year: 'numeric',month: '2-digit',day: '2-digit',hour: '2-digit',minute: '2-digit',second: '2-digit',hour12: false});document.getElementById('current-time').textContent = timeString;
}updateSystemTime();setInterval(updateSystemTime, 1000);setTimeout(function() {location.reload();}, 1000);</script>
</body>
</html>
)rawliteral";/* UART事件处理任务 */
static void uart_event_task(void *pvParameters)
{uart_event_t event;size_t buffered_size;uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);for (;;){if (xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY)){bzero(dtmp, RD_BUF_SIZE);switch (event.type){case UART_DATA:uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);if (event.size == 15){Voltage = dtmp[3];Voltage = Voltage << 8;Voltage |= dtmp[4];Current = dtmp[5];Current = Current << 8;Current |= dtmp[6];Power = (Voltage * Current) / 10.0f;ESP_LOGI(TAG, "电能数据: %dV, %.1fA, %.1fW", Voltage, Current / 10.0f, Power);}else if (event.size == 9){Hum = dtmp[3];Hum = Hum << 8;Hum |= dtmp[4];Tem = dtmp[5];Tem = Tem << 8;Tem |= dtmp[6];ESP_LOGI(TAG, "温湿度数据: %.1f°C, %.1f%%", Tem / 10.0f, Hum / 10.0f);}break;case UART_FIFO_OVF:ESP_LOGW(TAG, "UART FIFO溢出");uart_flush_input(EX_UART_NUM);xQueueReset(uart0_queue);break;case UART_BUFFER_FULL:ESP_LOGW(TAG, "UART缓冲区满");uart_flush_input(EX_UART_NUM);xQueueReset(uart0_queue);break;case UART_BREAK:ESP_LOGW(TAG, "UART线路断开");break;case UART_FRAME_ERR:ESP_LOGW(TAG, "UART帧错误");break;default:ESP_LOGW(TAG, "未知UART事件: %d", event.type);break;}}}free(dtmp);vTaskDelete(NULL);
}/* 串口发送任务 */
void uart_T_task(void *p)
{while (1){uart_write_bytes(EX_UART_NUM, get_jsy_value, 8);vTaskDelay(pdMS_TO_TICKS(300));uart_write_bytes(EX_UART_NUM, get_val, 8);vTaskDelay(pdMS_TO_TICKS(300));}
}/* WiFi事件处理 */
static void wifi_event_handler(void *arg, esp_event_base_t event_base,int32_t event_id, void *event_data)
{if (event_id == WIFI_EVENT_AP_STACONNECTED){wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;ESP_LOGI(TAG, "设备连接: " MACSTR ", AID=%d", MAC2STR(event->mac), event->aid);}else if (event_id == WIFI_EVENT_AP_STADISCONNECTED){wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;ESP_LOGI(TAG, "设备断开: " MACSTR ", AID=%d, 原因=%d", MAC2STR(event->mac), event->aid, event->reason);}
}/* 初始化WiFi AP */
void wifi_init_softap(void)
{ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_ap();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL));wifi_config_t wifi_config = {.ap = {.ssid = EXAMPLE_ESP_WIFI_SSID,.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),.channel = EXAMPLE_ESP_WIFI_CHANNEL,.password = EXAMPLE_ESP_WIFI_PASS,.max_connection = EXAMPLE_MAX_STA_CONN,.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg = {.required = true,},},};if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0){wifi_config.ap.authmode = WIFI_AUTH_OPEN;}ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "WiFi AP启动完成. SSID:%s 密码:%s 信道:%d",EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
}/* HTTP请求处理函数:处理根路径"/"的GET请求,返回带实时数据的HTML页面 */
static esp_err_t root_get_handler(httpd_req_t *req)
{// 分配内存存储HTML内容(长度为模板长度+200,预留数据填充空间)char *html_content = (char *)malloc(strlen(HTML_PAGE) + 200);if (!html_content){                             // 若内存分配失败httpd_resp_send_500(req); // 发送500(服务器内部错误)响应return ESP_FAIL;          // 返回失败}// 格式化HTML内容,将实时数据填充到HTML代码模板的占位符中snprintf(html_content, strlen(HTML_PAGE) + 200, HTML_PAGE,Tem / 10.0f,         // 温度(实际值 = 存储值/10)Hum / 10.0f,         // 湿度(实际值 = 存储值/10)Voltage,             // 电压Current / 10.0f,     // 电流(实际值 = 存储值/10)Power);              // 功率// 发送HTTP响应httpd_resp_set_type(req, "text/html");httpd_resp_send(req, html_content, strlen(html_content));free(html_content); // 释放内存return ESP_OK;
}/* HTTP服务器URI配置:定义根路径"/"的处理规则 */
static httpd_uri_t root = {.uri = "/",                  // 匹配的URI路径.method = HTTP_GET,          // 支持的HTTP方法(GET).handler = root_get_handler, // GET方法的 处理函数.user_ctx = NULL             // 用户上下文数据(无)
};/* 启动HTTP服务器 */
static httpd_handle_t start_webserver(void)
{httpd_handle_t server = NULL;                   // 服务器句柄httpd_config_t config = HTTPD_DEFAULT_CONFIG(); // 默认服务器配置config.lru_purge_enable = true;                 // 启用LRU(最近最少使用)缓存清理// 启动HTTP服务器if (httpd_start(&server, &config) == ESP_OK){// 注册根路径"/"的处理函数httpd_register_uri_handler(server, &root);ESP_LOGI(TAG, "HTTP服务器已启动,端口: %d", config.server_port);return server;}ESP_LOGE(TAG, "HTTP服务器启动失败!");return NULL;
}void app_main(void)
{// 初始化NVSesp_err_t ret = nvs_flash_init();if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ret = nvs_flash_init();}ESP_ERROR_CHECK(ret);// 初始化UARTuart_config_t uart_config = {.baud_rate = 9600,.data_bits = UART_DATA_8_BITS,.parity = UART_PARITY_DISABLE,.stop_bits = UART_STOP_BITS_1,.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,.source_clk = UART_SCLK_DEFAULT,};uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);uart_param_config(EX_UART_NUM, &uart_config);uart_set_pin(EX_UART_NUM, GPIO_NUM_4, GPIO_NUM_5, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);// 创建任务xTaskCreate(uart_event_task, "uart_event_task", 4046, NULL, 12, NULL);xTaskCreate(uart_T_task, "uart_T_task", 4046, NULL, 10, NULL);// 初始化时间setenv("TZ", "CST-8", 1);tzset(); // 应用时区设置// 初始化WiFi和HTTP服务器ESP_LOGI(TAG, "初始化WiFi AP...");wifi_init_softap();ESP_LOGI(TAG, "启动HTTP服务器...");httpd_handle_t server = start_webserver();ESP_LOGI(TAG, "系统已启动完成");ESP_LOGI(TAG, "请连接热点: %s", EXAMPLE_ESP_WIFI_SSID);ESP_LOGI(TAG, "然后在浏览器访问: http://192.168.4.1");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94442.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

雅江工程解锁墨脱秘境:基础条件全展示(区位、地震、景点、天气)

目录 前言 一、区位信息 1、空间位置 2、区位介绍 二、地震信息 1、历史地震信息 2、5.0级以上大地震 三、景点信息 1、景点列表分布 2、4A级以上景点 四、天气信息 1、天气实况 2、天气应对挑战 五、总结 前言 相信最近大家对雅江电站的超级大工程项目应该有所耳…

​​机器学习贝叶斯算法

​​一、引言​​在当今机器学习领域&#xff0c;贝叶斯算法犹如一颗璀璨的明星。你是否想过&#xff0c;垃圾邮件过滤系统是如何准确判断一封邮件是否为垃圾邮件的呢&#xff1f;这背后可能就有贝叶斯算法的功劳。今天&#xff0c;我们就一同走进贝叶斯算法的世界&#xff0c;…

Chisel芯片开发入门系列 -- 18. CPU芯片开发和解释8(流水线架构的代码级理解)

以【5 Stage pipeline CPU】搜索图片&#xff0c;选取5幅有代表性的图列举如下&#xff0c;并结合Chisel代码进行理解和点评。 图1&#xff1a;原文链接如下 https://acsweb.ucsd.edu/~dol031/posts/update/2023/04/10/5stage-cpu-pipeline.html 点评&#xff1a;黑色的部分…

Docker容器中文PDF生成解决方案

在Docker容器中生成包含中文内容的PDF文件时&#xff0c;经常遇到中文字符显示为方块或乱码的问题。本文将详细介绍如何在Docker环境中配置中文字体支持&#xff0c;实现完美的中文PDF生成。 问题现象 当使用wkhtmltopdf、Puppeteer或其他PDF生成工具时&#xff1a; 中文字符…

2.java集合,线程面试题(已实践,目前已找到工作)

1线程的创建方式 继承Thread类实现Runnable接口实现Callable接口 2.这三种方式在项目中的使用有哪些&#xff0c;一般都是怎么用的 继承thread类实现线程的方式通过实现run方法来实现线程&#xff0c;通过run进行线程的启用实现runnable方法实现run方法&#xff0c;然后通过thr…

站在前端的角度,看鸿蒙页面布局

从Web前端转向鸿蒙&#xff08;HarmonyOS&#xff09;开发时&#xff0c;理解其页面布局的相似与差异是快速上手的核心。鸿蒙的ArkUI框架在布局理念上与Web前端有诸多相通之处&#xff0c;但也存在关键区别。以下从五个维度系统分析&#xff1a; &#x1f4e6; 一、盒子模型&a…

JavaWeb遗传算法、TSP、模拟退火、ACO算法等实战应用

Java Web中实现遗传算法的应用 以下是关于Java Web中实现遗传算法的应用场景和实例的整理,涵盖不同领域的解决方案和实现方法: 遗传算法基础结构 在Java Web中实现遗传算法通常需要以下核心组件: 种群初始化:随机生成初始解集。 适应度函数:评估个体优劣。 选择操作:轮…

【图像算法 - 09】基于深度学习的烟雾检测:从算法原理到工程实现,完整实战指南

一、项目背景与需求 视频介绍 【图像算法 - 09】基于深度学习的烟雾检测&#xff1a;从算法原理到工程实现&#xff0c;完整实战指南今天我们使用深度学习来训练一个烟雾明火检测系统。这次我们使用了大概一万五千张图片的数据集训练了这次的基于深度学习的烟雾明火检测模型&a…

间接制冷技术概念及特征

1、基本概念 (1)间接制冷技术即二次制冷技术。常规做法:二次冷却液储液罐增加放置于制冷系统管路,促使冷量再快捷的传递给载冷剂,继而载冷剂冷量促使冷库达到制冷效果。间接制冷技术:通过常压的二次冷却介质进行大循环传送冷量,在直接制冷剂不易应用的位置或者不可运用直…

Antlr学习笔记 01、maven配置Antlr4插件案例Demo

文章目录前言源码插件描述pom引入插件案例&#xff1a;实现hello 标识符 案例1、引入Antlr4的pom运行依赖2、定义语义语法&#xff0c;配置.g4文件实现java代码3、编写完之后&#xff0c;执行命令实现编译4、编写单测测试使用参考文章资料获取前言 博主介绍&#xff1a;✌目前…

PostGIS面试题及详细答案120道之 (101-110 )

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

第十七天:原码、反码、补码与位运算

原码、反码、补码与位运算 一、原码、反码、补码 1、原码 定义&#xff1a;原码是一种简单的机器数表示法。对于一个有符号整数&#xff0c;最高位为符号位&#xff0c; 0 表示正数&#xff0c; 1 表示负数&#xff0c;其余位表示数值的绝对值。示例&#xff1a;以 8 位二进制…

一次完整的 Docker 启动失败排错之旅:从 `start-limit` 到 `network not found

一次完整的 Docker 启动失败排错之旅&#xff1a;从 start-limit 到 network not found 你是否也曾自信地敲下 sudo systemctl start docker&#xff0c;却只得到一个冰冷的 failed&#xff1f;这是一个开发者和运维工程师都可能遇到的场景。本文将通过一个真实的排错案例&…

Tdengine 时序库年月日小时分组汇总问题

年月分组select to_char(collection_time ,"yyyy-mm") AS date, cast(SUM(a.stage_value)as DOUBLE) as stage_value from TABLE GROUP BY date年月日分组select to_char(collection_time ,"yyyy-mm-dd") AS date, SUM(a.stage_value)as DOUBLE) as stage_…

数据结构(01)—— 数据结构的基本概念

408前置学习C语言基础也可以看如下专栏&#xff1a;打怪升级之路——C语言之路_ankleless的博客-CSDN博客 目录 1. 基本概念 1.1 数据 1.2 数据元素 1.3 数据项 1.4 组合项 1.5 数据对象 1.6 数据类型 2. 数据结构 2.1 逻辑结构 2.2 存储结构 2.3 数据的运算 在学…

什么是模型并行?

模型并行c 简单来说&#xff0c;就是把一个模型拆开来放到多个 GPU 上&#xff0c;一起训练&#xff0c;从而化解“显存塞不下模型”的问题!更多专业课程内容可以听取工信部电子标准院《人工智能大模型应用工程师》课程获得详解&#xff01;

跑yolov5的train.py时,ImportError: Failed to initialize: Bad git executable.

遇到的问题&#xff1a; Traceback (most recent call last):File "D:\miniconda\envs\yolov5\lib\site-packages\git\__init__.py", line 296, in <module>refresh()File "D:\miniconda\envs\yolov5\lib\site-packages\git\__init__.py", line 287…

TCP如何实现可靠传输?实现细节?

TCP如何实现可靠传输&#xff1f;实现细节&#xff1f;如何实现可靠传输&#xff1f;拥塞控制的主要机制TCP流量控制怎么实现的&#xff1f;如何实现可靠传输&#xff1f; TCP通过自身的序列号、确认应答、数据效验、超时重传、流量控制、拥塞避免&#xff0c;确保了数据传输的…

Linux 服务器性能监控、分析与优化全指南

Linux 服务器性能监控、分析与优化在现代 IT 架构中&#xff0c;Linux 服务器作为承载业务系统的核心载体&#xff0c;其性能表现直接决定了服务的稳定性、响应速度与用户体验。无论是高并发的 Web 服务、数据密集型的数据库集群&#xff0c;还是承载虚拟化平台的宿主机&#x…

基于wenet和模型做企业直播敏感语音屏蔽技术

本文介绍了基于Wenet语音识别工具包的实时敏感词屏蔽技术方案。该方案通过客户端缓存25秒直播内容&#xff0c;利用Wenet的流式识别和断句检测功能&#xff0c;实时检测讲师语音中的敏感词&#xff0c;并将对应位置的语音替换为"哔"声。文章详细阐述了Wenet的两种识别…