HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备连接
HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备连接
概述
蓝牙技术是一种无线通信技术,可以在短距离内传输数据。它是由爱立信公司于1994年提出的,使用2.4 GHz的ISM频段,可以在10米左右的距离内进行通信。可以用于连接手机、耳机、音箱、键盘、鼠标、打印机等各种设备。特点是低功耗、低成本、简单易用。目前已经发展到了第五代,支持更高的数据传输速率和更广的覆盖范围。
实现原理
蓝牙的实现原理是基于无线电技术的短距离通信协议,使用2.4GHz频段的无线电波进行通信,使用频率跳跃技术(Frequency Hopping Spread Spectrum,FHSS)来避免与其他无线设备的干扰。在通信过程中,蓝牙设备会发送和接收数据包,并且使用不同的蓝牙协议来控制通信流程和数据传输。
蓝牙服务
在连接蓝牙设备时,查找蓝牙服务是一项重要的步骤。蓝牙服务是蓝牙设备上提供的功能或特性的抽象表示,它们定义了设备可以提供的各种功能,比如数据传输、音频播放、传感器数据等。每个蓝牙服务都包含一个或多个特征(Characteristics),这些特征描述了服务所提供的具体功能或属性。
查找蓝牙服务的主要作用包括:
- 识别设备功能:通过查找蓝牙服务,可以了解到连接的蓝牙设备所提供的功能和特性。这有助于应用程序确定如何与设备进行交互,并选择正确的服务来执行所需的操作。
- 建立通信通道:一旦找到了需要的蓝牙服务,应用程序可以与设备建立通信通道,以便发送和接收数据。通常,应用程序需要与设备的特定服务进行通信,才能执行相应的操作。
- 配置和控制设备:通过蓝牙服务,应用程序可以向设备发送命令或配置参数,以控制设备的行为或进行设置。例如,控制蓝牙音箱的音量、切换播放模式等。
- 获取设备信息:蓝牙服务通常还包含有关设备的一些信息,如设备名称、型号、制造商信息等。应用程序可以通过服务获取这些信息,以便在用户界面中显示或用于其他目的。
总之,查找蓝牙服务是连接蓝牙设备并与之通信的重要步骤,它允许应用程序识别设备功能并与之交互,从而实现各种有用的功能和应用场景。
蓝牙连接流程分析
下边我们来分析下鸿蒙中使用BLE蓝牙进行连接和通信的流程。以下是对BLE蓝牙连接流程的总结,结合了GattClientDevice
相关的API方法:
1. 扫描发现设备
- 启动扫描:使用
startBLEScan()
方法开始扫描周围的蓝牙LE设备。可以通过ScanSettings
和ScanFilter
配置扫描参数,比如扫描模式、超时时间、需要匹配的设备条件等。 - 监听扫描结果:注册
ble.on('BLEDeviceFind', onReceiveEvent)
事件监听器,当发现设备时,系统会回调此事件,提供发现的设备信息,如设备ID、名称等。
2. 建立连接
- 获取GattClientDevice实例:在扫描结果的回调中,使用发现的设备ID调用
ble.createGattClientDevice('设备 id')
获取GattClientDevice
实例,代表远程蓝牙设备。 - 连接设备:调用
GattClientDevice.connect()
方法建立与蓝牙设备的连接。连接成功或失败可以通过监听GattClientDevice
实例上的BLEConnectionStateChange
事件得知。
3. 获取蓝牙服务并通信
- 发现服务:连接成功后,调用
GattClientDevice.getServices()
方法来发现远程设备支持的服务。这些服务是设备提供的特定功能集。 - 获取特征值:发现服务后,通过服务UUID获取特定服务下的特征值(Characteristic)对象。
- 通信过程:
- 通知特征值对象(监听数据更新):若要接收蓝牙设备主动发送的数据,需要启用特征值的通知功能。
- 写入特征值对象(向蓝牙设备发送数据):若要向设备发送数据,使用特征值对象的
writeCharacteristicValue
方法。
蓝牙连接流程封装
连接前,需要先检测授权
授权检测
// 1. 授权扫描和连接设备
scanAndConnect=()=>{
}
aboutToAppear(): void {
// 先检查授权和开关状态,然后搜索设备和连接
ecBlue.checkBluePermission(this.scanAndConnect)
}
设备扫描
- 设置连接 loading
- 调用扫描方法,获取设备 id(连接使用)
- 没有扫到设备,重连提示
scanAndConnect = () => {
this.loading.open()
ecDevice.scanDevice({
type: "mac",
value: deviceParamsStore.getStore()
.nodeId!
}, (list) => {
if (list.length > 0) {
const deviceId: string = list[0].deviceId
Log.info('发现设备:' + deviceId)
} else {
// 连接失败
this.loading.close()
this.blueDialog.open()
}
})
}
封装连接
import { ble, constant } from '@kit.ConnectivityKit';
import { Log } from '@abner/log';
class EcDevice {
// ...
// 客户端连接实例
dev: ble.GattClientDevice | null = null
/**
* 1. 连接BLE设备
* @param deviceId
*/
connectBloodDevice(deviceId: string) {
this.destroy()
this.dev = ble.createGattClientDevice(deviceId)
// 1. 连接设备
this.dev.connect()
this.dev.on('BLEConnectionStateChange', async (res) => {
if (res.state === constant.ProfileConnectionState.STATE_CONNECTED) {
Log.info('连上设备了')
try {
// 2. 发现服务
const res = await this.dev?.getServices()
// 3. 获取服务
const ser = res?.find(item => item.serviceUuid.startsWith('00001000'))
if (ser) {
// 写入特征值对象(给蓝牙设备发送数据)
const writeChar = ser.characteristics.find(c => c.characteristicUuid.startsWith('00001001'))
// 通知特征值对象(获取蓝牙设备发送数据)
const notifyChar = ser.characteristics.find(c => c.characteristicUuid.startsWith('00001002'))
// 4. 开启特征值监听:获取连接状态和测量结果
this.dev?.on('BLECharacteristicChange', (res) => {
// TODO:coding...
})
await this.dev?.setCharacteristicChangeNotification(notifyChar, true)
// 5. 发送通信数据包, 连接设备
if (writeChar) {
await this.dev?.writeCharacteristicValue({
serviceUuid: writeChar.serviceUuid,
characteristicUuid: writeChar.characteristicUuid,
// 数据包
characteristicValue: null,
descriptors: []
}, ble.GattWriteType.WRITE)
}
}
} catch (e) {
this.destroy()
Log.error('设备连接报错:' + JSON.stringify(e))
}
}
})
}
destroy() {
if (this.dev) {
try {
this.dev.disconnect()
} catch (e) {
Log.error('设备断开报错:' + JSON.stringify(e))
}
this.dev.close()
this.dev = null
}
}
}
连接设备
- 定义连接方法
dev: ble.GattClientDevice | null = null
/**
* 1. 连接某血糖设备
* @param deviceId
* @param cb:state=》0 连接成功 | 1 测量中 | 2 测量结果 val=> 测量结果
*/
connectBloodDevice(deviceId: string, cb: BloodLinkCallback) {
this.dev = ble.createGattClientDevice(deviceId)
// 1. 连接设备
this.dev.connect()
this.dev.on('BLEConnectionStateChange', (res) => {
if (res.state === constant.ProfileConnectionState.STATE_CONNECTED) {
Log.info('连上设备了')
}
})
}
- 定义连接销毁方法
destroy() {
if (this.dev) {
try {
this.dev.disconnect()
} catch (e) {
Log.error('设备断开报错:' + JSON.stringify(e))
}
this.dev.close()
this.dev = null
}
}
- 获取设备蓝牙服务和特征值
if (res.state === constant.ProfileConnectionState.STATE_CONNECTED) {
Log.info('连上设备了')
try {
// 2. 发现服务
const res = await this.dev?.getServices()
// 3. 找到服务
const ser = res?.find(item => item.serviceUuid.startsWith('00001000'))
if (ser) {
// 写入特征值对象(给蓝牙设备发送数据)
const writeChar = ser.characteristics.find(c => c.characteristicUuid.startsWith('00001001'))
// 通知特征值对象(获取蓝牙设备发送数据)
const notifyChar = ser.characteristics.find(c => c.characteristicUuid.startsWith('00001002'))
}
} catch (e) {
this.destroy()
Log.error('设备报错:' + JSON.stringify(e))
}
}
设备通信
- 开启通知特征值监听:获取连接状态和结果
// 4. 开启特征值监听:获取连接状态和结果
this.dev?.on('BLECharacteristicChange', (res) => {
Log.info(res.characteristicValue)
})
await this.dev?.setCharacteristicChangeNotification(notifyChar, true)
- 使用写入特征值给血糖设备发送连接确认数据
if (ser) {
// 写入特征值对象(给蓝牙设备发送数据)
const writeChar = ser.characteristics.find(c => c.characteristicUuid.startsWith('00001001'))
// 通知特征值对象(获取蓝牙设备发送数据)
const notifyChar = ser.characteristics.find(c => c.characteristicUuid.startsWith('00001002'))
// 4. 开启特征值监听:获取连接状态和结果
// ...
// 5. 发送00数据包, 连接设备
if (writeChar) {
const data = this.createData('0x00')
await this.dev?.writeCharacteristicValue({
serviceUuid: writeChar.serviceUuid,
characteristicUuid: writeChar.characteristicUuid,
characteristicValue: data.buffer,
descriptors: []
}, ble.GattWriteType.WRITE)
}
}
- 处理特征值监听回调
// 4. 开启特征值监听:获取连接状态和结果
this.dev?.on('BLECharacteristicChange', (res) => {
const buff = new Uint8Array(res.characteristicValue)
Log.warn('设备数据:' + buff)
Log.warn('数据长度:' + buff.length)
if (buff.length === 18) {
// 1. 连接成功
cb(0)
}
if (buff.length === 6) {
// 2. 测量中
cb(1)
} else if (buff.length === 12) {
// 3. 测量结果
const result = this.getResult(buff)
cb(2, result)
this.destroy()
}
})
总结
本文基于鸿蒙BLE模块,对设备连接的通用流程做了抽象封装。实际开发中,开发者可能需要根据实际情况分别处理不同 BLE 设备连接通信过程,不同设备间通信确认的方式有所不同,这里需要特别注意!
更多关于HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备连接的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备连接的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对帖子标题“HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备连接”的问题,以下是专业且简洁的回答:
在HarmonyOS鸿蒙Next物联网(IoT)开发中,连接BLE(蓝牙低功耗)设备通常涉及以下几个关键步骤:
-
初始化BLE管理器:首先,需要在应用中初始化BLE管理器,以准备进行BLE设备的扫描和连接。
-
扫描BLE设备:使用BLE管理器提供的扫描功能,搜索附近的BLE设备。扫描过程中,可以设置过滤条件以快速定位目标设备。
-
连接BLE设备:一旦找到目标设备,即可发起连接请求。连接过程中,可能需要处理设备认证和配对等流程。
-
通信与服务发现:连接成功后,可以开始与BLE设备进行数据通信,并发现设备提供的服务及特征值。这通常涉及读写操作,以实现具体功能。
-
断开连接:当不再需要与BLE设备通信时,应主动断开连接以释放资源。
请注意,HarmonyOS鸿蒙Next平台可能提供了特定的API和框架来简化BLE设备的连接和管理。开发者应参考官方文档和示例代码,确保正确实现上述步骤。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html,