325 lines
8.7 KiB
JavaScript
325 lines
8.7 KiB
JavaScript
Page({
|
|
data: {
|
|
devices: [],
|
|
isSearching: false,
|
|
status: '未连接',
|
|
connected: false,
|
|
skipCount: 0,
|
|
connectedDeviceId: null,
|
|
deviceServices: [],
|
|
deviceCharacteristics: [],
|
|
intervalId: null // 用于存储定时器ID
|
|
},
|
|
|
|
// 1. 初始化蓝牙模块
|
|
startBluetooth() {
|
|
wx.openBluetoothAdapter({
|
|
success: () => {
|
|
console.log('蓝牙初始化成功');
|
|
wx.showToast({ title: '蓝牙已开启', icon: 'success' });
|
|
},
|
|
fail: (res) => {
|
|
console.error('蓝牙初始化失败', res);
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '请打开手机蓝牙并授权小程序使用',
|
|
showCancel: false,
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
// 2. 搜索设备
|
|
searchDevices() {
|
|
this.setData({ isSearching: true, devices: [] });
|
|
|
|
// 启动搜索
|
|
wx.startBluetoothDevicesDiscovery({
|
|
allowDuplicatesKey: false,
|
|
success: () => {
|
|
console.log('开始搜索设备');
|
|
// 监听发现设备事件
|
|
wx.onBluetoothDeviceFound((res) => {
|
|
console.log('发现新设备', res.devices);
|
|
res.devices.forEach(device => {
|
|
if (device.name || device.localName) {
|
|
const exists = this.data.devices.find(d => d.deviceId === device.deviceId);
|
|
if (!exists) {
|
|
this.setData({
|
|
devices: [...this.data.devices, device]
|
|
});
|
|
}
|
|
}
|
|
});
|
|
});
|
|
},
|
|
fail: (err) => {
|
|
console.error('搜索设备失败', err);
|
|
wx.showToast({ title: '搜索失败', icon: 'error' });
|
|
this.setData({ isSearching: false });
|
|
}
|
|
});
|
|
|
|
// 设置超时自动停止
|
|
setTimeout(() => {
|
|
wx.stopBluetoothDevicesDiscovery();
|
|
this.setData({ isSearching: false });
|
|
console.log('停止搜索');
|
|
}, 10000); // 10秒后停止
|
|
},
|
|
|
|
// 3. 连接设备
|
|
connectDevice(e) {
|
|
const device = e.currentTarget.dataset.device;
|
|
console.log('尝试连接设备', device);
|
|
|
|
wx.createBLEConnection({
|
|
deviceId: device.deviceId,
|
|
success: () => {
|
|
console.log('连接成功', device.deviceId);
|
|
this.setData({
|
|
status: '已连接',
|
|
connected: true,
|
|
connectedDeviceId: device.deviceId
|
|
});
|
|
|
|
// 获取设备的服务
|
|
this.getDeviceServices(device.deviceId);
|
|
},
|
|
fail: (err) => {
|
|
console.error('连接失败', err);
|
|
wx.showToast({ title: '连接失败', icon: 'error' });
|
|
}
|
|
});
|
|
},
|
|
|
|
// 获取设备的服务
|
|
getDeviceServices(deviceId) {
|
|
wx.getBLEDeviceServices({
|
|
deviceId: deviceId,
|
|
success: (res) => {
|
|
console.log('uuid',res.services[1].uuid);
|
|
console.log('设备服务', res.services);
|
|
this.setData({
|
|
deviceServices: res.services
|
|
});
|
|
|
|
// 获取第一个服务的特征值
|
|
if (res.services.length > 0) {
|
|
console.log('uuid',res.services[1].uuid);
|
|
this.getDeviceCharacteristics(deviceId, res.services[1].uuid);
|
|
}
|
|
},
|
|
fail: (err) => {
|
|
console.error('获取服务失败', err);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 获取第一个服务的特征值
|
|
getDeviceCharacteristics(deviceId, serviceId) {
|
|
wx.getBLEDeviceCharacteristics({
|
|
deviceId: deviceId,
|
|
serviceId: serviceId,
|
|
success: (res) => {
|
|
console.log('服务特征值', res.characteristics);
|
|
this.setData({
|
|
deviceCharacteristics: res.characteristics
|
|
});
|
|
// 启动接收数据通知
|
|
this.startNotify(deviceId, serviceId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 发送启动和获取计数命令
|
|
this.sendCommandJump(deviceId, serviceId,'Clean Count');
|
|
this.sendCommandJump(deviceId, serviceId,'Start Count');
|
|
this.sendCommandJump(deviceId, serviceId,'Get CT');
|
|
// this.sendGetCountCommandJump(deviceId, serviceId);
|
|
},
|
|
fail: (err) => {
|
|
console.error('获取特征值失败', err);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 启动接收数据通知
|
|
startNotify(deviceId, serviceId) {
|
|
const characteristics = this.data.deviceCharacteristics;
|
|
characteristics.forEach(characteristic => {
|
|
if (characteristic.properties.notify) {
|
|
wx.notifyBLECharacteristicValueChange({
|
|
deviceId: deviceId,
|
|
serviceId: serviceId,
|
|
characteristicId: characteristic.uuid,
|
|
state: true,
|
|
success: () => {
|
|
console.log('启动数据通知');
|
|
},
|
|
fail: (err) => {
|
|
console.error('启动通知失败', err);
|
|
}
|
|
});
|
|
// 接收数据
|
|
wx.onBLECharacteristicValueChange((res) => {
|
|
console.log('接收到数据', res.value);
|
|
if (res.deviceId === deviceId && res.characteristicId === characteristic.uuid) {
|
|
console.log('接收到数据', res.value);
|
|
this.handleReceivedDataJump(res.value);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// 每1秒发送一次获取计数命令
|
|
this.intervalId = setInterval(() => {
|
|
this.sendGetCountCommandJump(deviceId, serviceId);
|
|
}, 1000); // 1000 毫秒 = 1秒
|
|
},
|
|
|
|
// 发送清除命令
|
|
sendCleanCommandJump(deviceId, serviceId) {
|
|
const writeCharacteristic = this.data.deviceCharacteristics.find(c => c.properties.write);
|
|
if (!writeCharacteristic) {
|
|
console.error('没有可写的特征值');
|
|
return;
|
|
}
|
|
const startCommand = "$Clean Count!";
|
|
const commandData = this.stringToArrayBuffer(startCommand);
|
|
wx.writeBLECharacteristicValue({
|
|
deviceId: deviceId,
|
|
serviceId: serviceId,
|
|
characteristicId: writeCharacteristic.uuid,
|
|
value: commandData,
|
|
success: () => {
|
|
console.log("启动命令发送成功");
|
|
},
|
|
fail: (error) => {
|
|
console.error("启动命令发送失败", error);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 发送启动/暂停/恢复/清零/结束 获取计数命令
|
|
sendCommandJump(deviceId, serviceId,codeStr) {
|
|
const writeCharacteristic = this.data.deviceCharacteristics.find(c => c.properties.write);
|
|
if (!writeCharacteristic) {
|
|
console.error('没有可写的特征值');
|
|
return;
|
|
}
|
|
const startCommand = `$${codeStr}!`;
|
|
const commandData = this.stringToArrayBuffer(startCommand);
|
|
wx.writeBLECharacteristicValue({
|
|
deviceId: deviceId,
|
|
serviceId: serviceId,
|
|
characteristicId: writeCharacteristic.uuid,
|
|
value: commandData,
|
|
success: () => {
|
|
console.log(codeStr,"命令发送成功");
|
|
},
|
|
fail: (error) => {
|
|
console.error(codeStr,"命令发送失败", error);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 发送获取计数命令
|
|
sendGetCountCommandJump(deviceId, serviceId) {
|
|
const writeCharacteristic = this.data.deviceCharacteristics.find(c => c.properties.write);
|
|
if (!writeCharacteristic) {
|
|
console.error('没有可写的特征值');
|
|
return;
|
|
}
|
|
const getCommand = "$Get CT!";
|
|
const commandData = this.stringToArrayBuffer(getCommand);
|
|
wx.writeBLECharacteristicValue({
|
|
deviceId: deviceId,
|
|
serviceId: serviceId,
|
|
characteristicId: writeCharacteristic.uuid,
|
|
value: commandData,
|
|
success: () => {
|
|
console.log("获取计数命令发送成功");
|
|
},
|
|
fail: (error) => {
|
|
console.error("获取计数命令发送失败", error);
|
|
}
|
|
});
|
|
},
|
|
|
|
// 处理接收到的数据
|
|
handleReceivedDataJump(arrayBuffer) {
|
|
const uint8Array = new Uint8Array(arrayBuffer);
|
|
const resultString = this.arrayBufferToString(uint8Array.buffer);
|
|
const value = this.extractNumber(resultString);
|
|
console.log("解析结果:", value);
|
|
this.setData({ skipCount: value });
|
|
},
|
|
|
|
// 将 ArrayBuffer 转换为字符串
|
|
arrayBufferToString(buffer) {
|
|
const view = new Uint8Array(buffer);
|
|
let result = '';
|
|
for (let i = 0; i < view.length; i++) {
|
|
result += String.fromCharCode(view[i]);
|
|
}
|
|
return result;
|
|
},
|
|
|
|
// 提取数字部分
|
|
extractNumber(input) {
|
|
const match = input.match(/^\$(0*)(\d+),/);
|
|
if (match) {
|
|
return match[2].replace(/^0+/, ''); // 去除前导零
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// 将字符串转为 ArrayBuffer
|
|
stringToArrayBuffer(str) {
|
|
const buffer = new ArrayBuffer(str.length);
|
|
const view = new Uint8Array(buffer);
|
|
for (let i = 0; i < str.length; i++) {
|
|
view[i] = str.charCodeAt(i) & 0xFF;
|
|
}
|
|
return buffer;
|
|
},
|
|
|
|
// 断开连接
|
|
disconnectDevice() {
|
|
// 停止定时器
|
|
if (this.intervalId) {
|
|
clearInterval(this.intervalId);
|
|
}
|
|
|
|
wx.closeBLEConnection({
|
|
deviceId: this.data.connectedDeviceId,
|
|
success: () => {
|
|
console.log('断开连接');
|
|
this.setData({
|
|
status: '未连接',
|
|
connected: false
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|