微信小程序 藍牙固件升級

通過小程序連接藍牙設備後,需要對設備進行固件升級

一、獲取藍牙設備固件的Version,進行對比

wx.writeBLECharacteristicValue({
      deviceId: deviceId,//IOS中爲DeviceId,Android中爲Mac地址
      serviceId: serviceId,//服務ID,這裏針對的是隻進行升級時候的端口,如F000FFC0-XXX
      characteristicId: characterId,//特性ID,針對升級獲取設備Version的端口,如F000FFC1-XXX
      value: buffer,//發送的數據,硬件要求發送的是什麼就發送什麼轉換爲buffer類型
      success: function (res) {
        console.log('發送成功', res)  //在這裏獲取到現在版本的信息,提前與硬件溝通好,如何獲取
      },
      fail: function (err) {
        console.log('發送失敗:', err, 'code' + err.errCode)
      },
      complete: function (complete) {}
    })

二、請求bin文件,即固件需要升級的文件

bin文件即可以進行升級的文件,可以通過後臺接口請求

1. 解析bin文件,獲取到bin文件裏面的內容
2. var pathArrayBuffer = wx.getFileSystemManager().readFileSync(tempFilePath,/** 不填默認爲ArrayBuffer類型 */);//tempFilePath爲請求到的路徑
3. var buf = new Uint8Array(pathArrayBuffer);

三、版本對比

 let nVersion = [buf[x], buf[x], buf[x], buf[x]];//buf[x]爲十進制,buf[X]根據情況自己填寫
 let oVersion = [unit.hexChangeToTen(data.substr(x, y)), unit.hexChangeToTen(data.substr(x, y)), unit.hexChangeToTen(data.substr(x, y)),unit.hexChangeToTen(data.substr(x, y))]; //data爲第一步中獲取到的設備version信息,根據您情況獲取,如data.substr(0, 2));
 var startTransfer = false;
 if (oVersion[x] != nVersion[x] || oVersion[y] != oVersion[y]) {
   if (oVersion[z] == nVersion[z] && oVersion[r] == oVersion[r]) {
       //可以進行升級,判斷條件根據產品硬件設定,這裏只是參考的一種
       startTransfer = true;
     }
   }
   if (startTransfer) {
 	  console.log(''進行升級)
   }
   else{
  	  console.log('最新版本,無需升級')
   }

四、準備開始升級

① 第一次發送的數據

//根據要求,需要先進行驗證數據,如版本號,儲存器版本號,數據大小、長度等,這裏16進制字符串
var lenStr = (buf.length / 4).toString(16);
 let array = ['xx', 'xx', 'xx', 'xx', nVersion[x].toString(16), nVersion[x].toString(16), lenStr.substr(x, y), lenStr.substr(x, y), 'xx', 'xx', 'xx', 'xx', 'xx', 'xx', nVersion[x].toString(16), nVersion[x].toString(16)];
var bufferStr = '';
for (let i = 0; i < array.length; i++) {
  bufferStr = bufferStr + array[i]
 }

var buffer = unit.string2ArrayBuffer(bufferStr);//16進制字符串轉換爲ArrayBuffer格式
wx.writeBLECharacteristicValue({
      deviceId: deviceId,//IOS中爲DeviceId,Android中爲Mac地址
      serviceId: serviceId,//服務ID,如F000FFC0-XXX
      characteristicId: characterId,//特性ID,如F000FFC1-XXX,特別注意這裏是FFC1
      value: buffer,//發送的數據,硬件要求發送的是什麼就發送什麼轉換爲buffer類型
      success: function (res) {
        console.log('發送成功', res)
        //開始發送bin文件數據,到②
      },
      fail: function (err) {
        console.log('發送失敗:', err, 'code' + err.errCode)
      },
      complete: function (complete) {}
    })

② 發送bin文件的數據

    var inter = setInterval(function(){
      var byte = new Array();
      for(let i = 0; i < 18; i++){
        if(i <= 1){
          byte[0] = parseInt(x%256);
          byte[1] = parseInt(x/256);//特別注意,int類型,float類型會得到x.yy,'.'也算是一個字符
        }
        else{
          if(i-2 + x*16 < that.data.oadData.length){
            byte[i] = that.data.oadData[i-2 + x*16]
          }
          else{
            byte[i] = 0xFF;
          }
        }
      }

      var bufferStr = '';
      for(let i = 0; i < byte.length; i++){
        var value = byte[i].toString(16);
        if(value.length == 1){
          value = '0'+value;//特別強調,如果是0,必須變成00
        }
        bufferStr = bufferStr + value;
      }
	
	var buffer = unit.string2ArrayBuffer(bufferStr);//16進制字符串轉換爲ArrayBuffer格式
wx.writeBLECharacteristicValue({
      deviceId: deviceId,//IOS中爲DeviceId,Android中爲Mac地址
      serviceId: serviceId,//服務ID,如F000FFC0-XXX
      characteristicId: characterId,//特性ID,如F000FFC2-XXX,特別注意這裏是FFC2
      value: buffer,//發送的數據,硬件要求發送的是什麼就發送什麼轉換爲buffer類型
      success: function (res) {
        console.log('發送成功', res)
      },
      fail: function (err) {
        console.log('發送失敗:', err, 'code' + err.errCode)
      },
      complete: function (complete) {}
    })
      x++;
      if(x*16 >= that.data.oadData.length){
        console.log('升級結束')
        wx.hideLoading()
        clearInterval(inter)
        that.data.isUpdate = false;
        x = 0;
        wx.showToast({
          title: '升級成功',
          complete:function(){
            wx.navigateBack({
              complete: (res) => {},
            })
          }
        })
      }
    },70)

注意事項

  1. 發送字節不能超過20字節,要不會報錯,如 writeBLECharacteristicValue:fail write characteristics error. 10008, errMsg=The value’s length is invalid.
  2. 使用16進制字符串進行拼接,在拼接過程中,如0、1這種只有一位的,必須變成00兩位,預防在字符轉換時出錯;
  3. that.data.oadData是bin文件數據,也就是在第二步中的buf
  4. 升級中使用的characteristicId需要特別注意
  5. 提示:在測試中,真機調試使用interval會比較慢,並不會達到理想的20ms發送一次,基本是一秒一次,上傳體驗版後,使用體驗版interval會變回正常,這裏使用70ms會比較好,雖然說理論上可以達到20ms,但是種種原因會導致發送過快而失敗。

附上需要的數據轉換辦法

16進制字符串轉ArrayBuffer

/** 16進制字符串轉ArrayBuffer */
function hexString2ArrayBuffer(hexStr) {
  var count = hexStr.length / 2;
  let buffer = new ArrayBuffer(count);
  let dataView = new DataView(buffer);
  for (var i = 0; i < count; i++) {
    var curCharCode = parseInt(hexStr.substr(i * 2, 2), 16);
    dataView.setUint8(i, curCharCode);
  }
  return buffer;
}

16進制轉10進制

/** 16進制轉換爲10進制 */
function hexChangeToTen(buffer) {
  var tenStr = '0';
  for (var i = buffer.length - 1; i >= 0; i--) {
    let str = parseInt(buffer.substr(i, 1)) * Math.pow(16, buffer.length - i - 1);
    tenStr = parseInt(tenStr) + str;
  }
  return tenStr;
}
創作不易,mark一下,如有需要交流(微信:hkj_930504)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章