1. 程式人生 > >ionic專案中JavaScript與ble(低功耗藍芽)裝置傳輸資料

ionic專案中JavaScript與ble(低功耗藍芽)裝置傳輸資料

需要實現的目標: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 an ArrayBuffer

也就是說我要傳的這個【時間】必須包裝成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個數據。(此處誤,是ios lightblue app解析之後再發送的)

因素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;

完。