bluetooth
搜索蓝牙
// 开始搜索蓝牙
document.addEventListener('plusready', function() {
plus.bluetooth.openBluetoothAdapter({
success:function(e){
console.log('open success: '+JSON.stringify(e));
// 开始搜索附近的蓝牙设备
startBluetoothDevicesDiscovery()
},
fail:function(e){
console.log('open failed: '+JSON.stringify(e));
}
});
})
// 开始搜索附近的蓝牙设备
function startBluetoothDevicesDiscovery(){
plus.bluetooth.startBluetoothDevicesDiscovery({
success:function(e){
console.log('start discovery success: '+JSON.stringify(e));
// 监听发现新设备
onBluetoothDeviceFound();
setTimeout(function () {
stopBluetoothDevicesDiscovery() // 停止搜寻附近的蓝牙外围设备
},2000)
},
fail:function(e){
console.log('start discovery failed: '+JSON.stringify(e));
}
});
}
// 监听发现新设备
function onBluetoothDeviceFound(){
plus.bluetooth.onBluetoothDeviceFound(function(e){
var devices = e.devices;
console.log('device found: '+e.length);
for(var i in devices){
console.log(i+': '+JSON.stringify(devices[i]));
// {"RSSI":-53,"advertisData":{},"deviceId":"3D340000-0000-1111-1DF8-1C0C9F9B630D","localName":"小米电视","name":"小米电视"}
// advertisData: *(ArrayBuffer 类型 )* 蓝牙设备的广播数据段中的ManufacturerData数据段
// 根据广播包识别设备
var adv = new Uint8Array(device.advertisData);
}
});
}
// 停止搜寻附近的蓝牙外围设备
function stopBluetoothDevicesDiscovery(){
plus.bluetooth.stopBluetoothDevicesDiscovery({
success: function (e) {
},
fail: function (e) {
},
complete: function () {
}
});
}
// 获取固件版本号
根据广播包识别设备信息
var adv = new Uint8Array(device.advertisData);
// data = 65,70,74,0,3,133,65,1,35,0 返回十进制数
问题:已知数据133、65代表版本号(133、65并不是版本号,需要解析该数据获取真正的版本号),解析过后的数据由16bits表示,11~8表示主版本号,7~4表示次版本号,0~3表示修订版本号,那么如何解析该数据获取版本号?
var adv = new Uint8Array(device.advertisData);
// 65,70,74,0,3,133,65,1,35,0
var v1 = adv[5] // 133
var v2 = adv[6] // 65
// 转换成8位无符号整型数组
var uint8 = new Uint8Array([v1,v2])
// DataView从二进制ArrayBuffer对象中读取数
var buffer = new DataView(uint8.buffer)
var uint16 = buffer.getUint16() // 34113 返回无符号短整型16位数
// 转换成二进制
var va = uint16.toString(2) // 1000 0101 0100 0001
// 截取二进制
var sliceValue1 = va.slice(4, 8); // 0101
var sliceValue2 = va.slice(8, 12); // 0100
var sliceValue3 = va.slice(12); // 0001
// 转换成十进制
var version1 = parseInt(sliceValue1, 2); // 5
var version2 = parseInt(sliceValue2, 2); // 4
var version3 = parseInt(sliceValue3, 2); // 1
// 版本号为5-4-1
读取设备传过来的数据(监听低功耗蓝牙设备的特征值变化)
// 监听低功耗蓝牙设备的特征值变化
plus.bluetooth.onBLECharacteristicValueChange(function(e) {
// e为 {"deviceId":"04:39:26:FE:00:C9","serviceId":"1113BBB4-2910-4C3E-A9A3-3979B76A6A60","characteristicId":"0000FFE5-0000-1000-0000-00805F9B3400","value":{}}
// 获取数据
var value = new Uint8Array(e.value);
// 53 48 51 11 05 05 05 09 80 26 35 80 26 35 80 26 35 00 00 00 00 AD 50
})
校验设备传过来的数据对不对
如何校验?
根据协议提供的校验公式进行数据校验。判断根据公式算出来的校验码是否等于数据传过来的校验码,如果不等于,该数据则不对,抛弃该数据。
校验公式为从 类型 开始到 数据 计算出和sum; checksum = ((0x100 - (sum&0xFF)) & 0xFF),校验代码如下:
var value = new Uint8Array(e.value); // value为设备传过来的值
// 53 48 51 11 05 05 05 09 80 26 35 80 26 35 80 26 35 00 00 00 00 AD 50
var sum = 0;
for (var i = 1; i < value.length - 2; i++) {
sum += value[i];
}
var check = (0x100 - (sum & 0xff)) & 0xFF;
console.log("验证校验码:" + check.toString(16));
if (check != checkNum) {
console.error("校验失败!!!!!!!!");
}
根据子指令获取相应的数据
已知数据中的第5位为子指令,第5到20位为该指令对应的数据data。比如说代表设备温度的子指令是十六进制数05,则data代表温度
var value = new Uint8Array(e.value); // value为设备传过来的值
// 53 48 51 11 05 05 05 09 80 26 35 80 26 35 80 26 35 00 00 00 00 AD 50
// 子指令
var subInstruct = value[4]; // 05
// 数据
var data = value.slice(5, length + 5 - 1);
if(subInstruct.toString(16) == 5){
var view = new DataView(value.buffer);
console.log("加热片 1 目标温度:" + view.getUint8(5)); // 目标温度
var bin = view.getUint16(3).toString(2).padStart(16, 0); // 示例:0000 0000 0011 0100
console.log("当前温度:" + parseInt(bin.slice(8), 2)); // bit7~0:当前温度
}
向蓝牙设备写入值
写入的值(writeBLECharacteristicValue)与设备传过来的值(onBLECharacteristicValueChange)格式一致。
// 数据格式: 头部 类型 指令 子指令+数据的长度 子指令 数据 校验码 尾部
// 拼装成固定格式数据
var temp = [0x53, 0x48, 0x51, data.length + 1, instruction];
if (data.length > 0) {
for (var i = 0; i < data.length; i++) {
temp.push(data[i]);
}
}
var sum = 0;
for (var i = 1; i < temp.length; i++) {
sum += temp[i];
}
check = (0x100 - (sum & 0xff)) & 0xFF;
temp.push(check) // 校验码
temp.push(0x50) // 尾部
console.log('写入:'+ JSON.stringify(temp))
plus.bluetooth.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
value: new Uint8Array(temp),
success: function(e) {
console.log('write characteristics success');
},
fail: function(e) {
console.log('write characteristics failed:'+JSON.stringify(e));
}
});
写入成功,值会从订阅(onBLECharacteristicValueChange)返回,继续校验数据,根据子指令获取数据data。