开发者必备:【物联网设备】蓝牙微信小程序测试工具(自开发)

目录

一、蓝牙微信小程序测试工具应用场景

二、蓝牙微信小程序测试工具开发实现思路

三、需要处理的问题

四、微信小程序蓝牙API

五、代码示例

六、主要功能说明

七、优化后代码

八、开发与测试建议

在物联网(IoT)设备开发中,蓝牙功能的测试至关重要。为了帮助开发者更高效、便捷地进行蓝牙设备测试,我们可以自己开发了一款专用的蓝牙微信小程序测试工具。用作开发测试或者量产测试。

一、蓝牙微信小程序测试工具应用场景

适用场景:

  • 物联网设备开发者:用于测试蓝牙设备的各项功能和性能。
  • 嵌入式系统开发者:用于调试蓝牙模块和协议。
  • 移动应用开发者:用于验证蓝牙功能的集成和交互。
  • 对蓝牙设备有兴趣的爱好者。

二、蓝牙微信小程序测试工具开发实现思路

1.检查蓝牙适配器状态,请求授权。

2.初始化蓝牙适配器,开始扫描设备。

3.在扫描过程中收集设备信息,包括RSSI。

4.展示设备列表,点击后连接设备。

5.连接后获取服务,找到特征值,订阅通知或读取数据。

6.定时更新信号强度,或者通过监听设备更新来获取最新RSSI。

7.处理断开连接和错误情况。

三、需要处理的问题

  • 设备重复出现在列表中,需要根据deviceId去重。

  • 扫描过程中如何处理设备更新,可能需要使用数组更新并重新渲染。

  • 连接设备时的异步操作,需要正确处理回调或Promise。

  • 信号强度的更新频率,避免过于频繁导致性能问题。

  • 用户界面友好,显示连接状态和日志信息。

四、微信小程序蓝牙API

微信小程序提供了丰富的蓝牙 API,用于搜索、连接和操作蓝牙设备。详细的 API 文档是开发的基础。

蓝牙 (Bluetooth) | 微信开放文档

重点关注以下 API:

  • wx.openBluetoothAdapter:初始化蓝牙模块。

  • wx.startBluetoothDevicesDiscovery:开始搜索附近的蓝牙设备。

  • wx.stopBluetoothDevicesDiscovery:停止搜索。

  • wx.createBLEConnection:连接到指定的蓝牙设备。

  • wx.closeBLEConnection:断开连接。

  • wx.getBLEDeviceServices:获取蓝牙设备的服务。

  • wx.getBLEDeviceCharacteristics:获取蓝牙服务的特征值。

  • wx.readBLECharacteristicValue:读取特征值。

  • wx.writeBLECharacteristicValue:写入特征值。

  • wx.notifyBLECharacteristicValueChange:启用特征值变化通知。

五、代码示例

以下是一个基于微信小程序的蓝牙测试工具示例代码,包含蓝牙设备扫描、信号强度检测和基础连接功能:

// app.json 配置
{
  "pages": ["index/index"],
  "window": {
    "navigationBarTitleText": "蓝牙信号测试"
  },
  "permission": {
    "scope.userLocation": {
      "desc": "需要获取位置权限以使用蓝牙功能"
    }
  }
}
// index/index.js
Page({
  data: {
    devices: [],       // 发现的设备列表
    connected: false,  // 连接状态
    logs: [],          // 操作日志
    scanning: false    // 扫描状态
  },

  onLoad() {
    this.initBluetooth();
  },

  // 初始化蓝牙适配器
  initBluetooth() {
    const that = this;
    wx.openBluetoothAdapter({
      success() {
        that.log('蓝牙适配器初始化成功');
        wx.getBluetoothAdapterState({
          success(res) {
            that.log(`当前蓝牙状态:${res.available ? '可用' : '不可用'}`);
          }
        });
      },
      fail(err) {
        that.log('蓝牙初始化失败: ' + JSON.stringify(err));
      }
    });
  },

  // 开始扫描设备
  startScan() {
    const that = this;
    if (this.data.scanning) return;

    this.setData({ scanning: true });
    this.log('开始扫描蓝牙设备...');

    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success() {
        that.log('扫描启动成功');
        wx.onBluetoothDeviceFound((res) => {
          res.devices.forEach(device => {
            if (!device.name && !device.localName) return;
            that.updateDeviceList(device);
          });
        });
      }
    });
  },

  // 更新设备列表
  updateDeviceList(device) {
    const devices = this.data.devices;
    const index = devices.findIndex(d => d.deviceId === device.deviceId);

    const info = {
      name: device.name || device.localName,
      deviceId: device.deviceId,
      rssi: device.RSSI,
      advertisData: device.advertisData
    };

    if (index === -1) {
      devices.push(info);
    } else {
      devices[index] = info;
    }

    this.setData({ devices });
  },

  // 停止扫描
  stopScan() {
    const that = this;
    wx.stopBluetoothDevicesDiscovery({
      success() {
        that.setData({ scanning: false });
        that.log('已停止扫描');
      }
    });
  },

  // 连接设备
  connectDevice(e) {
    const deviceId = e.currentTarget.dataset.deviceId;
    const device = this.data.devices.find(d => d.deviceId === deviceId);
    const that = this;

    this.log(`正在连接 ${device.name}...`);
    
    wx.createBLEConnection({
      deviceId,
      success() {
        that.setData({ connected: true });
        that.log('连接成功');
        that.getBLEDeviceServices(deviceId);
      },
      fail(err) {
        that.log('连接失败: ' + JSON.stringify(err));
      }
    });
  },

  // 获取设备服务
  getBLEDeviceServices(deviceId) {
    const that = this;
    wx.getBLEDeviceServices({
      deviceId,
      success(res) {
        res.services.forEach(serviceId => {
          if (serviceId.isPrimary) {
            that.getBLEDeviceCharacteristics(deviceId, serviceId.uuid);
          }
        });
      }
    });
  },

  // 获取特征值
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success(res) {
        res.characteristics.forEach(characteristic => {
          if (characteristic.properties.notify) {
            // 启用特征值订阅
            wx.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: characteristic.uuid,
              state: true
            });
          }
        });
      }
    });
  },

  // 断开连接
  disconnect() {
    const that = this;
    wx.closeBLEConnection({
      deviceId: this.data.currentDeviceId,
      success() {
        that.setData({ connected: false });
        that.log('已断开连接');
      }
    });
  },

  // 日志记录
  log(msg) {
    const logs = this.data.logs;
    logs.unshift(msg);
    this.setData({ logs: logs.slice(0, 50) }); // 最多保留50条
  },

  onUnload() {
    this.stopScan();
    if (this.data.connected) this.disconnect();
    wx.closeBluetoothAdapter();
  }
})
<!-- index/index.wxml -->
<view class="container">
  <view class="controls">
    <button 
      type="primary" 
      bindtap="startScan"
      disabled="{{scanning}}"
    >开始扫描</button>
    <button 
      type="warn" 
      bindtap="stopScan"
      disabled="{{!scanning}}"
    >停止扫描</button>
    <button 
      type="{{connected ? 'warn' : 'default'}}" 
      bindtap="disconnect"
      disabled="{{!connected}}"
    >{{connected ? '断开连接' : '未连接'}}</button>
  </view>

  <view class="device-list">
    <view wx:for="{{devices}}" 
          wx:key="deviceId"
          class="device-item"
          bindtap="connectDevice"
          data-device-id="{{item.deviceId}}">
      <text class="device-name">{{item.name}}</text>
      <view class="device-info">
        <text>信号强度: {{item.rssi}} dBm</text>
        <text>MAC: {{item.deviceId}}</text>
      </view>
    </view>
  </view>

  <view class="log-area">
    <text class="log-title">操作日志:</text>
    <scroll-view scroll-y style="height: 200px;">
      <text wx:for="{{logs}}" class="log-item">{{item}}\n</text>
    </scroll-view>
  </view>
</view>
/* index/index.wxss */
.container {
  padding: 20rpx;
}

.controls {
  margin-bottom: 20rpx;
  display: flex;
  justify-content: space-between;
}

.device-item {
  padding: 20rpx;
  border-bottom: 1rpx solid #eee;
}

.device-name {
  font-weight: bold;
  display: block;
  margin-bottom: 10rpx;
}

.device-info {
  display: flex;
  justify-content: space-between;
  color: #666;
  font-size: 24rpx;
}

.log-area {
  margin-top: 40rpx;
  border-top: 1rpx solid #eee;
  padding-top: 20rpx;
}

.log-title {
  font-weight: bold;
  display: block;
  margin-bottom: 10rpx;
}

.log-item {
  font-size: 24rpx;
  color: #666;
  display: block;
  line-height: 1.6;
}

六、主要功能说明

1.蓝牙信号检测

  • 通过RSSI值显示信号强度(单位dBm)

  • 数值越接近0表示信号越强(通常-50dBm为优良信号,-90dBm以下为弱信号)

2.核心功能

  • 蓝牙设备扫描与展示

  • 实时信号强度显示

  • 设备连接/断开

  • 服务与特征值发现

  • 数据通信支持

3.使用注意事项

  • 需要用户授权蓝牙和位置权限

  • iOS可能需要位置权限才能扫描BLE设备

  • 不同设备RSSI测量方式可能有差异

  • 保持设备在有效通信范围内(通常10米内)

4.测试扩展方向

  • 增加信号强度变化折线图

  • 添加数据收发测试功能

  • 实现自动信号质量评估

  • 增加设备过滤功能

  • 支持信号强度历史记录

七、优化后代码

// app.js
App({
  onLaunch() {
    console.log('App Launching...');
  }
});

// pages/index/index.js
Page({
  data: {
    devices: [], // 存储扫描到的蓝牙设备
    connectedDeviceId: null, // 已连接的设备ID
    serviceId: null, // 选定的服务ID
    characteristicId: null, // 选定的特征值ID
    receivedData: '', // 接收到的数据
    deviceFilter: '' // 设备名称过滤关键字
  },

  onLoad() {
    this.checkBluetoothPermission(); // 检查并请求蓝牙权限
  },

  // 检查并请求蓝牙权限
  checkBluetoothPermission() {
    wx.getSetting({
      success: res => {
        if (!res.authSetting['scope.bluetooth']) {
          wx.authorize({
            scope: 'scope.bluetooth',
            success: this.openBluetooth,
            fail: () => {
              console.error('Bluetooth permission denied');
              wx.showModal({
                title: 'Permission Required',
                content: 'This app requires Bluetooth access. Please enable it in settings.',
                showCancel: false
              });
            }
          });
        } else {
          this.openBluetooth();
        }
      }
    });
  },

  // 初始化蓝牙适配器
  openBluetooth() {
    wx.openBluetoothAdapter({
      success: this.startDiscovery,
      fail: err => console.error('Bluetooth initialization failed', err)
    });
  },

  // 开始扫描蓝牙设备
  startDiscovery() {
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: false,
      success: this.getDevices,
      fail: err => console.error('Discovery failed', err)
    });
  },

  // 获取扫描到的蓝牙设备
  getDevices() {
    wx.onBluetoothDeviceFound(res => {
      const newDevices = res.devices
        .filter(device => device.RSSI > -70)
        .filter(device => !this.data.deviceFilter || (device.name && device.name.includes(this.data.deviceFilter)))
        .map(device => ({
          name: device.name || 'Unknown',
          deviceId: device.deviceId,
          RSSI: device.RSSI
        }));
      
      this.setData({ devices: [...this.data.devices, ...newDevices] });
    });
  },

  // 设置设备过滤关键字
  setDeviceFilter(event) {
    this.setData({ deviceFilter: event.detail.value });
  },

  // 连接选中的蓝牙设备
  connectDevice(event) {
    const deviceId = event.currentTarget.dataset.id;
    wx.createBLEConnection({
      deviceId,
      success: () => {
        console.log('Connected to', deviceId);
        this.setData({ connectedDeviceId: deviceId });
        this.getServices(deviceId);
      },
      fail: err => console.error('Connection failed', err)
    });
  },

  // 获取设备的所有服务
  getServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: res => {
        if (res.services.length > 0) {
          this.getCharacteristics(deviceId, res.services[0].uuid);
        }
      }
    });
  },

  // 获取设备服务的所有特征值
  getCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: res => {
        if (res.characteristics.length > 0) {
          this.setData({
            serviceId: serviceId,
            characteristicId: res.characteristics[0].uuid
          });
          this.enableNotify(deviceId, serviceId, res.characteristics[0].uuid);
        }
      }
    });
  },

  // 发送数据到蓝牙设备
  sendData() {
    const { connectedDeviceId, serviceId, characteristicId } = this.data;
    if (!connectedDeviceId || !serviceId || !characteristicId) return;
    
    const buffer = new ArrayBuffer(1);
    new DataView(buffer).setUint8(0, 1);
    
    wx.writeBLECharacteristicValue({
      deviceId: connectedDeviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      value: buffer,
      success: () => console.log('Data sent successfully'),
      fail: err => console.error('Failed to send data', err)
    });
  },

  // 开启 notify 监听特征值变化
  enableNotify(deviceId, serviceId, characteristicId) {
    wx.notifyBLECharacteristicValueChange({
      deviceId,
      serviceId,
      characteristicId,
      state: true,
      success: () => console.log('Notify enabled for', characteristicId),
      fail: err => console.error('Enable notify failed', err)
    });

    wx.onBLECharacteristicValueChange(res => {
      const receivedData = new Uint8Array(res.value).join(',');
      this.setData({ receivedData });
      console.log('Received data:', receivedData);
    });
  }
});

八、开发与测试建议

  • 真机测试:
    • 蓝牙功能的测试必须在真机上进行,微信开发者工具的模拟器可能无法提供准确的结果。
    • 在不同型号的手机上进行测试,确保兼容性。
  • 调试技巧:
    • 利用微信开发者工具的调试功能,查看蓝牙通信的日志和数据。
    • 使用第三方蓝牙调试工具,辅助分析蓝牙通信协议。
  • 用户体验优化:
    • 提供清晰的加载提示和操作反馈,避免用户感到困惑。
    • 优化蓝牙连接和数据传输的性能,减少延迟。

 

扩展阅读:

开发者必备【5款蓝牙调试工具】-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

34号树洞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值