TQ Printer Firmware (ESP32-S3)

本仓库是 TalkingQ 热敏打印设备固件,当前已经完成四层分层重构,并切换为 "按键驱动 + 云端语音/文生图 + 本地打印" 的运行模式。

当前状态2026-03:

  • 提供打印、语音、配网、屏幕预览能力
  • 仅保留 Wi-Fi 配网 SoftAP HTTP 服务(http://192.168.4.1

Warning

本仓库当前配置默认开启 Flash EncryptionSecure Boot(安全启动)。 这类安全特性通常涉及 eFuse 烧写与不可逆行为,配置不当可能导致设备无法按预期启动、升级或调试。 在烧录、量产或对外发布前,请务必根据你的产品安全策略与运维流程,先在 menuconfig / sdkconfig 中完成适配与复核,再执行构建和烧录。

当前能力

  • 热敏打印驱动(固定 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

架构分层

依赖方向严格为:

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

先激活环境:

export PATH=/opt/homebrew/bin:$PATH
export IDF_PATH=/Users/moyyang/esp/v5.5.2/esp-idf
source $IDF_PATH/export.sh

首次仅需执行一次目标设置:

idf.py set-target esp32s3

构建:

idf.py build

烧录并查看串口日志:

idf.py -p <PORT> flash monitor

清理后全量重编:

idf.py fullclean && idf.py build

运行流程

  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 配网行为

  • 启动时优先加载 NVS 中保存的 STA 凭据(命名空间 wifi_cfg
  • 若无凭据或连接失败,启动 SoftAP + 本地 HTTP 配网页
  • 配网入口:
    • 页面: GET /http://192.168.4.1
    • 扫描: GET /scan
    • 提交: POST /provision
  • 凭据仅在 STA 连接成功后写入 NVS

语音与打印行为

  • MIC_KEY:
    • 按下(长按开始阈值): 尝试启动语音会话并进入说话流程
    • 松开: 发送停止说话信号
  • 语音链路:
    • WebSocket 建链后发送 Start
    • 对话中按状态发送 RequestToSpeak / SendSpeech / StopSpeech
    • 后台有心跳任务维持会话
    • 当回复首句包含 /*提示词*/ 标记时,会触发一次文生图并自动提交打印任务
  • 打印链路:
    • 所有任务进入队列,由单 worker 顺序执行
    • 默认打印前会做纸张/电量/温度校验
    • 图像与文本最终都会转为 384 宽 1bpp raster

关键配置(menuconfig -> TQ Printer Config

  • 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.csv16MB:

  • 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

重新生成示例:

python3 -m pip install --user pillow
python3 tools/gen_cn16_font.py \
  --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
Description
No description provided
Readme 165 MiB
Languages
C 67.4%
Python 29.2%
HTML 2.9%
CMake 0.5%