diff --git a/CONSOLE_SIMPLE_INIT_BLOG_ZH.md b/CONSOLE_SIMPLE_INIT_BLOG_ZH.md new file mode 100644 index 0000000..41869dc --- /dev/null +++ b/CONSOLE_SIMPLE_INIT_BLOG_ZH.md @@ -0,0 +1,164 @@ +# 用 `console_simple_init` 给 ESP-IDF 项目加一个可交互控制台(中文实践) + +很多时候我们在调 ESP32 项目时,会遇到这种场景: + +- 想临时执行一个命令看状态 +- 想在线触发某个动作(比如开关某个外设) +- 不想每次都改代码、烧录、再看日志 + +这时候,一个可交互的 Console 就非常有价值。 + +这篇文章记录一个通用做法:在任何 ESP-IDF 项目里,用 `espressif/console_simple_init` 快速接入命令行控制台。 + +## 一、为什么用它 + +原生 `esp_console` 功能很完整,但初始化流程相对分散。`console_simple_init` 的价值在于把常用步骤封装成了 4 个 API: + +- `console_cmd_init()`:初始化控制台 +- `console_cmd_user_register()`:注册用户命令 +- `console_cmd_all_register()`:自动注册插件命令 +- `console_cmd_start()`:启动 REPL + +一句话:快速可用,适合先跑通再扩展。 + +## 二、接入步骤 + +### 1. 添加组件依赖 + +```bash +idf.py add-dependency "espressif/console_simple_init^1.1.0" +``` + +或者在 `idf_component.yml` 里手动添加: + +```yaml +dependencies: + idf: ">=5.0" + espressif/console_simple_init: ^1.1.0 +``` + +### 2. 在 CMake 里声明依赖 + +在你的组件 `CMakeLists.txt`(例如 `main/CMakeLists.txt`)里: + +```cmake +idf_component_register( + SRCS "main.c" + INCLUDE_DIRS "." + REQUIRES console_simple_init console +) +``` + +这里建议把 `console` 显式写上,能避免一类常见的 include/IntelliSense 问题(后文会讲)。 + +### 3. 在代码里初始化并注册命令 + +```c +#include +#include "esp_check.h" +#include "console_simple_init.h" + +static int cmd_hello(int argc, char **argv) +{ + (void)argc; + (void)argv; + printf("hello from console\n"); + return 0; +} + +void app_main(void) +{ + // 你的项目里需确保 NVS 和默认事件循环已初始化 + + ESP_ERROR_CHECK(console_cmd_init()); + ESP_ERROR_CHECK(console_cmd_user_register("hello", cmd_hello)); + ESP_ERROR_CHECK(console_cmd_all_register()); // 可选 + ESP_ERROR_CHECK(console_cmd_start()); +} +``` + +### 4. 烧录后验证 + +```bash +idf.py flash monitor +``` + +在 `esp>` 提示符输入: + +- `help` +- `hello` + +如果能看到输出,说明接入成功。 + +## 三、一个很常见的坑 + +### 现象 + +- `#include "console_simple_init.h"` 报 include 错 +- 或提示找不到 `esp_console.h` + +### 本质 + +`console_simple_init.h` 会依赖 `esp_console.h`。如果你的组件没有显式依赖 `console`,编辑器索引有时会解析不到。 + +### 解决 + +1. CMake 增加 `REQUIRES console` +2. 执行: + +```bash +idf.py reconfigure +idf.py build +``` + +3. 在 VS Code 刷新索引(Reset IntelliSense Database + Reload Window) + +## 四、另一个常见坑:串口写入超时 + +### 现象 + +Monitor 日志里反复出现: + +- `Writing to serial is timing out...` + +### 本质 + +Console 所用的通道(UART / USB CDC / USB Serial/JTAG)和你当前 monitor 连接端口不一致。 + +### 解决 + +在 `menuconfig` 里把 console 输出通道配置成和你实际连接一致: + +- `Component config -> ESP System Settings -> Channel for console output` + +改完后重新 build + flash。 + +## 五、为什么它适合做“运维入口” + +当项目复杂起来后,你会很自然地需要这些命令: + +- `status`:看系统状态 +- `sensor`:看传感器实时值 +- `pump on/off`:控制执行器 +- `wifi status`:看联网状态 + +有了 console,这些能力都能在不改 UI 的情况下快速加上。 + +## 六、我建议的演进路线 + +1. 先做 1~2 个命令跑通链路 +2. 加参数解析和错误提示 +3. 按模块分组命令(sensor/io/net) +4. 给危险动作加确认机制 + +## 七、总结 + +`console_simple_init` 的优势不是“功能比 `esp_console` 更多”,而是把接入门槛降得很低: + +- 依赖加上 +- 几个 API 调用 +- 很快就能得到可交互的调试入口 + +对于早期开发和现场调试,它能显著减少反复烧录的成本。 + + diff --git a/CONSOLE_SIMPLE_INIT_TUTORIAL.md b/CONSOLE_SIMPLE_INIT_TUTORIAL.md new file mode 100644 index 0000000..efb48bb --- /dev/null +++ b/CONSOLE_SIMPLE_INIT_TUTORIAL.md @@ -0,0 +1,174 @@ +# ESP-IDF `console_simple_init` Tutorial (Project-Independent) + +This guide is a standalone tutorial for adding and using `espressif/console_simple_init` in any ESP-IDF project. + +## 1. What This Component Does + +`console_simple_init` is a convenience wrapper around ESP-IDF console/REPL setup. + +It provides these APIs: + +- `console_cmd_init()` +- `console_cmd_user_register()` +- `console_cmd_all_register()` +- `console_cmd_start()` + +Header: + +```c +#include "console_simple_init.h" +``` + +## 2. Add Dependency + +Run: + +```bash +idf.py add-dependency "espressif/console_simple_init^1.1.0" +``` + +Or edit your component manifest (`idf_component.yml`): + +```yaml +dependencies: + idf: ">=5.0" + espressif/console_simple_init: ^1.1.0 +``` + +## 3. Declare CMake Dependency + +In your component `CMakeLists.txt` (for example `main/CMakeLists.txt`): + +```cmake +idf_component_register( + SRCS "main.c" + INCLUDE_DIRS "." + REQUIRES console_simple_init console +) +``` + +Why include `console` explicitly? + +- `console_simple_init.h` uses `esp_console.h`. +- Explicit `REQUIRES console` avoids include path and IntelliSense issues. + +## 4. Minimal Working Example + +```c +#include +#include "esp_check.h" +#include "console_simple_init.h" + +static int cmd_hello(int argc, char **argv) +{ + (void)argc; + (void)argv; + printf("hello from console\n"); + return 0; +} + +void app_main(void) +{ + // Ensure required system init is done in your app: + // - NVS initialized + // - default event loop created + + ESP_ERROR_CHECK(console_cmd_init()); + ESP_ERROR_CHECK(console_cmd_user_register("hello", cmd_hello)); + ESP_ERROR_CHECK(console_cmd_all_register()); // optional + ESP_ERROR_CHECK(console_cmd_start()); +} +``` + +## 5. Preconditions + +Before starting console, make sure your app has initialized: + +- NVS (`nvs_flash_init`) +- default event loop (`esp_event_loop_create_default`) + +If your project already has a network/bootstrap module, these may already be done. + +## 6. How to Use at Runtime + +1. Flash firmware. +2. Open monitor (`idf.py monitor`). +3. At prompt `esp>`, type: + +```text +help +hello +``` + +## 7. Console Channel Selection (Important) + +Pick the console channel to match your physical connection: + +- UART +- USB CDC +- USB Serial/JTAG + +If channel and monitor port do not match, you may see warnings like write timeout when typing commands. + +Configure via `menuconfig`: + +- `Component config -> ESP System Settings -> Channel for console output` + +Then rebuild and flash. + +## 8. Common Issues + +### Issue A: `#include` errors for `console_simple_init.h` or `esp_console.h` + +Checklist: + +- Added dependency in `idf_component.yml` +- Added `REQUIRES console_simple_init console` in `CMakeLists.txt` +- Re-run: + +```bash +idf.py reconfigure +idf.py build +``` + +- Refresh editor index/IntelliSense + +### Issue B: Serial port busy while flashing + +Another monitor/process holds the port. + +- Close monitor first +- Retry `idf.py flash` + +### Issue C: Console starts but input behaves poorly + +Your terminal may not support escape sequences/history editing. + +Use a terminal that supports VT sequences. + +## 9. Next Step Ideas + +- Add commands for system status (`status`) +- Add commands for peripheral control (`pump on`, `light off`) +- Add argument parsing and help text +- Group commands by module for maintainability + +## 10. Quick Command Template + +Use this template to add a command quickly: + +```c +static int cmd_name(int argc, char **argv) +{ + // parse args + // run logic + // print result + return 0; +} + +ESP_ERROR_CHECK(console_cmd_user_register("name", cmd_name)); +``` + +--- + +This tutorial is intentionally generic so it can be reused in any ESP-IDF codebase. diff --git a/dependencies.lock b/dependencies.lock index 78101a0..bffcc4c 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -9,6 +9,16 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 2.0.0 + espressif/console_simple_init: + component_hash: b488b12318f3cb6e0b55b034bd12956926d45f0e1396442e820f8ece4776c306 + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.1.0 espressif/esp_lvgl_port: component_hash: b6360960f47b6776462e7092861b3ea66477ffb762a01baa0aecbb3d74cd50f4 dependencies: @@ -60,9 +70,10 @@ dependencies: version: 9.5.0 direct_dependencies: - espressif/bh1750 +- espressif/console_simple_init - espressif/esp_lvgl_port - idf - k0i05/esp_ahtxx -manifest_hash: 5762034b4c66072216d7ea1b788e5406026bf0ac8db349bd46ccb04dc37ff0d1 +manifest_hash: 876b8b787041413cd7d3f71227f1618dceac35f343e17a5874d56c77837d0705 target: esp32c3 version: 2.0.0 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 35199ae..3198b6e 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "main.c" INCLUDE_DIRS "." - REQUIRES wifi-connect esp_lvgl_port lvgl_st7735s_use i2c_master_messager io_device_control + REQUIRES wifi-connect esp_lvgl_port lvgl_st7735s_use i2c_master_messager io_device_control console_simple_init console ) diff --git a/main/idf_component.yml b/main/idf_component.yml index 0f890f0..71515b2 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -17,3 +17,4 @@ dependencies: espressif/esp_lvgl_port: ^2.7.2 espressif/bh1750: ^2.0.0 k0i05/esp_ahtxx: ^1.2.7 + espressif/console_simple_init: ^1.1.0 diff --git a/main/main.c b/main/main.c index cee4e47..efa0a46 100755 --- a/main/main.c +++ b/main/main.c @@ -9,6 +9,7 @@ #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 #ifndef CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE #define CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE 0 @@ -41,12 +42,23 @@ static const char *TAG = "main"; +static int cmd_hello(int argc, char **argv) +{ + printf("hello from BotanicalBuddy\n"); + return 0; +} + void app_main(void) { // 初始化 Wi-Fi 配网组件,支持长按按键进入配网 ESP_ERROR_CHECK(wifi_connect_init()); printf("设备启动完成:长按按键进入配网模式,手机连接 ESP32-* 后访问 http://192.168.4.1\n"); + ESP_ERROR_CHECK(console_cmd_init()); + ESP_ERROR_CHECK(console_cmd_user_register("hello", cmd_hello)); + ESP_ERROR_CHECK(console_cmd_all_register()); // 可选:自动注册插件命令 + ESP_ERROR_CHECK(console_cmd_start()); + // 启动 LVGL 演示程序,显示简单的界面 ESP_ERROR_CHECK(start_lvgl_demo()); @@ -120,7 +132,6 @@ void app_main(void) { ESP_ERROR_CHECK(lvgl_st7735s_set_center_text("Sensor waiting...")); } - } else if (i2c_ready) {