【前言】
在手机随手都在的时代,使用微信小程可以方便的对周围的蓝牙设备进行交互,是大趋势,而且可以跨平台。虽然官方提供了非常好的APP,但是如果自己能写一个小程序,来实现对STM32WBA55CG的控制,那不是挺有成就感。这一篇就分享如何制一个自己的微信小序来实现既定的功能。
【准备工作】
安装一个微信小程序开发工具,并注册一个用户。
他的教程在微信官方示例时有很多入门级的教程。
developers.weixin.qq.com/miniprogram/dev/framework/
这里提供了非常详细的教程。大家花个几个小时就可以开始自己的微信小程制作了。
【实现步骤】
1、进入****:连接硬件能力 / 蓝牙 / 介绍
在他的底部有一个在开发者工具中预览效果的链接,点击之后就可以导入一个蓝牙的基础项目了。
2、新建一个页面,里面放置一个开关,与两个显示温度、湿度的控件,编写的他代码如下:
device.wxml
<view class="connected_info" wx:if="{{connected}}"> <view> <text>已连接到 {{name}}</text> <view class="operation"> <button wx:if="{{canWrite}}" size="mini" bindtap="writeBLECharacteristicValue">写数据</button> <button size="mini" bindtap="closeBLEConnection">断开连接</button> </view> </view> <view wx:for="{{chs}}" wx:key="index" style="font-size: 12px; margin-top: 10px;"> <view>特性UUID: {{item.uuid}}</view> <view>特性值: {{item.value}}</view> </view> </view> <view class="container"> <!-- 开关按键 --> <switch checked="{{switchChecked}}" bindchange="switchChange" /> <!-- 温度显示控件 --> <view class="display-item"> <text>温度:</text> <text>{{temperature}}°C</text> </view> <!-- 湿度显示控件 --> <view class="display-item"> <text>湿度:</text> <text>{{humidity}}%</text> </view> </view>
2、device.wxss:
.container { display: flex; flex-direction: column; align-items: center; padding: 20rpx; } .switch { margin-bottom: 30rpx; } .display-item { display: flex; align-items: center; margin-bottom: 20rpx; } .display-item text:first-child { margin-right: 10rpx; font-weight: bold; }
3、device.js:
const app = getApp() function inArray(arr, key, val) { for (let i = 0; i < arr.length; i++) { 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(''); } Page({ data: { deviceId: null, name:null, inputValue: '', connected: false, chs: [], temperature: '25', humidity: '60', switchChecked: false, // 开关初始状态为关闭 }, onLoad: function(options) { const deviceId = app.globalData.deviceId; const name = app.globalData.name; console.log('name:' + name) console.log('deviceId:' + deviceId) wx.createBLEConnection({ deviceId, success: (res) => { this.setData({ connected: true, name, deviceId, }) this.getBLEDeviceServices(deviceId) } }) }, getBLEDeviceServices(deviceId) { wx.getBLEDeviceServices({ deviceId, success: (res) => { for (let i = 0; i < res.services.length; i++) { if (res.services[i].isPrimary) { this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid) return } } } }) }, getBLEDeviceCharacteristics(deviceId, serviceId) { 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.properties.read) { wx.readBLECharacteristicValue({ deviceId, serviceId, characteristicId: item.uuid, }) } if (item.properties.write) { this.setData({ canWrite: true }) this._deviceId = deviceId this._serviceId = serviceId this._characteristicId = item.uuid this.writeBLECharacteristicValue() } if (item.properties.notify || item.properties.indicate) { wx.notifyBLECharacteristicValueChange({ deviceId, serviceId, characteristicId: item.uuid, state: true, }) } } }, fail(res) { console.error('getBLEDeviceCharacteristics', res) } }) // 操作之前先监听,保证第一时间获取数据 wx.onBLECharacteristicValueChange((characteristic) => { const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId) const data = {} if (idx === -1) { data[`chs[${this.data.chs.length}]`] = { uuid: characteristic.characteristicId, value: ab2hex(characteristic.value) } } else { data[`chs[${idx}]`] = { uuid: characteristic.characteristicId, value: ab2hex(characteristic.value) } } if(characteristic.characteristicId == '0000FE42-8E22-4541-9D4C-21EDAE82ED19') { let dataView = new DataView(characteristic.value) const temp = (dataView.getUint8(0))*10 + dataView.getUint8(1); const hum = dataView.getUint8(2)*10 + dataView.getUint8(3); this.setData({ humidity: hum, temperature: temp, }) } this.setData(data); }) }, writeBLECharacteristicValue() { // 向蓝牙设备发送一个0x00的16进制数据 let buffer = new ArrayBuffer(2) let dataView = new DataView(buffer) dataView.setUint8(0, 0); dataView.setUint8(0, 1); wx.writeBLECharacteristicValue({ deviceId: this._deviceId, serviceId: this._serviceId, characteristicId: this._characteristicId, value: buffer, success (res) { console.log('writeBLECharacteristicValue success', res.errMsg) }, fail (err) { console.log('writeBLECharacteristicValue fail', err.errMsg) } }) }, switchChange: function (e) { // 获取开关改变后的状态值 const checked = e.detail.value; let buffer = new ArrayBuffer(2) let dataView = new DataView(buffer) dataView.setUint8(0, 0); if(checked){ // 向蓝牙设备发送一个0x00的16进制数据 dataView.setUint8(1, 1); }else{ dataView.setUint8(1, 0); } wx.writeBLECharacteristicValue({ deviceId: this._deviceId, serviceId: this._serviceId, characteristicId: this._characteristicId, value: buffer, success (res) { console.log('writeBLECharacteristicValue success', res.errMsg) }, fail (err) { console.log('writeBLECharacteristicValue fail', err.errMsg) } }) this.setData({ switchChecked: checked }); } })
在app.js中添加全局变量用于传递参数:
App({ globalData: { deviceId: "", name: "", chs: [], }, onLaunch: function () { } })
修改index.js的查找到服务的转接与参数保存:
createBLEConnection(e) { const ds = e.currentTarget.dataset const deviceId = ds.deviceId const name = ds.name // 添加跳转函数 app.globalData.deviceId = deviceId; app.globalData.name = name; wx.navigateTo({ url: 'device' })
这样就完成了微信小程序的制作。
使用方法:
打开微信小程序,点击开始扫描,搜索到有Peer to Peer Server设备,点击后就跳转到数据展示与控制的页面:
到此,我们就实现了开关与关闭开发板的LED灯,同时也可以获取到开发板的温湿度。
【总结】
使用微信小程序,可以轻松通过手机与蓝牙设备的交互。