小程序连接蓝牙设备并发送指令

支付宝小程序:开放平台-官方文档地址:https://docs.alipay.com/mini/api/bluetooth-api#a-namegfgkonamyopenbluetoothadapter
微信小程序:公众平台-官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/wx.closeBluetoothAdapter.html

支付宝小程序

介绍

依次用到了支付宝小程序提供的这几个接口:(已知服务id和特征id的情况)

  • 初始化蓝牙模块:my.openBluetoothAdapter。可在页面加载的时候调用
  • 关闭蓝牙模块:my.closeBluetoothAdapter。可在初始化失败(可能蓝牙未打开)的时候调用
  • 开始搜寻附近的蓝牙外围设备:my.startBluetoothDevicesDiscovery。初始化完成或点击事件里调用,搜寻到设备或超时时记得停止搜寻
  • 停止搜寻附近的蓝牙外围设备:my.stopBluetoothDevicesDiscovery。搜索到设备或请求超时时调用
  • 监听搜索到新蓝牙设备时事件:my.onBluetoothDeviceFound。搜索到时记得移除事件监听
  • 移除寻找到新的蓝牙设备事件的监听:my.offBluetoothDeviceFound。搜索到设备时调用
  • 连接蓝牙设备:my.connectBLEDevice。放在监听事件的回调函数里
  • 断开连接:my.disconnectBLEDevice。特定事件调用
  • 向蓝牙设备特征值中写入数据:my.writeBLECharacteristicValue。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用
  • 读取蓝牙设备特征值中的数据:my.readBLECharacteristicValue。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用

在不清楚服务id和特征id值的情况、或在调试阶段,可使用的接口:获取蓝牙设备所有 service(服务) my.getBLEDeviceServices、获取蓝牙设备所有 characteristic(特征值) my.getBLEDeviceCharacteristics。记住这个顺序:用macId或蓝牙名去匹配蓝牙,在蓝牙连接成功时会获得deviceId,用deviceId去获取想要的serverId,用deviceId和serverId去获取想要的characteristicId,再用这三个id去读/写数据。

代码示例

此示例中的服务id和特征值id为固定值,所以没有去主动获取。如果需要获取可在连接成功时调用相应接口

axml文件:





js文件:

Page({
    data: {
        deviceId: "",    //设备id
        serviceId: "abc0",    //固定的服务id
        characteristicId: "abc1",   //固定的特征值id-1
        randomCharacteristicId: "FFF2"    //固定的特征值id-2
    },
    onLoad() {
        var that = this;
        my.openBluetoothAdapter({    //初始化蓝牙模块
            success: (res) => {
                that.searchBluetooth();    //开始搜索蓝牙设备
            },
            fail:(res) => {
                console.log("------初始化蓝牙模块失败!!------");
                my.alert({ content: "请开启手机蓝牙后再试!" });
            }
        });
    },
    //移除事件监听
    onUnload() { my.offBluetoothDeviceFound(this.callback); },

    searchBluetooth: function(){    //开始搜索蓝牙设备
        var that = this;
        my.startBluetoothDevicesDiscovery({
            services: [],
            success: (res) => {
                my.showLoading({ content: '正在搜索蓝牙设备' });
                //搜索到蓝牙事件监听
                that.callback = that.callback.bind(that);
                my.onBluetoothDeviceFound(that.callback);
                //5s内未搜索到设备,关闭搜索,关闭蓝牙模块
                setTimeout(function(){
                    if (!that.data.deviceId){
                        my.hideLoading();
                        my.showToast({ type: 'exception', content: '搜索设备超时', duration: 3000 });
                        console.log("搜索设备超时");
                        my.stopBluetoothDevicesDiscovery({});       //关闭搜索
                        my.offBluetoothDeviceFound(that.callback);  //移除搜索设备监听
                        my.closeBluetoothAdapter({});    //关闭蓝牙模块
                    }
                }, 5000);
            },
            fail:(res) => {
                console.log("-------调用搜寻蓝牙设备失败--------");
            }
        });
    },

    callback(res) {    //新搜索到设备的回调函数(通过蓝牙名去匹配)
        var deviceObj = res.devices[0];    //{"deviceId": "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "RSSI": -83, "manufacturerData": "", "deviceName": "ABCDEFG", "advertisData":"", "localName": "ABCDEFG", "name": "ABCDEFG"}
        var name = deviceObj.name || deviceObj.deviceName;
        if(name && name === "13579"){    //搜索到的目标蓝牙设备信息
            my.stopBluetoothDevicesDiscovery({});       //关闭搜索
            my.offBluetoothDeviceFound(this.callback);  //移除搜索设备监听
            this.setData({ deviceId: deviceObj.deviceId });    //存储目标蓝牙设备id
            this.connectBLEDevice();    //去连接蓝牙设备
        }
    },

    connectBLEDevice: function(){       //连接低功耗蓝牙设备
        var that = this;
        var deviceId = that.data.deviceId;
        my.connectBLEDevice({
            deviceId: that.data.deviceId,
            success: (res) => {
                console.log("蓝牙连接成功");
                my.hideLoading();
            },
            fail:(res) => {}
        });
    },

    disconnectBLEDevice: function(){    //断开与低功耗蓝牙设备的连接
        var that = this;
        my.disconnectBLEDevice({
            deviceId: that.data.deviceId,
            success: (res) => {
                console.log("已断开连接!!");
            },
            fail:(res) => {}
        });
    },

    writeBluetoothData1: function(){      //写入执行1指令
        var that = this;
        my.writeBLECharacteristicValue({
            deviceId: that.data.deviceId,
            serviceId: that.data.serviceId,
            characteristicId: that.data.characteristicId,
            value: "123456789"
        });
    },

    writeBluetoothData2: function(){      //写入执行2指令
        var that = this;
        my.writeBLECharacteristicValue({
            deviceId: that.data.deviceId,
            serviceId: that.data.serviceId,
            characteristicId: that.data.characteristicId,
            value: "987654321"
         });
    }
});

微信小程序

介绍

用法与支付宝小程序基本相同,几点不同如下:

  • 没有 移除寻找到新的蓝牙设备事件的监听 方法;
  • 连接蓝牙设备后返回的服务id和特性值id与支付宝的不同,是一个很长的字符串(我这里先去获取了服务id和特性值id,然后将它们做了个存储,方便后续使用);
  • 读取蓝牙设备特征值中的数据 接口,返回的是一个二进制数据。使用的时候需做下处理,且要在wx.onBLECharacteristicValueChange方法回调中接收数据;
  • 向蓝牙设备特征值中写入数据 接口,需写入二进制数据。需转换数据格式后再写入。

依次用到了微信小程序提供的这几个接口:

  • 初始化蓝牙模块:wx.openBluetoothAdapter。可在页面加载的时候调用;
  • 关闭蓝牙模块:wx.closeBluetoothAdapter
  • 开始搜寻附近的蓝牙外围设备:wx.startBluetoothDevicesDiscovery。初始化完成或点击事件里调用,搜索并连接到设备后记得停止搜寻;
  • 停止搜寻附近的蓝牙外围设备:wx.stopBluetoothDevicesDiscovery。已经找到需要的蓝牙设备并不需要继续搜索时调用;
  • 监听寻找到新设备的事件:wx.onBluetoothDeviceFound
  • 连接蓝牙设备:wx.createBLEConnection
  • 断开连接:wx.closeBLEConnection
  • 获取蓝牙设备所有服务(service):wx.getBLEDeviceServices
  • 获取蓝牙设备某个服务中所有特征值(characteristic):wx.getBLEDeviceCharacteristics
  • 向蓝牙设备特征值中写入二进制数据:wx.writeBLECharacteristicValue。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用
  • 读取蓝牙设备特征值中的二进制数据值:wx.readBLECharacteristicValue。读取到的信息需要在 onBLECharacteristicValueChange 方法注册的回调中获取。

代码示例

axml文件:





js文件:


Page({
    data: {
        deviceId: ""    //设备id
    },
    onLoad() {
        var that = this;
        wx.openBluetoothAdapter({    //初始化蓝牙模块
            success: (res) => {
                that.startBluetoothDevicesDiscovery();    //开始搜索蓝牙设备
            },
            fail: (res) => {
                console.log("------初始化蓝牙模块失败!!------");
                wx.showLoading({ title: '请打开蓝牙', icon: 'loading', duration: 3000 })
            }
        });
    },
    //当退出页面,断开蓝牙连接
    onUnload() {
        wx.closeBLEConnection({
            deviceId: this.data.deviceId,
            success(res) { }
        })
    },

    startBluetoothDevicesDiscovery: function(){    //开始搜索蓝牙设备
        var that = this;
        wx.startBluetoothDevicesDiscovery({
            allowDuplicatesKey: true,
            services: [],
            success: (res) => {
                //搜索到新的蓝牙设备时触发事件
                that.callback = that.callback.bind(that);
                wx.onBluetoothDeviceFound(that.callback);
                //5s内未搜索到设备,关闭搜索,关闭蓝牙模块
                setTimeout(function () {
                    if (!that.data.deviceId) {
                        that.setData({ hiddenLoading: true });
                        wx.showToast({title: '搜索设备超时',duration: 3000 })
                        console.log("搜索设备超时");
                        wx.stopBluetoothDevicesDiscovery({});       //关闭搜索
                        wx.closeBluetoothAdapter({});    //关闭蓝牙模块
                    }
                }, 5000);
            },
            fail: (res) => { }
        });
    },

    callback(res) {    //新搜索到设备的回调函数(通过mac地址去匹配)
        var deviceObj = res.devices[0];
        if (this.data.mac.toLowerCase() === deviceObj.manufacturerData.toLowerCase()) {
            wx.stopBluetoothDevicesDiscovery({});       //关闭搜索
            this.setData({ deviceId: deviceObj.deviceId });    //存储目标蓝牙设备id
            this.connectBLEDevice();    //去连接蓝牙设备
        }
    },

    connectBLEDevice: function(){       //连接低功耗蓝牙设备
        var that = this;
        var deviceId = that.data.deviceId;
        wx.createBLEConnection({
            deviceId: that.data.deviceId,
            success: (res) => {      //连接蓝牙设备成功
                wx.getBLEDeviceServices({
                    deviceId: that.data.deviceId,
                    success(res) {    //获取服务id成功
                        that.setData({ serviceId: res.services[1].uuid});
                        wx.getBLEDeviceCharacteristics({
                            deviceId: that.data.deviceId,
                            serviceId: that.data.serviceId,
                            success(res) {      //获取特性值id成功
                                that.setData({ characteristicId: res.characteristics[0].uuid });
                                that.setData({ randomCharacteristicId: res.characteristics[1].uuid });
                                wx.onBLECharacteristicValueChange(function (res) {
                                    //读取数据成功回调-接收并存储转换后的数据
                                    that.setData({ charact1: that.ab2hex(res.value) });
                                });
                                wx.readBLECharacteristicValue({    //读取二进制数据
                                    deviceId: that.data.deviceId,
                                    serviceId: that.data.serviceId,
                                    characteristicId: that.data.randomCharacteristicId,
                                    success: (res) => { }
                                });
                            }
                        })
                    }
                })
            },
            fail: (res) => {
                console.log("连接蓝牙设备失败");
                console.log(res);
            }
        });
    },

    ab2hex: function(buffer) {      //将二进制数组进行转换
        var hexArr = Array.prototype.map.call(
            new Uint8Array(buffer),
            function (bit) {
                return ('00' + bit.toString(16)).slice(-2)
            }
        )
        return hexArr.join('');
    },

    closeBLEConnection: function(){    //断开与低功耗蓝牙设备的连接
        var that = this;
        wx.closeBLEConnection({
            deviceId: that.data.deviceId,
            success: (res) => { console.log("已断开连接!!"); }
        });
    },

    writeBluetoothData1: function(){      //写入执行1指令
        var that = this;
        wx.writeBLECharacteristicValue({
            deviceId: that.data.deviceId,
            serviceId: that.data.serviceId,
            characteristicId: that.data.characteristicId,
            value: that.getBinaryData("0B0075")
        });
    },

    writeBluetoothData2: function(){      //写入执行2指令
        var that = this;
        wx.writeBLECharacteristicValue({
            deviceId: that.data.deviceId,
            serviceId: that.data.serviceId,
            characteristicId: that.data.characteristicId,
            value: that.getBinaryData("75000B")
        });
    },
    
    getBinaryData: function (message) {       //将数据转为二进制数组
        let buffer = new ArrayBuffer(6);
        let dataView = new DataView(buffer);
        var numTitle = 0;
        for (var i = 0; i < message.length; i = i + 2) {
            var numStr16 = message.substr(i, 2);
            var num = parseInt(numStr16, 16);
            dataView.setUint8(numTitle, num);
            numTitle++;
        }
        return buffer;
    }
});

最后

匹配蓝牙设备的时候,可以通过设备名,但是如果附近有多个同名的设备时,就需要通过mac地址来匹配对应的蓝牙设备了。而在苹果手机上返回的mac地址是经过处理后不准确的。如果有这种情况可以联系蓝牙设备硬件方,将mac地址存入manufacturerData中,通过它的值去匹配&连接蓝牙。

你可能感兴趣的:(小程序)