ESP32 DevKit v1 · pinport
готово
⋮

Бортовой компьютер автомобиля на ESP32: OBD-II по CAN, SN65HVD230 и панель Settings

Читает данные автомобиля через диагностический разъём OBD-II: обороты, скорость, температуры, расход, коды неисправностей и VIN. Связь по CAN через трансивер SN65HVD230, транспорт ISO-TP, запросы UDS для VAG, дисплей 16×2 и панель Settings. В симуляторе автомобиль задаётся свойствами детали, а схема проверяется на ошибки монтажа.

Что на схеме

Плата ESP32 DevKit v1, к ней подключены:

  • Трансивер CAN SN65HVD230 (модуль) «Трансивер CAN» — xc
  • Разъём OBD-II автомобиля (CAN) «Автомобиль (OBD-II)» — obd
  • LCD 16x2 (I2C) «Дисплей» — lcd1
  • Кнопка «Страница / сброс» — btn

Задействованы выводы платы: 3V3, GND, D5, D4, VIN, D21, D22, D13. Всего соединений на схеме: 13.

Схема и что на ней

Бортовой компьютер: плата ESP32 подключается к диагностическому разъёму OBD-II автомобиля по шине CAN, опрашивает блок управления двигателем и показывает данные на дисплее 16×2 и на странице Settings. Задумано для автомобилей группы VAG (VW, Audi, Škoda, SEAT), но стандартные службы OBD-II одинаковы у всех машин с CAN.

Связь с шиной идёт через модуль трансивера SN65HVD230: контроллер TWAI в ESP32 выдаёт логические уровни на выводах TX и RX, а шине нужна дифференциальная пара CANH/CANL. Трансивер питается от 3,3 В — это его штатное питание, и с логикой ESP32 он согласован без делителей.

Что подключено

  • SN65HVD230 (модуль): CTX — к D5 (передатчик TWAI), CRX — к D4 (приёмник), 3V3 и GND — к плате; CANH и CANL — к выводам 6 и 14 разъёма OBD-II.
  • Разъём OBD-II: вывод 6 — CANH, 14 — CANL, 4 и 5 — земля, 16 — плюс бортсети. Земля модуля и земля автомобиля должны быть общими.
  • Дисплей LCD1602 (I2C, 0x27) на D21/D22 и кнопка на D13. Короткое нажатие листает страницы (скорость и обороты, поездка, коды), долгое — сбрасывает поездку.
  • Плата питается от бортсети через понижающий преобразователь 12→5 В с защитой от выбросов (в автомобиле напряжение доходит до десятков вольт при отключении нагрузки); вывод 16 напрямую на плату подключать нельзя. В симуляторе плата питается от USB.

Что читается и как

Скетч опрашивает показания службой OBD-II 01: обороты, скорость, температуры охлаждающей жидкости, масла, воздуха на впуске и снаружи, нагрузку, дроссель, расход воздуха (MAF), давление во впуске, уровень топлива, напряжение бортсети, коррекции топлива и угол опережения. По одному запросу за раз, с паузой из настройки (по умолчанию 120 мс).

Какие показания есть у конкретного автомобиля, скетч спрашивает сам: запросы PID 00, 20 и 40 возвращают битовые маски, и то, чего в автомобиле нет, отмечается как «нет в автомобиле» и больше не опрашивается. Кроме того, скетч раз в пять секунд читает состояние (PID 01): лампа двигателя и число кодов; если число изменилось — читает сами коды (служба 03).

Из показаний считается то, чего в автомобиле нет: мгновенный расход по расходу воздуха (для бензинового двигателя: воздух/топливо 14,7 по массе, плотность топлива 740 г/л; для дизеля и наддувных двигателей на обеднённой смеси оценка неточна), средний расход, пробег и время поездки, запас хода по остатку топлива и объёму бака.

Транспорт: ISO-TP

Диагностические ответы длиннее семи байт (VIN — 20 байт, список кодов) не помещаются в один кадр CAN и передаются по ISO 15765-2. Блок присылает первый кадр (0x1N), после чего тестер обязан ответить кадром Flow Control (0x30) — иначе блок через секунду бросает передачу. Скетч отвечает сам и собирает кадры продолжения (0x2N) по порядку. Если кадр продолжения потерян или пришёл не в свою очередь, ответ отбрасывается.

Адресация 11-битная: запрос двигателю — 0x7E0, ответ — 0x7E8; коробка передач — 0x7E1/0x7E9; запрос «всем» — 0x7DF. Приёмный фильтр контроллера настроен на диапазон 0x700–0x7FF, весь остальной трафик шины отбрасывается аппаратно.

Скорость шины

Диагностическая шина автомобилей группы VAG работает на 500 кбит/с; на некоторых автомобилях встречаются 250 и 125. Скорость контроллера и шины обязана совпадать: при несовпадении кадры не распознаются, подтверждения нет, счётчик ошибок передачи растёт до 128 (состояние «пассивная ошибка»), и в панели видно «ошибки передачи 128, не ушло кадров N». Скорость выбирается в панели; драйвер при этом перезапускается.

Панель Settings

  • Сейчас: связь, состояние контроллера CAN (счётчики ошибок) и все показания.
  • Поездка: расход мгновенный и средний, пробег, время, средняя и максимальная скорость, запас хода.
  • Коды неисправностей: лампа, коды с расшифровкой для двадцати самых частых (в том числе типичных для VAG — P0016, P0299, P0420…), кнопки «Прочитать» и «Сбросить».
  • Автомобиль: VIN, блоки на шине (запрос всем), поддерживаемые показания.
  • Свой запрос UDS (служба 22): адрес запроса, адрес ответа и идентификатор данных (DID). Автомобили VAG отдают «измеряемые блоки» именно так; какие DID есть у вашей машины и что они означают, зависит от блока и поколения — их берут из документации к вашему блоку. В симуляторе автомобиль знает F190 (VIN), F187 и F189; на остальные отвечает отказом 0x31, как настоящий блок.
  • Настройки: скорость шины, кому слать запросы, пауза между запросами, объём бака, что опрашивать, журнал кадров CAN.

Запись в автомобиль заперта. Сброс кодов (служба 04) сбрасывает не только лампу, но и готовность мониторов диагностики, поэтому запрос выполняется только при включённом выключателе «Разрешить запись» в настройках; он не сохраняется и после каждой перезагрузки платы снова выключен. Это заготовка под управление: когда понадобится, например, автономный отопитель, команды пойдут по тому же пути — через этот выключатель.

В симуляторе

Автомобиль на шине — деталь «Разъём OBD-II». Её свойства — показания, которые отдают блоки: обороты, скорость, температуры, коды неисправностей (через запятую, например P0171,P0300), VIN, скорость шины. Менять их можно на ходу, и они сразу оказываются на дисплее и в панели. Режим «городской цикл» сам ведёт скорость и обороты по 90-секундной кривой.

Симулятор проверяет монтаж и называет причину, если связи нет: нет трансивера между платой и разъёмом, перепутаны CANH и CANL, не запитан трансивер, нет общей земли, вывод CTX не подведён к плате, прошивка передаёт на другой вывод, чем подключён трансивер, скорость не совпадает. Сообщение попадает в журнал симулятора.

Чего в модели нет: арбитража с другими узлами (на шине один собеседник), шлюза, который в настоящей машине пропускает не все запросы, служб сеансов и кодов доступа, а также VAG-овских транспортных протоколов TP 2.0 и KWP — они использовались до перехода на UDS и требуют отдельной реализации.

Что заменить при сборке

  • поставить преобразователь 12→5 В и предохранитель на питание платы; трансивер — от 3V3 платы;
  • убедиться, что на модуле SN65HVD230 вывод Rs посажен на землю (быстрый режим), а перемычка терминатора 120 Ом снята: шина автомобиля уже терминирована с обоих концов;
  • в LCD-модулях подтяжки I2C нередко идут на 5 В — для ESP32 это перебор, снимите перемычки подтяжки или поставьте преобразователь уровней;
  • проверить скорость шины и адреса вашего автомобиля; для расширенных измерений VAG — документация к блоку.

Дальше: отопитель

Управление автономным отопителем (Webasto) — следующий шаг. Способ зависит от модели отопителя: одни управляются по диагностической шине автомобиля, другие — по собственной линии. Заготовка готова: запись в автомобиль заперта отдельным выключателем, а очередь запросов уже умеет отправлять произвольные службы и разбирать отрицательные ответы.

Библиотеки

Пример собирается с библиотеками:

  • WiFi
  • Preferences
  • LittleFS
  • LiquidCrystal I2C
  • Settings

Они уже установлены на сервере сборки — отмечать их в проекте вручную не нужно, список приезжает вместе с примером.

Как это устроено в коде

Основное, чем пользуется скетч:

  • Preferences — хранение настроек во flash, переживает перезапуск
  • LiquidCrystal_I2C — текстовый экран 16×2 по двум проводам
  • millis() — миллисекунды с запуска: на них строят работу без остановки
  • Serial.println() — печатает строку в монитор порта
  • WiFi.begin() — подключается к точке доступа виртуального Wi-Fi
  • delay() — пауза, на время которой ядро занято ожиданием
  • WiFi.softAP() — поднимает собственную точку доступа
  • Serial.printf() — печатает в монитор порта с форматированием
  • digitalRead() — читает уровень на выводе
  • Serial.begin() — открывает монитор порта на заданной скорости
  • pinMode() — назначает выводу режим: выход, вход или вход с подтяжкой
  • digitalWrite() — выставляет на выводе высокий или низкий уровень

В скетче 972 строки; свои функции: setDefaults(), saveSettings(), loadSettings(), note(), hexId(), hexBytes(), canStart(), canStop(); подключено заголовков: 8. Сам скетч открыт на соседней вкладке — его можно менять и запускать заново.

Что попробовать изменить

  1. Нажмите «Запустить». В мониторе порта: «CAN: запущен на 500 кбит/с», через несколько секунд — «сканирование: 7E8 (двигатель); 7E9 (коробка передач)» и VIN. Сценарий сам меняет показания автомобиля; чтобы управлять вручную, снимите галочку «запускать со сценарием».
  2. Нажмите на деталь obd («Автомобиль») и задайте скорость 60 км/ч и обороты 2400: на дисплее появится V60 n2400. Кнопкой btn листайте страницы: скорость и обороты, поездка (пробег, расход), коды.
  3. Откройте «Веб-интерфейс»: все показания, расход сейчас и средний, пробег и запас хода. Поставьте у obd режим «городской цикл» — скорость и обороты пойдут по кривой сами.
  4. Впишите в свойство dtc коды неисправностей, например P0171,P0300: через несколько секунд лампа загорится, коды появятся в панели с расшифровкой. Кнопка «Сбросить» ничего не сделает, пока не включён выключатель «Разрешить запись».
  5. В панели, в разделе «Свой запрос UDS», отправьте запрос F190 на адрес 7E0 (ответ с адреса 7E8) — придёт VIN; идентификатор 1234 вернёт отказ 0x31.
  6. Поставьте у obd скорость шины 250 кбит/с: связь пропадёт, в панели ошибки передачи вырастут до 128, а в журнале симулятора будет сказано, что скорости не совпали. Верните 500 — связь восстановится. Выберите 250 кбит/с в панели — драйвер перезапустится на новой скорости.
  7. Разорвите провод CANH или CANL, уберите общую землю или подключите CTX к другому выводу — журнал симулятора назовёт причину.

Смотрите также

← Все примеры галереи

Схема
Проект из галереи — запускать можно, менять нельзя.

      
Сборка ещё не запускалась.

    Печатайте в Serial числа — они станут графиком. Serial.println(t); — один ряд, Serial.printf("t:%.1f h:%.1f\n", t, h); — два с подписями. Формат тот же, что понимает плоттер Arduino IDE.