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)
    }

} 

person surToTheW    schedule 06.12.2018    source источник
comment
Если характеристика 0xAAAA (четыре шестнадцатеричных), теоретически они должны быть задокументированы организацией Bluetooth, проверьте там doc. Если нет, то как узнать, какие характеристики мне нужны для отправки AT-команд? Это просто обратная инженерия.   -  person Larme    schedule 06.12.2018
comment
@Larme Здесь они не задокументированы - bluetooth.com/specifications/gatt/services - если это ты имеешь в виду. Я почти уверен, какой сервис и характеристики мне следует использовать - сервис с характеристиками записи и уведомления. Но не совсем уверен. Еще интересно, почему не работает, если это действительно так. Может, у меня просто неправильный код.   -  person surToTheW    schedule 06.12.2018
comment
Не пишет? Что ж, если он, например, принимает только массив целых чисел, ваша команда недействительна. Почему "010D\r", преобразованный в Data с использованием кодировки UTF8, должен быть допустимым сообщением? Кто тебе это сказал?   -  person Larme    schedule 06.12.2018
comment
@Larme Вы, наверное, правы. На первой итерации я инициировал связь с эмулятором OBD2 (тогда ключа не было) через Wi-Fi. И я отправил данные таким образом, используя сокет. Это работало хорошо. Но мне нужно, чтобы он работал над BLE, и, возможно, мне следует отправить данные другим способом и ожидать чего-то другого. Есть ли способ понять это без документального подтверждения?   -  person surToTheW    schedule 07.12.2018
comment
Как было сказано ранее, это обратный инжиниринг. Если вы можете его прочитать и у него есть значения, я думаю, что отправляемое значение должно быть того же типа. Но это еще далеко впереди.   -  person Larme    schedule 07.12.2018


Ответы (1)


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

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

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

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

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

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

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

person DrMickeyLauer    schedule 15.12.2018
comment
Связь осуществляется путем записи значений на периферийное устройство и последующего чтения значений в peripheralDidUpdateValueForCharacteristic? Или должно быть что-то еще? - person surToTheW; 23.01.2019
comment
Вы правы, это практически все, что нужно. Кстати, я опубликовал свою библиотеку OBD2 @ github.com/mickeyl/LTSupportAutomotive - возможно, это помощь. - person DrMickeyLauer; 24.01.2019
comment
Это отличная библиотека. Я пробовал использовать его для наших нужд, но по какой-то причине получаемое мной значение не является ожидаемым (в formattedResponse). Отладка действительно непростая, потому что я не могу найти хороший симулятор. Вы случайно не знаете хороший симулятор OBD2 (тоже не слишком дорогой)? - person surToTheW; 24.01.2019
comment
Если вы серьезно относитесь к разработке OBD2 (что касается использования различных стандартных протоколов транспортных средств), я рекомендую diamex.de/dxshop/Diamex-OBD2-Profi-Simulator-alle-Protokolle, что составляет около 300 евро, но стоит каждого пенни. - person DrMickeyLauer; 28.01.2019
comment
@DrMickeyLauer, не могли бы вы взглянуть на: stackoverflow.com/questions/61090365/ - person Ride Sun; 08.04.2020