230 lines
6.5 KiB
JavaScript
Raw Normal View History

2025-06-06 15:17:30 +08:00
Page({
data: {
devices: [],
isSearching: false,
status: '未连接',
connected: false,
skipCount: 0,
connectedDeviceId: null,
deviceServices: [],
deviceCharacteristics: []
},
// 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('设备服务', res.services);
this.setData({
deviceServices: res.services
});
// 获取第一个服务的特征值
if (res.services.length > 0) {
this.getDeviceCharacteristics(deviceId, res.services[0].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.startFreeJumpRope(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.handleReceivedData(res.value);
}
});
}
});
},
// 发送启动自由跳绳命令
startFreeJumpRope(deviceId, serviceId) {
const command = 3; // 启动自由跳绳的命令
const code = 1;
const parameter = 0; // 启动自由跳绳参数为0
// 获取蓝牙设备的特征值(特征值应是你已经连接的蓝牙设备的写入特征值)
const characteristic = this.data.deviceCharacteristics.find(c => c.properties.write);
if (!characteristic) {
console.error('没有可写的特征值');
return;
}
// 构建命令数据
const commandData = new ArrayBuffer(4);
const dataView = new DataView(commandData);
dataView.setUint8(0, 0x03);
dataView.setUint8(1, 0x01);
dataView.setUint8(2, 0x00);
dataView.setUint8(3, 0x00);
// 发送命令到设备
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristic.uuid,
value: commandData,
success: () => {
console.log("自由跳绳已启动!");
},
fail: (error) => {
console.error("启动自由跳绳失败", error);
}
});
},
// 处理接收到的数据
handleReceivedData(arrayBuffer) {
// 1. 创建 Int16Array 视图(从 ArrayBuffer 读取)
const int16Array = new Int16Array(arrayBuffer);
// 2. 检查长度是否足够(至少 3 个元素)
if (int16Array.length < 3) {
console.error("Int16Array length is too short!");
return;
}
// 3. 读取索引 2 的值
const value = int16Array[2];
// 4. 更新数据
this.setData({ skipCount: value });
},
// 4. 断开连接
disconnectDevice() {
wx.closeBLEConnection({
deviceId: this.data.connectedDeviceId,
success: () => {
console.log('断开连接');
this.setData({
status: '未连接',
connected: false
});
}
});
}
});