[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-79997":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":13,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":14,"forks30d":14,"starsTrendScore":18,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":14,"starSnapshotCount":14,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},79997,"AI_DesktopCat_Qwen3.5Omni","AI-FanGe\u002FAI_DesktopCat_Qwen3.5Omni","AI-FanGe","An ai hardware using qwen3.5 omni as its model.",null,"Python",213,50,1,0,37,103,140,111,5.12,"MIT License",false,"main",true,[],"2026-06-12 02:03:56","# AICat 复刻教程\n\nAICat 是一个基于 `Seeed XIAO ESP32S3 Sense` 的桌面机器猫项目。它把屏幕表情、摄像头、麦克风、扬声器、舵机动作和网页控制整合在一起，适合硬件爱好者按步骤复刻、改造和继续扩展，3D打印的模型和软硬件代码都在项目中。\n\n\n## 项目总览\n\n### 成品效果\n\n![AICat 成品效果](docs\u002Fimages\u002Foverview-finished-aicat.png)\n\n### 结构拆解\n\n![AICat 结构拆解](docs\u002Fimages\u002Foverview-exploded-assembly.png)\n\n### 主要物料清单\n\n![AICat 主要物料清单](docs\u002Fimages\u002Foverview-bom.png)\n\n### 总接线表\n\n![AICat 总接线表](docs\u002Fimages\u002Foverview-wiring-table.png)\n\n### 按功能拆分的接线参考\n\n![AICat 按功能拆分接线参考](docs\u002Fimages\u002Foverview-wiring-by-function.png)\n\n## 项目能做什么\n\n- 用 `ST7789` 小屏显示状态、文字和表情动画。\n- 用 XIAO ESP32S3 Sense 板载摄像头把画面传到电脑端网页。\n- 用板载麦克风采集语音，交给后端做 ASR 和 AI 对话。\n- 用 `MAX98357A` 播放 AI 回复或提示音。\n- 用 `PCA9685` 控制嘴巴、尾巴、耳朵等普通 PWM 舵机。\n- 用 `STS3032` 总线舵机控制四条腿，并支持走路、坐下、跳跃等动作。\n- 用浏览器打开后端控制台，调试视频、语音、表情和舵机。\n\n## 当前推荐入口\n\n- ESP32 主固件：`upload_facial_expression\u002Fintegrated\u002Fintegrated.ino`\n- Python 后端：`upload_facial_expression\u002Fintegrated\u002Fserver\u002Fapp.py`\n- 后端依赖：`upload_facial_expression\u002Fintegrated\u002Fserver\u002Frequirements.txt`\n- 表情\u002F动画生成工具：`upload_facial_expression\u002Fflash_files\u002F`、`upload_facial_expression\u002Fmouth_flash_files\u002F`\n\n\n## 你需要准备的硬件\n\n- `Seeed XIAO ESP32S3 Sense`，带摄像头和麦克风版本。\n- `ST7789` SPI 屏幕，当前代码按 `170x320` 屏幕调试。\n- `MAX98357A` I2S 功放模块和小喇叭。\n- `PCA9685` 16 路 PWM 舵机驱动板。\n- `STS3032` 总线舵机和对应 TTL\u002F总线转接模块。\n- 普通 PWM 舵机若干，用于嘴巴、尾巴、耳朵等动作。\n- 外部舵机电源，按你的舵机规格选择，一般不要直接从 ESP32 给舵机供电。\n- 杜邦线、面包板或自制 PCB、USB 数据线、稳定的 5V\u002F舵机电源。\n\n重要提醒：所有外部电源的 `GND` 必须和 ESP32 的 `GND` 共地。舵机电流较大，供电不稳会导致重启、抽搐或串口乱码。\n\n## 主要材料购买搜索参考\n\n下面这些图是购买时可以参考的关键词和外观。不同店铺标题会有差异，重点看型号、尺寸、接口和电压参数是否匹配。\n\n### XIAO ESP32S3 Sense 主控\n\n搜索关键词：`Seeed Studio XIAO ESP32S3 Sense 摄像头 麦克风`、`XIAO ESP32 S3 Sense 视觉 AI`。\n\n![Seeed Studio XIAO ESP32S3 Sense 购买参考](docs\u002Fimages\u002Fmaterial-xiao-esp32s3-sense.png)\n\n注意要买 `Sense` 版本，不是普通 `XIAO ESP32S3`。Sense 版本带摄像头扩展板和板载麦克风，本项目的视频和语音输入依赖它。\n\n### 1.83 寸圆角 SPI LCD 屏\n\n搜索关键词：`1.83寸 圆角 LCD SPI IPS 65K`、`1.83inch LCD Module SPI`。\n\n![1.83 寸圆角 LCD 购买参考](docs\u002Fimages\u002Fmaterial-lcd-1-83.png)\n\n当前代码按 `ST7789`、`170x320` 一类小屏调试。购买时确认是 `SPI` 接口，并留意排线\u002F杜邦线接口是否方便接到 XIAO。\n\n### 小型 2g \u002F 3.7g 塑料齿轮舵机\n\n搜索关键词：`2g 数码舵机 塑料齿轮`、`3.7g 舵机 180度`、`机器人 DIY 小舵机`。\n\n![2g 和 3.7g 小舵机购买参考](docs\u002Fimages\u002Fmaterial-micro-servo-2g-3g7.png)\n\n这类舵机适合做耳朵、嘴巴、小尾巴等轻负载动作。优先选 `180度` 普通 PWM 舵机，注意不要让结构卡死，否则容易烧舵机。\n\n### MG90S 金属齿轮舵机\n\n搜索关键词：`MG90S 14克 金属齿轮 舵机 180度`、`MG90S 90-180 自由角度`。\n\n![MG90S 金属齿轮舵机购买参考](docs\u002Fimages\u002Fmaterial-mg90s-servo.png)\n\nMG90S 比 2g 小舵机力矩更大，适合负载稍高的位置。购买时选 `180度` 版本，不要买成连续旋转 `360度` 版本，除非你已经改了控制逻辑。\n\n## 接线说明\n\n按 `upload_facial_expression\u002Fintegrated\u002Fintegrated.ino` 当前配置接线。\n\n屏幕 `ST7789`：\n\n- `CS` 接 `D0`\n- `DC` 接 `D1`\n- `RST` 接 `EN`，代码里配置为不单独控制复位脚\n- `SCK` 接 `D8`\n- `MOSI` 接 `D10`\n- `VCC` 接 `3.3V`\n- `GND` 接 `GND`\n\n`PCA9685` 舵机驱动：\n\n- `SDA` 接 `D4`\n- `SCL` 接 `D5`\n- `VCC` 接 `3.3V` 或 `5V`，看模块说明\n- `V+` 接外部舵机电源\n- `GND` 接公共地\n- 当前代码约定 `CH12=嘴巴`、`CH13=尾巴`、`CH14=左耳`、`CH15=右耳`\n\n`STS3032` 总线舵机：\n\n- `TX` 接 `D6 \u002F GPIO43`\n- `RX` 接 `D7 \u002F GPIO44`\n- 波特率为 `1000000`\n- 当前代码约定 `ID1=左前腿`、`ID2=右前腿`、`ID3=左后腿`、`ID4=右后腿`\n\n`MAX98357A` 扬声器模块：\n\n- `BCLK` 接 `D3 \u002F GPIO4`\n- `LRC` 接 `D2 \u002F GPIO3`\n- `DIN` 接 `D9 \u002F GPIO8`\n- `VCC` 接 `5V`\n- `GND` 接公共地\n\n摄像头和麦克风使用 `XIAO ESP32S3 Sense` 板载硬件，不需要额外接线。\n\n## 电脑环境准备\n\n建议使用 macOS、Windows 或 Linux 都可以，下面命令以 macOS\u002FLinux 终端为例。\n\n1. 安装 Python，建议 `3.10` 到 `3.12`。\n2. 安装 Arduino IDE。\n3. 在 Arduino IDE 里安装 ESP32 开发板支持。\n\n   如果 Arduino IDE 还没有 ESP32 板卡包，打开 `Arduino IDE -> Settings`，在 `Additional boards manager URLs` 里加入：\n\n   ```text\n   https:\u002F\u002Fraw.githubusercontent.com\u002Fespressif\u002Farduino-esp32\u002Fgh-pages\u002Fpackage_esp32_index.json\n   ```\n\n   然后打开 `Tools -> Board -> Boards Manager`，搜索 `esp32`，安装 `esp32 by Espressif Systems`。\n\n4. 选择开发板 `XIAO ESP32S3` 或 `Seeed XIAO ESP32S3`。\n5. 打开 PSRAM。摄像头和动画缓存需要 PSRAM。\n6. 上传代码前先确认分区表。\n\n   这个项目会把 facial expression 素材写进 `LittleFS`，默认分区空间通常不够。烧录写入工具和最终主固件时，都要使用同一套带较大文件系统空间的分区表。\n\n   推荐做法：\n\n   - 如果 Arduino IDE 的 `Tools -> Partition Scheme` 里有 `Custom`，选择 `Custom`。\n   - 确认当前 sketch 目录里有对应的 `partitions.csv`，例如 `upload_facial_expression\u002Fintegrated\u002Fpartitions.csv`、`upload_facial_expression\u002Fflash_files\u002Fpartitions.csv` 或 `upload_facial_expression\u002Fmouth_flash_files\u002Fpartitions.csv`。\n   - 如果你的 Arduino IDE 没有 `Custom` 选项，可以先选 `8M with spiffs` 或 `No OTA (Large APP)` 这类空间更大的选项；素材多时再参考 `upload_facial_expression\u002F分区表说明.md` 配自定义分区。\n   - 改分区表会清空 ESP32 Flash 里的文件系统数据，所以改完分区后要重新上传 facial expression 素材。\n\n7. 安装 Arduino 库。\n\n   在 Arduino IDE 打开 `Tools -> Manage Libraries`，逐个搜索并安装这些库：\n\n```bash\nESP32Servo\nAdafruit GFX Library\nAdafruit ST7735 and ST7789 Library\nAdafruit PWM Servo Driver Library\nArduinoWebsockets\nJPEGDEC\nSCServo\n```\n\n如果 Arduino IDE 搜不到某个库，可以去库作者的 GitHub 下载 ZIP 后用“项目 -> 加载库 -> 添加 .ZIP 库”导入。\n\n## 配置后端服务\n\n进入后端目录并安装依赖：\n\n```bash\ncd upload_facial_expression\u002Fintegrated\u002Fserver\npython3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npip install -r requirements.txt\n```\n\n如果你用 Windows PowerShell，激活虚拟环境的命令通常是：\n\n```powershell\n.venv\\Scripts\\Activate.ps1\n```\n\n创建本地环境变量文件：\n\n```bash\ncat > .env \u003C\u003C 'EOF'\nDASHSCOPE_API_KEY=sk-your-api-key-here\nASR_DEBUG_RAW=0\nEOF\n```\n\n`DASHSCOPE_API_KEY` 要换成你自己的阿里云 DashScope API Key。不要把真实 `.env` 上传到 GitHub。\n\n启动后端：\n\n```bash\npython app.py\n```\n\n默认服务地址是：\n\n```text\nhttp:\u002F\u002F0.0.0.0:8081\n```\n\n在浏览器里访问电脑局域网地址，例如：\n\n```text\nhttp:\u002F\u002F192.168.2.7:8081\n```\n\n电脑 IP 要以你自己的局域网为准。macOS 可以在“系统设置 -> Wi-Fi -> 详细信息”里看，也可以运行：\n\n```bash\nipconfig getifaddr en0\n```\n\n## 配置 ESP32 固件\n\n打开文件：\n\n```text\nupload_facial_expression\u002Fintegrated\u002Fintegrated.ino\n```\n\n先修改 Wi-Fi 和电脑后端地址：\n\n```cpp\nconst char* WIFI_SSID   = \"YOUR_WIFI_SSID\";\nconst char* WIFI_PASS   = \"YOUR_WIFI_PASSWORD\";\nconst char* SERVER_HOST = \"192.168.2.7\";\nconst uint16_t SERVER_PORT = 8081;\n```\n\n把 `YOUR_WIFI_SSID`、`YOUR_WIFI_PASSWORD` 换成你的 Wi-Fi，把 `SERVER_HOST` 换成运行 Python 后端那台电脑的局域网 IP。\n\nArduino IDE 推荐设置：\n\n- Board：`XIAO ESP32S3`\n- PSRAM：`Enabled`\n- USB CDC On Boot：`Enabled`，方便看串口日志\n- Upload Speed：先用稳定值，如果失败再降低\n- Partition Scheme：上传前必须和 facial expression 写入工具保持一致，推荐 `Custom` 或带大文件系统空间的 8MB 分区方案\n\n确认分区表后再点击上传。烧录完成后打开串口监视器，波特率按代码或 IDE 默认设置查看日志。你应该能看到 Wi-Fi 连接和 WebSocket 连接相关输出。\n\n## 第一次联调\n\n建议按这个顺序排查，先让最小链路跑通，再逐步打开复杂功能。\n\n1. 先启动 Python 后端，确认浏览器能打开 `http:\u002F\u002F电脑IP:8081`。\n2. 再给 ESP32 上电，串口里确认它连上同一个 Wi-Fi。\n3. 看后端终端是否出现 camera\u002Faudio WebSocket 连接日志。\n4. 在网页里查看摄像头画面是否出现。\n5. 测试屏幕文字或表情命令。\n6. 单独测试 PCA9685 上的嘴巴、尾巴、耳朵舵机。\n7. 单独测试 STS3032 四腿舵机，确认 ID 和方向没有接反。\n8. 最后再测试语音输入、AI 回复和扬声器播放。\n\n如果网页能打开但 ESP32 连不上，通常是 `SERVER_HOST` 写错、电脑防火墙拦截、ESP32 和电脑不在同一个局域网，或者路由器开启了 AP 隔离。\n\n## 表情和动画素材\n\n为了让仓库适合上传 GitHub，大体积素材和生成出的 `batch_*.h`、`mouth_batch_*.h` 没有放进仓库。你可以自己准备素材后重新生成。\n\n相关工具在：\n\n- `upload_facial_expression\u002Fflash_files\u002Fgenerate_all_headers.py`\n- `upload_facial_expression\u002Fflash_files\u002Fvideo_to_jpeg_frames.py`\n- `upload_facial_expression\u002Fflash_files\u002Faudio_to_adpcm.py`\n- `upload_facial_expression\u002Fmouth_flash_files\u002Fgenerate_mouth_headers.py`\n- `upload_facial_expression\u002Fmouth_flash_files\u002Fvideo_to_jpeg_frames.py`\n\n### 上传 facial expression 到 ESP32\n\n表情素材最终会写入 ESP32 的 `LittleFS`。流程分成两步：先把素材转换成可烧录的头文件，再用专门的写入固件分批写进 Flash。\n\n1. 准备表情帧素材。\n\n   推荐把每个表情或动画放成单独文件夹，文件名按顺序编号，例如：\n\n   ```text\n   upload_facial_expression\u002Fdata\u002F\n   ├── anim1\u002F\n   │   ├── 0001.jpg\n   │   ├── 0002.jpg\n   │   └── ...\n   ├── anim2\u002F\n   │   └── ...\n   └── anim3\u002F\n       └── ...\n   ```\n\n   图片建议使用 `JPEG`，尺寸控制在屏幕能显示的范围内，例如 `170x320` 或更小。单张图片越小，上传越稳，也越不容易塞爆 Flash。\n\n2. 生成表情批次头文件。\n\n   ```bash\n   cd upload_facial_expression\u002Fflash_files\n   python3 generate_all_headers.py\n   ```\n\n   脚本会扫描 `upload_facial_expression\u002Fdata\u002F`，生成 `batch_1.h`、`batch_2.h` 等文件。每个批次控制在较小体积，避免 Arduino 编译时超限。\n\n3. 用写入工具烧录第一批。\n\n   打开：\n\n   ```text\n   upload_facial_expression\u002Fflash_files\u002Fflash_files.ino\n   ```\n\n   把文件顶部的批次号设为 `1`：\n\n   ```cpp\n   #define BATCH_NUMBER 1\n   ```\n\n   在 Arduino IDE 里选择和主固件一致的开发板、PSRAM 和分区表设置。这里很关键：上传 `flash_files.ino` 前也要选同一份自定义分区表，不能写入工具用一种分区、最终 `integrated.ino` 又用另一种分区。\n\n   然后上传这个写入工具。打开串口监视器，第一次写入时输入：\n\n   ```text\n   F\n   W\n   ```\n\n   `F` 会格式化 LittleFS，`W` 会把当前批次写入 Flash。只在第一批或你想清空重来时使用 `F`。\n\n4. 继续写入后续批次。\n\n   如果生成了多个 `batch_*.h`，就重复下面步骤：\n\n   - 把 `BATCH_NUMBER` 改成 `2`、`3`、`4` ...\n   - 重新上传 `flash_files.ino`\n   - 串口只输入 `W`\n\n   后续批次不要再输入 `F`，否则会把前面已经写进去的表情素材清空。\n\n5. 写入嘴部表情素材。\n\n   嘴部素材使用独立目录，推荐结构如下：\n\n   ```text\n   upload_facial_expression\u002Fmouth_flash_files\u002Fdata\u002F\n   ├── mouth_closed\u002F\n   ├── mouth_small_open\u002F\n   ├── mouth_big_open\u002F\n   ├── mouth_wide\u002F\n   └── mouth_round\u002F\n   ```\n\n   生成嘴部批次头文件：\n\n   ```bash\n   cd upload_facial_expression\u002Fmouth_flash_files\n   python3 generate_mouth_headers.py\n   ```\n\n   然后打开：\n\n   ```text\n   upload_facial_expression\u002Fmouth_flash_files\u002Fmouth_flash_files.ino\n   ```\n\n   按 `mouth_batch_1.h`、`mouth_batch_2.h` 的数量修改 `BATCH_NUMBER`，上传前继续使用同一套分区表。每次上传后在串口输入 `W`。这里也不要输入 `F`，否则会清空之前写入的普通表情动画。\n\n6. 烧回主固件。\n\n   所有表情和嘴部素材写入完成后，再重新烧录主固件：\n\n   ```text\n   upload_facial_expression\u002Fintegrated\u002Fintegrated.ino\n   ```\n\n   主固件启动后会从 LittleFS 读取这些素材，用于屏幕表情、嘴部动画和情绪动作。\n\n### 分区表注意事项\n\n如果素材比较多，默认文件系统空间可能不够。可以参考 `upload_facial_expression\u002F分区表说明.md`，使用项目里的自定义分区表：\n\n- `upload_facial_expression\u002Fpartitions_custom.csv`\n- `upload_facial_expression\u002Fflash_files\u002Fpartitions.csv`\n- `upload_facial_expression\u002Fmouth_flash_files\u002Fpartitions.csv`\n- `upload_facial_expression\u002Fintegrated\u002Fpartitions.csv`\n\n关键点是：写入工具和最终主固件要使用兼容的分区表。修改分区表会清空 Flash 里的文件系统数据，所以改完分区后需要重新上传表情素材。\n\n推荐顺序是：先确定分区表，再上传 `flash_files.ino` 写普通表情，再上传 `mouth_flash_files.ino` 写嘴部表情，最后上传 `integrated.ino`。中途不要再切换分区表。\n\n生成物体积很大，建议只保存在本地，不要提交到 GitHub。仓库的 `.gitignore` 已经忽略了 `batch_*.h` 和 `mouth_batch_*.h`。\n\n## 常见问题\n\n### 后端启动后提示没有 API Key\n\n检查 `upload_facial_expression\u002Fintegrated\u002Fserver\u002F.env` 是否存在，里面是否写了：\n\n```bash\nDASHSCOPE_API_KEY=sk-your-api-key-here\n```\n\n如果你只想测试硬件，可以先不配置 AI 功能，优先验证网页、视频、舵机和屏幕。\n\n### ESP32 一动舵机就重启\n\n大概率是舵机供电不足或没有共地。舵机电源请单独供电，并把外部电源 `GND` 和 ESP32 `GND` 接在一起。\n\n### 摄像头没有画面\n\n先看串口是否初始化摄像头成功，再看后端是否收到 `\u002Fws\u002Fcamera` 连接。还要确认 ESP32 和电脑在同一 Wi-Fi，`SERVER_HOST` 是电脑 IP，不是 ESP32 IP。\n\n### 扬声器没声音\n\n检查 `MAX98357A` 的 `BCLK\u002FLRC\u002FDIN` 是否和代码一致，喇叭是否接好，模块供电是否为 `5V`。如果你改过引脚，需要同步改 `integrated.ino` 里的 `I2S_SPK_BCLK`、`I2S_SPK_LRCK`、`I2S_SPK_DIN`。\n\n### STS3032 舵机动作不对\n\n确认舵机 ID 是否和代码约定一致，串口 TX\u002FRX 是否接反，供电电压是否符合舵机要求。第一次测试时不要让机构承受负载，先空载验证方向和角度范围。\n\n\n## 后续可改造方向\n\n- 给猫做更稳定的外壳和舵机固定结构。\n- 把 Wi-Fi 配置做成网页配网，避免每次改代码烧录。\n- 把表情素材做成可替换包。\n- 给动作系统增加更多情绪映射，例如开心、困、撒娇、生气。\n- 增加电池供电和低电量保护。\n","AICat 是一个基于 Seeed XIAO ESP32S3 Sense 的桌面机器猫项目，集成了屏幕表情、摄像头、麦克风、扬声器和舵机动作等功能。该项目通过 ST7789 屏幕显示状态和表情动画，利用板载摄像头传输画面至电脑端网页，并通过麦克风采集语音进行 ASR 和 AI 对话处理。此外，它还使用 MAX98357A 播放音频，PCA9685 控制普通 PWM 舵机，以及 STS3032 总线舵机控制四条腿的动作。适合硬件爱好者复刻、改造和扩展，适用于教育、娱乐和 DIY 机器人领域。",2,"2026-06-11 03:58:50","CREATED_QUERY"]