微信小程序实现蓝牙开锁、开门、开关、指令发送成功,但蓝牙设备毫无反应、坑

文章目录

  • 开源
  • html
  • JavaScript


开源

wx联系本人获取源码(开源): MJ682517


html

<view>
	<view class="p_l_36 p_r_36">
		<input class="w_100_ h_80 lh_80 ta_c b_2s_eee radius_20" value="{{instructVal}}" type="text" placeholder="请输入开门指令" bindinput="bindinput" />
	view>
	
	<view class="m_t_36 w_50_ h_90 lh_90 m_l_a m_r_a bc_409eff radius_10 color_fff ta_c" catchtap="openBluetoothAdapter">蓝牙开锁view>
view>

JavaScript

需要从下往上阅读,使用函数自调的方式解决API不能及时获取数据的问题,替换方案是使用定时器,但是个人觉得定时器不好,所以使用了函数自调的方式实现获取不到数据的问题。

getBluetoothDevices方法中获取deviceIdgetBLEDeviceServices方法中获取到serviceId,获取到的是数组,取数组中的uuid作为serviceId值,具体用哪个值,需要与蓝牙设备文档比对;getBLEDeviceCharacteristics方法中获取characteristicId,获取到的是数组,取数组中的uuid作为characteristicId值。

一般情况的对应的值如下
serviceId: 0000FFB0-0000-1000-8000-00805F9B34FB
notifyId: 0000FFB2-0000-1000-8000-00805F9B34FB
writeId: 0000FFB1-0000-1000-8000-00805F9B34FB
注意观察第一个横杠前面最后两位的值,不难发现规律。
写入的指令一般是以十六进制(EE03E30100)字符串的方式,最后转为二进制发送给蓝牙。

坑: 在不确定蓝牙文档是否正确的情况下,写入成功,但是蓝牙设备毫无反应,那么大概率就是写入的指令有问题,所以需要校对一下指令是否正确。

蓝牙文档需要与厂商获取。

获取蓝牙服务值方法getBLEDeviceServices
获取蓝牙特征值方法getBLEDeviceCharacteristics。特征值一般包括两个,一个代表写入值,一个代表读取值,意思是说写入的是需要把写入的特征值带上,读取的时候把读取的特征值带上。

notifyBLECharacteristicValueChange方法启用蓝牙低功耗设备特征值变化时的notify功能,订阅特征。此时传入的是读取的特征值。

// index.js
let timeout = undefined;

Page({
  data: {
    devices: [],
    deviceId: '',
    services: [],
    serviceId: '',
    characteristics: [],
    characteristicId: '',
    instructVal: 'EE03E30100'
  },
  // 指令输入
  bindinput({
    detail: {
      value
    }
  }) {
    this.setData({
      instructVal: value
    });
  },

  // 失败时的统一提示
  failShowToast(title = '开锁失败') {
    clearTimeout(timeout);
    timeout = undefined;
    wx.hideLoading();
    wx.showToast({
      icon: 'none',
      title
    });
  },

  /**
   * 根据不同方法名调用方法,统一定时器的触发判断,
   * 当定时器触发时,无法确定当前调用的方法是哪个
   * @param {String} fnName 
   */
  methodExecution(fnName = '') {
    if (timeout) this[fnName]();
  },

  // 关闭蓝牙模块
  closeBluetoothAdapter() {
    let that = this;

    // 关闭蓝牙模块
    wx.closeBluetoothAdapter({
      success() {},
      fail() {
        that.methodExecution('closeBluetoothAdapter');
      }
    });
  },

  // 断开与蓝牙低功耗设备的连接
  closeBLEConnection() {
    let that = this;

    // 断开与蓝牙低功耗设备的连接
    wx.closeBLEConnection({
      deviceId: that.data.deviceId,
      success() {
        that.closeBluetoothAdapter();
      },
      fail() {
        that.methodExecution('closeBLEConnection');
      }
    });
  },

  // 向蓝牙低功耗设备特征值中写入二进制数据
  writeBLECharacteristicValue() {
    let that = this;

    let str = that.data.instructVal;

    if (!str) return wx.showToast({
      title: '请输入指令',
      icon: 'none'
    });

    /* 将数值转为ArrayBuffer类型数据 */
    let typedArray = new Uint8Array(str.match(/[\da-f]{2}/gi).map((h) => parseInt(h, 16))),
      buffer = typedArray.buffer;

    // 向蓝牙低功耗设备特征值中写入二进制数据
    wx.writeBLECharacteristicValue({
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      characteristicId: '0000FFB1-0000-1000-8000-00805F9B34FB',
      value: buffer,
      success() {
        clearTimeout(timeout);
        timeout = undefined;
        wx.hideLoading();
        wx.showToast({
          icon: 'none',
          title: '开锁成功'
        });
        // that.closeBLEConnection();
      },
      fail() {
        that.methodExecution('writeBLECharacteristicValue');
      }
    });
  },

  // 监听蓝牙低功耗设备的特征值变化事件
  onBLECharacteristicValueChange() {
    let that = this;

    // 监听蓝牙低功耗设备的特征值变化事件
    wx.onBLECharacteristicValueChange((res) => {
      if (res.value) {
        that.writeBLECharacteristicValue();
      } else {
        that.methodExecution('onBLECharacteristicValueChange');
      }
    });
  },

  // 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征
  notifyBLECharacteristicValueChange() {
    let that = this;

    // 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征
    wx.notifyBLECharacteristicValueChange({
      state: true,
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      characteristicId: that.data.characteristicId,
      success() {
        that.onBLECharacteristicValueChange();
      },
      fail() {
        that.methodExecution('notifyBLECharacteristicValueChange');
      }
    });
  },

  // 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
  getBLEDeviceCharacteristics() {
    let that = this;

    // 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
    wx.getBLEDeviceCharacteristics({
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      success({
        characteristics
      }) {
        that.setData({
          characteristics,
          characteristicId: '0000FFB2-0000-1000-8000-00805F9B34FB'
        }, () => that.notifyBLECharacteristicValueChange());
      },
      fail() {
        that.methodExecution('getBLEDeviceCharacteristics');
      }
    });
  },

  // 获取蓝牙低功耗设备所有服务 (service)
  getBLEDeviceServices() {
    let that = this;

    // 获取蓝牙低功耗设备所有服务 (service)
    wx.getBLEDeviceServices({
      deviceId: that.data.deviceId,
      success({
        services
      }) {
        that.setData({
          services,
          serviceId: '0000FFB0-0000-1000-8000-00805F9B34FB'
        }, () => that.getBLEDeviceCharacteristics());
      },
      fail() {
        that.methodExecution('getBLEDeviceServices');
      }
    });
  },

  // 停止搜寻附近的蓝牙外围设备
  stopBluetoothDevicesDiscovery() {
    let that = this;

    // 停止搜寻附近的蓝牙外围设备
    wx.stopBluetoothDevicesDiscovery({
      success() {
        that.getBLEDeviceServices();
      },
      fail() {
        that.methodExecution('stopBluetoothDevicesDiscovery');
      }
    });
  },

  // 连接蓝牙低功耗设备
  createBLEConnection() {
    let that = this;

    // 连接蓝牙低功耗设备
    wx.createBLEConnection({
      deviceId: that.data.deviceId,
      success() {
        that.stopBluetoothDevicesDiscovery();
      },
      fail() {
        that.methodExecution('createBLEConnection');
      }
    });
  },

  // 获取在蓝牙模块生效期间所有搜索到的蓝牙设备
  getBluetoothDevices() {
    let that = this;

    // 获取在蓝牙模块生效期间所有搜索到的蓝牙设备
    wx.getBluetoothDevices({
      success({
        devices
      }) {
        for (let i = 0; i < devices.length; i++) {
          const item = devices[i];
          if (item.name === 'YX_0A45320C78C6') {
            item.ASUUID = item.advertisServiceUUIDs[0];

            that.setData({
              devices: item,
              deviceId: item.deviceId
            }, () => that.createBLEConnection());

            break;
          }
        }

        that.methodExecution('getBluetoothDevices');
      },
      fail() {
        that.methodExecution('getBluetoothDevices');
      }
    });
  },

  // 开始搜寻附近的蓝牙外围设备
  startBluetoothDevicesDiscovery() {
    let that = this;

    // 开始搜寻附近的蓝牙外围设备
    wx.startBluetoothDevicesDiscovery({
      // 此字段会导致startBluetoothDevicesDiscovery不执行
      // services: ['YX'],
      success() {
        that.getBluetoothDevices();
      },
      fail() {
        that.methodExecution('startBluetoothDevicesDiscovery');
      }
    });
  },

  // 蓝牙开锁
  openBluetoothAdapter() {
    let that = this,
      thatData = that.data;

    if (!that.data.instructVal) return wx.showToast({
      title: '请输入指令',
      icon: 'none'
    });

    if (timeout) return wx.showToast({
      title: '加载中',
      icon: 'none'
    });

    wx.showLoading({
      title: '加载中',
      mask: true
    });

    timeout = setTimeout(() => {
      that.failShowToast('开锁失败');
    }, 1000 * 26);

    if (thatData.deviceId && thatData.serviceId && thatData.characteristicId) return that.writeBLECharacteristicValue();

    // 初始化蓝牙模块
    wx.openBluetoothAdapter({
      success() {
        that.setData({
          devices: [],
          deviceId: '',
          services: [],
          serviceId: '',
          characteristics: [],
          characteristicId: ''
        }, () => that.startBluetoothDevicesDiscovery());
      },
      fail() {
        that.failShowToast('查看手机蓝牙是否打开');
      }
    });
  },
  
  onLoad() {
  
  }
})

你可能感兴趣的:(web前端,微信小程序,工具,微信小程序,小程序,前端,web)