avatar

Ebit

编程爱好者
欢迎交流!

全部文章总字数:434.8k


⣿⣿⣿⣿⣿⣿⡿⢛⠝⣠⡾⠋⠁⢀⣴⡶⣎⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣮⣭⣙⡻⠿⠋⣠⡞⠟⠃⠀⢀⡌⠻⢿⣿⣿
⣿⣿⣿⣿⣿⡿⠁⢀⣼⠟⠀⠀⣀⣽⣿⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡍⢀⣴⡏⠁⠀⠀⢠⣿⣿⣷⣦⡹⣿
⣿⣿⣿⣿⣿⢣⣄⠈⠁⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠾⠏⡇⠀⡄⣠⡿⣿⣿⣿⣿⣿⣾
⣿⣿⣿⣿⣏⣿⣿⡦⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠐⢿⣿⡼⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡟⣱⣿⣿⣿⣿⣿⣿⠃⣿⡿⣿⣿⣿⣿⣿⡟⠈⢿⣿⣿⣿⣿⢿⣻⣿⣿⣿⣿⡄⠀⠀⠀⠘⣮⣿⠝⢻⣿⣿⣿⣿
⣿⣿⣿⣿⣿⢏⣼⡿⣻⣿⣿⣿⣿⠃⢀⢹⡇⣿⣿⣿⣿⣿⣷⠀⡈⢻⣿⣿⣿⣎⢿⣏⢿⣿⣿⣷⡀⠀⠀⠀⠘⣿⡇⠘⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣞⡝⣴⣿⣿⣿⣿⠃⢠⣿⠸⡇⢹⣿⣿⣿⢻⣿⡀⣿⡌⢻⣿⣿⣿⡌⣿⡌⣿⣿⣿⣷⠀⠀⠀⠀⠈⠧⢠⣿⣿⣿⣿
⣿⣿⣿⣿⣿⡿⣸⣿⣿⣿⣿⠇⢀⡛⣛⣇⢇⠈⣿⣿⣿⡎⣿⠁⢛⣛⡀⢛⡿⢿⣿⡘⣧⢹⣿⣿⣿⡇⢠⣄⡀⣠⠀⠈⢻⣿⣿⣿
⣿⣿⣿⣿⣿⢡⣿⣿⣿⣿⡏⢀⡟⣸⣿⣿⡌⠀⡸⣿⣿⣷⢸⠀⢸⣿⣿⣄⠻⣿⣿⣧⢹⢸⣿⣿⣿⣿⠸⡿⢰⣿⠀⢀⠻⣿⣿⣿
⣿⣿⣿⣿⡏⣾⣿⣿⣿⣿⠀⣾⠻⠿⠿⢿⣷⡀⢣⢻⣿⣿⡆⠀⢸⣯⡻⠿⣧⡘⢿⣿⣆⠀⣿⣿⣿⣿⡇⠀⠈⠉⠀⢸⡆⢸⣿⣿
⣿⣿⣿⣿⣁⣿⣿⣿⣿⡇⠘⠁⣠⡶⠂⠀⠙⣷⡈⢧⠹⣿⣇⢠⠈⠉⣠⣤⡄⠈⠙⠿⣿⡄⣿⣿⣿⣿⡇⠰⠖⠃⠀⢸⣷⠈⣿⣿
⣿⣿⣿⣼⣿⣿⣿⣿⣿⠀⢀⣾⣿⠟⠁⠀⠀⣿⣷⡀⣅⢹⣿⠘⡇⣿⣿⡿⠆⠀⠀⠀⠈⠃⠛⣿⣿⣿⡇⠀⠀⠀⠀⣿⣿⠀⣿⣿
⣿⣿⠟⣻⠿⣿⣿⣿⡟⠀⢸⣿⣿⡄⡄⠠⡀⣿⣿⣷⣜⣷⣬⣁⣿⣿⣿⠀⠀⡀⠀⠀⣧⢸⢡⣿⣿⡟⠁⠀⠀⠀⢰⣿⣿⡆⣿⣿
⣿⣿⣤⣿⠀⣿⣿⣿⡇⠀⠀⢿⣿⣷⣼⣯⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠻⠯⠟⣰⡟⠀⣾⣿⣿⡇⠀⠀⠀⠀⣿⣿⣿⡇⣿⣿
⣿⣿⣿⣿⡆⢹⣏⢿⡇⢠⣖⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⣼⣿⣿⣿⡇⠀⠀⠀⣠⣿⣿⣿⣧⣿⣿
⣿⣿⣿⣿⡱⠀⢿⡎⡡⠾⠿⢀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣡⢰⢃⣿⣿⣿⠁⠀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣷⣀⣄⢸⣿⣿⣭⣝⡊⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠂⣾⣿⣿⡟⢀⡆⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⢿⣿⣿⣿⣿⣿⣿⢠⠙⢿⣿⣿⣿⣷⣬⡻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⡀⢸⣿⣿⢻⠇⠸⠃⠿⠿⠿⣿⣿⣿⣿⣿⣿
⢿⣿⣿⣿⣿⣿⡏⣸⠀⡇⠙⢿⣿⣿⣿⣿⣷⣍⠻⢿⣿⣿⣿⣿⣿⠿⢛⣭⡶⢋⣼⠇⣿⣿⡏⠀⠀⠀⣼⢛⣵⣾⣶⣮⡻⣿⣿⣿
⢸⣿⣿⣿⣿⣿⡇⣿⠀⠁⠀⡀⣍⠻⣿⣿⣿⣿⣧⣠⠙⠛⠋⢭⣶⡿⢟⣩⣶⣿⠟⣼⣿⠟⠀⠀⢀⣾⣵⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡇⣿⠀⣤⡀⣷⡝⣰⣿⣿⣿⣿⣿⠏⠰⠿⠀⣨⣵⣾⣿⣿⠟⠁⣼⡿⢋⣀⣤⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡇⡿⣸⣿⣷⡟⣼⣿⣿⣿⣿⣿⡏⣠⣾⣿⡆⡸⣿⠿⣋⣵⢎⣚⣫⣴⣿⣿⡏⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡇⢠⣿⡿⢋⣾⣿⣿⣿⣿⣿⡟⢠⣿⣿⠏⡀⢧⠁⢺⣿⣿⣿⣿⡿⣻⣿⡟⣰⡿⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡇⣿⠏⠀⣿⣿⣿⣿⣿⣿⡟⠀⣼⡿⢁⢸⣧⣄⢀⡈⢿⣿⣿⣭⣾⣿⡟⣰⡿⣰⠇⣼⡄⣰⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⠘⠁⠆⠀⣿⣿⣿⣿⣿⡟⣰⡶⣿⢡⠏⢸⣿⠋⠚⣡⡈⣿⣿⣿⣿⠟⣱⣿⣇⠉⣴⠟⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿

2025-05-28T00:00:00.000Z

只有在不得不的时候,才选择离开 arduino 进行更细致的开发.有现成模块的情况下,90%情况下都可以用 arduino 框架,只要能满足需求就行.如果需要更细致的控制,这次尝试了 esp-idf,作为终极开发框架,明显比 stm32cubeide 更好用,它的配置和编译都可以通过命令行完成,而且有更好的中文文档支持.开发流程也是类似 arduino 的从模板开始,集成其他模板和第三方库也还算方便,docker 提供的统一环境避免了很多配置环境(比如像 keil 那样)的麻烦.

这里是这次的一些关键配置:

[<项目名称>/.devcontainer/devcontainer.json]

{
	"name": "ESP-IDF QEMU",
	"build": {
		"dockerfile": "Dockerfile"
	},
	"customizations": {
		"vscode": {
			"settings": {
				"terminal.integrated.defaultProfile.linux": "bash",
				"idf.espIdfPath": "/opt/esp/idf",
				"idf.toolsPath": "/opt/esp",
				"idf.gitPath": "/usr/bin/git"
			},
			"extensions": ["espressif.esp-idf-extension", "espressif.esp-idf-web"]
		}
	},
	"runArgs": ["--privileged"],
	"containerEnv": {
		"HTTP_PROXY": "http://172.17.0.1:7890",
		"HTTPS_PROXY": "http://172.17.0.1:7890",
		"http_proxy": "http://172.17.0.1:7890",
		"https_proxy": "http://172.17.0.1:7890",
		"NO_PROXY": "localhost,127.0.0.1"
	}
}

注意代理配置,这里的代理地址是通过ip addr show docker0获取的宿主机的 bridge 网关地址,这个固定网关是配置一次就能在宿主机下不同网络环境下使用的.

[<项目名称>/.clangd]

CompileFlags:
  # clangd 从这里拿 compile_commands.json
  CompilationDatabase: build/compile_commands.json

  # 插入本机 triple,覆盖 xtensa-esp32-unknown-elf
  Add: ["-target", "x86_64-unknown-linux-gnu"]

  # 删除所有 clangd 不认识的编译选项
  Remove:
    [
      "-mlongcalls",
      "-mrecord-mcount",
      "-fno-shrink-wrap",
      "-fstrict-volatile-bitfields",
      "-fno-tree-switch-conversion",
    ]

这样设置之后应该能正确在容器内使用和宿主机相同的 clangd 进行代码补全和语法检查.(注意在容器内安装 clangd:sudo apt install clangd)

idf 有两个依赖项定义文件,分别是CMakeLists.txtidf_component.yml,前者是 cmake 的配置文件,后者是 idf 的组件定义文件.这两个文件都可以用来定义依赖关系和编译选项. idf 的组件定义文件idf_component.yml可以用来定义组件(特别是第三方库)的名称、版本、依赖关系等信息,例如:

[<项目名称>/main/idf_component.yml]

## IDF Component Manager Manifest File
dependencies:
  ## Required IDF version
  idf:
    version: ">=4.1.0"
  # # Put list of dependencies here
  # # For components maintained by Espressif:
  # component: "~1.0.0"
  # # For 3rd party components:
  # username/component: ">=1.0.0,<2.0.0"
  # username2/component2:
  nopnop2002/ssd1306:
    git: https://github.com/nopnop2002/esp-idf-ssd1306.git
    path: components/ssd1306
  espressif/led_strip: "*"

关于组件管理可以参考这些 ai 的回答:

你可以使用 ESP-IDF 的组件管理器(`idf-component` 命令)在命令行中安装第三方库。

**基本用法:**

1. **安装依赖到当前项目:**
   ```bash
   idf.py add-dependency 'username/component@version'
   ```
   例如安装 ssd1306 组件:
   ```bash
   idf.py add-dependency 'nopnop2002/ssd1306^1.0.0'
   ```

2. **手动编辑 `idf_component.yml` 后同步依赖:**
   ```bash
   idf.py reconfigure
   ```
   或
   ```bash
   idf.py fullclean && idf.py build
   ```

3. **查看所有依赖:**
   ```bash
   idf.py deps
   ```

**注意:**
- 组件管理器会自动下载依赖到 `.idf-component-manager` 目录。
- 你也可以直接编辑 `idf_component.yml`,然后用 `idf.py reconfigure` 让依赖生效。

**官方文档参考:**
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/tools/idf-component-manager.html

idf 的配置文件CMakeLists.txt可以用来定义编译选项、源文件等信息,例如:

[<项目名称>/main/CMakeLists.txt]

idf_component_register(
    SRCS "wifi.c" "pir.c" "ldr.c" "ws2812.c" "display.c" "voice.c" "webserver.c" "tcp_client.c" "main.c"
    INCLUDE_DIRS "."
    REQUIRES ssd1306 led_strip
    PRIV_REQUIRES esp_event driver esp_netif esp_wifi nvs_flash esp_adc esp_http_server json
)

其他的就是在/main文件夹下正常的编写C和H文件即可,就像大一时候的成绩管理系统一样,而且这次还有clangd.注意某些报错可以暂时不用管,可能是clangd没有找到对应文件,应该是一些配置问题,只要能编译通过就行.编译并下载的命令:idf.py flash(注意提前配置好串口和烧录选项).

当然,总体上说,esp-idf 还是比arduino复杂很多,不过胜在官方支持的特定库比如语音识别.而且还适用于自制芯片开发,这点是arduino做不到的.如果有现成的模块,还是建议用arduino框架,毕竟它的生态和社区支持更好.

涉及网络连接问题的,还是要从整个网络连通的一端开始调试,最好每个环节都有连通性报告,就好像pcb设计中的电路发光二极管检查点一样.硬件端采用串口输出,后端采用api 接口返回状态,前端采用状态提示框显示.这样可以快速定位问题.