您的位置:首页 > Web前端 > JavaScript

ionic项目中JavaScript与ble(低功耗蓝牙)设备传输数据

2016-01-08 14:50 686 查看
需要实现的目标:app向ble传输一个时间。

根据协议,所传输的时间格式为(全部为hex,中间无空格):c0 00 10 01 07 15 15 15 08

前两位为协议头(byte0,、byte1),接下来分别是为(byte2~byte8):年 月 日 时 分 秒 时区

————————————————————

cordova中ble插件(https://github.com/don/cordova-plugin-ble-central)写(write)功能的数据格式是:data: binary data, use anArrayBuffer

也就是说我要传的这个【时间】必须包装成ArrayBuffer数据。(ArrayBuffer传输示例代码如下:)

// send 1 byte to switch a light on
var data = new Uint8Array(1);
data[0] = 1;
ble.write(device_id, "FF10", "FF11", data.buffer, success, failure);

// send a 3 byte value with RGB color
var data = new Uint8Array(3);
data[0] = 0xFF;  // red
data[1] = 0x00; // green
data[2] = 0xFF; // blue
ble.write(device_id, "ccc0", "ccc1", data.buffer, success, failure);

// send a 32 bit integer
var data = new Uint32Array(1);
data[0] = counterInput.value;
ble.write(device_id, SERVICE, CHARACTERISTIC, data.buffer, success, failure);


————————————————————

此时我产生疑惑:

1、这个所谓的【时间】数据究竟是一个值还是几个值?

2、如果是一个值,怎么传输【c00010010715151508】这样一个值?

3、如果是好几个值,又改怎么用ArrayBuffer来传输呢?

————————————————————

为什么我会产生这样的疑惑?

答:ble硬件方在用类iOS上的lightblue工具测试向ble外设写入数据时,一次性写入的数据是“c00010010715151508”,然后外设成功解析出了所要的时间。

然后我就误以为我用js也只需要传这一个数据就行,于是写成了类似下面样子的代码:

var data = new Uint8Array(1);
data[0] = 'c00010010715151508';
ble.write(device_id, "FF10", "FF11", data.buffer, success, failure);


说实话当时写就意识到完全不对,data[0]岂不成了一个字符串了,我难道要传一个字符串么。

后来想了想,lightblue端写的‘c00010010715151508’是一个hex(十六进制数),这一点可以确定。

于是我又试图用stringToHex、parseInt等转换值的方法,来处理‘c00010010715151508’,结果都失败了。

————————————————————

解决方法:

因素1:在ble硬件端检查了他们正确获取到的值的log:

也就是说硬件方把lightblue所传过来的‘c00010010715151508’,拆分成了9个数据。

因素2:再次回顾了【ArrayBuffer传输示例代码】,可以好几个值一起传呢,还能直接给array中元素赋hex呢。

因素3:我传一个小值时,是可以成功的,例如data[0] = 1;硬件方接收到的就是01(hex);我传一个正整数16,硬件方接收到的就是10(hex)。

因此我尝试先传两个值,分别是正整数16和16,如下

var data = new Uint8Array(2);
data[0] = 16;
data[1] = 16;


我pc端wireshark成功捕获到了10 10。到了这一步,我就知道应该有戏了。

也就是说,我只要让wireshark成功捕获到这样的数据不就行了嘛。

于是这么写:(该是hex的就赋hex,该是int的就赋int)

var data = new Uint8Array(9);
data[0] = 0xc0;//直接传16进制数
data[1] = 0x00;
data[2] = year;//js所获得的年份
data[3] = month;
data[4] = day;
data[5] = hours;
data[6] = minutes;
data[7] = seconds;
data[8] = 8;


完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: