基于蓝牙低功耗(BLE)技术打造一款智能车位锁,可以让用户直接用iPhone控制车位升降、实时查看车位状态,并接收碰撞报警。在iOS平台上,Core Bluetooth框架提供了与BLE外设通信的完整能力。本文将以一个典型的智能车位锁为外设,展示如何利用Core Bluetooth在APP中实现设备扫描、连接、服务发现、特征读写以及通知订阅,从而完成状态检测、远程升降控制和防撞报警功能。

Core Bluetooth角色划分与UUID设计
Core Bluetooth将设备分为两种角色:中心设备(Central)和外设(Peripheral)。在我们的场景中,iPhone作为中心,车位锁作为外设。中心负责扫描并连接外设,探索其服务和特征,然后读写特征值或订阅通知。外设则广播自己的存在,并维护一个GATT(通用属性协议)数据库,其中包含了定义好的服务(Service)和特征(Characteristic)。
为了让APP和车位锁能够互相识别,需要预先约定一组UUID。BLE中的服务UUID和特征UUID通常是128位的,但也可以采用16位标准UUID或自定义的128位UUID。以车位锁为例,我们可以定义以下UUID(示例):
// 服务UUID:车位锁主服务 let lockServiceUUID = CBUUID(string: "A000") // 特征UUID: // 状态特征——支持通知,用于上报升/降状态 let statusCharacteristicUUID = CBUUID(string: "A001") // 控制特征——支持写入,用于发送升/降指令 let controlCharacteristicUUID = CBUUID(string: "A002") // 报警特征——支持通知,当碰撞发生时外设上报 let alarmCharacteristicUUID = CBUUID(string: "A003")
实际项目中更推荐使用完整的128位UUID,并注意在固件侧与APP侧保持严格一致。中心设备在扫描时还可以通过服务UUID过滤掉不相关的BLE设备,提升扫描效率。
在开始所有操作之前,需要初始化CBCentralManager实例,并指定其代理。初始化的同时iOS会检查蓝牙状态,只有在状态变为.poweredOn后,才能进行后续的扫描和连接操作。通常我们会在代理方法centralManagerDidUpdateState(_:)中处理蓝牙状态变化。
扫描连接与车位状态同步
中心管理器就绪后,就可以调用scanForPeripherals方法开始扫描周围正在广播的车位锁。为了提高效率,可以传入之前定义的服务UUID数组,只扫描包含该服务的设备。扫描到设备后,代理方法centralManager(_:didDiscover:advertisementData:rssi:)会被触发,我们可以在其中记录发现的CBPeripheral对象并展示给用户。
用户选择一个车位锁后,中心设备发起连接请求:centralManager.connect(peripheral, options: nil)。连接成功后会回调centralManager(_:didConnect:),此时外设的delegate应被设置为我们自己的管理器,并调用peripheral.discoverServices([lockServiceUUID])来发现指定的服务。
服务发现完成后,在peripheral(_:didDiscoverServices:error:)中遍历服务并进一步发现特征:
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
if service.uuid == lockServiceUUID {
peripheral.discoverCharacteristics(
[statusCharacteristicUUID, controlCharacteristicUUID, alarmCharacteristicUUID],
for: service
)
}
}
}
发现特征后,我们对状态特征开启通知(Notify)。这是实现车位状态实时检测的关键:APP不需要反复轮询,当车位锁状态变化时(例如上升到位或下降到位),它会通过BLE通知将最新状态推送给APP。在代理方法peripheral(_:didDiscoverCharacteristicsFor:error:)中,找到状态特征并调用peripheral.setNotifyValue(true, for: statusCharacteristic)。一旦通知被成功启用,外设推送的状态值就会在peripheral(_:didUpdateValueFor:error:)中被捕获,APP解析数据后即可更新界面上的车位状态(升起、降下或运动中)。
这种基于通知的同步方式既保证了实时性,又避免了频繁的主动读取带来的功耗和延迟。车位锁在电机运行过程中可以持续发送中间状态,让UI展示动态效果。
远程升降与防撞报警实现
控制车位锁升降的核心是向控制特征写入指令。在连接且已发现控制特征后,APP可以构造包含升降命令的数据(通常是一个字节的0x01代表升起,0x00代表降下),并通过peripheral.writeValue(_:for:type:)发送。写入类型(CBCharacteristicWriteType)一般选择.withResponse,这样外设回复ACK即可确认指令已接收。写入成功后,车位锁开始动作,同时状态特征会连续推送变化,形成闭环反馈。
防撞报警功能则依赖另一个特征——报警特征。车位锁硬件中集成加速度传感器或震动传感器,当检测到外力碰撞时,外设自动将报警事件打包到报警特征,并通过通知通道发送给已连接的手机。APP在收到报警特征值更新后,可以立即弹出本地通知或触发声音报警,告知车主可能有人尝试侵入车位。这种机制同样采用通知订阅,无需APP主动查询,响应延迟极低。
为了提升可靠性,报警特征可以携带更丰富的信息,如碰撞强度、时间戳等。数据格式由固件和APP共同约定,通常采用简单的二进制协议或TLV结构。APP解析数据后记录日志,甚至可以联动摄像头抓拍,实现完整的安防闭环。
连接管理与功耗优化
蓝牙车位锁常需长期运行,因此对连接的稳定性和功耗要求较高。APP进入后台或被用户切换时,应妥善处理连接状态。可以利用Core Bluetooth的后台执行模式(需要在Info.plist中添加bluetooth-central后台模式)来保持连接,并接收通知。但要特别注意,后台运行会增加功耗,因此最好在用户离开控制界面后断开连接,或切换到低频率监听模式。
重连策略同样重要。车位锁可能因为信号遮挡或距离过远断开,APP应监听centralManager(_:didDisconnectPeripheral:error:),并尝试自动重连。可以设置指数退避的重连间隔,避免频繁扫描耗电。当多个车位锁同时存在时,APP应允许用户创建“我的车位”列表,优先连接常用设备。
在特征读写方面,尽量打包多个相关状态到一个特征中,减少特征数量和发现时间。控制指令写入后,可立即读取状态特征确认执行结果,但应避免在短时间内重复写入相同指令,防止电机堵转。通过状态通知的节流处理,APP可以过滤掉不必要的UI刷新,进一步降低CPU占用。
整篇方案的代码均基于iOS自带的Core Bluetooth框架,无需引入第三方库,兼容性好,且能充分利用系统层面对BLE的优化。从扫描、连接到服务与特征的交互,每一步都遵循了标准的BLE GATT流程,使得智能车位锁的开发变得清晰可控。你可以将上述示例代码集成到自己的工程中,并结合实际的硬件UUID和协议进行定制,快速打造出一款稳定、易用的蓝牙车位锁控制应用。
Core_Bluetooth蓝牙智能车位锁iOS蓝牙开发修改时间:2026-08-12 15:04:25