一、添加蓝牙权限:

1.添加蓝牙权限(工程/app.json):

{...,"permission": {"scope.bluetooth": {"desc": "BLE蓝牙开发"},"scope.userLocation": {"desc": "BLE蓝牙开发定位"},"scope.userLocationBackground": {"desc": "BLE蓝牙开发后台定位"}}
}

二、实现扫描/连接/接收BLE设备数据:

1.实现BLE蓝牙设备扫描:

const TIMEOUT = 10000;
var isInit = false
var isScanning = false
var timer = null
var mTimeout = TIMEOUT;
//开始扫描
function startScan({timeout = TIMEOUT,onFindCallback,onStopCallback
}) {if (isScanning) returnconsole.log('0.开始初始化蓝牙 >>>>>>')mTimeout = timeoutlistenerScanResult(onFindCallback) //监听扫描结果wx.openBluetoothAdapter({ // 初始化蓝牙mode: 'central', //小程序作为中央设备success: (res) => { //初始化蓝牙成功isScanning = trueconsole.log('1.开始扫描设备 >>>>>>')wx.startBluetoothDevicesDiscovery({allowDuplicatesKey: false}) //开始搜索蓝牙设备startTimer(onStopCallback)},fail: (res) => { //初始化蓝牙失败if (res.errCode !== 10001) returnwx.onBluetoothAdapterStateChange((res) => {if (!res.available) returnisScanning = trueconsole.log('1.开始扫描设备 >>>>>>')wx.startBluetoothDevicesDiscovery({allowDuplicatesKey: false}) //开始搜索蓝牙设备startTimer(onStopCallback)})}})
}function startTimer(onStopCallback) {cancelTimer()timer = setTimeout(function () {stopScan()if (onStopCallback != null && typeof onStopCallback === 'function') {onStopCallback() //停止扫描回调外部}}, mTimeout) //默认10秒后停止扫描
}function cancelTimer() {if (timer != null) {clearTimeout(timer)timer = null}
}
//监听并处理扫描结果
function listenerScanResult(onFindCallback) {if (isInit) returnisInit = truewx.onBluetoothDeviceFound((res) => { //监听扫描结果res.devices.forEach((device) => {if (!device.name.startsWith('T')) return //过滤非本公司蓝牙设备console.log('扫到设备, deviceName: ', device.name)if (onFindCallback != null && typeof onFindCallback === 'function') {onFindCallback(device) //找到设备回调外部}})})
}
//是否扫描中
function isScan() {return isScanning
}
//停止扫描
function stopScan() {console.log('停止扫描设备 >>>>>>')cancelTimer()if (!isScanning) return;isScanning = false;wx.stopBluetoothDevicesDiscovery() //停止扫描
}module.exports = {startScan,isScan,stopScan
}

2.实现连接设备/接收数据:

var Scan = require('../ble/scan/Scan')
const SET_MODE_SERVICE_UUID = "0000180f-0000-1000-8000-00805f9b34fb" //设置模式-服务UUID
const SET_MODE_CHARACTERISTIC_UUID = "00002a19-0000-1000-8000-00805f9b34fb" //设置模式-特征值UUID
const SET_MODE_DESCRIPTOR_UUID = "00002902-0000-1000-8000-00805f9b34fb" //设置模式-特征值描述UUID(固定不变)
const WRITE_DATA_SERVICE_UUID = "01ff0100-ba5e-f4ee-5ca1-eb1e5e4b1ce1" //写数据-服务UUID
const WRITE_DATA_CHARACTERISTIC_UUID = "01ff0101-ba5e-f4ee-5ca1-eb1e5e4b1ce1" //写数据-特征值UUID
const ENABLE_NOTIFICATION_VALUE = [0x01, 0x00]; //启用Notification模式
const DISABLE_NOTIFICATION_VALUE = [0x00, 0x00]; //停用Notification模式
const ENABLE_INDICATION_VALUE = [0x02, 0x00]; //启用Indication模式
const TIMEOUT = 10000;
var timer = null
var onConnected = null
var onDisconnect = null
var onRead = null
var writeService = null
var writeCharacteristic = null
var isConnecting = false
var isConnected = false
var mDevice = nullfunction startTimeoutCheck() {cancelTimeoutCheck()timer = setTimeout(function () {close() //超时后关闭蓝牙连接}, TIMEOUT) //10秒后超时
}function cancelTimeoutCheck() {if (timer != null) {clearTimeout(timer)timer = null}
}
//1.扫描
function start({deviceName,timeout = 10000,onDeviceNotFindCallback,onConnectedCallback,onDisconnectCallback,onReadCallback
}) { //开始扫描if (isConnecting || isConnected) returnonConnected = onConnectedCallbackonDisconnect = onDisconnectCallbackonRead = onReadCallbackScan.startScan({timeout: timeout,onFindCallback: function (device) { //找到设备回调函数if (device.name == deviceName) {mDevice = deviceScan.stopScan() //停止扫描connect(device) //转 - 2.连接}},onStopCallback: function () { //停止扫描回调函数if (mDevice == null) {console.log("没找到设备 >>>>>>")onDeviceNotFindCallback() //没扫描到设备时, 回调外部}}})
}
//2.连接
function connect(device) { //开始连接console.log("2.开始连接 >>>>>>deviceName: " + device.name)isConnecting = truestartTimeoutCheck()wx.createBLEConnection({deviceId: device.deviceId, //设备的 deviceIdsuccess: () => { // 连接成功console.log("连接成功 >>>>>>deviceName: " + device.name)cancelTimeoutCheck()if (onConnected != null && typeof onConnected === 'function') {onConnected() //连接成功回调外部}requestMtu(device); //设置MTUdiscoverServices(device) //开始扫描服务},fail: (res) => { //连接失败console.log("连接失败 >>>>>>deviceName: " + device.name)cancelTimeoutCheck()close() //连接失败关闭蓝牙连接if (onDisconnect != null && typeof onDisconnect === 'function') {onDisconnect() //关闭连接回调外部}}})
}
//2.1.设置MTU
function requestMtu(device) {console.log("2.1.请求设置mtu为512 >>>>>>name: " + device.name)wx.setBLEMTU({deviceId: device.deviceId,mtu: 200, //最大传输字节success: (res) => { // mtu设置成功console.log("mtu设置成功 >>>>>>deviceName: " + device.name + " 当前mtu: " + res.mtu)},fail: () => { // mtu设置失败console.log("mtu设置失败 >>>>>>deviceName: " + device.name)}})
}
//3.发现服务
function discoverServices(device) {console.log("3.开始发现服务 >>>>>>deviceName: " + device.name)startTimeoutCheck()wx.getBLEDeviceServices({deviceId: device.deviceId, //设备的 deviceIdsuccess: (res) => {console.log("发现服务成功 >>>>>>deviceName: " + device.name)cancelTimeoutCheck()isConnecting = falseisConnected = truevar len = res.services.lengthfor (let i = 0; i < len; i++) {var serviceItem = res.services[i]var serviceUuid = serviceItem.uuid;if (serviceUuid.toUpperCase() == SET_MODE_SERVICE_UUID.toUpperCase()) { //找到设置模式的服务console.log("3.1.找到设置模式的服务 >>>>>>deviceName: " + device.name + "  serviceUuid: " + SET_MODE_SERVICE_UUID)readCharacteristics(device, serviceItem); //读取特征值} else if (serviceUuid.toUpperCase() == WRITE_DATA_SERVICE_UUID.toUpperCase()) { //找到写数据的服务console.log("3.2.找到写数据的服务 >>>>>>deviceName: " + device.name + "  serviceUuid: " + WRITE_DATA_SERVICE_UUID)writeService = serviceItem;readCharacteristics(device, serviceItem); //读取特征值}}}})
}
//4.读取特征值(读出设置模式与写数据的特征值)
function readCharacteristics(device, serviceItem) {wx.getBLEDeviceCharacteristics({deviceId: device.deviceId, //设备的 deviceIdserviceId: serviceItem.uuid, // 上一步中找到的某个服务idsuccess: (res) => {var len = res.characteristics.lengthfor (let i = 0; i < len; i++) {var characteristicItem = res.characteristics[i]var characteristicUuid = characteristicItem.uuid;if (characteristicUuid.toUpperCase() == SET_MODE_CHARACTERISTIC_UUID.toUpperCase()) { //找到设置模式的特征值console.log("4.1.找到设置模式的特征值 >>>>>>deviceName: " + device.name + "  characteristicUUID: " + SET_MODE_CHARACTERISTIC_UUID);setNotificationMode(device, serviceItem, characteristicItem); //设置为Notification模式(设备主动给手机发数据)} else if (characteristicUuid.toUpperCase() == WRITE_DATA_CHARACTERISTIC_UUID.toUpperCase()) { //找到写数据的特征值console.log("4.2.找到写数据的特征值 >>>>>>deviceName: " + device.name + "  characteristicUUID: " + WRITE_DATA_CHARACTERISTIC_UUID);writeCharacteristic = characteristicItem; //保存写数据的征值}}}})
}
//4.1.设置为Notification模式(设备主动给手机发数据),Indication模式需要手机读设备的数据
function setNotificationMode(device, serviceItem, characteristicItem) {console.log("4.1.设置为通知模式 >>>>>>name: " + device.name)wx.onBLECharacteristicValueChange((data) => { //监听设备数据if (data == null) return;console.log("接收数据 >>>>>>name: " + device.name + "  data: " + data);onRead(data); //回调外部,返回设备发送的数据})wx.notifyBLECharacteristicValueChange({deviceId: device.deviceId,serviceId: serviceItem.uuid,characteristicId: characteristicItem.uuid,state: true,}) //为指定特征的值设置通知if (characteristicItem.properties.write) { // 该特征值可写(即设置模式的descriptor)console.log("发送Notification模式给设备 >>>>>>name: " + device.name);let buffer = new ArrayBuffer(2)let bufSet = new DataView(buffer)bufSet.setInt16(0, ENABLE_NOTIFICATION_VALUE[0])bufSet.setInt16(1, ENABLE_NOTIFICATION_VALUE[1])wx.writeBLECharacteristicValue({deviceId: device.deviceId,serviceId: serviceItem.serviceId,characteristicId: characteristicItem.uuid,value: buffer,}) //发送Notification模式给设备}
}
//发送指令到设备
function writeCommand(data) {console.log("发送指令给设备 >>>>>>deviceName: " + device.name + "  data: " + data);var len = data.length;let buffer = new ArrayBuffer(len)let bufSet = new DataView(buffer)for (let i = 0; i < len; i++) {bufSet.setUint8(i, data[i])}wx.writeBLECharacteristicValue({deviceId: device.deviceId,serviceId: writeService.serviceId,characteristicId: writeCharacteristic.uuid,value: buffer,}) //发送指令给设备
}
//断开连接
function close(device) {console.log("断开连接 >>>>>>deviceName: " + device.name);isConnecting = falseisConnected = falsewx.closeBLEConnection({deviceId: device.deviceId,}) //断开连接wx.closeBluetoothAdapter({}) //关闭蓝牙
}module.exports = {start,close
}

3.调用例子:

var ConnectManager = require('../../utils/ble/ConnectManager')
...//省略其他
ConnectManager.start({deviceName: "T11302002020169", //待连接设备的名称onDeviceNotFindCallback: function () { //没找到设备},onConnectedCallback: function () { //连接成功回调},onDisconnectCallback: function () { //连接关闭回调},onReadCallback: function (data) {   //设备发过来的数据},
})

微信小程序:BLE蓝牙开发相关推荐

  1. 微信小程序之蓝牙开发虚拟摇杆

    文章用于学习记录 文章目录 前言 一.App Inventor 二.uni-app 三.微信小程序 3.1 示例&应用 3.2 服务值与特征值 3.3 控制指令 3.4 测试 3.5 十六进制 ...

  2. 微信小程序-BLE蓝牙实现demo

    终于实现了蓝牙的功能,也找到了合适的硬件,记录一下自己需要注意和总结的地方 具体的搜索.连接.断开.消息传输都已经实现了,作为项目的一个页面完成了 相应的代码地址,具体的蓝牙代码在pages/blue ...

  3. 微信小程序--Ble蓝牙

    在前面已经写了两篇关于Android蓝牙和ios 蓝牙开发的文章,今天带来的是微信小程序蓝牙实现. Android蓝牙 ios蓝牙(Swift) 有一段时间没有.没有写关于小程序的文章了.3月28日, ...

  4. uni-app、微信小程序低功耗蓝牙开发及使用

    引导 今天在这里记录分享一下低功耗蓝牙的使用方法和需要注意的地方 如果使用的微信小程序原生开发,使用方法是一样的,只需要把所有uni换成wx就行 例 wx.openBluetoothAdapter({ ...

  5. 微信小程序低功耗蓝牙BLE快速开发js

    文章目录 1.前言 2.资料 3.BLE连接流程 BLE连接原理 4.index.js页面加载流程详细说明 完整代码: 1.前言 目的: 1.为了能三分钟快速开发BLE模块,特此做一个笔记,按照笔记的 ...

  6. 微信小程序实现蓝牙BLE(demo版)

    微信小程序实现蓝牙BLE(看文章最后一句话) 这是楼主在学校自己开发的用蓝牙小程序控制机械臂的(独立开发的). https://pan.baidu.com/s/1AmCW_ARhu--eapzd8Af ...

  7. 微信小程序/uni-app 蓝牙打印开发教程和常见问题总结【文末附源码】

    微信小程序/uni-app 蓝牙打印开发教程和常见问题总结[文末附源码] 文章目录 微信小程序/uni-app 蓝牙打印开发教程和常见问题总结[文末附源码] 1️⃣ 写在前面 2️⃣ 蓝牙连接流程 3 ...

  8. 在HbuilderX中实现微信小程序下蓝牙连接打印机完整实战案例

    1.基础开发环境,所用到的 Api 以及实现的思路. 应用场景: 商家打印小票,小票包含顾客消费的商品明细信息以及末尾附上二维码,二维码供顾客扫码开票. HbuilderX开发工具: HBuilder ...

  9. 开源一个基于微信小程序的蓝牙室内定位软件(附下载链接)

    文章目录 1. 运行环境要求 2. 软件功能及程序说明 2.1 软件组成 2.2 主要功能 2.3 文件及函数功能说明 3. 软件设计及操作说明 4. 完整版代码获取 1. 运行环境要求 软件运行环境 ...

  10. 微信小程序开发登录界面mysql_微信小程序 欢迎界面开发的实例详解

    微信小程序 欢迎界面 市面上大多数的app都会有一个欢迎界面,下面将演示如何通过微信小程序实现一个欢迎界面. 下面将会按照以下的顺序介绍: 布局的实现 逻辑的实现 样式的实现 1.布局的实现 整个布局 ...

最新文章

  1. New Year Tree(dfs序+线段树+二进制)
  2. shell 生成指定范围随机数与随机字符串 .
  3. python读取邮件发送日期和时间_Python读取指定日期邮件的实例
  4. linux日志中有空格,linux中统计排序的内容含有空白行的解决办法
  5. centos linux编译c,紧急提醒!Linux是如何编译C语言程序文件的?CentOS 8的gcc使用方法介绍...
  6. IOS考试题3字体变大变小
  7. 【渝粤教育】电大中专电子商务网站建设与维护 (14)作业 题库
  8. Windows核心编程学习九:利用内核对象进行线程同步
  9. centos上nginx转发tcp请求
  10. k3c最新官改非常稳定了_软件聚分享库APP最新版下载-软件聚分享库v1.0.0安卓版下载...
  11. 利用Openyxl为excel批量插入表头行(Excel读写基础操作)——上
  12. 22种手机使用中的常见问题及处理方法
  13. cocos2dx图片闪亮_SassDoc 2-闪亮的流章鱼出来了!
  14. 读《人脸自动机器识别》
  15. 记账软件分享,教你如何记账并管理所有账目
  16. 云麦体脂秤华为体脂秤_华为、小米、联想的智能体脂秤三国杀
  17. C语言的前置++和后置++
  18. 非递归、递归遍历二叉树!
  19. 麦克风阵列杂音很重解决方案(科大讯飞麦克风阵列+6.0)
  20. JAVA公路车几何图_单车基械匠:读懂自行车几何角度图,是你成为老鸟的关键一步...

热门文章

  1. sql 后台运行远程服务器,在SQLServer中通过.NET远程的执行SQL文件
  2. 从第一台计算机到云计算,从第一台计算机诞生到现在经历了几个阶段
  3. 友情提示:破坏计算机信息系统罪
  4. margin 无效的情形
  5. linux上wds部署服务,WDS服务器的部署与配置
  6. 关于TCP的CLOSE_WAIT
  7. C++中count函数用法
  8. 在亚马逊上你知道怎么定价-跨境知道
  9. lunix针对用户的常用操作命令
  10. 记录测试数据的bat脚本