OBD2 BLE Communication - как отправлять AT команды и получать данные

У меня есть ключ OBD2, и мне нужно узнать скорость автомобиля (используя BLE и iOS-устройство). В документации, поставляемой с ключом, не упоминались службы и характеристики, но при некоторой отладке я обнаружил несколько. Назовем их сервисом 1, 2, 3.

  1. Служба 1 имеет одну характеристику со свойством Read и свойством WriteWithoutResponse
  2. Сервис 2 имеет одну характеристику: свойство Read и свойство Notify
  3. Сервис 3 имеет две характеристики: характеристика A со свойством Read и свойство Notify, а характеристика B со свойством Write и свойство WriteWithoutResponse

Как узнать, какие характеристики мне нужны для отправки 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)
    }

} 

1 ответ

Решение

Прежде всего, если вы говорите, например, с помощью ELM327 - который является одним из наиболее распространенных чипов OBD2 - вам лучше не начинать с PID (например, 010D), а точнее инициализируйте его AT последовательность команд (подробности см. в соответствующем руководстве).

Следующий, peripheralDidUpdateNotificationState неправильный метод делегата. Это срабатывает всякий раз, когда вы подписываетесь или отменяете подписку на признак, а не когда его значение изменяется. Вы хотите реализовать метод делегата peripheralDidUpdateValueForCharacteristic вместо.

Тем не менее, проблема в том, что адаптеры OBD2 BLE не используют фиксированные профили GATT. Большинство (если не все) адаптеры BLE OBD2 работают так, что они предлагают одну услугу с одной или двумя характеристиками:

  • Характеристика записи. Это то, где мобильное устройство может записывать свои AT-команды (в случае, например, ELM327) и PID.
  • Характеристика уведомления. Это тот, где результаты от автомобиля (ECU) возвращаются.

Получив доступ к этим характеристикам, вы можете реализовать последовательный протокол OBD2 (например, используя очередь команд, которая записывает и ожидает ответа, прежде чем передать готовую команду на прикладной уровень).

Некоторые адаптеры BLE объединяют эти два свойства в одну. Если вы хотите поддерживать произвольные адаптеры, вам нужно будет добавить экран "выберите свой адаптер", где вы будете проверять найденные адаптеры, запоминать характеристики и затем общаться.

Таким образом, можно писать приложения, которые работают со всеми видами адаптеров BLE OBD2 и не только поддерживают выбранную группу поставщиков, например, таких как OBD2 Expert (Disclaimer: я являюсь автором этого программного обеспечения).

Другие вопросы по тегам