步骤
1、搜索附近蓝牙设备并连接指定犬牌。
2、根据指定的外围设备 UUID 获取该外围设备的所有服务。
3、根据指定的外围设备 UUID 及其服务 UUID 获取该外围设备的所有特征 (Characteristic)。
注意项: 循环出该设备的每个服务中的所有特征的UUID,经测试,犬卫士配套的蓝牙计步犬牌的特征值为‘22’,即找到properties=‘22’的服务 如下图。
properties的值由硬件厂商设定。
4、通过设备id和服务UUID写入指令数据。
注意项:发送指令成功后再执行监听操作,并发执行或监听setNotify先于writeValueForCharacteristic执行,指令均发送失败。
每次发送获取计步数据指令前,必须先发送更新(同步)时间指令并成功返回。
犬卫士配套计步犬牌规定:第一次使用硬件的时候必须先更新(同步)时间,犬牌计步功能才可正常运行;
指令数据包结构如下
帧头[1] | 协议头[1] | 版本[1] | 命令[1] | 数据区长度[2] | 数据[n] | 校验[1] | 帧尾[1] |
‘B’ | 0x02 | 0x01 | 0x01~0xFF | n | data[n] | crc | ‘L’ |
更新(同步)时间指令:
... | 命令[1] | 数据长度[2] | 数据[2] | ...... | |
... | 0x03 | 0007 | 7Byte | ... |
(其中year占用2个byte,其他为1个byte)
其中每个协议中的帧头、协议头、版本、校验、帧尾相同,同意协议不同指令间只有命令、数据长度和数据不同;
协议头:数值“0x01~0xFF”,不同的产品采用不同的协议头,通过协议头可以识别出产品种类。
版本:协议版本增量定义,用于区分同款产品在功能上的支持差异。
数据区长度:数值,0x0000-0xffff,表示数据区的数据长度0~65536。
数据区:数据区可以没有,最长为65536个字节。
校验:和校验,从帧头到校验前,字节累加。
例如指令为 ‘42020103070007e60429113938eb4c’
其中42表示帧头字母‘B’的十六进制;02表示协议头0x02以此类推;
由文档可知,year占用两个byte,2022年以07E6来表示;
效验eb为效验之前所有字节累加之和。计算方法如下
需要注意的是校验不能超过两个字节,当累加超过0xff时,采取低八位运算。方法如下:
high = (unit >> 8) & 0xff; //高8位
low = unit & 0xff; //低8位
例如效验累加起来等于0x7e6,占用内存超出范围,则取低八位0x7e6&0xff经过计算为e6;
一般情况,除了时间同步指令为需计算的动态指令,其他为固定指令。
大小端(高低位)相关知识点:
1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
2) Big-Endian 就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
5、写成数据成功后根据指定的外围设备 UUID 及其服务 UUID 和特征 UUID 监听数据回发。
注意项:监听setNotify方法所需参数(服务UUID和特征UUID)和discoverCharacteristics方法中一致。
6、处理监听到的数据。
注意项:
监听数据回发当value值为‘02’之后的为当前天的步数。
定义是每20分钟保存一笔计步数据,一共保存3天。上传时把所有数据上传。
获取计步数据协议同之前的: 42020101010001484C
获取时,首先回收到rsp,表示收到数据,rsp格式同之前的定义。
接下来,会分包发送3天的数据,每天的格式相同,说明如下:
第一包: 0x00 (1个字节,表示开始发送第一天的数据)
第二包以及后续所有包,每包20个字节,发送内容为:
rtc(16字节) + step0(4字节) + step1(4字节) + step2(4字节)。。。
其中rtc参看下面的结构体th_rtc_t; 表示当天的第一笔存储计步的时间。
step参考下面的结构体th_stepUnit_t;
其中idx = hour * 3 + min/20,即24小时制,从每天0点0分开始,idx = 0; 0点20,idx = 1; 依次类推。 每个小时存3笔数据
step表示20分钟内的计步数据
注意:上传的数据包含全天的数据,假如当天有部分时间没有开机,那么数据全0。 app可以根据idx数据去填充即可,自行计算时间。
typedef struct
{
u16 year;
u16 month;
u16 day;
u16 hour;
u16 min;
u16 sec;
}th_rtc_t;
typedef struct
{
u16 idx;
u16 step;
}th_stepUnit_t;
typedef struct
{
th_rtc_t rtc;
th_stepUnit_t step[MAX_STEP_UNIT_NUM];
}th_step_t;