注意:目前版本为ClassC族协议派生初版,尚未开始对项目进行定制化适配,仅供参考。
简洁起见,描述中 flowcontrol(流控) 在以下文档中 使用未带 0x 前缀的 fc 缩写表示。 同样,opcode(操作数) 使用 OPCODE 表示。
在文档描述中 ->MCU 和 APP-> 均表示移动端发送至MCU, MCU-> 和 ->APP 均表示MCU发送至移动端。
在本文档中,形如 13 的无前缀数字表示十进制数
形如 0x13 的以 0x 为前缀的数字表示十六进制数
形如 0b11011011 的以 0b 为前缀的数字表示二进制数
在本文档中, 没有 使用 BCD 编码
为便于理解,在某些如时间日期等的协议描述中使用了十进制来表示, 注意,这里举例说明,如果有描述为 13 点 33 分的时间, 其对应十六进制描述应该为 0x0D 点 0x21 分
本项目使用Bluetooth Low Energy 5.0标准进行交互。
Host设备需要支持Extended advertisement特性以便使用长广播进行设备的扫描。
本项目使用MTU = 247 bytes的配置。
以下为设备广播帧所包含的信息
设备类型: 0x06 (LE General Discoverable Mode, BR/EDR not supported.)
UUID:默认包含 微信服务 (客制化model可能变更)
厂商信息: 0x50 , 0x50 , 设备识别码 (1byte), 符合微信接口的Mac地址 (6bytes)
缩略广播名
完整广播名
服务Base UUID: fb349b5f800000800010000000000000
通用发送特征UUID: 0xA801 (Notify)
通用接收特征UUID: 0xA802 (Write,WOR)
本协议基于Corumi-ClassC协议族派生。
数据帧结构如下:
字节序号 |
内容 |
备注 |
0 |
fc |
流控位,数据包时序与完整性控制 |
1 |
载荷长度 |
|
2~n |
载荷内容 |
|
其中,载荷内容的结构如下:
载荷内容字节序号 |
内容 |
备注 |
2 |
index |
索引 |
3 |
opcode |
操作数 |
4~n |
|
参数 |
使用一个 byte ,为一个 0~255 的数值。
作为最近发送数据包的唯一标识。对于任何数据包的返回包都应具有相同的流控数值。 在同时乱序发送多个数据包时,流控可以用来区分各个数据包的返回包。
为达到区分的目的,请勿连续使用相同的流控数值。一般建议采用递增的数值作为流控。
表示协议帧中载荷的长度,接收方按此处长度进行解析,超出此长度定义的内容将被忽略。
协议功能的第一级分类。包含在协议内容的标题中。
协议功能的第二级分类。包含在协议内容的次级标题中。
具体协议相关的详细参数内容等。
索引列表
长度为 0 的数据包表示 ACK ,如下所示:
序号 |
内容 |
值 |
0 |
流控 |
同发送 |
1 |
长度 |
0 |
简洁起见,在以下内容中均以 ACK 直接表示,而不再重复描述其结构。
0xFF 的接口索引表示返回了一个错误。
当长度为 3 时,表示返回了一个 16位 的通用错误代码。
Code |
含义 |
401 |
设备未注册 |
404 |
接口不存在 |
405 |
无效的操作数 |
406 |
无效的参数 |
410 |
方法未实现或已删除 |
例:
->MCU: fc , length=3 , 0xAB , 0x02 , 0x01 调用 0xAB 接口
MCU->: fc , length=3 , 0xFF , 0x94 , 0x01 返回错误 0x194=404 ,表示接口 0xAB 不存在
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x01 |
3 |
操作数 |
0x01 |
4 |
参数 |
/ |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x01 |
3 |
操作数 |
0x01 |
4 |
年 |
0~99 |
5 |
月 |
1~12 |
6 |
日 |
1~31 |
7 |
时 |
0~23 |
8 |
分 |
0~59 |
9 |
秒 |
0~59 |
10 |
时区时 |
-12~+14 |
11 |
时区分 |
-59~+59 |
返回的时间与日期均为 UTC时间 ,时区使用 8位有符号数 表示, MCU 计算时区会使用时区时和时区分相加,请保证符号正确。
-6 , -30 表示 UTC-6:30 , +6 , +30 表示 UTC+6:30
-6 , +30 会计算出 UTC-5:30 的结果,为保持代码的可读性,请勿如此使用
例:
->MCU: fc , length=2 , 0x01 , 0x01
MCU->: fc , length=10 , 0x01 , 0x01 , 0x14 (2020年), 0x0A (10月) , 0x0F (15日) , hour , minute , sec , timezone-hr , timezone-min
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x01 |
3 |
操作数 |
0x02 |
4 |
年 |
0~99 |
5 |
月 |
1~12 |
6 |
日 |
1~31 |
7 |
时 |
0~23 |
8 |
分 |
0~59 |
9 |
秒 |
0~59 |
10 |
时区时 |
-12~+14 |
11 |
时区分 |
-59~+59 |
返回:ACK
当未包含时区信息(长度为8)时,视参数时间为 本地时间 ,否则为 UTC时间
例1:
->MCU: fc , length=8 , 0x01 , 0x02 , year(0-99) , month , day , hour , minute , sec
MCU->: ACK
例2:
->MCU: fc , length=10 , 0x01 , 0x02 , year(0-99) , month , day , hour , minute , sec , timezone-hr , timezone-min
MCU->: ACK
参数使用1个 byte 中的8个 bit 来分别表示提醒种类,如下表所示:
参数bit |
含义 |
7 |
\ |
6 |
\ |
5 |
\ |
4 |
\ |
3 |
\ |
2 |
来电 |
1 |
其他 |
0 |
\ |
app提醒包含在其他类别中
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x01 |
4 |
参数bit |
x |
返回:ACK
例1:
->MCU: fc , length=3 , 0x03 , 0x01 , 0x04 (来电)
MCU->: ACK
例2:
->MCU: fc , length=3 , 0x03 , 0x01 , 0x02 (其他)
MCU->: ACK
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x02 |
4 |
参数bit |
x |
返回:ACK
例:
->MCU: fc , length=3 , 0x03 , 0x02 , 0x04 (取消电话)
MCU->: ack
当参数为2字节数字时,表示设置提醒间隔。 当参数长度为0时,表示获取提醒间隔。
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x03 |
4~5 |
提醒间隔 |
2字节秒数 |
返回:ACK
下面表示,当参数长度为0,获取提醒间隔
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x03 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x03 |
4~5 |
提醒间隔 |
2字节秒数 |
例1:
->MCU: fc , length=4 , 0x03 , 0x03 , 0x02 , 0x01 (表示提醒间隔设置为0x0102=258秒)
MCU->: ack
例2:
->MCU: fc , length=2 , 0x03 , 0x03
MCU->: fc , length=4 , 0x03 , 0x03 , 0x04 , 0x01 (表示获取到提醒间隔为0x0104=260秒)
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x04 |
4 |
设置 |
0x01 |
5 |
参数 |
x |
返回:ACK
使用 0xFF 参数可简单的开启所有提醒。 使用 0x00 参数可简单的关闭所有提醒。
例1:
->MCU: fc , length=4 , 0x03 , 0x04 , 0x01 , 0x04 (来电提醒开启,且其他提醒关闭)
MCU->: ACK
例2:
->MCU: fc , length=4 , 0x03 , 0x04 , 0x01 , 0x02 (其他提醒开启,且来电提醒关闭)
MCU->: ACK
例3:
->MCU: fc , length=4 , 0x03 , 0x04 , 0x01 , 0x06 (其他与来电提醒均开启)
MCU->: ACK
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x05 |
4 |
获取 |
0x02 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x05 |
4 |
参数 |
x |
例1:
->MCU: fc , length=3 , 0x03 , 0x05 , 0x02
MCU->: fc , length=3 , 0x03 , 0x05 , 0x04 (来电提醒开启,其他提醒关闭)
例2:
->MCU: fc , length=3 , 0x03 , 0x05 , 0x02
MCU->: fc , length=3 , 0x03 , 0x05 , 0xff (所有提醒均开启)
内容推送(TODO:UPDATE).OPCODE[0x11]
推送提醒内容至屏幕显示
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x03 |
3 |
操作数 |
0x11 |
4~n |
参数 |
x |
返回:ACK
当超过单帧数据长度时,使用 总览 中描述的延续包传输方式。
例1: 这个示例发送了如下一段文本: 「 这是一段测试文本, 用来测试显示推送内容的功能。 」
->MCU: fc , 2(索引和操作数长度)+67(字符串长度) , 0x03 , 0x11 , 0xe8 , 0xbf , 0x99 , 0xe6 , 0x98 , 0xaf , 0xe4 , 0xb8 , 0x80 , 0xe6 , 0xae , 0xb5 , 0xe6 , 0xb5 , 0x8b , 0xe8
MCU->: ack
->MCU: fc+1 , length=0xFF , 0x03 , 0x11 , 0xaf , 0x95 , 0xe6 , 0x96 , 0x87 , 0xe6 , 0x9c , 0xac , 0x2c , 0xe7 , 0x94 , 0xa8 , 0xe6 , 0x9d , 0xa5 , 0xe6
MCU->: ack
->MCU: fc+2 , length=0xFF , 0x03 , 0x11 , 0xb5 , 0x8b , 0xe8 , 0xaf , 0x95 , 0xe6 , 0x98 , 0xbe , 0xe7 , 0xa4 , 0xba , 0xe6 , 0x8e , 0xa8 , 0xe9 , 0x80
MCU->: ack
->MCU: fc+3 , length=0xFF , 0x03 , 0x11 , 0x81 , 0xe5 , 0x86 , 0x85 , 0xe5 , 0xae , 0xb9 , 0xe7 , 0x9a , 0x84 , 0xe5 , 0x8a , 0x9f , 0xe8 , 0x83 , 0xbd
MCU->: ack
->MCU: fc+4 , length=0xFF , 0x03 , 0x11 , 0xe3 , 0x80 , 0x82
MCU->: ack
开关功能位定义:
参数bit |
含义 |
7 |
\ |
6 |
\ |
5 |
\ |
4 |
\ |
3 |
\ |
2 |
\ |
1 |
抬手亮屏 |
0 |
\ |
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x04 |
3 |
操作数 |
0x11 |
4 |
参数 |
x |
返回:ACK
例1:
->MCU: fc , length=3 , 0x04 , 0x11 , 0x02 (打开抬手亮屏)
MCU->: ACK
例2:
->MCU: fc , length=3 , 0x04 , 0x11 , 0x00 (关闭抬手亮屏)
MCU->: ACK
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x04 |
3 |
操作数 |
0x12 |
4 |
参数 |
x |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x04 |
3 |
操作数 |
0x12 |
4 |
参数 |
x |
例:
->MCU: fc , length=2 , 0x04 , 0x12
MCU->: fc , length=3 , 0x04 , 0x12 , 0x02 (抬手亮屏已打开)
除非特殊说明,否则一般默认支持 5 组闹钟
在闹钟设置中,使用1个byte的8个bit来表示重复设置的内容,如下表所示:
参数bit |
含义 |
7 |
是否重复 |
6 |
Sat |
5 |
Fri |
4 |
Thu |
3 |
Wed |
2 |
Tue |
1 |
Mon |
0 |
Sun |
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x05 |
3 |
操作数 |
0x01 |
4 |
编号 |
x |
5 |
闹钟时 |
x |
6 |
闹钟分 |
x |
7 |
重复设置 |
x |
8 |
开关 |
0为关,1为开 |
返回:ACK
例:
->MCU: fc , length=7 , 0x05 , 0x01 , 0x00 , 8 , 14 , 0xBE , 1 (设置0号闹钟,时间: 8:14 重复: 周一 - 周五 开启)
MCU->: ack
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x05 |
3 |
操作数 |
0x02 |
4 |
编号 |
x |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x05 |
3 |
操作数 |
0x02 |
4 |
闹钟时 |
x |
5 |
闹钟分 |
x |
6 |
重复设置 |
x |
7 |
开关 |
x |
例:
->MCU:fc , length=3 , 0x05 , 0x02 , 0x03 (获取3号闹钟)
MCU->:fc , length=7 , 0x05 , 0x02 , 10 , 25 , 0xC1 , 1 (时间: 10:25 重复: 周六/周日 开启)
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x21 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x21 |
4 |
识别码 |
x |
例:
APP->: fc , length=2 , 0x06 , 0x21
->APP: fc , length , 0x06 , 0x21 , 0x01(识别码)
设备分类识别码同时放置于广播包厂商信息的第 3 个字节处
访问设备信息列表获取更多信息
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x22 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x22 |
4~n |
识别码 |
x |
例:
APP->: fc , length=2 , 0x06 , 0x22
->APP: fc , length , 0x06 , 0x22 , {0xA1,0xB2,0xC3,0xD4,0xE5,0xF6}(唯一识别码)
返回的长度由具体设备决定,一般不少于 6 个字节
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x10 |
3 |
内容选择 |
* 0x00:项目名称 |
|
|
* 0x01:分支名称 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x10 |
4~n |
字符串 |
string |
例1:
APP->: fc , length=3 , 0x06 , 0x10 , 0x00
->APP: fc , length , 0x06 , 0x10 , "CSW-V1-30"
例2:
APP->: fc , length=3 , 0x06 , 0x10 , 0x01
->APP: fc , length , 0x06 , 0x10 , "LSK"
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x11 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x11 |
4~n |
字符串 |
string |
例:
APP->: fc , length=2 , 0x06 , 0x11
->APP: fc , length , 0x06 , 0x11 , 'v' , '1' , '.' , '0'
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x12 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x12 |
4~n |
字符串 |
string |
例:
APP->: fc , length=2 , 0x06 , 0x12
->APP: fc , length , 0x06 , 0x12 , 日期字符串
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x13 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x13 |
4~n |
字符串 |
string |
例:
APP->: fc , length=2 , 0x06 , 0x13
->APP: fc , length , 0x06 , 0x13 , 时间字符串
发送:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x14 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x14 |
4~n |
字符串 |
string |
例:
APP->: fc , length=2 , 0x06 , 0x14
->APP: fc , length , 0x06 , 0x14 , 序列号字符串
系统 |
值 |
iOS |
0x00 |
Android |
0x01 |
Other |
0xFF |
因为兼容原因,本条需根据长度判断是获取还是设置,长度为 2 则为获取,为 3 则为设置
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x03 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x03 |
4 |
系统类型 |
x |
例:
APP->: fc , length=2 , 0x06 , 0x03
->APP: fc , length=3 , 0x06 , 0x03 , 0x00(ios)
设置:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x03 |
4 |
系统类型 |
x |
返回:ACK
例:
APP->: fc , length=3 , 0x06 , 0x03 , 0x01(android)
->APP: ack
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x04 |
4 |
获取 |
0x00 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x04 |
4 |
字符串 |
x |
例:
->MCU: fc , length=3 , 0x06 , 0x04 , 0x00
MCU->: fc , length=8 , 0x06 , 0x04 , 'C' , 'O' , 'R' , 'U' , 'M' , 'I'
设置:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x04 |
4 |
设置 |
0x01 |
5~n |
名称 |
string |
返回:ACK
例:
->MCU: fc , length=7 , 0x06 , 0x04 , 0x01 , 'T' , 'E' , 'S' , 'T'
MCU->: ACK
更改广播名称后,重启生效。可询问用户是否立即重启,然后发送重启命令。
广播名称设置不能超过12字节。如果长度为 0 ,或者第一个字节为 0x00 ,将视为无效。 iOS可能由于缓存原因不会立即更新显示名称
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x05 |
4 |
获取 |
0x00 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x05 |
4~9 |
mac地址 |
x |
例:
->MCU: fc , length=3 , 0x06 , 0x05 , 0x00
MCU->: fc , length=8 , 0x06 , 0x05 , 0xDE , 0xAD , 0xBF , 0xCC , 0xAA , 0xEE
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x06 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x06 |
4 |
绑定状态 |
x |
例:
->MCU: fc , length=2 , 0x06 , 0x06
MCU->: fc , length=3 , 0x06 , 0x06 , 0x01(已绑定)
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x30 |
4 |
获取 |
0x01 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x30 |
4~7 |
总震动时长(ms) |
x |
8~11 |
提醒震动次数(次) |
x |
12~15 |
提醒震动时长(ms) |
x |
例:
->MCU : fc , length=3 , 0x06 , 0x30 , 0x01
MCU-> : fc , length=14 , 0x06 , 0x30 , 0x34 , 0x02 , 0x01 , 0x00 , 0x28 , 0x00 , 0x00 , 0x00 , 0x40 , 0x9c , 0x00 , 0x00 (总震动时长=0x10234=66.100秒) (提醒震动=0x28=40次) (提醒震动时长=0x9c40=40.000秒)
清除:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x30 |
4 |
清除 |
0x04 |
返回:ACK
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x31 |
4 |
获取 |
0x01 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x31 |
4~7 |
总亮屏时长(ms) |
x |
8~11 |
抬腕亮屏次数(次) |
x |
12~15 |
抬腕亮屏时长(ms) |
x |
例:
->MCU : fc , length=3 , 0x06 , 0x31 , 0x01
MCU-> : fc , length=14 , 0x06 , 0x31 , 0x10 , 0x0e , 0x00 , 0x00 , 0x20 , 0x03 , 0x00 , 0x00 , 0x57 , 0x04 , 0x00 , 0x00 (总亮屏时长=0xe10=3600秒) (抬腕亮屏次数=0x320=800次) (抬腕亮屏时长=0x457=1111秒)
清除:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x31 |
4 |
清除 |
0x04 |
返回:ACK
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x32 |
4 |
获取 |
0x01 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x32 |
4~7 |
心率测量时长(s) |
x |
8~11 |
心率测量次数(次) |
x |
例:
->MCU : fc , length=3 , 0x06 , 0x32 , 0x01
MCU-> : fc , length=10 , 0x06 , 0x32 , 0x83 , 0x04 , 0x00 , 0x00 , 0x19 , 0x00 , 0x00 , 0x00 , (心率测量=0x483=1155秒) (心率测量次数=0x19=25次)
清除:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x32 |
4 |
清除 |
0x04 |
返回:ACK
获取:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x33 |
4 |
获取 |
0x01 |
返回:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x33 |
4~7 |
蓝牙广播时长(s) |
x |
8~11 |
蓝牙连接时长(s) |
x |
例:
->MCU : fc , length=3 , 0x06 , 0x33 , 0x01
MCU-> : fc , length=14 , 0x06 , 0x33 , 0x03 , 0x02 , 0x01 , 0x00 , 0x01 , 0x02 , 0x03 , 0x00 , 0x71 , 0x00 , 0x00 , 0x00 (广播=0x10203=66051秒) (连接=0x30201=197121秒) (断开=0x71=113次)
清除:
序号 |
内容 |
值 |
2 |
接口索引 |
0x06 |
3 |
操作数 |
0x33 |
4 |
清除 |
0x04 |
返回:ACK
序号 |
内容 |
值 |
2 |
接口索引 |
0x07 |
3 |
操作数 |
0xE0/0xE2 |
例: * APP->: fc , length=2 , 0x07 , 0xE0 * ->APP: fc , length=2 , 0x07 , 0xE1 * APP->: fc , length=2 , 0x07 , 0xE2
接收到 0xE0 指令后,设备将返回 0xE1 指令。 接收到 0xE2 指令后,设备将在数秒后关闭蓝牙,并使其 LED 灯低频闪烁,表示测试通过,可分拣出。
序号 |
内容 |
值 |
2 |
接口索引 |
0x07 |
3 |
操作数 |
0xFE |
例:
* ``APP->:`` ``fc`` , ``length=2`` , ``0x07`` , ``0xFE``
返回:ACK
序号 |
内容 |
值 |
2 |
接口索引 |
0x07 |
3 |
操作数 |
0xFF |
例: * APP->: fc , length=2 , 0x07 , 0xFF
返回:ACK
在未同步过时间时,设备将不会储存数据。
获取最近7天计步总数(TODO:UPDATE).OPCODE[0x01]
数据格式如下:
序号 |
内容 |
值 |
0 |
当天步数低位 |
0xLL |
1 |
当天步数高位 |
0xHH |
2 |
昨天步数低位 |
X |
3 |
昨天步数高位 |
X |
4 |
前天步数低位 |
X |
5 |
前天步数高位 |
X |
n |
依次类推 |
X |
如上表所示,当天数据的值即为 0xHHLL
获取数据:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x01 |
4 |
参数 |
0x01(获取) |
返回数据:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x01 |
4~n |
计步数据 |
X |
例: * APP->: fc , length=3 , 0x08 , 0x01 , 0x01(获取) * ->APP: fc , length=17 , 0x08 , 0x01 , 18(当月号数) , 0x34(当天数据低位) , 0x12(当天数据高位) , 0xZZ(前一天数据低位) , 0xYY(前一天数据高位)......
以上返回数据表示,数据读取时为当月18号,当天数据为0x1234=4660步,一条命令可发送7天数据
获取计步目标:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x02 |
4 |
参数 |
0x01 |
返回计步目标:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x02 |
4 |
目标低位 |
0xLL |
5 |
目标高位 |
0xHH |
例: * ->MCU: fc , length=3 , 0x08 , 0x02 , 0x01 * MCU->: fc , length=4 , 0x08 , 0x02 , 0xE8 , 0x03 获取计步目标为0x3E8=1000步
设定计步目标:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x02 |
4 |
参数 |
0x02 |
4 |
目标低位 |
0xLL |
5 |
目标高位 |
0xHH |
返回:ACK
例: * ->MCU: fc , length=5 , 0x08 , 0x02 , 0x02 , 0xE8 , 0x03 设置计步目标为0x3E8=1000步 * MCU->: ack
获取心率测量结果:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x03 |
返回心率测量结果:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x03 |
4~7 |
unix时间戳 |
X |
8 |
心率值 |
Y |
例: * APP->: fc , length=3 , 0x08 , 0x03 * ->APP: fc , length=7 , 0x08 , 0x03 , {0x06,0xF2,0x3D,0x5B}时间戳 , 0x59(心率=89)
以上返回数据表示,数据读取时 unix 时间戳为 0x5B3DF206 ,心率为 0x59=89
当返回心率为 0xFF=255 时,表示没有数据
请求获取详细数据:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x10 |
4 |
参数 |
0x01 |
5 |
数据类型 |
X |
返回详细数据概况:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x10 |
4 |
数据类型 |
X |
5 |
数据包数量低位 |
X |
6 |
数据包数量高位 |
X |
请求获取详细数据,在获取数据包前必须请求。此请求会返回数据包的总数, 并且会临时锁定所有对应数据类型的数据包,防止新产生的数据包造成干扰。 当一分钟内没有获取详细数据时,会自动解除数据包锁定。
例1: * ->MCU: fc , length=4 , 0x08 , 0x10 , 0x01(请求) , 0x01(计步数据) * MCU->: fc , length=5 , 0x08 , 0x10 , 0x01(计步数据) , 0xE8 , 0x03 返回数据包数为 0x3E8=1000 个数据包
例2: * ->MCU: fc , length=4 , 0x08 , 0x10 , 0x01(请求) , 0x02(心率数据) * MCU->: fc , length=5 , 0x08 , 0x10 , 0x02(心率数据) , 0x10 , 0x01 返回数据包数为 0x110=272 个数据包
获取详细数据(TODO:UPDATE).OPCODE[0x11]
获取详细数据:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x11 |
4 |
参数 |
0x01 |
5 |
数据类型 |
X |
6 |
索引低位 |
X |
7 |
索引高位 |
X |
8 |
配置 |
Flag |
返回详细数据:
序号 |
内容 |
值 |
2 |
接口索引 |
0x08 |
3 |
操作数 |
0x11 |
4~n |
数据包 |
X |
获取数据包的内容。
计步数据包格式为 unix时间戳(4)-数据类型(1)-扩展(1)-数据值(2) , 其中,计步数据类型为 0x01 ,时间戳与数据值表示在这个时间戳与上个时间戳之间产生的步数。
心率数据包格式为 unix时间戳(4)-数据类型(1)-数据值(1) , 其中,心率数据类型为 0x02 ,时间戳与数据值表示在这个时间戳测量的心率。
睡眠数据包格式为 unix时间戳(4)-数据类型(1)-数据值(1) , 其中,睡眠数据类型为 0x03 ,时间戳与数据值表示在这个时间戳之后的睡眠状态。
当 配置Flag=0x01 时,表示启用 burst 模式,将一次返回两个数据包,分别为请求的索引和索引+1的数据包。否则,返回一个数据包。
当 配置Flag=0x11 时,表示启用 burstx4 模式,将一次通过4个数据帧返回8个数据包,为请求的索引到索引+7的数据包。
.. warning:: 注意, burstx4 模式下,请求速率不能超过连接间隔,否则会发生丢包。即如果连接间隔以6Hz计算,则每秒最多请求6次。
返回的4个数据帧的流控会顺次递增。当返回的数据帧超过数据范围时,超出的数据包将不会返回。
例1:
* ->MCU: fc , length=6 , 0x08 , 0x11 , 0x01 , 0x01 , 0x05 , 0x00 普通模式获取第5个计步数据包 * MCU->: fc , length=10 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳(0x5B3DF206) , {0x01}(计步数据) , {0xFF} , {0xE8,0x03}(1000步)
例2:
* ->MCU: fc , length=7 , 0x08 , 0x11 , 0x01 , 0x01 , 0x05 , 0x00 , 0x01 burst模式获取第5和第6个计步数据包 * MCU->: fc , length=18 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳1(0x5B3DF206) , {0x01}(计步数据) , {0xFF} , {0xE8,0x03}(1000步) , {0xB0,0xF2,0x3D,0x5B}时间戳2(0x5B3DF2B0) , {0x01}(计步数据) , {0xFF} , {0xE7,0x03}(999步)
例3:
* ->MCU: fc , length=6 , 0x08 , 0x11 , 0x01 , 0x02(心率数据) , 0x02 , 0x00 普通模式获取第2个心率数据包 * MCU->: fc , length=10 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳(0x5B3DF206) , {0x02}(心率数据) , {0x51}(心率81)
例4:
* ->MCU: fc , length=7 , 0x08 , 0x11 , 0x01 , 0x02 , 0x04 , 0x00 , 0x01 burst模式获取第4和第5个心率数据包 * MCU->: fc , length=14 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳1(0x5B3DF206) , {0x02}(心率数据) , {0x51}(心率81) , {0xB0,0xF2,0x3D,0x5B}时间戳2(0x5B3DF2B0) , {0x02}(心率数据) , {0x53}(心率83)
当使用 burst 模式获取到超出范围的数据包时,数据类型会填充为 0xFF
例5:
* ->MCU: fc , length=7 , 0x08 , 0x11 , 0x01 , 0x01 , 0x04 , 0x00 , 0x11 burstx4 模式获取第4至第11个计步数据包 * MCU->: fc , length=18 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳1(0x5B3DF206) , {0x01}(计步数据) , {0xFF} , {0xE8,0x03}(1000步) , {0xB0,0xF2,0x3D,0x5B}时间戳2(0x5B3DF2B0) , {0x01}(计步数据) , {0xFF} , {0xE7,0x03}(999步) * MCU->: fc+1 , length=18 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳1(0x5B3DF206) , {0x01}(计步数据) , {0xFF} , {0xE8,0x03}(1000步) , {0xB0,0xF2,0x3D,0x5B}时间戳2(0x5B3DF2B0) , {0x01}(计步数据) , {0xFF} , {0xE7,0x03}(999步) * MCU->: fc+2 , length=18 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳1(0x5B3DF206) , {0x01}(计步数据) , {0xFF} , {0xE8,0x03}(1000步) , {0xB0,0xF2,0x3D,0x5B}时间戳2(0x5B3DF2B0) , {0x01}(计步数据) , {0xFF} , {0xE7,0x03}(999步) * MCU->: fc+3 , length=18 , 0x08 , 0x11 , {0x06,0xF2,0x3D,0x5B}时间戳1(0x5B3DF206) , {0x01}(计步数据) , {0xFF} , {0xE8,0x03}(1000步) , {0xB0,0xF2,0x3D,0x5B}时间戳2(0x5B3DF2B0) , {0x01}(计步数据) , {0xFF} , {0xE7,0x03}(999步)
第 1 个数据包为最新的数据包。 一种建议的同步数据方式是,从第 1 包开始往后同步,直到遇到重复(同步过)的 时间戳 或者同步完了所有数据包为止。当遇到重复的 时间戳 后,再检查最后一个数据包的时间戳是否已经重复(同步过),如果没有,则从最后一个数据包往前同步,直到遇到重复(同步过)为止。 当需要计算有多少数据包没有同步时,可以使用二分法读取,由于数据包一般不会储存超过 2k 个,所以至多 11 次读取便可以确定最后同步的数据包的位置。
创建人 | admin |
文档编辑权限 | 创建者私有 |
文档阅读权限 | 来自分类 |
分类阅读权限 | 所有人 |
分类编辑权限 | 所有人 |
分类审核权限 | 无 |
修改日期 | 修改人 | 备注 |
2021-06-03 18:39:51[当前版本] | admin | CREAT |