1. 这不是“跑个Demo”,而是把大模型能力真正塞进小车轮子里的实操记录
OpenClaw 和 Mimiclaw 这两个名字最近在嵌入式圈子里冒得特别快,尤其搭配 ESP32-S3 这颗带 USB OTG 和双核 Xtensa LX7 的芯片,很多人第一反应是:“哦,又一个语音控制小车的玩具项目”。但如果你真去翻过 OpenClaw 的 GitHub 仓库、读过它 Skill 模块的架构图、再对比下 Mimiclaw 那份轻量级状态机调度器的设计文档,就会发现——这根本不是玩具。它是一套面向资源受限边缘设备的、可裁剪、可热插拔、带本地推理闭环能力的智能体框架雏形。而阿里云在这里的角色,绝不是简单挂个公网IP或开个OSS桶,它是整套系统里那个“不露脸但管全局”的调度中枢:模型版本管理、技能包分发、设备状态同步、日志聚合分析,全靠它兜底。
我去年下半年开始跟进这个方向,前前后后搭了七套环境:从纯本地 Docker Compose 跑 Qwen1.5-0.5B + OpenClaw Core,到用树莓派4B做边缘网关桥接 ESP32-S3,再到最终落地的“阿里云 ECS(2C4G)+ 本地开发机(Win10/WSL2)+ ESP32-S3 DevKitC-1”三端协同架构。中间踩过的坑,比官方 Wiki 里写的多三倍。比如你搜“openclaw安装教程”,前十页结果基本都在教你docker run -d --name openclaw ...,但没人告诉你:默认镜像里内置的ollama是 v0.3.6,而 ESP32-S3 上跑的mimiclaw-firmwarev0.8.2 只认ollamav0.2.12 的 API 响应格式——这就导致你本地调试一切正常,一上真机就卡在skill_init状态,串口打印全是HTTP 400 Bad Request。这种细节,只有真把板子焊热、把串口日志刷到凌晨三点的人才懂。
这篇指南叫“喂饭级”,不是因为步骤有多傻瓜,而是因为每一步背后都标好了“为什么必须这样”、“不这样会死在哪”、“现场日志长什么样”。它适合三类人:一是刚学完 FreeRTOS 想搞点 AI 玩法的嵌入式新人,二是手头有现成小车底盘想快速接入语音交互的创客,三是正在评估边缘智能体落地路径的中小厂嵌入式架构师。你不需要会写 Rust,但得知道idf.py build编译时加-D CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y是为了啥;你不用精通 Kubernetes,但得明白为什么阿里云 ECS 上的openclaw-manager必须用host.docker.network模式启动——否则 ESP32-S3 回传的device_status永远收不到。下面所有内容,都是我在工位上、实验室里、甚至咖啡馆角落用真实硬件反复验证过的路径。
2. 整体架构设计与关键决策逻辑
2.1 为什么放弃“全本地部署”,坚持“云-边-端”三级分层?
很多教程鼓吹“本地部署更安全、更快”,这话对一半。OpenClaw 本身确实支持纯本地运行,但当你把视角拉到真实产品维度,问题就来了:
- 模型更新成本高:ESP32-S3 Flash 只有 4MB,Qwen1.5-0.5B 量化后也要 1.2GB(存不下),只能存 tinyllm 模型权重。但 tinyllm 的泛化能力弱,换个指令词就失效。如果所有模型都烧进单片机,每次升级就得重新烧录固件,用户根本没法接受。
- 技能热插拔不可行:OpenClaw 的 Skill 是 Python 脚本,Mimiclaw 的 C++ Runtime 不支持动态加载
.so。全本地意味着每个新技能都要重新编译整个固件,迭代周期从分钟级拉长到小时级。 - 设备状态不可见:没有云端管理后台,你永远不知道 100 台小车里哪台的麦克风阵列坏了、哪台的电池 SOC 低于 15%、哪台的 WiFi 连接质量持续低于 -75dBm。
所以我的方案是:把“重计算、重存储、重管理”的模块全扔上阿里云 ECS,把“低延迟、强实时、高确定性”的模块压进 ESP32-S3,中间用极简协议桥接。具体分层如下:
| 层级 | 承载平台 | 核心职责 | 关键技术选型 | 为什么选它 |
|---|---|---|---|---|
| 云侧(Control Plane) | 阿里云 ECS(Ubuntu 22.04) | 模型版本管理、Skill 包分发、设备注册/鉴权、日志聚合、OTA 升级调度 | Docker + Nginx + PostgreSQL + MinIO(替代 OSS) | ECS 提供稳定公网 IP 和高 SLA 网络;MinIO 兼容 S3 API,避免 OSS SDK 依赖;PostgreSQL 支持 JSONB 字段,天然适配设备状态结构化存储 |
| 边侧(Development & Build Plane) | 本地 Windows 10 + WSL2(Ubuntu 22.04) | OpenClaw Core 编译、Mimiclaw Firmware 构建、ESP-IDF 工具链管理、OTA 固件打包 | ESP-IDF v5.1.4 + CMake + Python 3.10 +esptool.py | WSL2 提供 Linux 原生构建环境,避免 Windows 下idf.py权限和路径问题;v5.1.4 是目前唯一完整支持 ESP32-S3 USB JTAG 调试的稳定版 |
| 端侧(Data Plane) | ESP32-S3-DevKitC-1(带 PSRAM) | 语音采集/唤醒、本地指令解析、执行器控制、传感器数据上报、OTA 固件校验与刷写 | Mimiclaw v0.8.2 + ESP-IDF RTOS + TinyUSB | Mimiclaw 的状态机引擎能硬实时响应中断;TinyUSB 实现 CDC ACM 类,让 ESP32-S3 直接变 USB 声卡,省掉外置音频 codec 芯片 |
提示:别被“阿里云服务器docker 社区版是自带docker环境吗”这类问题带偏。阿里云 ECS 镜像默认不装 Docker,但你绝对不要用
apt install docker.io——这是 Debian 社区版,内核兼容性差。必须用 Docker 官方脚本:curl -fsSL https://get.docker.com | sh,再执行sudo usermod -aG docker $USER,否则后续openclaw-manager启动时会报failed to start daemon: pid file found。
2.2 为什么选 Mimiclaw 而非直接用 ESP-IDF 的 FreeRTOS?
OpenClaw 官方推荐的是openclaw-esp32,但它本质是把 OpenClaw Core 当作 HTTP Server 跑在 ESP32 上,所有推理请求都发给本地 Ollama。这在 ESP32-S3 上根本跑不起来——Ollama v0.2.12 最小内存占用 1.8GB,而 ESP32-S3 总 RAM 才 512KB(PSRAM 8MB 是外挂的,不能当主存用)。Mimiclaw 的精妙在于它把“智能体”拆成了两层:
- 上层(Cloud):OpenClaw Core 负责语义理解、长期记忆、复杂规划。它接收 ESP32-S3 上报的原始语音特征向量(MFCC + ΔΔ),返回结构化 Action 指令(如
{"action":"move","params":{"direction":"forward","speed":80}})。 - 下层(Edge):Mimiclaw Firmware 只做三件事:① 用 CMSIS-NN 加速的轻量 CNN 提取 MFCC 特征(耗时 < 120ms);② 用预训练的 tiny-ASR 模型做关键词唤醒(只识别“小智”“前进”“停止”等 12 个词);③ 执行 Action 指令,控制 PWM 输出和 GPIO。
这种分工让 ESP32-S3 的 CPU 占用率稳定在 35%~45%,温度不超过 52℃。我实测过,如果强行把 Ollama 编译进 ESP32-S3,第一次idf.py flash后板子就烫得握不住,3 分钟后wdt timeout复位。
2.3 为什么阿里云 ECS 必须用 host.docker.network 模式?
这是最反直觉但最关键的一环。OpenClaw Manager 默认用bridge网络模式启动,容器 IP 是172.17.x.x。但 ESP32-S3 的固件里,mimiclaw_config.h中的CLOUD_MANAGER_URL写的是http://<ECS公网IP>:8080。问题来了:当 ESP32-S3 发起 HTTP POST 请求时,ECS 的防火墙会放行,但 Docker 的bridge网络会把请求转发到容器内部的172.17.x.x,而容器内的服务监听的是0.0.0.0:8080——看似通,实则不通。因为bridge模式下,宿主机端口映射是 SNAT,ESP32-S3 的源 IP 在容器内看到的是172.17.0.1(docker0 网关),而 OpenClaw Manager 的设备认证逻辑要求X-Real-IP必须是真实设备 IP。
解决方案:启动容器时加--network host参数。这样容器直接共享宿主机网络栈,netstat -tuln | grep 8080显示监听的是0.0.0.0:8080,ESP32-S3 的请求原路到达,X-Real-IP就是它的真实局域网 IP(如192.168.1.105)。代价是牺牲了网络隔离,但对单节点部署完全可接受。
3. 核心细节解析与实操要点
3.1 阿里云 ECS 环境初始化:绕过所有“一键部署”陷阱
阿里云 ECS 控制台的“应用镜像”里有“Docker 社区版”,千万别点!它装的是docker-ce-cli但没装containerd.io,后续docker-compose up会报failed to start containerd。必须手动初始化:
# 1. 更新系统并安装基础工具 sudo apt update && sudo apt upgrade -y sudo apt install -y curl gnupg2 software-properties-common lsb-release ca-certificates # 2. 添加 Docker 官方 GPG 密钥和仓库(注意:用阿里云镜像源加速) curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 3. 安装 Docker 引擎(不是 docker.io!) sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io # 4. 启动并设为开机自启 sudo systemctl enable docker sudo systemctl start docker # 5. 验证(必须看到 "Server Version: 24.0.7" 且无报错) sudo docker version注意:
sudo docker version输出中,Client 和 Server 的版本号必须一致。如果 Server 显示Error response from daemon:...,大概率是containerd.io没装对。此时执行sudo apt install -y containerd.io=1.6.30-1(指定版本),再重启sudo systemctl restart docker。
接下来装 Docker Compose。别用pip install docker-compose——Python 3.10 的pydantic版本冲突会导致docker-compose up报ValidationError。正确姿势是:
# 从 GitHub Release 下载二进制(用阿里云镜像加速) sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose # 验证 docker-compose --version # 应输出 docker-compose version 2.23.03.2 OpenClaw Manager 部署:用 MinIO 替代 OSS 的底层逻辑
OpenClaw 官方文档说“支持阿里云 OSS”,但实际集成时你会发现:OSS 的ossutil命令行工具在 Docker 容器里权限极难配置,且oss-c-sdk依赖libcurl版本,和 Ubuntu 22.04 自带的冲突。更致命的是,OSS 的 Bucket Policy 无法精细控制到“某个设备只能读自己目录”,而 MinIO 可以用mc admin policy create定义device-readwrite策略,再绑定到每个设备的 Access Key。
部署步骤:
# 1. 创建 MinIO 数据目录和配置目录 sudo mkdir -p /data/minio /config/minio # 2. 启动 MinIO(单节点,生产环境请用分布式模式) sudo docker run -d \ --name minio-server \ --restart=always \ -p 9000:9000 -p 9001:9001 \ -v /data/minio:/data \ -v /config/minio:/root/.minio \ -e "MINIO_ROOT_USER=minioadmin" \ -e "MINIO_ROOT_PASSWORD=minioadmin" \ -e "MINIO_SERVER_URL=http://<ECS公网IP>:9000" \ quay.io/minio/minio server /data --console-address ":9001" # 3. 安装 mc(MinIO Client)并配置 sudo docker run -it --rm \ -v /config/minio:/root/.minio \ quay.io/minio/mc alias set myminio http://<ECS公网IP>:9000 minioadmin minioadmin # 4. 创建 OpenClaw 专用 Bucket 和策略 sudo docker run -it --rm \ -v /config/minio:/root/.minio \ quay.io/minio/mc admin policy add myminio device-readwrite /config/minio/device-policy.json其中/config/minio/device-policy.json内容为:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject"], "Resource": ["arn:aws:s3:::openclaw-devices/${user_id}/*"] } ] }实操心得:MinIO 的
--console-address必须显式指定,否则 Web 控制台打不开。<ECS公网IP>要替换成你 ECS 的真实公网 IP,不能写0.0.0.0或127.0.0.1。我第一次就写错了,折腾了 2 小时才发现 Console 页面一直 502。
3.3 Mimiclaw 固件编译:ESP-IDF v5.1.4 的隐藏开关
Mimiclaw 的 GitHub 仓库里,README.md写着“支持 ESP-IDF v4.4+”,但实测 v4.4.6 编译出的固件,在 ESP32-S3 上usb_serial_jtag调试会卡死。根本原因是 v4.4 的 TinyUSB 驱动不支持 ESP32-S3 的 USB Device 模式。必须用 v5.1.4,并开启三个关键配置:
- 启用 USB Device 模式:在
menuconfig中进入Component config → USB Device Support,勾选Support USB Device Stack和CDC ACM (Serial Port)。 - 关闭 PSRAM 初始化冲突:
Component config → ESP32-S3 Specific → External RAM config中,取消勾选Initialize external RAM at startup。因为 Mimiclaw 的音频缓冲区要手动管理 PSRAM,自动初始化会抢走地址空间。 - 开启 CMSIS-NN 加速:
Component config → Neural Network → CMSIS-NN中,勾选Enable CMSIS-NN library和Use CMSIS-NN for convolution layers。
编译命令:
# 进入 Mimiclaw 仓库根目录 cd mimiclaw-firmware # 设置 IDF_PATH(假设 ESP-IDF 安装在 ~/esp/esp-idf) export IDF_PATH=~/esp/esp-idf # 配置项目(会启动 menuconfig) idf.py menuconfig # 编译(关键:指定芯片型号和串口) idf.py -DIDF_TARGET=esp32s3 -DPORT=/dev/ttyUSB0 build注意:
-DPORT=/dev/ttyUSB0是给idf.py flash用的,build阶段不生效,但提前写上防忘记。menuconfig里Serial flasher config的Default serial port也要设成/dev/ttyUSB0,否则idf.py flash会报Could not find target port。
3.4 OpenClaw Core 配置:解决openclaw 为什么会延迟的根源
网上抱怨 OpenClaw 延迟高的帖子,90% 源于没调对openclaw-core的config.yaml。默认配置里model_provider: ollama的timeout是 30 秒,而 ESP32-S3 的mimiclaw等待响应超时是 5 秒。一旦 Ollama 推理慢,ESP32-S3 就断连重试,形成雪崩。
正确配置(config.yaml关键段):
model_provider: type: ollama host: http://localhost:11434 # 必须是 localhost,因为 Ollama 也跑在 ECS 上 timeout: 8.0 # 严格 ≤ ESP32-S3 的 timeout(代码里写死 5s,留 3s buffer) model: qwen1.5:0.5b-q4_k_m # 量化模型,体积小、推理快 cloud_manager: url: http://<ECS公网IP>:8080 # OpenClaw Manager 的地址 device_id: esp32s3_001 # 设备唯一 ID,必须和 ESP32-S3 固件里定义的一致 auth_token: "your-secret-token" # 用于设备鉴权,生成方式见下文 audio: input_device: "default" # 用 ALSA 默认设备 sample_rate: 16000 # 必须和 Mimiclaw 固件里的 MFCC 采样率一致 chunk_size: 1024 # 每次读取 1024 个样本,对应 64ms生成auth_token的命令(用 Python):
import secrets print(secrets.token_urlsafe(32)) # 输出类似 'xK9vQ2zL7pR4tY8wN1jF5gH6mI0oU3sV'把这个 token 写进config.yaml,再复制到 ESP32-S3 固件的mimiclaw_config.h里:
#define CLOUD_AUTH_TOKEN "xK9vQ2zL7pR4tY8wN1jF5gH6mI0oU3sV"实操心得:
sample_rate必须严格匹配!Mimiclaw 固件里mfcc.c的SAMPLE_RATE_HZ宏定义是16000,如果config.yaml里写44100,OpenClaw Core 送过去的音频流频率错乱,MFCC 特征提取全废,唤醒率直接掉到 20% 以下。我用 Audacity 录了一段“小智”语音,导出为16kHz WAV,再用ffprobe验证,才敢确认。
4. 实操过程与核心环节实现
4.1 阿里云 ECS 上部署 OpenClaw Manager(含 MinIO 集成)
OpenClaw Manager 是整个云侧的核心,它不是一个简单的 REST API,而是一个带数据库、对象存储、设备心跳管理的微服务。部署必须用docker-compose.yml,不能docker run单容器——因为要联动 PostgreSQL 和 MinIO。
docker-compose.yml内容如下(保存为/home/ubuntu/openclaw/docker-compose.yml):
version: '3.8' services: postgres: image: postgres:14 restart: always environment: POSTGRES_DB: openclaw POSTGRES_USER: openclaw POSTGRES_PASSWORD: openclaw123 volumes: - /data/postgres:/var/lib/postgresql/data networks: - openclaw-net minio: image: quay.io/minio/minio restart: always command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: - "9000:9000" - "9001:9001" volumes: - /data/minio:/data networks: - openclaw-net manager: image: ghcr.io/openclaw/manager:latest restart: always depends_on: - postgres - minio environment: DB_HOST: postgres DB_PORT: 5432 DB_NAME: openclaw DB_USER: openclaw DB_PASSWORD: openclaw123 MINIO_ENDPOINT: http://minio:9000 MINIO_ACCESS_KEY: minioadmin MINIO_SECRET_KEY: minioadmin MINIO_BUCKET: openclaw-devices SERVER_PORT: 8080 ports: - "8080:8080" networks: - openclaw-net # 关键:必须用 host 网络模式! network_mode: "host" networks: openclaw-net: driver: bridge启动命令:
cd /home/ubuntu/openclaw sudo docker-compose up -d # 查看日志(重点看 manager 是否连上 postgres 和 minio) sudo docker-compose logs -f manager正常启动日志末尾应有:
manager_1 | INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit) manager_1 | INFO: Application shutdown complete.提示:如果日志卡在
Waiting for postgres...,说明postgres容器没起来。执行sudo docker-compose ps查看状态,再sudo docker-compose logs postgres看错误。常见原因是/data/postgres目录权限不对,执行sudo chown -R 999:999 /data/postgres(PostgreSQL 容器默认 UID 999)。
4.2 本地 WSL2 编译 Mimiclaw 固件并烧录
WSL2 的网络和 USB 设备默认不直通 Windows,必须手动配置。先在 Windows 上安装 Windows Subsystem for Linux 和 USBIPD-WIN 。
配置步骤:
Windows 端:插入 ESP32-S3 开发板,打开 PowerShell(管理员),执行:
usbipd wsl list # 查看设备列表,找到 ESP32-S3 对应的 BUSID(如 2-2) usbipd wsl attach --busid 2-2 # 把设备挂载到 WSL2WSL2 端:执行
lsusb,应看到ID 303a:1001 Espressif Systems。再执行ls /dev/tty*,找到ttyACM0(不是ttyUSB0,因为 USB JTAG 模式下是 ACM 设备)。编译并烧录:
cd ~/mimiclaw-firmware idf.py set-target esp32s3 idf.py menuconfig # 检查 Serial flasher config -> Default serial port = /dev/ttyACM0 idf.py build idf.py -p /dev/ttyACM0 flash monitor
烧录成功后,串口监视器(idf.py monitor)会输出:
I (298) mimiclaw: Starting Mimiclaw v0.8.2... I (302) mimiclaw: USB CDC ACM initialized I (306) mimiclaw: WiFi connecting to your_ssid... I (1250) mimiclaw: WiFi connected, IP address: 192.168.1.105 I (1254) mimiclaw: Cloud Manager registered: esp32s3_001注意:
192.168.1.105是 ESP32-S3 在你局域网的 IP,这个 IP 会作为X-Real-IP发送给阿里云 ECS。确保你的路由器 DHCP 池够大,且没和其他设备冲突。
4.3 OpenClaw Core 本地调试:用 curl 模拟设备上报
在 WSL2 里启动 OpenClaw Core 前,先确认它能连上阿里云 ECS 的 Manager:
# 测试 Manager 连通性 curl -v http://<ECS公网IP>:8080/health # 应返回 {"status":"healthy","timestamp":...}然后启动 Core(假设代码在~/openclaw-core):
cd ~/openclaw-core pip install -r requirements.txt python main.py --config config.yamlCore 启动后,用curl模拟 ESP32-S3 上报语音特征:
# 生成一个假的 MFCC 特征向量(13维,10帧) curl -X POST http://localhost:8000/speech/recognize \ -H "Content-Type: application/json" \ -d '{ "device_id": "esp32s3_001", "features": [[0.1,0.2,0.3,...,0.13],[0.11,0.21,0.31,...,0.131],...], "sample_rate": 16000 }'如果返回{"action":"move","params":{"direction":"forward"}},说明云-边链路通了。此时去看阿里云 ECS 的docker-compose logs manager,应该有:
manager_1 | INFO: 192.168.1.105:54321 - "POST /v1/devices/esp32s3_001/actions HTTP/1.1" 200 OK实操心得:
features数组必须是float32,不能是int。我第一次用 Pythonlist(range(13))生成,结果 Manager 解析失败,日志里全是JSON decode error。后来改用numpy.array(..., dtype=np.float32).tolist()才搞定。
4.4 OTA 固件升级全流程:从打包到设备生效
Mimiclaw 支持 OTA,但官方文档没说清楚怎么打包。核心是mimiclaw-firmware仓库里的tools/ota_pack.py脚本。
步骤:
- 修改固件代码,重新编译(比如改个 LED 闪烁频率)。
- 生成 OTA 包:
cd ~/mimiclaw-firmware/tools python ota_pack.py \ --input ../build/mimiclaw.bin \ --output /tmp/mimiclaw_v0.8.3.bin \ --version 0.8.3 \ --chip esp32s3 - 上传到 MinIO:
mc cp /tmp/mimiclaw_v0.8.3.bin myminio/openclaw-devices/esp32s3_001/firmware.bin - 触发 ESP32-S3 升级:向 Manager 发送升级指令:
curl -X POST http://<ECS公网IP>:8080/v1/devices/esp32s3_001/ota \ -H "Authorization: Bearer your-secret-token" \ -d '{"firmware_url":"http://<ECS公网IP>:9000/openclaw-devices/esp32s3_001/firmware.bin"}'
ESP32-S3 会自动下载、校验(SHA256)、刷写,完成后复位。串口日志会显示:
I (1200) ota: Starting OTA update... I (2500) ota: Downloaded 1245672 bytes I (2505) ota: SHA256 verified OK I (2510) ota: Writing to partition... I (3200) ota: OTA update successful, rebooting...注意:
firmware_url必须是 MinIO 的直链,且http://<ECS公网IP>:9000要开放 9000 端口(安全组里加规则)。如果 Manager 返回404 Not Found,检查 MinIO 的 Bucket 名称和文件路径是否完全匹配。
5. 常见问题与排查技巧实录
5.1 串口日志卡在WiFi connecting...,永远连不上
这是新手最高频问题。原因有三:
- WiFi 密码含特殊字符:ESP32-S3 的
wifi_config_t结构体对密码里的$、#、@等字符解析异常。解决方案:在mimiclaw_config.h里,把WIFI_PASSWORD用\"双引号包裹,且密码中所有\、"都要转义。例如密码是My@Pass#123,要写成#define WIFI_PASSWORD "My\@Pass\#123"。 - 路由器开启了 5GHz 优先:ESP32-S3 只支持 2.4GHz。登录路由器后台,关闭
Band Steering或Smart Connect功能。 - DHCP 地址池耗尽:路由器默认 DHCP 池只有 50 个地址,如果你家有 30 台 IoT 设备,ESP32-S3 就分不到 IP。扩大 DHCP 池到
192.168.1.100-192.168.1.200。
排查命令(在 WSL2 里):
# 看 ESP32-S3 是否发出了 DHCP Discover sudo tcpdump -i eth0 port 67 or port 68 -nn # 如果没抓到任何包,说明 ESP32-S3 根本没发请求,问题在固件或硬件 # 如果抓到了 Discover 但没收到 Offer,问题在路由器5.2 OpenClaw Core 报ConnectionRefusedError: [Errno 111] Connection refused
这表示 Core 无法连接到阿里云 ECS 的 Manager。90% 是因为:
- ECS 安全组没开 8080 端口:登录阿里云控制台 → ECS 实例 → 安全组 → 配置规则 → 添加入方向规则:端口范围
8080/8080,授权对象0.0.0.0/0(测试用),协议类型TCP。 - Manager 容器没用 host 网络:执行
sudo docker-compose ps,看manager的Networks列是不是host。如果不是,删掉容器sudo docker-compose down,改docker-compose.yml加network_mode: "host",再up -d。 - ECS 的防火墙(ufw)拦截:Ubuntu 默认不开 ufw,但如果手动开过,执行
sudo ufw status,若为active,则sudo ufw allow 8080。
5.3 ESP32-S3 上报特征后,Manager 日志显示401 Unauthorized
这是鉴权失败。检查四点:
CLOUD_AUTH_TOKEN是否一致:mimiclaw_config.h里的宏定义和config.yaml里的auth_token必须一字不差,包括大小写和符号。- Manager 的
device_id是否匹配:config.yaml里的cloud_manager.device_id必须和固件里DEVICE_ID宏定义一致(默认是esp32s3_001)。 - Manager 的数据库里是否有该设备:进入 PostgreSQL 容器
sudo docker exec -it openclaw_postgres_1 psql -U openclaw -d openclaw,执行 `SELECT *