first commit
This commit is contained in:
459
ESP32_ESP-IDF移植实施文档.md
Normal file
459
ESP32_ESP-IDF移植实施文档.md
Normal file
@@ -0,0 +1,459 @@
|
||||
# lyfPrinter 上位机 APP 迁移到 ESP32(ESP-IDF) 实施文档
|
||||
|
||||
本文档基于当前 Android 上位机 APP 实现(`MainActivity + ECBLE + BlueHandler + 各预览页`),给出一套可落地的 ESP32/ESP-IDF 迁移方案。
|
||||
|
||||
适用目标:
|
||||
- 让 ESP32 作为 BLE Central 连接 `lyfPrinter` 热敏打印机
|
||||
- 复用现有私有打印协议(`0x00~0x07`、`0xA0~0xA4`)
|
||||
- 在 ESP32 上实现打印、状态监控、标签纸定位、OTA(打印机固件)能力
|
||||
|
||||
---
|
||||
|
||||
## 1. 现有 APP 能力基线(迁移输入)
|
||||
|
||||
Android 端关键行为:
|
||||
|
||||
1. 扫描过滤设备名 `lyfPrinter`
|
||||
2. 连接 BLE 外设并绑定特征:
|
||||
- Notify: `0000fff1-0000-1000-8000-00805f9b34fb`
|
||||
- Write: `0000fff2-0000-1000-8000-00805f9b34fb`
|
||||
3. 请求 `MTU=247`
|
||||
4. 向写特征发送私有协议帧,接收 Notify 回包并解析状态
|
||||
5. 打印流程:
|
||||
- 输入内容转 384 点宽位图
|
||||
- 二值化
|
||||
- 行取模(8 像素打包 1 字节)
|
||||
- 按 240 字节数据体分包(整帧 244 字节)
|
||||
- 按应答节奏发送完毕
|
||||
6. 打印前后控制:
|
||||
- 开启/关闭 VH 电源
|
||||
- 设置热参数(浓度映射)
|
||||
- 结束后走纸留白
|
||||
|
||||
可参考:
|
||||
- `APP_BLE打印控制实现说明.md`
|
||||
- `BLE_PAIRING_PARAMETERS.md`
|
||||
|
||||
---
|
||||
|
||||
## 2. 迁移目标定义
|
||||
|
||||
建议按两级目标推进:
|
||||
|
||||
### 2.1 M1(必做,先跑通)
|
||||
|
||||
1. 扫描/连接/重连
|
||||
2. 状态查询与解析(纸张、电量、温度)
|
||||
3. 基础打印(接收已编码点阵数据后发送)
|
||||
4. 标签纸 gap 定位与偏移读写
|
||||
|
||||
### 2.2 M2(增强)
|
||||
|
||||
1. ESP32 端文本渲染与位图编码
|
||||
2. 图片/二维码本地生成与打印
|
||||
3. 打印机 OTA 完整流程
|
||||
4. UI 层(按键、串口命令、Web、LCD+LVGL 任一)
|
||||
|
||||
---
|
||||
|
||||
## 3. ESP-IDF 技术选型建议
|
||||
|
||||
推荐:
|
||||
- ESP-IDF `v5.1+` 或 `v5.2+`
|
||||
- BLE Host:`NimBLE`(内存占用更低,Central 场景稳定)
|
||||
|
||||
备选:
|
||||
- Bluedroid 也可实现,但本项目建议优先 NimBLE。
|
||||
|
||||
编译配置建议(`menuconfig`):
|
||||
|
||||
1. 启用 BLE(NimBLE)
|
||||
2. 增大 GATT MTU 到 `247`
|
||||
3. 提升 BT controller/host 内存预算
|
||||
4. 打开 NVS(存储设备地址、标签偏移、最近配置)
|
||||
|
||||
---
|
||||
|
||||
## 4. Android 到 ESP32 模块映射
|
||||
|
||||
| Android 类 | 迁移后模块 | 说明 |
|
||||
|---|---|---|
|
||||
| `MainActivity` | `printer_ble_scan.c` + `app_cli.c` | 扫描、设备选择、连接触发 |
|
||||
| `ECBLE` | `printer_ble_client.c` | GATT 连接、服务发现、通知订阅、写特征 |
|
||||
| `BlueHandler` | `printer_proto.c` + `printer_engine.c` | 协议封装/解析、状态机、分包与流控 |
|
||||
| `DataConvertTool` | `image_raster.c` | 二值化、384宽缩放、行取模 |
|
||||
| 各 PreviewActivity | `content_renderer_*.c` | 文本/二维码/模板渲染 |
|
||||
| `otaUpdateActivity` | `printer_ota.c` | `A0~A4` 升级流程 |
|
||||
|
||||
建议目录:
|
||||
|
||||
```text
|
||||
components/
|
||||
printer_ble/
|
||||
include/printer_ble_client.h
|
||||
printer_ble_client.c
|
||||
printer_proto/
|
||||
include/printer_proto.h
|
||||
printer_proto.c
|
||||
printer_engine/
|
||||
include/printer_engine.h
|
||||
printer_engine.c
|
||||
image_raster/
|
||||
include/image_raster.h
|
||||
image_raster.c
|
||||
printer_ota/
|
||||
include/printer_ota.h
|
||||
printer_ota.c
|
||||
main/
|
||||
app_main.c
|
||||
app_cli.c
|
||||
app_config.c
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. BLE 迁移要点(与 Android 行为对齐)
|
||||
|
||||
### 5.1 扫描与过滤
|
||||
|
||||
逻辑对齐 Android:
|
||||
- 仅处理设备名 `lyfPrinter`
|
||||
- 保存 MAC、RSSI、最后发现时间
|
||||
- 支持“按 MAC 直连”模式(量产更稳)
|
||||
|
||||
### 5.2 建链流程
|
||||
|
||||
1. `scan -> connect`
|
||||
2. `discover service/characteristics`
|
||||
3. 找到 `FFF1/FFF2`
|
||||
4. 对 `FFF1` 写 CCCD `0x0001` 开启 Notify
|
||||
5. 交换 MTU(目标 247)
|
||||
|
||||
### 5.3 写入策略
|
||||
|
||||
与 Android 保持一致:
|
||||
- Write Without Response
|
||||
- 发送内容使用十六进制帧字节序列
|
||||
|
||||
### 5.4 断线策略
|
||||
|
||||
建议状态机:
|
||||
- `DISCONNECTED`
|
||||
- `SCANNING`
|
||||
- `CONNECTING`
|
||||
- `DISCOVERING`
|
||||
- `READY`
|
||||
- `PRINTING`
|
||||
|
||||
断线后:
|
||||
- 延时 300ms 重连
|
||||
- 最多重试 4 次(与 Android 一致)
|
||||
- 失败后回 `SCANNING`
|
||||
|
||||
---
|
||||
|
||||
## 6. 私有协议迁移(核心)
|
||||
|
||||
### 6.1 指令定义
|
||||
|
||||
```c
|
||||
// 打印
|
||||
#define CMD_POWER 0x00
|
||||
#define CMD_GET_STATUS 0x01
|
||||
#define CMD_SET_DISTANCE 0x02
|
||||
#define CMD_SET_PARAM 0x03
|
||||
#define CMD_SEND_DATA 0x04
|
||||
#define CMD_GAP_MOVE 0x05
|
||||
#define CMD_GET_LABEL_OFFSET 0x06
|
||||
#define CMD_SET_LABEL_OFFSET 0x07
|
||||
|
||||
// OTA
|
||||
#define CMD_BOOT_JUMP_BOOT 0xA0
|
||||
#define CMD_BOOT_ERASE_PAGE 0xA1
|
||||
#define CMD_BOOT_WRITE_DATA 0xA2
|
||||
#define CMD_BOOT_JUMP_APP 0xA3
|
||||
#define CMD_BOOT_GET_VERSION 0xA4
|
||||
```
|
||||
|
||||
### 6.2 帧结构
|
||||
|
||||
常规帧:
|
||||
|
||||
```text
|
||||
[addr:1][func:1][lenH:1][lenL:1][payload:len][checksum:optional]
|
||||
```
|
||||
|
||||
校验和规则:
|
||||
- 从 `addr` 到 payload 最后一个字节累加,取低 8 位
|
||||
|
||||
与 Android 对齐点:
|
||||
- 控制类命令一般带校验
|
||||
- `CMD_SEND_DATA(0x04)` 数据帧可不带校验(当前 Android 逻辑)
|
||||
|
||||
### 6.3 回包解析
|
||||
|
||||
按 `func` 分发处理:
|
||||
|
||||
1. `0x01`:设备状态
|
||||
2. `0x04`:数据发送 ACK,用于释放“发送下一包”锁
|
||||
3. `0x05`:标签定位完成
|
||||
4. `0x06`:标签偏移读取结果
|
||||
5. `0xA1~0xA4`:OTA流程响应
|
||||
|
||||
---
|
||||
|
||||
## 7. 打印引擎迁移设计
|
||||
|
||||
### 7.1 打印参数映射
|
||||
|
||||
浓度映射(与 Android 对齐):
|
||||
- `较淡 -> 1000`
|
||||
- `中等 -> 1500`
|
||||
- `较浓 -> 2000`
|
||||
- `最深 -> 3000`
|
||||
|
||||
打印前序列:
|
||||
|
||||
1. `CMD_POWER` 开
|
||||
2. `CMD_SET_PARAM(hot_mode, move_time, hot_time)`
|
||||
3. 分包发送 `CMD_SEND_DATA`
|
||||
|
||||
打印后序列:
|
||||
|
||||
1. `CMD_POWER` 关
|
||||
2. `CMD_SET_DISTANCE(12.5mm)` 留白走纸
|
||||
|
||||
### 7.2 分包规则
|
||||
|
||||
与 Android 同步:
|
||||
- 单帧上限 244 bytes
|
||||
- 协议头 4 bytes
|
||||
- 数据体 240 bytes(384 点宽 -> 48 bytes/行 -> 每包 5 行)
|
||||
|
||||
流控策略:
|
||||
- 发出数据包后等待 `0x04` ACK
|
||||
- 首包后可短延时一次
|
||||
- 后续每包 ACK 驱动
|
||||
- ACK 超时建议 `2~5s`,整任务超时 `30s`
|
||||
|
||||
### 7.3 打印状态门限
|
||||
|
||||
建议保持一致:
|
||||
- 缺纸:禁止打印
|
||||
- 电量 `<=40%`:禁止打印
|
||||
- 温度 `>=60℃`:禁止打印
|
||||
|
||||
---
|
||||
|
||||
## 8. 图像处理迁移策略(重点)
|
||||
|
||||
ESP32 内存有限,不建议一次性处理大图。推荐 3 种模式:
|
||||
|
||||
### 8.1 模式 A(推荐首版)
|
||||
|
||||
外部(PC/手机/云)先生成“384宽 + 二值化 + 行取模”数据,ESP32 仅负责协议发送。
|
||||
|
||||
优点:
|
||||
- 开发最快
|
||||
- ESP32 负载最低
|
||||
|
||||
### 8.2 模式 B(文本优先)
|
||||
|
||||
ESP32 只做文本/模板渲染,不做复杂图片解码。
|
||||
|
||||
优点:
|
||||
- 资源可控
|
||||
- 适合收据、标签、测试页
|
||||
|
||||
### 8.3 模式 C(全本地)
|
||||
|
||||
ESP32 本地做图片解码+缩放+二值化+取模。需外接 PSRAM,建议 ESP32-S3。
|
||||
|
||||
---
|
||||
|
||||
## 9. FreeRTOS 任务模型建议
|
||||
|
||||
建议拆成 4 个任务 + 2 个队列:
|
||||
|
||||
1. `ble_task`
|
||||
- 处理 GAP/GATT 事件
|
||||
2. `proto_task`
|
||||
- 帧收发、ACK 管理、回包解析
|
||||
3. `print_task`
|
||||
- 打印流程状态机(预热、分包、收尾)
|
||||
4. `cmd_task`
|
||||
- 外部命令入口(串口/Web/UI)
|
||||
|
||||
队列:
|
||||
- `q_cmd`:业务命令(print/status/ota)
|
||||
- `q_evt`:BLE/协议事件(connected/ack/timeout)
|
||||
|
||||
同步对象:
|
||||
- `EventGroup`:`READY`、`ACK_04`、`GAP_OK`、`OTA_ACK`
|
||||
- `Mutex`:写特征互斥
|
||||
|
||||
---
|
||||
|
||||
## 10. 关键 C 接口建议
|
||||
|
||||
```c
|
||||
// BLE
|
||||
esp_err_t printer_ble_start_scan(void);
|
||||
esp_err_t printer_ble_connect_by_name(const char *name);
|
||||
esp_err_t printer_ble_write(const uint8_t *data, size_t len, bool no_rsp);
|
||||
|
||||
// 协议
|
||||
size_t printer_proto_build_frame(uint8_t addr, uint8_t cmd,
|
||||
const uint8_t *payload, uint16_t len,
|
||||
bool with_checksum, uint8_t *out);
|
||||
void printer_proto_handle_notify(const uint8_t *data, size_t len);
|
||||
|
||||
// 打印引擎
|
||||
esp_err_t printer_engine_print_raw(const uint8_t *raw, size_t len, int hot_time);
|
||||
esp_err_t printer_engine_get_status(void);
|
||||
esp_err_t printer_engine_gap_move(void);
|
||||
esp_err_t printer_engine_set_label_offset(uint8_t value);
|
||||
|
||||
// OTA
|
||||
esp_err_t printer_ota_run(const uint8_t *fw, size_t len);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. OTA 迁移(针对打印机固件升级)
|
||||
|
||||
流程对齐 Android:
|
||||
|
||||
1. `A0` 跳 Boot
|
||||
2. `A1` 擦页(按 1024 bytes 估页数)
|
||||
3. `A2` 写入(单包 236 bytes 数据)
|
||||
4. `A3` 跳回 App
|
||||
5. `A4` 读版本确认
|
||||
|
||||
建议:
|
||||
- 每步都有超时和重试(每步 3 次)
|
||||
- 断电恢复策略:记录 last packet index
|
||||
|
||||
---
|
||||
|
||||
## 12. 分阶段实施计划
|
||||
|
||||
### Phase 1(3~5天)
|
||||
|
||||
1. BLE 扫描连接 + 订阅通知 + MTU
|
||||
2. 实现 `GET_STATUS`
|
||||
3. 实现 `POWER / SET_PARAM / SEND_DATA / SET_DISTANCE`
|
||||
4. 用固定测试页 raw 数据打印
|
||||
|
||||
验收:
|
||||
- 可稳定打印 50 次无死锁
|
||||
|
||||
### Phase 2(3~7天)
|
||||
|
||||
1. 文本模板渲染
|
||||
2. 标签定位/偏移
|
||||
3. 设备参数保存(NVS)
|
||||
|
||||
验收:
|
||||
- 标签纸对齐稳定
|
||||
|
||||
### Phase 3(3~7天)
|
||||
|
||||
1. OTA 全流程
|
||||
2. 回归测试与异常恢复
|
||||
|
||||
验收:
|
||||
- 升级成功率 > 99%
|
||||
|
||||
---
|
||||
|
||||
## 13. 测试清单
|
||||
|
||||
基础通信:
|
||||
|
||||
1. 扫描到 `lyfPrinter`
|
||||
2. 连接后找到 `FFF1/FFF2`
|
||||
3. Notify 有数据
|
||||
4. MTU 协商到 247
|
||||
|
||||
协议一致性:
|
||||
|
||||
1. 每条命令帧结构正确
|
||||
2. 校验和与 Android 一致
|
||||
3. `0x04` ACK 能正确驱动分包
|
||||
|
||||
打印质量:
|
||||
|
||||
1. 浓度 4 档效果一致
|
||||
2. 长图连续打印无丢行
|
||||
3. 结束留白距离稳定
|
||||
|
||||
异常场景:
|
||||
|
||||
1. 打印中断线后可恢复
|
||||
2. 缺纸/低电/高温阻断生效
|
||||
3. OTA 超时重试有效
|
||||
|
||||
---
|
||||
|
||||
## 14. 常见问题与规避
|
||||
|
||||
1. `write without response` 太快导致对端缓存溢出
|
||||
规避:严格按 `0x04 ACK` 节奏发送。
|
||||
|
||||
2. 连接成功但收不到 Notify
|
||||
规避:确认 CCCD 写成功且未被后续重连覆盖。
|
||||
|
||||
3. 打印偏移不稳定
|
||||
规避:先 `GAP_MOVE`,再按偏移走纸,偏移值写入 NVS。
|
||||
|
||||
4. ESP32 内存不足
|
||||
规避:首版采用“外部预编码 raw 数据”,不在设备端做重图像处理。
|
||||
|
||||
---
|
||||
|
||||
## 15. 最小可用迁移路径(建议)
|
||||
|
||||
如果你希望最快落地,按下面最小路径:
|
||||
|
||||
1. 先只做 BLE + 协议 + raw 发送
|
||||
2. 用串口命令输入 `print_raw/status/gap/offset`
|
||||
3. 打通后再逐步补 UI 和本地渲染
|
||||
|
||||
这样可以最短时间复用 Android 的核心协议能力,并把主要风险收敛在 BLE 链路与分包流控上。
|
||||
|
||||
---
|
||||
|
||||
## 16. 附:协议发送伪代码
|
||||
|
||||
```c
|
||||
void do_print(const uint8_t *raw, size_t raw_len, int hot_time) {
|
||||
send_cmd_power(true); // 0x00
|
||||
send_cmd_set_param(1, 2, hot_time); // 0x03
|
||||
|
||||
const size_t chunk = 240;
|
||||
size_t off = 0;
|
||||
int idx = 0;
|
||||
|
||||
while (off < raw_len) {
|
||||
size_t n = (raw_len - off > chunk) ? chunk : (raw_len - off);
|
||||
send_cmd_data(raw + off, n); // 0x04
|
||||
|
||||
if (idx > 0) {
|
||||
if (!wait_ack_04(3000)) {
|
||||
// 超时处理:重发或中止
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
off += n;
|
||||
idx++;
|
||||
}
|
||||
|
||||
send_cmd_power(false); // 0x00
|
||||
send_cmd_set_distance(12.5f); // 0x02
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user