OBD2 BLE通信——如何发送AT命令和接收数据
OBD2 BLE Communication - how to send AT commands and receive data
我有一个 OBD2 适配器,需要通过它获取车辆的速度(使用 BLE 和 iOS 设备)。加密狗附带的文档没有提到服务和特性,但通过一些调试我发现了一些。我们称它们为服务 1、2、3。
- 服务 1 具有一个具有读取 属性 和 WriteWithoutResponse 属性
的特征
- 服务 2 具有一个读取 属性 和通知 属性
特征
- 服务 3 有两个特征:具有读取 属性 和通知 属性 的特征 A 以及具有写入 属性 和 WriteWithoutResponse 属性
的特征 B
如何知道characteristic/s我需要发送AT命令并接收相应的数据,然后如何发起这个通信。我特别需要能够获得速度。先感谢您。
我尝试了以下但没有任何反应:
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristic in service.characteristics! {
if characteristic.properties.contains(.notify) {
peripheral.setNotifyValue(true, for: characteristic)
}
if characteristic.properties.contains(.write) {
let commandString = "010D\r"
if let commandData = commandString.data(using: .utf8) {
peripheral.writeValue(commandData, for: characteristic, type: .withoutResponse)
peripheral.writeValue(commandData, for: characteristic, type: .withResponse)
}
}
}
}
然后期待以下内容:
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
if let value = characteristic.value {
let text = String(data: value, encoding: String.Encoding.utf8)
self.onNotifyReceived(text)
}
}
首先,如果您通过 ELM327 等最常见的 OBD2 芯片进行通话,您最好不要从 PID(例如 010D
)开始,而是使用适当的初始化它AT
命令序列(有关详细信息,请参阅相应的手册)。
接下来,peripheralDidUpdateNotificationState
是错误的委托方法。只要您订阅或取消订阅某个特征,就会触发此事件,而不是在其值发生变化时触发。您想改为实现委托方法 peripheralDidUpdateValueForCharacteristic
。
也就是说,问题是:OBD2 BLE 适配器不使用任何固定的 GATT 配置文件。大多数(如果不是全部)BLE OBD2 适配器的工作方式是,它们提供具有一两个特征的服务:
- 写特性。这是移动设备可以将其 AT 命令(例如,在 ELM327 的情况下)和 PID 写入的地方。
- 通知特征。这是返回汽车 (ECU) 结果的地方。
一旦您获得了这些特性,您就可以实现 OBD2 串行协议(例如,在将完成的命令传输到应用层之前,使用写入并等待响应的命令队列)。
一些 BLE 适配器将这两个特性合并为一个特性。如果你想支持任意适配器,你将不得不添加一个 'select your adapter' 屏幕,你可以在其中探测找到的适配器,记住特性,然后进行通信。
这样就可以编写适用于各种 BLE OBD2 适配器的应用程序,而不仅仅是支持选定的少数供应商,例如 OBD2 Expert(免责声明:我是该软件的作者) .
我有一个 OBD2 适配器,需要通过它获取车辆的速度(使用 BLE 和 iOS 设备)。加密狗附带的文档没有提到服务和特性,但通过一些调试我发现了一些。我们称它们为服务 1、2、3。
- 服务 1 具有一个具有读取 属性 和 WriteWithoutResponse 属性 的特征
- 服务 2 具有一个读取 属性 和通知 属性 特征
- 服务 3 有两个特征:具有读取 属性 和通知 属性 的特征 A 以及具有写入 属性 和 WriteWithoutResponse 属性 的特征 B
如何知道characteristic/s我需要发送AT命令并接收相应的数据,然后如何发起这个通信。我特别需要能够获得速度。先感谢您。
我尝试了以下但没有任何反应:
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristic in service.characteristics! {
if characteristic.properties.contains(.notify) {
peripheral.setNotifyValue(true, for: characteristic)
}
if characteristic.properties.contains(.write) {
let commandString = "010D\r"
if let commandData = commandString.data(using: .utf8) {
peripheral.writeValue(commandData, for: characteristic, type: .withoutResponse)
peripheral.writeValue(commandData, for: characteristic, type: .withResponse)
}
}
}
}
然后期待以下内容:
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
if let value = characteristic.value {
let text = String(data: value, encoding: String.Encoding.utf8)
self.onNotifyReceived(text)
}
}
首先,如果您通过 ELM327 等最常见的 OBD2 芯片进行通话,您最好不要从 PID(例如 010D
)开始,而是使用适当的初始化它AT
命令序列(有关详细信息,请参阅相应的手册)。
接下来,peripheralDidUpdateNotificationState
是错误的委托方法。只要您订阅或取消订阅某个特征,就会触发此事件,而不是在其值发生变化时触发。您想改为实现委托方法 peripheralDidUpdateValueForCharacteristic
。
也就是说,问题是:OBD2 BLE 适配器不使用任何固定的 GATT 配置文件。大多数(如果不是全部)BLE OBD2 适配器的工作方式是,它们提供具有一两个特征的服务:
- 写特性。这是移动设备可以将其 AT 命令(例如,在 ELM327 的情况下)和 PID 写入的地方。
- 通知特征。这是返回汽车 (ECU) 结果的地方。
一旦您获得了这些特性,您就可以实现 OBD2 串行协议(例如,在将完成的命令传输到应用层之前,使用写入并等待响应的命令队列)。
一些 BLE 适配器将这两个特性合并为一个特性。如果你想支持任意适配器,你将不得不添加一个 'select your adapter' 屏幕,你可以在其中探测找到的适配器,记住特性,然后进行通信。
这样就可以编写适用于各种 BLE OBD2 适配器的应用程序,而不仅仅是支持选定的少数供应商,例如 OBD2 Expert(免责声明:我是该软件的作者) .