作者:admin于 2021年06月03日 发布在分类 / 产品相关 / 通讯模块 / 接入规范与标准 下,并于 2021年06月03日 编辑
    蓝牙空中协议

       269

       0


    注意:目前版本为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

     

    参数

    1. 流控

    使用一个 byte ,为一个 0~255 的数值。

    作为最近发送数据包的唯一标识。对于任何数据包的返回包都应具有相同的流控数值。 在同时乱序发送多个数据包时,流控可以用来区分各个数据包的返回包。

    为达到区分的目的,请勿连续使用相同的流控数值。一般建议采用递增的数值作为流控。

    2. 长度

    表示协议帧中载荷的长度,接收方按此处长度进行解析,超出此长度定义的内容将被忽略。

    3. 索引

    协议功能的第一级分类。包含在协议内容的标题中。

    4. 操作数

    协议功能的第二级分类。包含在协议内容的次级标题中。

    5. 参数

    具体协议相关的详细参数内容等。


    协议内容

    索引列表

    ACK

    返回错误0xFF

    时间日期0x01

    通知提醒0x03

    系统设置0x04

    闹钟设定0x05

    系统信息0x06

    系统操作0x07

    数据交互0x08

    ACK

    长度为 0 的数据包表示 ACK ,如下所示:

    序号

    内容

    0

    流控

    同发送

    1

    长度

    0

    简洁起见,在以下内容中均以 ACK 直接表示,而不再重复描述其结构。

    返回错误

    索引:0xFF

    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 不存在

    时间日期

    索引:0x01

    获取当前时间日期.OPCODE[0x01]

    发送:

    序号

    内容

    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

    设置当前时间与日期.OPCODE[0x02]

    发送:

    序号

    内容

    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

    通知提醒

    索引:0x03

    参数使用1 byte 中的8 bit 来分别表示提醒种类,如下表所示:

    参数bit

    含义

    7

    \

    6

    \

    5

    \

    4

    \

    3

    \

    2

    来电

    1

    其他

    0

    \

    app提醒包含在其他类别中

    更新.OPCODE[0x01]

    发送:

    序号

    内容

    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

    取消.OPCODE[0x02]

    发送:

    序号

    内容

    2

    接口索引

    0x03

    3

    操作数

    0x02

    4

    参数bit

    x

    返回:ACK

    例:

    ->MCU: fc , length=3 , 0x03 , 0x02 , 0x04 (取消电话)

    MCU->: ack

    设置/获取间隔.OPCODE[0x03]

    当参数为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)

    设置提醒开关.OPCODE[0x04]

    发送:

    序号

    内容

    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

    获取提醒开关.OPCODE[0x05]

    发送:

    序号

    内容

    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

    系统设置

    索引:0x04

    设置开关功能位.OPCODE[0x11]

    开关功能位定义:

    参数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

    获取开关功能位.OPCODE[0x12]

    发送:

    序号

    内容

    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 (抬手亮屏已打开)

    闹钟设定

    索引:0x05

    除非特殊说明,否则一般默认支持 5 组闹钟

    在闹钟设置中,使用1byte8bit来表示重复设置的内容,如下表所示:

    参数bit

    含义

    7

    是否重复

    6

    Sat

    5

    Fri

    4

    Thu

    3

    Wed

    2

    Tue

    1

    Mon

    0

    Sun

    设置闹钟.OPCODE[0x01]

    发送:

    序号

    内容

    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

    获取闹钟.OPCODE[0x02]

    发送:

    序号

    内容

    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 重复周六/周日 开启)

    系统信息

    索引:0x06

    获取设备分类识别码.OPCODE[0x21]

    发送:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x21

    返回:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x21

    4

    识别码

    x

    例:

    APP->: fc , length=2 , 0x06 , 0x21

    ->APP: fc , length , 0x06 , 0x21 , 0x01(识别码)

    设备分类识别码同时放置于广播包厂商信息的第 3 个字节处

    访问设备信息列表获取更多信息

    获取设备唯一识别码.OPCODE[0x22]

    发送:

    序号

    内容

    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 个字节

    获取OTA名称.OPCODE[0x10]

    发送:

    序号

    内容

    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"

    获取固件版本.OPCODE[0x11]

    发送:

    序号

    内容

    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'

    获取编译日期.OPCODE[0x12]

    发送:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x12

    返回:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x12

    4~n

    字符串

    string

    例:

    APP->: fc , length=2 , 0x06 , 0x12

    ->APP: fc , length , 0x06 , 0x12 , 日期字符串

    获取编译时间.OPCODE[0x13]

    发送:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x13

    返回:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x13

    4~n

    字符串

    string

    例:

    APP->: fc , length=2 , 0x06 , 0x13

    ->APP: fc , length , 0x06 , 0x13 , 时间字符串

    获取编译序列号.OPCODE[0x14]

    发送:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x14

    返回:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x14

    4~n

    字符串

    string

    例:

    APP->: fc , length=2 , 0x06 , 0x14

    ->APP: fc , length , 0x06 , 0x14 , 序列号字符串

    系统类型.OPCODE[0x03]

    系统

    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

    广播名称.OPCODE[0x04]

    获取:

    序号

    内容

    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可能由于缓存原因不会立即更新显示名称

    获取MAC地址.OPCODE[0x05]

    获取:

    序号

    内容

    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

    获取绑定状态.OPCODE[0x06]

    获取:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x06

    返回:

    序号

    内容

    2

    接口索引

    0x06

    3

    操作数

    0x06

    4

    绑定状态

    x

    :

    ->MCU: fc , length=2 , 0x06 , 0x06

    MCU->: fc , length=3 , 0x06 , 0x06 , 0x01(已绑定)

    获取马达使用率数据.OPCODE[0x30]

    获取:

    序号

    内容

    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

    获取屏幕使用率数据.OPCODE[0x31]

    获取:

    序号

    内容

    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

    获取心率使用率数据.OPCODE[0x32]

    获取:

    序号

    内容

    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

    获取蓝牙使用率数据.OPCODE[0x33]

    获取:

    序号

    内容

    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

    系统操作

    索引:0x07

    0xE0-0xE2.链路测试

    序号

    内容

    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 灯低频闪烁,表示测试通过,可分拣出。

    设备重启.OPCODE[0xFE]

    序号

    内容

    2

    接口索引

    0x07

    3

    操作数

    0xFE

    例:

    * ``APP->:`` ``fc`` , ``length=2`` , ``0x07`` , ``0xFE``

    返回:ACK

    设备关机.OPCODE[0xFF]

    序号

    内容

    2

    接口索引

    0x07

    3

    操作数

    0xFF

    例: * APP->: fc , length=2 , 0x07 , 0xFF

    返回:ACK

    数据交互

    索引:0x08

    在未同步过时间时,设备将不会储存数据。

    获取最近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天数据

    每日计步目标.OPCODE[0x02]

    获取计步目标:

    序号

    内容

    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

    获取最后心率测量结果.OPCODE[0x03]

    获取心率测量结果:

    序号

    内容

    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 时,表示没有数据

    请求获取详细数据.OPCODE[0x10]

    请求获取详细数据:

    序号

    内容

    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
    文档编辑权限 创建者私有
    文档阅读权限 来自分类
    分类阅读权限 所有人
    分类编辑权限 所有人
    分类审核权限
    标签

    数据 length 索引 内容 fc  操作 接口 作数 操作数 序号
    历史版本

    修改日期 修改人 备注
    2021-06-03 18:39:51[当前版本] admin CREAT
    同类知识
    相关知识

    MIOTO WIKI-V3.2.0