4、命令集设计:按摩仪常用命令的编码规则

好,这一章我们来聊聊命令集设计。说白了,就是按摩仪上位机和下位机之间,到底怎么「说话」。

我在做第一个按摩仪项目时,犯过一个低级错误——命令编码太随意。启动用0x01,停止用0x02,后来加了个「暂停」功能,编码冲突了。嗯,那场面挺尴尬的。所以今天我把这些经验整理出来,希望能帮你少走弯路。

4.1 命令编码的基本原则

我个人习惯,命令编码要遵循三个原则:

  • 唯一性:每个命令对应唯一一个编码,不能有二义性
  • 可扩展性:预留一些编码空间,方便后续增加功能
  • 简洁性:能用1个字节就别用2个,嵌入式资源很宝贵

重要提醒:命令编码最好按功能分组。比如0x10-0x1F留给模式控制,0x20-0x2F留给力度调节。这样一看编码就知道是干什么的。

4.2 按摩仪常用命令编码表

下面是我在项目中实际用过的编码方案,你可以直接参考:

命令名称 编码(十六进制) 数据长度 说明
启动 0x01 1字节 开始按摩,默认模式
停止 0x02 1字节 立即停止所有动作
模式切换 0x10 2字节 第2字节指定模式编号
力度调节 0x20 2字节 第2字节为力度值1-10
加热控制 0x30 2字节 第2字节:0关闭,1开启
查询状态 0x40 1字节 请求当前工作状态

我的小技巧:编码从0x01开始,不要用0x00。因为很多单片机初始化后内存默认是0x00,容易误判。我曾经就因为这个排查了半天。

4.3 命令帧结构设计

光有编码还不够,你得把命令「打包」发送。我建议用固定长度的帧结构:

帧头(1字节) + 命令编码(1字节) + 数据(0-2字节) + 校验(1字节) + 帧尾(1字节)

举个例子,发送「力度调节到5」:

0xAA  0x20  0x05  0xCF  0x55
帧头  命令  力度  校验  帧尾

这里校验我用的是累加和校验。0xAA + 0x20 + 0x05 = 0xCF,简单实用。

4.4 各命令的详细设计

4.4.1 启动命令

启动命令最简单,就一个字节0x01。但要注意:

  • 如果按摩仪已经在运行,收到启动命令应该忽略还是重启?
  • 我建议:如果正在运行,返回一个「忙」状态码,不要直接覆盖

4.4.2 停止命令

停止命令0x02,优先级最高。不管按摩仪在做什么,收到就立即停止。

注意:停止后电机有惯性,不能立即断电。我建议在停止命令后加一个200ms的减速过程,否则用户体验很差。

4.4.3 模式切换命令

模式切换需要两个字节:0x10 + 模式编号。

模式编号定义:

模式编号 模式名称 说明
0x01 揉捏模式 模拟人手揉捏
0x02 敲击模式 有节奏的敲打
0x03 推拿模式 线性推压
0x04 组合模式 多种模式循环

你想想看,如果只用一个字节,0x10既表示「模式切换」又表示「切换到模式1」,那不乱套了?所以必须分开。

4.4.4 力度调节命令

力度调节命令0x20,数据字节范围1-10。1最轻,10最重。

这里有个坑:不同模式下的力度感觉不一样。揉捏模式下的5档,和敲击模式下的5档,用户感觉可能完全不同。我建议在固件里做归一化处理。

4.4.5 加热控制命令

加热控制0x30,数据字节0或1。

我曾经遇到过一个问题:用户连续发送加热开启命令,下位机每次收到都重新初始化加热模块,导致加热片频繁通断。后来我加了一个「状态判断」——如果已经在加热,收到开启命令直接忽略。

4.5 命令响应的设计

上位机发了命令,下位机得回应吧?我习惯用统一的响应格式:

0xAA  0x80  命令编码  状态码  校验  0x55

状态码定义:

  • 0x00:成功
  • 0x01:命令不支持
  • 0x02:参数错误
  • 0x03:设备忙
  • 0xFF:未知错误

举个例子,上位机发送力度调节到5,下位机成功执行后回复:

0xAA  0x80  0x20  0x00  0xCA  0x55

避坑指南:响应帧里的命令编码一定要原样返回。这样上位机才知道「哦,刚才那个力度调节命令执行成功了」。我曾经省略了这个字段,结果多命令并发时根本分不清哪个成功了。

4.6 实际项目中的经验总结

最后,分享几个我在项目中踩过的坑:

  1. 命令超时处理:上位机发送命令后,如果500ms内没收到响应,应该重发。最多重发3次。
  2. 命令队列:不要一次发太多命令。我建议上位机维护一个发送队列,等收到响应后再发下一条。
  3. 广播命令:如果一台电脑控制多台按摩仪,命令里要带设备地址。我一般用帧头的第2个字节做地址。
  4. 调试接口:保留一个0xFF作为调试命令,可以读取固件版本、运行日志等。这个在生产环境要关掉。

嗯,命令集设计就讲到这里。下一章我们会聊通信协议的具体实现,包括怎么处理粘包、怎么保证数据完整性。到时候见。