From 4ff1bb8e67c30406722f79467a86ae958d2c56ce Mon Sep 17 00:00:00 2001 From: qcl_123 <5212384+qcl_123@user.noreply.gitee.com> Date: Tue, 17 Mar 2026 09:51:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=AB=E7=94=B5=E6=9E=81?= =?UTF-8?q?=E8=93=9D=E7=89=99=E5=AF=B9=E6=8E=A5=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bluetooth_demo_F01/pages/index/index.js | 622 ++++++++++++------------ bluetooth_demo_J01.zip | Bin 0 -> 7994 bytes bluetooth_demo_L01.zip | Bin 0 -> 6653 bytes bluetooth_demo_L08.zip | Bin 0 -> 7794 bytes bluetooth_demo_L08/pages/index/index.js | 10 +- bluetooth_demo_L08_NSDK.zip | Bin 8417 -> 0 bytes 6 files changed, 318 insertions(+), 314 deletions(-) create mode 100644 bluetooth_demo_J01.zip create mode 100644 bluetooth_demo_L01.zip create mode 100644 bluetooth_demo_L08.zip delete mode 100644 bluetooth_demo_L08_NSDK.zip diff --git a/bluetooth_demo_F01/pages/index/index.js b/bluetooth_demo_F01/pages/index/index.js index 958ba19..86fa80d 100644 --- a/bluetooth_demo_F01/pages/index/index.js +++ b/bluetooth_demo_F01/pages/index/index.js @@ -1,321 +1,325 @@ const util = require("../../utils/util"); const { - inArray, - ab2hex + inArray, + ab2hex } = util const plugin = requirePlugin("sdkPlugin").AiLink; Page({ - data: { - devices: [], - connected: false, - cmd: '', - name: '', - weight: "", - height: "", - text: "", - imp: "", - uuid1: "", - uuid2: "", - uuid3: "", - deviceId: null, - }, - onLoad: function() {}, - // 初始化蓝牙模块 - openBluetoothAdapter() { - wx.openBluetoothAdapter({ - success: (res) => { - console.log('openBluetoothAdapter success', res) - wx.showToast({ - title: '蓝牙连接中', - icon: "none" - }) - this.startBluetoothDevicesDiscovery() - }, - fail: (res) => { - if (res.errCode === 10001) { - wx.showToast({ - title: '请打开蓝牙', - icon: "none" - }) - // 监听本机蓝牙状态变化的事件 - wx.onBluetoothAdapterStateChange((res) => { - console.log('onBluetoothAdapterStateChange', res) - if (res.available) { - this.startBluetoothDevicesDiscovery() - } - }) - } - } - }) - }, + data: { + devices: [], + connected: false, + cmd: '', + name: '', + weight: "", + height: "", + text: "", + imp: "", + uuid1: "", + uuid2: "", + uuid3: "", + deviceId: null, + }, + onLoad: function() {}, + // 初始化蓝牙模块 + openBluetoothAdapter() { + wx.openBluetoothAdapter({ + success: (res) => { + console.log('openBluetoothAdapter success', res) + wx.showToast({ + title: '蓝牙连接中', + icon: "none" + }) + this.startBluetoothDevicesDiscovery() + }, + fail: (res) => { + if (res.errCode === 10001) { + wx.showToast({ + title: '请打开蓝牙', + icon: "none" + }) + // 监听本机蓝牙状态变化的事件 + wx.onBluetoothAdapterStateChange((res) => { + console.log('onBluetoothAdapterStateChange', res) + if (res.available) { + this.startBluetoothDevicesDiscovery() + } + }) + } + } + }) + }, - // 开始搜寻附近的蓝牙外围设备 - startBluetoothDevicesDiscovery() { - if (this._discoveryStarted) { - return - } - this._discoveryStarted = true - wx.startBluetoothDevicesDiscovery({ - allowDuplicatesKey: true, - interval: 1000, //上报设备的间隔 - services: [ - "FFE0", - ], - success: (res) => { - console.log('startBluetoothDevicesDiscovery success', res) - this.onBluetoothDeviceFound() - }, - }) - }, - // 停止搜寻附近的蓝牙外围设备 - stopBluetoothDevicesDiscovery() { - wx.stopBluetoothDevicesDiscovery() - }, + // 开始搜寻附近的蓝牙外围设备 + startBluetoothDevicesDiscovery() { + if (this._discoveryStarted) { + return + } + this._discoveryStarted = true + wx.startBluetoothDevicesDiscovery({ + allowDuplicatesKey: true, + interval: 1000, //上报设备的间隔 + services: [ + "FFE0", + ], + success: (res) => { + console.log('startBluetoothDevicesDiscovery success', res) + this.onBluetoothDeviceFound() + }, + }) + }, + // 停止搜寻附近的蓝牙外围设备 + stopBluetoothDevicesDiscovery() { + wx.stopBluetoothDevicesDiscovery() + }, - // 找到新设备的事件 - onBluetoothDeviceFound() { - wx.onBluetoothDeviceFound((res) => { - res.devices.forEach(device => { - if (!device.name && !device.localName) { - return - } - if (device.name.indexOf('AiLink_') != -1) { - wx.stopBluetoothDevicesDiscovery() //搜索到名称为“AiLink_”的蓝牙后,停止搜寻附近的蓝牙 - const foundDevices = this.data.devices - const idx = inArray(foundDevices, 'deviceId', device.deviceId) - const data = {} - let buff = device.advertisData.slice(-6) - device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址 - let tempMac = Array.from(device.mac) - tempMac.reverse() - device.macAddr = ab2hex(tempMac, ':').toUpperCase() - if (idx === -1) { - data[`devices[${foundDevices.length}]`] = device - } else { - data[`devices[${idx}]`] = device - } - this.setData(data) - } - }) - }) - }, - // 连接低功耗蓝牙设备 - createBLEConnection(e) { - wx.showLoading({ - title: '连接中', - }) - const ds = e.currentTarget.dataset - const index = ds.index - this._device = this.data.devices[index] - const deviceId = ds.deviceId - const name = ds.name - this.mac = ds.mac - wx.createBLEConnection({ - deviceId, - success: (res) => { - this.setData({ - connected: true, - name, - deviceId, - }) - console.log("createBLEConnection:success") - this.onBLEConnectionStateChange() - this.getBLEDeviceServices(deviceId) - }, - fail: res => { - wx.hideLoading() - wx.showToast({ - title: '连接失败', - icon: 'none' - }) - } - }) - }, - //监听蓝牙连接状态 - onBLEConnectionStateChange() { - wx.onBLEConnectionStateChange((res) => { - if (!res.connected) { - setTimeout(() => { - wx.showToast({ - title: '连接已断开', - icon: 'none' - }) - }, 500) - this.setData({ - connected: false, - devices: [], - weight: "", - height: "", - text: "", - imp: "" - }) - } - }) - }, + // 找到新设备的事件 + onBluetoothDeviceFound() { + wx.onBluetoothDeviceFound((res) => { + res.devices.forEach(device => { + if (!device.name && !device.localName) { + return + } + console.log("name", device.name) + if (device.name.indexOf('AiLink_') != -1 || device.name.toLowerCase().indexOf( + 'pcf01') != -1) { + wx.stopBluetoothDevicesDiscovery() //搜索到名称为“AiLink_”的蓝牙后,停止搜寻附近的蓝牙 + const foundDevices = this.data.devices + const idx = inArray(foundDevices, 'deviceId', device.deviceId) + const data = {} + let buff = device.advertisData.slice(-6) + device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址 + let tempMac = Array.from(device.mac) + tempMac.reverse() + device.macAddr = ab2hex(tempMac, ':').toUpperCase() + if (idx === -1) { + data[`devices[${foundDevices.length}]`] = device + } else { + data[`devices[${idx}]`] = device + } + this.setData(data) + } + }) + }) + }, + // 连接低功耗蓝牙设备 + createBLEConnection(e) { + wx.showLoading({ + title: '连接中', + }) + const ds = e.currentTarget.dataset + const index = ds.index + this._device = this.data.devices[index] + const deviceId = ds.deviceId + const name = ds.name + this.mac = ds.mac + wx.createBLEConnection({ + deviceId, + success: (res) => { + this.setData({ + connected: true, + name, + deviceId, + }) + console.log("createBLEConnection:success") + this.onBLEConnectionStateChange() + this.getBLEDeviceServices(deviceId) + }, + fail: res => { + wx.hideLoading() + wx.showToast({ + title: '连接失败', + icon: 'none' + }) + } + }) + }, + //监听蓝牙连接状态 + onBLEConnectionStateChange() { + wx.onBLEConnectionStateChange((res) => { + if (!res.connected) { + setTimeout(() => { + wx.showToast({ + title: '连接已断开', + icon: 'none' + }) + }, 500) + this.setData({ + connected: false, + devices: [], + weight: "", + height: "", + text: "", + imp: "" + }) + } + }) + }, - // 获取蓝牙设备的 serviceId - getBLEDeviceServices(deviceId) { - wx.getBLEDeviceServices({ - deviceId, - success: (res) => { - for (let i = 0; i < res.services.length; i++) { - if (res.services[i].isPrimary && res.services[i].uuid.indexOf('FFE0') > -1) { - wx.showLoading({ - title: '获取设备的UUID成功', - }) - this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid) - return - } - } - } - }) - }, + // 获取蓝牙设备的 serviceId + getBLEDeviceServices(deviceId) { + wx.getBLEDeviceServices({ + deviceId, + success: (res) => { + for (let i = 0; i < res.services.length; i++) { + if (res.services[i].isPrimary && res.services[i].uuid.indexOf('FFE0') > -1) { + wx.showLoading({ + title: '获取设备的UUID成功', + }) + this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid) + return + } + } + } + }) + }, - // 获取蓝牙设备某个服务中所有特征值(characteristic) - /** - * read: true读,write: true写,notify: true广播 - */ - getBLEDeviceCharacteristics(deviceId, serviceId) { - let that = this - that._deviceId = deviceId - that._serviceId = serviceId - that._device.serviceId = serviceId - wx.hideLoading() - wx.getBLEDeviceCharacteristics({ - deviceId, - serviceId, - success: (res) => { - console.log('getBLEDeviceCharacteristics success', res.characteristics) - for (let i = 0; i < res.characteristics.length; i++) { - let item = res.characteristics[i]; - if (item.uuid.indexOf('0000FFE1') != -1) { - that.data.uuid1 = item.uuid //下发数据 - } else if (item.uuid.indexOf('0000FFE2') != -1) { - that.data.uuid2 = item.uuid //监听数据 - } else if (item.uuid.indexOf('0000FFE3') != -1) { - that.data.uuid3 = item.uuid //写入设置 - } - } + // 获取蓝牙设备某个服务中所有特征值(characteristic) + /** + * read: true读,write: true写,notify: true广播 + */ + getBLEDeviceCharacteristics(deviceId, serviceId) { + let that = this + that._deviceId = deviceId + that._serviceId = serviceId + that._device.serviceId = serviceId + wx.hideLoading() + wx.getBLEDeviceCharacteristics({ + deviceId, + serviceId, + success: (res) => { + console.log('getBLEDeviceCharacteristics success', res.characteristics) + for (let i = 0; i < res.characteristics.length; i++) { + let item = res.characteristics[i]; + if (item.uuid.indexOf('0000FFE1') != -1) { + that.data.uuid1 = item.uuid //下发数据 + } else if (item.uuid.indexOf('0000FFE2') != -1) { + that.data.uuid2 = item.uuid //监听数据 + } else if (item.uuid.indexOf('0000FFE3') != -1) { + that.data.uuid3 = item.uuid //写入设置 + } + } - // 打开监听 - wx.notifyBLECharacteristicValueChange({ - deviceId, - serviceId, - characteristicId: that.data.uuid2, - state: true, - }) - wx.notifyBLECharacteristicValueChange({ - deviceId, - serviceId, - characteristicId: that.data.uuid3, - state: true, - }) - // 初始化插件 - plugin.initPlugin(res.characteristics, that._device) - wx.onBLECharacteristicValueChange((characteristic) => { - let bleData = plugin.parseBleData(characteristic.value) - let dw1 = "kg" - if (bleData.status == 0) { - // 发送 男,22岁,185 - let A = 22 - let H = 185 - let sex = "0x01" - let age = "0x" + A.toString(16) - let height = "0x" + H.toString(16) - let arr = [0x01, parseInt(sex), parseInt(age), parseInt(height),0x00] - plugin.sendDataOfA7(arr) - console.log("握手成功", arr) - } else if (bleData.status == 1) { - let payload = ab2hex(bleData.data, '') - let type = payload.substring(0, 2) - let typeInfo = payload.substring(4, 6) - console.log("payload", payload) - if (type == "10" || type == "40") { //体脂模式 - let data = parseInt(payload.substring(6, 12), 16) - let num = payload.substring(12, 13) - let dw = payload.substring(13, 14) - if (dw == "1") { - dw1 = "斤" - } - if (num == "1") { - data = data / 10 - } - if (num == "2") { - data = data / 100 - } - if (num == "3") { - data = data / 1000 - } - if (typeInfo == "01") { - that.setData({ - weight: "实时体重是:" + data + dw1 - }) - } - if (typeInfo == "02") { - that.setData({ - weight: "稳定体重是:" + data + dw1 - }) - } - } - if (type == "14" || type == "41") { //身高模式 - let height = parseInt(payload.substring(4, 8), 16) - that.setData({ - height: "身高是:" + height - }) - } - if (type == "11") { //阻抗模式 - if (typeInfo == "03" || typeInfo == "04") { - let imp = parseInt(payload.substring(8, 12), 16) - console.log("imp", payload, imp) - that.setData({ - imp: "阻抗值:" + imp - }) - } - } - } - }) - }, - fail(res) { - console.error('getBLEDeviceCharacteristics', res) - } - }) - }, + // 打开监听 + wx.notifyBLECharacteristicValueChange({ + deviceId, + serviceId, + characteristicId: that.data.uuid2, + state: true, + }) + wx.notifyBLECharacteristicValueChange({ + deviceId, + serviceId, + characteristicId: that.data.uuid3, + state: true, + }) + // 初始化插件 + plugin.initPlugin(res.characteristics, that._device) + wx.onBLECharacteristicValueChange((characteristic) => { + let bleData = plugin.parseBleData(characteristic.value) + let dw1 = "kg" + if (bleData.status == 0) { + // 发送 男,22岁,185 + let A = 22 + let H = 185 + let sex = "0x01" + let age = "0x" + A.toString(16) + let height = "0x" + H.toString(16) + let arr = [0x01, parseInt(sex), parseInt(age), parseInt(height), + 0x00 + ] + plugin.sendDataOfA7(arr) + console.log("握手成功", arr) + } else if (bleData.status == 1) { + let payload = ab2hex(bleData.data, '') + let type = payload.substring(0, 2) + let typeInfo = payload.substring(4, 6) + console.log("payload", payload) + if (type == "10" || type == "40") { //体脂模式 + let data = parseInt(payload.substring(6, 12), 16) + let num = payload.substring(12, 13) + let dw = payload.substring(13, 14) + if (dw == "1") { + dw1 = "斤" + } + if (num == "1") { + data = data / 10 + } + if (num == "2") { + data = data / 100 + } + if (num == "3") { + data = data / 1000 + } + if (typeInfo == "01") { + that.setData({ + weight: "实时体重是:" + data + dw1 + }) + } + if (typeInfo == "02") { + that.setData({ + weight: "稳定体重是:" + data + dw1 + }) + } + } + if (type == "14" || type == "41") { //身高模式 + let height = parseInt(payload.substring(4, 8), 16) + that.setData({ + height: "身高是:" + height + }) + } + if (type == "11") { //阻抗模式 + if (typeInfo == "03" || typeInfo == "04") { + let imp = parseInt(payload.substring(8, 12), 16) + console.log("imp", payload, imp) + that.setData({ + imp: "阻抗值:" + imp + }) + } + } + } + }) + }, + fail(res) { + console.error('getBLEDeviceCharacteristics', res) + } + }) + }, - /** - * 断开蓝牙模块 - */ - closeBluetoothAdapter() { - wx.closeBluetoothAdapter() - this._discoveryStarted = false - wx.showToast({ - title: '断开蓝牙模块', - icon: 'none' - }) - this.setData({ - devices: [], - weight: "", - height: "", - text: "", - imp: "" - }) - }, - // 断开与低功耗蓝牙设备的连接 - closeBLEConnection() { - wx.closeBLEConnection({ - deviceId: this._deviceId - }) - wx.showToast({ - title: '断开蓝牙连接', - icon: 'none' - }) - this.setData({ - connected: false, - devices: [], - text: "", - height: "", - weight: "", - imp: "" - }) - }, + /** + * 断开蓝牙模块 + */ + closeBluetoothAdapter() { + wx.closeBluetoothAdapter() + this._discoveryStarted = false + wx.showToast({ + title: '断开蓝牙模块', + icon: 'none' + }) + this.setData({ + devices: [], + weight: "", + height: "", + text: "", + imp: "" + }) + }, + // 断开与低功耗蓝牙设备的连接 + closeBLEConnection() { + wx.closeBLEConnection({ + deviceId: this._deviceId + }) + wx.showToast({ + title: '断开蓝牙连接', + icon: 'none' + }) + this.setData({ + connected: false, + devices: [], + text: "", + height: "", + weight: "", + imp: "" + }) + }, -}); +}); \ No newline at end of file diff --git a/bluetooth_demo_J01.zip b/bluetooth_demo_J01.zip new file mode 100644 index 0000000000000000000000000000000000000000..c753a7a8d416200b9cc203a38a42f43cb5714ae1 GIT binary patch literal 7994 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 Ifq#AXf2;yyEdT%j literal 0 HcmV?d00001 diff --git a/bluetooth_demo_L01.zip b/bluetooth_demo_L01.zip new file mode 100644 index 0000000000000000000000000000000000000000..fec28f56b56700ae6153599202936984e97643c2 GIT binary patch literal 6653 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 bvZlz{zKet2_yYhW=#v|L*L?i%4&eU)-Z=+1 literal 0 HcmV?d00001 diff --git a/bluetooth_demo_L08.zip b/bluetooth_demo_L08.zip new file mode 100644 index 0000000000000000000000000000000000000000..1a7bce63b8192aac73516e24676481f441121cf9 GIT binary patch literal 7794 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