#include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_check.h" #include "esp_log.h" #include "wifi-connect.h" #include "lvgl_st7735s_use.h" #include "i2c_master_messager.h" #include "io_device_control.h" #include "console_simple_init.h" // 提供 console_cmd_user_register 和 console_cmd_all_register #include "console_user_cmds.h" #include "capactive_soil_moisture_sensor_V2.0.h" #ifndef CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE #define CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE 0 #endif #ifndef CONFIG_I2C_MASTER_MESSAGER_AHT30_ENABLE #define CONFIG_I2C_MASTER_MESSAGER_AHT30_ENABLE 0 #endif #ifndef CONFIG_I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS #define CONFIG_I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS 500 #endif #ifndef CONFIG_I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS #define CONFIG_I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS 2000 #endif #ifndef CONFIG_I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP #define CONFIG_I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP 1 #endif #define BOTANY_I2C_PORT I2C_NUM_0 #define BOTANY_I2C_SCL_GPIO GPIO_NUM_5 #define BOTANY_I2C_SDA_GPIO GPIO_NUM_4 #define BOTANY_BH1750_ENABLE CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE #define BOTANY_AHT30_ENABLE CONFIG_I2C_MASTER_MESSAGER_AHT30_ENABLE #define BOTANY_BH1750_PERIOD_MS CONFIG_I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS #define BOTANY_AHT30_PERIOD_MS CONFIG_I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS #define BOTANY_I2C_INTERNAL_PULLUP CONFIG_I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP static const char *TAG = "main"; static const char *wifi_status_short_str(wifi_connect_status_t status) { switch (status) { case WIFI_CONNECT_STATUS_IDLE: return "IDLE"; case WIFI_CONNECT_STATUS_PROVISIONING: return "PROV"; case WIFI_CONNECT_STATUS_CONNECTING: return "CONN"; case WIFI_CONNECT_STATUS_CONNECTED: return "UP"; case WIFI_CONNECT_STATUS_FAILED: return "FAIL"; case WIFI_CONNECT_STATUS_TIMEOUT: return "TIME"; default: return "UNKN"; } } static void wait_for_wifi_connected(void) { const uint32_t timeout_s = 120; uint32_t elapsed_half_s = 0; ESP_LOGI(TAG, "等待 Wi-Fi 连接成功后再初始化 console..."); while (wifi_connect_get_status() != WIFI_CONNECT_STATUS_CONNECTED) { if (elapsed_half_s >= (timeout_s * 2)) { ESP_LOGW(TAG, "等待 Wi-Fi 超时(%" PRIu32 "s),继续初始化 console", timeout_s); return; } vTaskDelay(pdMS_TO_TICKS(500)); elapsed_half_s++; // 每 5 秒打印一次等待状态,避免日志刷屏。 if ((elapsed_half_s % 10) == 0) { ESP_LOGI(TAG, "仍在等待 Wi-Fi 连接(%" PRIu32 "s)", elapsed_half_s / 2); } } ESP_LOGI(TAG, "Wi-Fi 已连接,开始初始化 console"); } void app_main(void) { // 初始化 Wi-Fi 配网组件,支持长按按键进入配网 ESP_ERROR_CHECK(wifi_connect_init()); printf("设备启动完成:长按按键进入配网模式,手机连接 ESP32-* 后访问 http://192.168.4.1\n"); // 启动 LVGL 演示程序,显示简单的界面 ESP_ERROR_CHECK(start_lvgl_demo()); // 初始化 IO 设备控制组件(GPIO1 水泵,GPIO10 光照,高电平有效) ESP_ERROR_CHECK(io_device_control_init()); i2c_master_messager_config_t i2c_cfg = { .i2c_port = BOTANY_I2C_PORT, .scl_io_num = BOTANY_I2C_SCL_GPIO, .sda_io_num = BOTANY_I2C_SDA_GPIO, .i2c_enable_internal_pullup = BOTANY_I2C_INTERNAL_PULLUP, .bh1750_enable = BOTANY_BH1750_ENABLE, .aht30_enable = BOTANY_AHT30_ENABLE, .bh1750_read_period_ms = BOTANY_BH1750_PERIOD_MS, .aht30_read_period_ms = BOTANY_AHT30_PERIOD_MS, .bh1750_mode = BH1750_CONTINUE_1LX_RES, }; bool i2c_ready = false; esp_err_t ret = i2c_master_messager_init(&i2c_cfg); if (ret == ESP_OK) { ret = i2c_master_messager_start(); } if (ret != ESP_OK) { ESP_LOGE(TAG, "I2C 传感器管理启动失败: %s", esp_err_to_name(ret)); ESP_LOGW(TAG, "请检查 I2C 引脚/上拉电阻/端口占用情况,系统将继续运行但不采集传感器"); ESP_ERROR_CHECK(lvgl_st7735s_set_center_text("I2C init failed")); } else { i2c_ready = true; } // 初始化电容式土壤湿度传感器(GPIO0 / ADC1_CH0)。 bool soil_ready = false; cap_soil_sensor_config_t soil_cfg = { .unit = CAP_SOIL_SENSOR_DEFAULT_UNIT, .channel = CAP_SOIL_SENSOR_DEFAULT_CHANNEL, .atten = ADC_ATTEN_DB_12, .bitwidth = ADC_BITWIDTH_DEFAULT, // 标定值来自当前实测:空气中约 3824,水中约 1463。 .air_raw = 3824, .water_raw = 1463, }; ret = cap_soil_sensor_init(&soil_cfg); if (ret != ESP_OK) { ESP_LOGE(TAG, "土壤湿度传感器初始化失败: %s", esp_err_to_name(ret)); } else { soil_ready = true; } // 按需求:仅在 Wi-Fi 确认连通后再初始化 console。 wait_for_wifi_connected(); ESP_ERROR_CHECK(console_cmd_init()); ESP_ERROR_CHECK(console_user_cmds_register()); ESP_ERROR_CHECK(console_cmd_all_register()); // 可选:自动注册插件命令 ESP_ERROR_CHECK(console_cmd_start()); for (;;) { cap_soil_sensor_data_t soil_data = {0}; if (soil_ready && cap_soil_sensor_read(&soil_data) == ESP_OK) { // 读取成功,当前版本仅保留采样流程,显示逻辑由用户自定义。 } i2c_master_messager_data_t sensor_data = {0}; if (i2c_ready && i2c_master_messager_get_data(&sensor_data) == ESP_OK) { // 读取成功,当前版本仅保留采样流程,显示逻辑由用户自定义。 } // TODO: 在这里实现你自己的 LCD 显示内容与排版。 // ESP_ERROR_CHECK(lvgl_st7735s_set_center_text("custom text")); vTaskDelay(pdMS_TO_TICKS(1000)); } }