From e010cc4e95b71ca6135c46f6f054b6be1cf1b37d Mon Sep 17 00:00:00 2001
From: shuai58 <2973810292@qq.com>
Date: Wed, 8 Dec 2021 09:18:31 +0800
Subject: [PATCH] =?UTF-8?q?2021/12/08=20=E8=93=9D=E7=89=99=E5=87=BA?=
=?UTF-8?q?=E5=8E=82=E6=B5=8B=E8=AF=95=E5=B0=8F=E7=A8=8B=E5=BA=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app.js | 5 +
app.json | 16 ++
app.wxss | 68 ++++++
pages/PCD01PRO/index.js | 328 +++++++++++++++++++++++++++++
pages/PCD01PRO/index.json | 4 +
pages/PCD01PRO/index.wxml | 42 ++++
pages/PCD01PRO/index.wxss | 1 +
pages/PCH0809/index.js | 422 ++++++++++++++++++++++++++++++++++++++
pages/PCH0809/index.json | 4 +
pages/PCH0809/index.wxml | 51 +++++
pages/PCH0809/index.wxss | 104 ++++++++++
pages/index/index.js | 344 +++++++++++++++++++++++++++++++
pages/index/index.json | 4 +
pages/index/index.wxml | 16 ++
project.config.json | 71 +++++++
sitemap.json | 7 +
utils/util.js | 30 +++
17 files changed, 1517 insertions(+)
create mode 100644 app.js
create mode 100644 app.json
create mode 100644 app.wxss
create mode 100644 pages/PCD01PRO/index.js
create mode 100644 pages/PCD01PRO/index.json
create mode 100644 pages/PCD01PRO/index.wxml
create mode 100644 pages/PCD01PRO/index.wxss
create mode 100644 pages/PCH0809/index.js
create mode 100644 pages/PCH0809/index.json
create mode 100644 pages/PCH0809/index.wxml
create mode 100644 pages/PCH0809/index.wxss
create mode 100644 pages/index/index.js
create mode 100644 pages/index/index.json
create mode 100644 pages/index/index.wxml
create mode 100644 project.config.json
create mode 100644 sitemap.json
create mode 100644 utils/util.js
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..ff15a95
--- /dev/null
+++ b/app.js
@@ -0,0 +1,5 @@
+//app.js
+App({
+ onLaunch: function () {
+ }
+})
\ No newline at end of file
diff --git a/app.json b/app.json
new file mode 100644
index 0000000..9994e3b
--- /dev/null
+++ b/app.json
@@ -0,0 +1,16 @@
+{
+ "pages": [
+ "pages/index/index",
+ "pages/PCD01PRO/index",
+ "pages/PCH0809/index"
+ ],
+ "window": {
+ "navigationBarBackgroundColor": "#0082FE",
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "蓝牙连接Demo",
+ "backgroundColor": "#eeeeee",
+ "backgroundTextStyle": "light"
+ },
+ "style": "v2",
+ "sitemapLocation": "sitemap.json"
+}
diff --git a/app.wxss b/app.wxss
new file mode 100644
index 0000000..e18f0d0
--- /dev/null
+++ b/app.wxss
@@ -0,0 +1,68 @@
+/**app.wxss**/
+view,
+cover-view,
+scroll-view,
+swiper,
+swiper-item,
+movable-area,
+movable-view,
+button,
+input,
+textarea,
+label,
+navigator {
+ box-sizing: border-box;
+}
+
+page {
+ --safe-bottom: env(safe-area-inset-bottom);
+}
+
+.container {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100vw;
+ height: 100vh;
+ padding-bottom: var(--safe-bottom);
+}
+
+.header {
+ width: 100%;
+}
+
+.header button {
+ font-size: 16px;
+ line-height: 40px;
+ width: 100% !important;
+ border-bottom: 1px solid #dfdfdf;
+}
+
+.device_item {
+ padding: 15px;
+ border-bottom: 1px solid #dfdfdf;
+}
+
+.weight {
+ width: 100%;
+ margin: 15px;
+ padding-bottom: 15px;
+ text-align: center;
+ font-size: 18px;
+ font-weight: 700;
+ border-bottom: 1px solid #dfdfdf;
+}
+.list{
+ width: 100%;
+ height: auto;
+ display: flex;
+ justify-content: space-around;
+ flex-wrap: wrap;
+}
+.item{
+ padding: 15px;
+ background: #f7f7f7;
+ border-radius: 10px;
+ margin-top: 15px;
+}
diff --git a/pages/PCD01PRO/index.js b/pages/PCD01PRO/index.js
new file mode 100644
index 0000000..5020739
--- /dev/null
+++ b/pages/PCD01PRO/index.js
@@ -0,0 +1,328 @@
+const util = require("../../utils/util");
+const {
+ inArray,
+ ab2hex
+} = util
+
+Page({
+ data: {
+ devices: [],
+ connected: false,
+ cmd: '',
+ name: '',
+ weight: "",
+ text: "",
+ imp: "",
+ 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, //是否允许重复上报同一设备
+ services: [ //要搜索蓝牙设备主 service 的 uuid 列表
+ "FFE0",
+ ],
+ success: (res) => {
+ console.log('startBluetoothDevicesDiscovery success', res)
+ this.onBluetoothDeviceFound()
+ },
+ })
+ },
+ // 停止搜寻附近的蓝牙外围设备
+ stopBluetoothDevicesDiscovery() {
+ wx.stopBluetoothDevicesDiscovery()
+ },
+
+ // 找到新设备的事件
+ onBluetoothDeviceFound() {
+ wx.onBluetoothDeviceFound((res) => {
+ res.devices.forEach(device => {
+ 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
+ }
+ console.log("131", data)
+ this.setData(data)
+ }
+ })
+ })
+ },
+ // 连接低功耗蓝牙设备
+ createBLEConnection(e) {
+ this._connLoading = true
+ wx.showLoading({
+ title: '连接中',
+ })
+ setTimeout(() => {
+ if (this._connLoading) {
+ this._connLoading = false
+ wx.hideLoading()
+ }
+ }, 6000)
+ 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 => {
+ this._connLoading = false
+ 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: "",
+ 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
+ }
+ }
+ }
+ })
+ },
+
+ // 获取蓝牙设备某个服务中所有特征值(characteristic)
+ /**
+ * read: true读,write: true写,notify: true广播
+ */
+ getBLEDeviceCharacteristics(deviceId, serviceId) {
+ this._deviceId = deviceId
+ this._serviceId = serviceId
+ this._device.serviceId = serviceId
+ wx.getBLEDeviceCharacteristics({
+ deviceId,
+ serviceId,
+ success: (res) => {
+ console.log('getBLEDeviceCharacteristics success', res.characteristics)
+ wx.showLoading({
+ title: '获取特征值成功',
+ })
+ //FFE1:write: true, FFE2:notify: true,FFE3:read: true, write: true, notify: true,
+ for (let i = 0; i < res.characteristics.length; i++) {
+ let characteristic = res.characteristics[i];
+ if (characteristic.uuid.indexOf("FFE2") != -1) {
+ if (characteristic.properties.notify == true) {
+ this.notifyBLECharacteristicValue(deviceId, serviceId, characteristic
+ .uuid)
+ console.log("ffe2服务的notifyId获取成功")
+ }
+ if (characteristic.properties.read == true) {
+ that.readId = characteristic.uuid
+ }
+ if (characteristic.properties.write == true) {
+ that.writeId = characteristic.uuid
+ }
+ break;
+ }
+ }
+ },
+ fail(res) {
+ console.error('getBLEDeviceCharacteristics', res)
+ }
+ })
+ },
+ //解析蓝牙返回数据
+ notifyBLECharacteristicValue(deviceId, serviceId, notifyId) {
+ let that = this
+ wx.notifyBLECharacteristicValueChange({
+ state: true, // 启用 notify 功能
+ deviceId: deviceId,
+ serviceId: serviceId,
+ characteristicId: notifyId,
+ success(res) {
+ wx.onBLECharacteristicValueChange(function(res) {
+ let value = ab2hex(res.value);
+ let num = value.substring(18, 19)
+ let dw = value.substring(19, 20)
+ let typeInfo = value.substring(10, 12)
+ console.log("16进制转化:", value);
+ if (value.length == 26) {
+ let data = parseInt(value.substring(13, 18), 16)
+ let dw1 = "kg"
+ if (dw == "1") {
+ dw1 = "斤"
+ console.log("体重单位:斤")
+ }
+ if (dw == "4") {
+ dw1 = "st:lb"
+ console.log("体重单位:st:lb,计算方法:1 * data + 5")
+ }
+ if (dw == "6") {
+ dw1 = "lb"
+ console.log("体重单位:lb")
+ }
+ if (num == "1") {
+ data = parseInt(value.substring(13, 18), 16) / 10
+ console.log("体重小数点后1位")
+ }
+ if (num == "2") {
+ data = parseInt(value.substring(13, 18), 16) / 100
+ console.log("体重小数点后2位")
+ }
+ if (num == "3") {
+ data = parseInt(value.substring(13, 18), 16) / 1000
+ console.log("体重小数点后3位")
+ }
+ if (typeInfo == "01") {
+ console.log("实时体重:", data)
+ that.setData({
+ weight: "实时体重是:" + data + dw1
+ })
+ }
+ if (typeInfo == "02") {
+ console.log("稳定体重:", data)
+ that.setData({
+ weight: "稳定体重是:" + data + dw1
+ })
+ }
+ }
+ if (value.length == 30) {
+ console.log("阻抗值:", value)
+ if (typeInfo == "03") {
+ let imp = parseInt(value.substring(17, 22), 16)
+ that.setData({
+ imp: "阻抗值:" + imp
+ })
+ }
+
+ }
+ if (value.toUpperCase() == "A90026023000589A") {
+ console.log("测量完成")
+ that.setData({
+ text: "测量完成"
+ })
+ }
+ });
+ },
+ fail(res) {
+ console.log("测量失败", res.value);
+ }
+ });
+ },
+
+ /**
+ * 断开蓝牙模块
+ */
+ closeBluetoothAdapter() {
+ wx.closeBluetoothAdapter()
+ this._discoveryStarted = false
+ wx.showToast({
+ title: '断开蓝牙模块',
+ icon: 'none'
+ })
+ this.setData({
+ devices: [],
+ weight: "",
+ text: "",
+ imp: ""
+ })
+ },
+ // 断开与低功耗蓝牙设备的连接
+ closeBLEConnection() {
+ wx.closeBLEConnection({
+ deviceId: this._deviceId
+ })
+ wx.showToast({
+ title: '断开蓝牙连接',
+ icon: 'none'
+ })
+ this.setData({
+ connected: false,
+ devices: [],
+ text: "",
+ weight: "",
+ imp: ""
+ })
+ },
+
+});
diff --git a/pages/PCD01PRO/index.json b/pages/PCD01PRO/index.json
new file mode 100644
index 0000000..b55b5a2
--- /dev/null
+++ b/pages/PCD01PRO/index.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {
+ }
+}
\ No newline at end of file
diff --git a/pages/PCD01PRO/index.wxml b/pages/PCD01PRO/index.wxml
new file mode 100644
index 0000000..cbe4525
--- /dev/null
+++ b/pages/PCD01PRO/index.wxml
@@ -0,0 +1,42 @@
+
+module.exports.max = function(n1, n2) {
+ return Math.max(n1, n2)
+}
+module.exports.len = function(arr) {
+ arr = arr || []
+ return arr.length
+}
+
+
+
+
+
+ {{weight}}
+ {{imp}}
+ {{text}}
+
+ 已发现 {{devices.length}} 个外围设备:
+
+
+
+ {{item.name}}
+ (信号强度: {{item.RSSI}}dBm)
+
+ mac地址: {{item.macAddr || item.deviceId}}
+
+
+
+
+
+
diff --git a/pages/PCD01PRO/index.wxss b/pages/PCD01PRO/index.wxss
new file mode 100644
index 0000000..23ef694
--- /dev/null
+++ b/pages/PCD01PRO/index.wxss
@@ -0,0 +1 @@
+/* pages/PCD01PRO/index.wxss */
\ No newline at end of file
diff --git a/pages/PCH0809/index.js b/pages/PCH0809/index.js
new file mode 100644
index 0000000..0639308
--- /dev/null
+++ b/pages/PCH0809/index.js
@@ -0,0 +1,422 @@
+const util = require("../../utils/util");
+const {
+ inArray,
+ ab2hex
+} = util
+
+Page({
+ data: {
+ devices: [],
+ connected: false,
+ cmd: '',
+ name: '',
+ weight: "",
+ text: "",
+ imp: "",
+ height: '',
+ isType: false,
+ sendVal: true,
+ pwdModal: false,
+ uuid1: null,
+ uuid2: null,
+ uuid3: null,
+ deviceId: null,
+ serviceId: null
+ },
+ onLoad: function() {
+ // let value = "A90026051401020001439A";
+ // let num = value.substring(18, 19)
+ // let type = value.substring(8, 10)
+ // let imp = parseInt(value.substring(10, 14), 16)
+ // console.log("16进制转化:", value, num, type, imp);
+ },
+ // 初始化蓝牙模块
+ 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, //是否允许重复上报同一设备
+ services: [ //要搜索蓝牙设备主 service 的 uuid 列表
+ "FFE0",
+ ],
+ success: (res) => {
+ console.log('startBluetoothDevicesDiscovery success', res)
+ this.onBluetoothDeviceFound()
+ },
+ })
+ },
+ // 停止搜寻附近的蓝牙外围设备
+ stopBluetoothDevicesDiscovery() {
+ wx.stopBluetoothDevicesDiscovery()
+ },
+
+ // 找到新设备的事件
+ onBluetoothDeviceFound() {
+ wx.onBluetoothDeviceFound((res) => {
+ res.devices.forEach(device => {
+ 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
+ }
+ console.log("131", data)
+ this.setData(data)
+ }
+ })
+ })
+ },
+ // 连接低功耗蓝牙设备
+ createBLEConnection(e) {
+ this._connLoading = true
+ wx.showLoading({
+ title: '连接中',
+ })
+ setTimeout(() => {
+ if (this._connLoading) {
+ this._connLoading = false
+ wx.hideLoading()
+ }
+ }, 6000)
+ 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 => {
+ this._connLoading = false
+ 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,
+ isType: false,
+ devices: [],
+ weight: "",
+ 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.data.serviceId = res.services[i].uuid
+ this.data.deviceId = deviceId
+ this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
+ return
+ }
+ }
+ }
+ })
+ },
+
+ // 获取蓝牙设备某个服务中所有特征值(characteristic)
+ /**
+ * read: true读,write: true写,notify: true广播
+ */
+ getBLEDeviceCharacteristics(deviceId, serviceId) {
+ this._deviceId = deviceId
+ this._serviceId = serviceId
+ this._device.serviceId = serviceId
+ let that = this
+ wx.getBLEDeviceCharacteristics({
+ deviceId,
+ serviceId,
+ success: (res) => {
+ wx.hideLoading()
+ console.log('getBLEDeviceCharacteristics success', res.characteristics)
+ for (let i = 0; i < res.characteristics.length; i++) {
+ let item = res.characteristics[i];
+ if (item.uuid.indexOf('FFE1') != -1) {
+ that.data.uuid1 = item.uuid //主服务 UUID
+ } else if (item.uuid.indexOf('FFE2') != -1) {
+ that.data.uuid2 = item.uuid //写入设置
+ } else if (item.uuid.indexOf('FFE3') != -1) {
+ that.data.uuid3 = item.uuid //监听数据
+ }
+ }
+ that.setData({
+ isType: true,
+ })
+ wx.notifyBLECharacteristicValueChange({
+ deviceId,
+ serviceId,
+ characteristicId: that.data.uuid2,
+ state: true,
+ })
+ wx.notifyBLECharacteristicValueChange({
+ deviceId,
+ serviceId,
+ characteristicId: that.data.uuid3,
+ state: true,
+ })
+ wx.onBLECharacteristicValueChange((res) => {
+ let value = ab2hex(res.value);
+ console.log("16进制转化:", value);
+ let num = value.substring(18, 19)
+ let dw = value.substring(19, 20)
+ let type = value.substring(8, 10)
+ let typeInfo = value.substring(10, 12)
+ console.log("16进制转化:", value);
+ if (type == '10') {
+ let data = parseInt(value.substring(13, 18), 16)
+ let dw1 = "kg"
+ if (dw == "1") {
+ dw1 = "斤"
+ console.log("体重单位:斤")
+ }
+ if (dw == "4") {
+ dw1 = "st:lb"
+ console.log("体重单位:st:lb,计算方法:1 * data + 5")
+ }
+ if (dw == "6") {
+ dw1 = "lb"
+ console.log("体重单位:lb")
+ }
+ if (num == "1") {
+ data = parseInt(value.substring(13, 18), 16) / 10
+ console.log("体重小数点后1位")
+ }
+ if (num == "2") {
+ data = parseInt(value.substring(13, 18), 16) / 100
+ console.log("体重小数点后2位")
+ }
+ if (num == "3") {
+ data = parseInt(value.substring(13, 18), 16) / 1000
+ console.log("体重小数点后3位")
+ }
+ if (typeInfo == "01") {
+ console.log("实时体重:", data)
+ that.setData({
+ weight: "实时体重是:" + data + dw1
+ })
+ }
+ if (typeInfo == "02") {
+ console.log("稳定体重:", data)
+ that.setData({
+ weight: "稳定体重是:" + data + dw1
+ })
+ }
+ }
+ if (type == "14" ) { //身高模式
+ let height = parseInt(value.substring(10, 14), 16)
+ that.setData({
+ height: "您的身高是:" + height
+ })
+ console.log("身高模式:", height)
+ }
+ if (type == "11") {
+ console.log("阻抗值:", value)
+ if (typeInfo == "03" || typeInfo == "04") {
+ let imp = parseInt(value.substring(17, 22), 16)
+ that.setData({
+ imp: "阻抗值:" + imp
+ })
+ }
+ }
+ if (value.toUpperCase() == "A90026023000589A") {
+ console.log("测量完成")
+ that.setData({
+ text: "测量完成"
+ })
+ }
+ });
+ },
+ fail(res) {
+ console.error('getBLEDeviceCharacteristics', res)
+ }
+ })
+ },
+ handleHeight(e) {
+ let that = this
+ let type = e.currentTarget.dataset.name
+ if (type == '1') {
+ let j = Number(26 + 3 + 6 + 1).toString(16)
+ let str = "A9002603060100" + j.substr(j.length - 2, 2) + "9A"
+ let buf = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function(h) {
+ return parseInt(h, 16)
+ }))
+ that.sendData(buf.buffer)
+ }
+ if (type == '3') {
+ that.setData({
+ pwdModal: true,
+ })
+ }
+ },
+ confirmPwd() {
+ let that = this
+ console.log(that.data.pwdInput)
+ if (!that.data.pwdInput) {
+ wx.showToast({
+ title: '请输入重量',
+ icon: 'none'
+ })
+ return
+ } else {
+ let w = Number(that.data.pwdInput.replace(/[&\|\\\*^%$#@\.-]/g, ""))
+ let j = Number(26 + 7 + 40 + w + 3 + 2).toString(16)
+ let atr = w.toString(16)
+ let num = 2
+ if (that.data.pwdInput.toString().split(".")[1].length) {
+ num = Number(that.data.pwdInput.toString().split(".")[1].length)
+ }
+ let str = "A90026074003" + atr + num + "000" + j.substr(j.length - 2, 2) + "9a"
+ console.log("协议:", j, j.substr(j.length - 2, 2), w, atr, num, str)
+ let buf = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function(h) {
+ return parseInt(h, 16)
+ }))
+ that.sendData(buf.buffer)
+ }
+ },
+ sendData(buffer) {
+ let that = this
+ console.log("指令信息", that.data.deviceId, that.data.serviceId, ab2hex(buffer))
+ wx.writeBLECharacteristicValue({
+ deviceId: that.data.deviceId,
+ serviceId: that.data.serviceId,
+ characteristicId: that.data.uuid2,
+ value: buffer,
+ success: res => {
+ console.log('下发指令', res.errMsg)
+ wx.showToast({
+ title: '下发指令成功',
+ icon: 'none'
+ })
+ this.setData({
+ pwdModal: false,
+ })
+ },
+ fail: res => {
+ wx.showToast({
+ title: '下发指令失败',
+ icon: 'none'
+ })
+ this.setData({
+ pwdModal: false,
+ })
+ console.log("失败", res);
+ },
+ })
+ },
+ closeModal() {
+ this.setData({
+ pwdModal: false,
+ })
+ },
+ /**
+ * 断开蓝牙模块
+ */
+ closeBluetoothAdapter() {
+ wx.closeBluetoothAdapter()
+ this._discoveryStarted = false
+ wx.showToast({
+ title: '断开蓝牙模块',
+ icon: 'none'
+ })
+ this.setData({
+ devices: [],
+ weight: "",
+ text: "",
+ imp: "",
+ isType: false
+ })
+ },
+ // 断开与低功耗蓝牙设备的连接
+ closeBLEConnection() {
+ wx.closeBLEConnection({
+ deviceId: this._deviceId
+ })
+ wx.showToast({
+ title: '断开蓝牙连接',
+ icon: 'none'
+ })
+ this.setData({
+ connected: false,
+ isType: false,
+ devices: [],
+ text: "",
+ weight: "",
+ imp: ""
+ })
+ },
+
+});
diff --git a/pages/PCH0809/index.json b/pages/PCH0809/index.json
new file mode 100644
index 0000000..b55b5a2
--- /dev/null
+++ b/pages/PCH0809/index.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {
+ }
+}
\ No newline at end of file
diff --git a/pages/PCH0809/index.wxml b/pages/PCH0809/index.wxml
new file mode 100644
index 0000000..1998a86
--- /dev/null
+++ b/pages/PCH0809/index.wxml
@@ -0,0 +1,51 @@
+
+ module.exports.max = function(n1, n2) {
+ return Math.max(n1, n2)
+ }
+ module.exports.len = function(arr) {
+ arr = arr || []
+ return arr.length
+ }
+
+
+
+
+
+ {{weight}}
+ {{imp}}
+ {{height}}
+ {{text}}
+
+ 已发现 {{devices.length}} 个外围设备:
+
+
+
+ {{item.name}}
+ (信号强度: {{item.RSSI}}dBm)
+
+ mac地址: {{item.macAddr || item.deviceId}}
+
+
+
+
+
+
+ 标定重量
+
+
+
+
+ 取消
+ 确定
+
+
+
diff --git a/pages/PCH0809/index.wxss b/pages/PCH0809/index.wxss
new file mode 100644
index 0000000..e57bbb6
--- /dev/null
+++ b/pages/PCH0809/index.wxss
@@ -0,0 +1,104 @@
+/* pages/PCH0809/index.wxss */
+.modal_wrapper {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: -1;
+ background: rgba(0, 0, 0, 0.5);
+ transition: .4s all;
+ height: 200vh;
+ opacity: 0;
+}
+
+.modal_wrapper_show {
+ transform: translateY(-100vh);
+ opacity: 1;
+ overflow-x: hidden;
+ overflow-y: auto;
+ z-index: 1000;
+}
+
+.remindModal {
+ position: absolute;
+ bottom: 50vh;
+ left: 50%;
+ z-index: 101;
+ transform: translate(-50%, 50%);
+ background: #fff;
+ width: 600rpx;
+ padding: 40rpx 60rpx;
+ border-radius: 20rpx;
+}
+
+.remindModal_title {
+ padding: 10rpx 30rpx 50rpx;
+ text-align: center;
+ font-size: 32rpx;
+}
+
+.remindModal_content {
+ font-size: 30rpx;
+ line-height: 1.6;
+ text-align: center;
+ padding-top: 30rpx;
+ min-height: 100rpx;
+}
+
+.remindModal_btn {
+ margin-top: 80rpx;
+ margin-bottom: 10rpx;
+ display: flex;
+ justify-content: space-evenly;
+}
+
+.remindModal_cancel_btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 45%;
+ height: 100rpx;
+ border: 1px solid transparent;
+ margin: auto;
+ background: #dfdfdf;
+ color: #fff;
+ font-size: 16px;
+ letter-spacing: 2rpx;
+ border-radius: 10px;
+ white-space: nowrap;
+}
+
+.modal_input_wrap {
+ width: 100%;
+ height: 80rpx;
+ padding: 0 10rpx;
+ border: 1px solid #dcdcdc;
+ border-radius: 10rpx;
+}
+
+.modal_input {
+ width: 100%;
+ height: 100%;
+ padding: 10rpx;
+ font-size: 30rpx;
+}
+
+.confirm_btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 45%;
+ height: 100rpx;
+ border: 1px solid transparent;
+ margin: auto;
+ background: #1977FF;
+ color: #fff;
+ font-size: 16px;
+ letter-spacing: 2rpx;
+ border-radius: 10px;
+ white-space: nowrap;
+}
+
+.item_hover {
+ background-color: rgba(0, 0, 0, .1);
+}
diff --git a/pages/index/index.js b/pages/index/index.js
new file mode 100644
index 0000000..3a44a08
--- /dev/null
+++ b/pages/index/index.js
@@ -0,0 +1,344 @@
+const util = require("../../utils/util");
+const {
+ inArray,
+ ab2hex
+} = util
+
+Page({
+ data: {
+ devices: [],
+ connected: false,
+ cmd: '',
+ name: '',
+ weight: "",
+ text: "",
+ imp: "",
+ deviceId: null,
+ },
+ onLoad: function() {
+ },
+ // 初始化蓝牙模块
+ editclick: function(e) {
+ let type = e.currentTarget.dataset.name
+ if (type == 'PCD01PRO') {
+ wx.navigateTo({
+ url: `/pages/PCD01PRO/index`
+ })
+ return
+ }
+ if (type == 'PCH0809') {
+ wx.navigateTo({
+ url: `/pages/PCH0809/index`
+ })
+ return
+ }
+ },
+ 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, //是否允许重复上报同一设备
+ services: [ //要搜索蓝牙设备主 service 的 uuid 列表
+ "FFE0",
+ ],
+ success: (res) => {
+ console.log('startBluetoothDevicesDiscovery success', res)
+ this.onBluetoothDeviceFound()
+ },
+ })
+ },
+ // 停止搜寻附近的蓝牙外围设备
+ stopBluetoothDevicesDiscovery() {
+ wx.stopBluetoothDevicesDiscovery()
+ },
+
+ // 找到新设备的事件
+ onBluetoothDeviceFound() {
+ wx.onBluetoothDeviceFound((res) => {
+ res.devices.forEach(device => {
+ 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
+ }
+ console.log("131", data)
+ this.setData(data)
+ }
+ })
+ })
+ },
+ // 连接低功耗蓝牙设备
+ createBLEConnection(e) {
+ this._connLoading = true
+ wx.showLoading({
+ title: '连接中',
+ })
+ setTimeout(() => {
+ if (this._connLoading) {
+ this._connLoading = false
+ wx.hideLoading()
+ }
+ }, 6000)
+ 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 => {
+ this._connLoading = false
+ 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: "",
+ 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
+ }
+ }
+ }
+ })
+ },
+
+ // 获取蓝牙设备某个服务中所有特征值(characteristic)
+ /**
+ * read: true读,write: true写,notify: true广播
+ */
+ getBLEDeviceCharacteristics(deviceId, serviceId) {
+ this._deviceId = deviceId
+ this._serviceId = serviceId
+ this._device.serviceId = serviceId
+ wx.getBLEDeviceCharacteristics({
+ deviceId,
+ serviceId,
+ success: (res) => {
+ console.log('getBLEDeviceCharacteristics success', res.characteristics)
+ wx.showLoading({
+ title: '获取特征值成功',
+ })
+ //FFE1:write: true, FFE2:notify: true,FFE3:read: true, write: true, notify: true,
+ for (let i = 0; i < res.characteristics.length; i++) {
+ let characteristic = res.characteristics[i];
+ if (characteristic.uuid.indexOf("FFE2") != -1) {
+ if (characteristic.properties.notify == true) {
+ this.notifyBLECharacteristicValue(deviceId, serviceId, characteristic
+ .uuid)
+ console.log("ffe2服务的notifyId获取成功")
+ }
+ if (characteristic.properties.read == true) {
+ that.readId = characteristic.uuid
+ }
+ if (characteristic.properties.write == true) {
+ that.writeId = characteristic.uuid
+ }
+ break;
+ }
+ }
+ },
+ fail(res) {
+ console.error('getBLEDeviceCharacteristics', res)
+ }
+ })
+ },
+ //解析蓝牙返回数据
+ notifyBLECharacteristicValue(deviceId, serviceId, notifyId) {
+ let that = this
+ wx.notifyBLECharacteristicValueChange({
+ state: true, // 启用 notify 功能
+ deviceId: deviceId,
+ serviceId: serviceId,
+ characteristicId: notifyId,
+ success(res) {
+ wx.onBLECharacteristicValueChange(function(res) {
+ let value = ab2hex(res.value);
+ let num = value.substring(18, 19)
+ let dw = value.substring(19, 20)
+ let typeInfo = value.substring(10, 12)
+ console.log("16进制转化:", value);
+ if (value.length == 26) {
+ let data = parseInt(value.substring(13, 18), 16)
+ let dw1 = "kg"
+ if (dw == "1") {
+ dw1 = "斤"
+ console.log("体重单位:斤")
+ }
+ if (dw == "4") {
+ dw1 = "st:lb"
+ console.log("体重单位:st:lb,计算方法:1 * data + 5")
+ }
+ if (dw == "6") {
+ dw1 = "lb"
+ console.log("体重单位:lb")
+ }
+ if (num == "1") {
+ data = parseInt(value.substring(13, 18), 16) / 10
+ console.log("体重小数点后1位")
+ }
+ if (num == "2") {
+ data = parseInt(value.substring(13, 18), 16) / 100
+ console.log("体重小数点后2位")
+ }
+ if (num == "3") {
+ data = parseInt(value.substring(13, 18), 16) / 1000
+ console.log("体重小数点后3位")
+ }
+ if (typeInfo == "01") {
+ console.log("实时体重:", data)
+ that.setData({
+ weight: "实时体重是:" + data + dw1
+ })
+ }
+ if (typeInfo == "02") {
+ console.log("稳定体重:", data)
+ that.setData({
+ weight: "稳定体重是:" + data + dw1
+ })
+ }
+ }
+ if (value.length == 30) {
+ console.log("阻抗值:", value)
+ if (typeInfo == "03") {
+ let imp = parseInt(value.substring(17, 22), 16)
+ that.setData({
+ imp: "阻抗值:" + imp
+ })
+ }
+
+ }
+ if (value.toUpperCase() == "A90026023000589A") {
+ console.log("测量完成")
+ that.setData({
+ text: "测量完成"
+ })
+ }
+ });
+ },
+ fail(res) {
+ console.log("测量失败", res.value);
+ }
+ });
+ },
+
+ /**
+ * 断开蓝牙模块
+ */
+ closeBluetoothAdapter() {
+ wx.closeBluetoothAdapter()
+ this._discoveryStarted = false
+ wx.showToast({
+ title: '断开蓝牙模块',
+ icon: 'none'
+ })
+ this.setData({
+ devices: [],
+ weight: "",
+ text: "",
+ imp: ""
+ })
+ },
+ // 断开与低功耗蓝牙设备的连接
+ closeBLEConnection() {
+ wx.closeBLEConnection({
+ deviceId: this._deviceId
+ })
+ wx.showToast({
+ title: '断开蓝牙连接',
+ icon: 'none'
+ })
+ this.setData({
+ connected: false,
+ devices: [],
+ text: "",
+ weight: "",
+ imp: ""
+ })
+ },
+
+});
diff --git a/pages/index/index.json b/pages/index/index.json
new file mode 100644
index 0000000..b55b5a2
--- /dev/null
+++ b/pages/index/index.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {
+ }
+}
\ No newline at end of file
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
new file mode 100644
index 0000000..fd90807
--- /dev/null
+++ b/pages/index/index.wxml
@@ -0,0 +1,16 @@
+
+ module.exports.max = function(n1, n2) {
+ return Math.max(n1, n2)
+ }
+ module.exports.len = function(arr) {
+ arr = arr || []
+ return arr.length
+ }
+
+
+
+
+ PCD01PRO
+ PCH08/09
+
+
diff --git a/project.config.json b/project.config.json
new file mode 100644
index 0000000..327660f
--- /dev/null
+++ b/project.config.json
@@ -0,0 +1,71 @@
+{
+ "description": "项目配置文件",
+ "packOptions": {
+ "ignore": []
+ },
+ "setting": {
+ "urlCheck": true,
+ "es6": false,
+ "enhance": true,
+ "postcss": true,
+ "preloadBackgroundData": false,
+ "minified": true,
+ "newFeature": false,
+ "coverView": true,
+ "nodeModules": false,
+ "autoAudits": false,
+ "showShadowRootInWxmlPanel": true,
+ "scopeDataCheck": false,
+ "uglifyFileName": false,
+ "checkInvalidKey": true,
+ "checkSiteMap": true,
+ "uploadWithSourceMap": true,
+ "compileHotReLoad": false,
+ "lazyloadPlaceholderEnable": false,
+ "useMultiFrameRuntime": true,
+ "useApiHook": true,
+ "useApiHostProcess": false,
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ },
+ "useIsolateContext": true,
+ "userConfirmedBundleSwitch": false,
+ "packNpmManually": false,
+ "packNpmRelationList": [],
+ "minifyWXSS": true,
+ "showES6CompileOption": false
+ },
+ "compileType": "miniprogram",
+ "libVersion": "2.16.0",
+ "projectname": "bluetooth_demo",
+ "debugOptions": {
+ "hidedInDevtools": []
+ },
+ "scripts": {},
+ "isGameTourist": false,
+ "simulatorType": "wechat",
+ "simulatorPluginLibVersion": {},
+ "appid": "wxcea3504a31518eb6",
+ "condition": {
+ "search": {
+ "list": []
+ },
+ "conversation": {
+ "list": []
+ },
+ "game": {
+ "list": []
+ },
+ "plugin": {
+ "list": []
+ },
+ "gamePlugin": {
+ "list": []
+ },
+ "miniprogram": {
+ "list": []
+ }
+ }
+}
\ No newline at end of file
diff --git a/sitemap.json b/sitemap.json
new file mode 100644
index 0000000..ca02add
--- /dev/null
+++ b/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file
diff --git a/utils/util.js b/utils/util.js
new file mode 100644
index 0000000..b00f2de
--- /dev/null
+++ b/utils/util.js
@@ -0,0 +1,30 @@
+function inArray(arr, key, val) {
+ if (!arr || !arr.length || typeof arr != 'object' || !Array.isArray(arr)) {
+ return -1
+ }
+ for (let i = 0; i < arr.length; i++) {
+ if (!key) {
+ if (arr[i] == val) {
+ return i
+ }
+ } else if (arr[i][key] === val) {
+ return i
+ }
+ }
+ return -1;
+}
+
+// ArrayBuffer转16进度字符串示例
+function ab2hex(buffer) {
+ var hexArr = Array.prototype.map.call(
+ new Uint8Array(buffer),
+ function(bit) {
+ return ('00' + bit.toString(16)).slice(-2)
+ }
+ )
+ return hexArr.join("");
+}
+module.exports = {
+ inArray,
+ ab2hex,
+}