From b59c69fb3fc6d8d5ff975bc672a0b86fc3ffe4ab Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 3 Mar 2026 15:56:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 239 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 158 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index a9b36c7..5e6f737 100644 --- a/README.md +++ b/README.md @@ -1,115 +1,192 @@ -# ESP32-S3 TQ Thermal Printer Firmware (No Business HTTP Server) +# TQ Printer Firmware (ESP32-S3) -This firmware now runs in printer mode and does not expose the previous -business REST endpoints (`/v1/*`). +本仓库是 TalkingQ 热敏打印设备固件,当前已经完成四层分层重构,并切换为 +"按键驱动 + 云端语音/文生图 + 本地打印" 的运行模式。 -## Features +当前状态(2026-03): +- 提供打印、语音、配网、屏幕预览能力 +- 仅保留 Wi-Fi 配网 SoftAP HTTP 服务(`http://192.168.4.1`) -- Thermal printer driver (single printer path) -- Auto-initialize printer driver during startup -- Async print queue and worker lifecycle management -- Printer precheck (paper / battery / temperature) -- MIC key push-to-talk voice flow (button-triggered, no HTTP trigger) -- Wi-Fi STA with SoftAP provisioning fallback -- Provisioning portal page at `http://192.168.4.1` (unchanged) -- Optional DashScope Z-Image integration for image generation +> [!WARNING] +> 本仓库当前配置默认开启 **Flash Encryption** 与 **Secure Boot**(安全启动)。 +> 这类安全特性通常涉及 eFuse 烧写与不可逆行为,配置不当可能导致设备无法按预期启动、升级或调试。 +> 在烧录、量产或对外发布前,请务必根据你的产品安全策略与运维流程,先在 `menuconfig` / `sdkconfig` 中完成适配与复核,再执行构建和烧录。 -## What Was Removed +## 当前能力 -- Business HTTP server in `control_plane` (including previous `/`, `/v1/health`, - `/v1/printer/*`, `/v1/print/*`, `/v1/jobs*`, `/v1/voice/*` endpoints) -- Related Kconfig items: - - `TQ_HTTP_PORT` - - `TQ_API_KEY` +- 热敏打印驱动(固定 384 像素宽) +- 打印任务队列与后台 worker(队列/运行/完成/失败/取消状态) +- 打印前安全检查(缺纸、电量、温度) +- MIC 按键按住说话/松开停止(push-to-talk) +- DashScope WebSocket 语音对话(`wss://dashscope.aliyuncs.com/api-ws/v1/inference`) +- DashScope Z-Image 文生图(HTTP) +- ST7789 屏幕预览(启动 logo、文本/图片预览) +- Wi-Fi STA 优先,失败后自动回退 SoftAP 配网 +- POWER_KEY 长按 2 秒触发优雅停机并释放 `POWER_HOLD` -## Build +## 架构分层 -Prerequisites: -- ESP-IDF v5.x -- ESP32-S3 board +依赖方向严格为: + +`app_composition -> control_plane -> domain -> platform` + +对应公开 facade 头文件: +- `components/app_composition/include/app_composition.h` +- `components/control_plane/include/control_plane.h` +- `components/domain/include/domain.h` +- `components/platform/include/platform.h` + +入口与职责: +- `app_composition`: 仅做启动装配(`app_main`) +- `control_plane`: 生命周期/策略编排 +- `domain`: 打印协议、语音会话、图像生成、屏幕预览等业务域能力 +- `platform`: Wi-Fi、按键、显示屏、热敏打印硬件、音频设备等底层抽象 + +更多分层说明: +- `components/platform/README.md` +- `components/domain/README.md` +- `components/control_plane/README.md` +- `components/app_composition/README.md` + +## 目录概览 + +- `components/`: 分层组件主目录 +- `main/Kconfig.projbuild`: 工程级 `menuconfig` 配置项 +- `partitions.csv`: 当前分区表(16MB flash,双 OTA 分区) +- `docs/gpio-map.md`: 当前实现与 `sdkconfig` 对齐后的 GPIO 映射 +- `tools/esptool-factory/`: 产线打包与加密烧录工具 + +## 构建环境 + +本项目按当前实际使用 ESP-IDF `v5.5.2`。 + +先激活环境: + +```bash +export PATH=/opt/homebrew/bin:$PATH +export IDF_PATH=/Users/moyyang/esp/v5.5.2/esp-idf +source $IDF_PATH/export.sh +``` + +首次仅需执行一次目标设置: ```bash -cd ai_printer idf.py set-target esp32s3 -idf.py menuconfig +``` + +构建: + +```bash idf.py build ``` -## Flash +烧录并查看串口日志: ```bash -cd ai_printer -idf.py -p /dev/tty.usbmodemXXXX flash monitor +idf.py -p flash monitor ``` -## Config +清理后全量重编: -In `menuconfig -> TQ Printer Config`: +```bash +idf.py fullclean && idf.py build +``` -- Wi-Fi provisioning: - - `TQ_WIFI_PROV_SOFTAP_SSID` - - `TQ_WIFI_PROV_SOFTAP_PASSWORD` - - `TQ_WIFI_PROV_SOFTAP_CHANNEL` - - `TQ_WIFI_PROV_SOFTAP_MAX_CONN` -- Thermal printer runtime and safety policy: - - `TQ_PRINTER_*` -- Z-Image HTTP fields: - - `TQ_Z_IMAGE_API_KEY` (optional, empty means fallback to `TQ_VOICE_API_KEY`) - - `TQ_Z_IMAGE_API_ENDPOINT` - - `TQ_Z_IMAGE_MODEL` - - `TQ_Z_IMAGE_DEFAULT_SIZE` - - `TQ_Z_IMAGE_TIMEOUT_MS` - - `TQ_Z_IMAGE_DOWNLOAD_TIMEOUT_MS` -- Voice and audio fields (used by MIC key push-to-talk flow): - - `TQ_VOICE_*` -- Board GPIO map: - - `TQ_POWER_*`, `TQ_LED_*`, `TQ_SCREEN_*`, `TQ_PRINT_*`, `TQ_SPI_*` - - `TQ_KEY_PRINT_BOOST_ENABLE_ON_BOOT` / `TQ_KEY_PRINT_BOOST_ACTIVE_HIGH` -- ST7789 screen fields: - - `TQ_SCREEN_ENABLE` - - `TQ_SCREEN_PIXEL_CLOCK_HZ` - - `TQ_SCREEN_SPI_MODE` - - `TQ_SCREEN_H_RES` / `TQ_SCREEN_V_RES` - - `TQ_SCREEN_DRAW_LINES` - - `TQ_SCREEN_COLOR_ORDER_BGR` - - `TQ_SCREEN_BACKLIGHT_ACTIVE_HIGH` - - `TQ_SCREEN_MIRROR_*` / `TQ_SCREEN_SWAP_XY` - - `TQ_SCREEN_X_GAP` / `TQ_SCREEN_Y_GAP` - - `TQ_SCREEN_RESET_PIN` +## 运行流程 -Board pin assignment reference: -- [`docs/gpio-map.md`](docs/gpio-map.md) +1. `app_main` 调用 `control_plane_lifecycle_start()` +2. 生命周期按顺序启动: + - `system_runtime_start()`(底层初始化 + Wi-Fi) + - 电源键事件绑定 + - `printer_protocol_init()` + - `voice_interaction_init()` + - `image_generation_schedule_prewarm()` +3. 若 `POWER_KEY` 长按触发关机事件: + - 先执行生命周期 stop(语音 -> 打印协议 -> 系统运行时) + - 最后 `platform_power_hold_set(false)` 断保持电 -## Wi-Fi Provisioning Behavior +## Wi-Fi 配网行为 -- Device first tries saved STA credentials from NVS (`wifi_cfg` namespace) -- If credentials are invalid or STA connect fails, device starts SoftAP portal -- Open `http://192.168.4.1` and submit credentials from the provisioning page -- Provisioning page supports Chinese/English switching and local language cache -- Credentials are written to NVS only after STA connect succeeds +- 启动时优先加载 NVS 中保存的 STA 凭据(命名空间 `wifi_cfg`) +- 若无凭据或连接失败,启动 SoftAP + 本地 HTTP 配网页 +- 配网入口: + - 页面: `GET /`(`http://192.168.4.1`) + - 扫描: `GET /scan` + - 提交: `POST /provision` +- 凭据仅在 STA 连接成功后写入 NVS -## Notes +## 语音与打印行为 -- This project no longer provides business HTTP API endpoints for print/voice/job - control. -- SoftAP provisioning HTTP service remains enabled by design. -- UTF-8 Chinese text rendering uses embedded 16x16 GB2312 glyphs. -- Large image buffers prefer PSRAM, then fall back to internal RAM. -- Partition table uses `partitions.csv` with a 4MB `factory` app partition on - 16MB flash modules. +- MIC_KEY: + - 按下(长按开始阈值): 尝试启动语音会话并进入说话流程 + - 松开: 发送停止说话信号 +- 语音链路: + - WebSocket 建链后发送 `Start` + - 对话中按状态发送 `RequestToSpeak` / `SendSpeech` / `StopSpeech` + - 后台有心跳任务维持会话 + - 当回复首句包含 `/*提示词*/` 标记时,会触发一次文生图并自动提交打印任务 +- 打印链路: + - 所有任务进入队列,由单 worker 顺序执行 + - 默认打印前会做纸张/电量/温度校验 + - 图像与文本最终都会转为 384 宽 1bpp raster -## Font Assets +## 关键配置(`menuconfig -> TQ Printer Config`) -Embedded files: +- Wi-Fi/配网: `TQ_WIFI_*` +- 生命周期重试与回退: `TQ_LIFECYCLE_*` +- 打印策略与保护阈值: `TQ_PRINTER_*` +- 文生图: `TQ_Z_IMAGE_*` +- 语音会话与音频参数: `TQ_VOICE_*` +- 板级 GPIO 映射: `TQ_POWER_*`, `TQ_LED_*`, `TQ_PRINT_*`, `TQ_SPI_*`, `TQ_SCREEN_*` +- 屏幕参数: `TQ_SCREEN_*` + +## 分区与镜像 + +当前使用 `partitions.csv`(16MB): + +- `ota_0` at `0x30000`, size `0x780000` +- `ota_1` at `0x7B0000`, size `0x780000` +- `nvs_key` 分区启用加密标记 + +`idf.py build` 后会自动执行 bin 同步目标,将构建产物同步到: + +- `tools/esptool-factory/bin/` + +## 字库资源 + +当前嵌入字库: - `components/domain/assets/fonts/cn16_index.bin` - `components/domain/assets/fonts/cn16_glyphs.bin` -Regenerate from your own CJK font: +重新生成示例: ```bash -cd ai_printer python3 -m pip install --user pillow python3 tools/gen_cn16_font.py \ - --font app/src/main/assets/fonts/msyh.ttc \ - --font-index 0 + --font /path/to/your/font.ttf \ + --font-index 0 \ + --out-dir components/domain/assets/fonts ``` + +## 验证建议(最小闭环) + +- 编译检查: `idf.py build` +- 设备验证: + - 首次上电无 Wi-Fi 时,确认可通过 `http://192.168.4.1` 配网 + - 配网后设备可连网并进入运行态 + - MIC_KEY 按住说话/松开停止流程可跑通 + - 至少完成一次打印闭环(文本或图像) + - POWER_KEY 长按可触发停机 + +## 安全说明 + +- 不要在源码中保留真实生产密钥 +- 请使用 `menuconfig` 或本地配置覆盖 `TQ_VOICE_API_KEY` / `TQ_Z_IMAGE_API_KEY` +- 不要提交本地 `sdkconfig` 变体、串口特定命令和 `build/` 产物 + +## 相关文档 + +- GPIO 映射: `docs/gpio-map.md` +- WebSocket 协议参考: `docs/websocket.md` +- Z-Image 参考: `docs/z-image.md` +- 产线打包工具: `tools/esptool-factory/README.md`