Гайд · CAN · OBD-II
Читаем живые данные из машины с ESP32 и CAN-шиной
Любая машина примерно с 2008 года говорит по CAN через порт OBD-II. У ESP32 уже есть встроенный CAN-контроллер (Espressif называет его TWAI), так что добавить нужно лишь трансивер SN65HVD230 за доллар — и можно стримить обороты, температуру ОЖ, скорость и десятки других значений на свой дашборд.
Если арбитраж CAN (доминантный/рецессивный) и дифференциальная пара тебе в новинку — начни с раздела CAN интерактивного разбора шин. Этот пост — практическое продолжение о том, как реально вытащить данные из авто.
Почему ESP32 тут идеален
- Встроенный контроллер TWAI (CAN) — не нужен SPI-модуль MCP2515, периферия прямо на чипе.
- Но пины ESP32 однопроводные, а CAN дифференциальный, поэтому трансивер всё же
нужен.
SN65HVD230работает на 3,3 В — чисто стыкуется с ESP32 (MCP2551 на 5 В и требует согласования уровней).
Подключение к порту OBD-II
SN65HVD230 ESP32
---------- -----
CTX / D (TX) <-- TWAI TX (напр. GPIO5)
CRX / R (RX) --> TWAI RX (напр. GPIO4)
VCC --> 3V3 // 3.3-В трансивер — идеален для ESP32
GND --> GND
CANH / CANL --> OBD-II пины 6 (H) и 14 (L)
// Шина авто уже терминирована — НЕ ставь 120 Ом на разъёме OBD.
Пин 6 OBD-II — это CAN-H, пин 14 — CAN-L, а пин 16 даёт постоянные 12 В (через понижающий преобразователь до 5 В для ESP32). У шины авто уже есть свои терминаторы 120 Ом — свой на разъёме перегрузит её.
Чтение кадров (только приём)
Используй встроенный driver/twai.h. Самая важная настройка —
TWAI_MODE_LISTEN_ONLY: она позволяет принимать, ни разу не выходя на
шину, так что физически нельзя помешать машине. Скорость для OBD-II — 500 кбит/с.
#include "driver/twai.h"
void setup() {
Serial.begin(115200);
twai_general_config_t g = TWAI_GENERAL_CONFIG_DEFAULT(
GPIO_NUM_5, GPIO_NUM_4, TWAI_MODE_LISTEN_ONLY); // только чтение = безопасно
twai_timing_config_t t = TWAI_TIMING_CONFIG_500KBITS(); // OBD-II = 500 кбит/с
twai_filter_config_t f = TWAI_FILTER_CONFIG_ACCEPT_ALL();
twai_driver_install(&g, &t, &f);
twai_start();
}
void loop() {
twai_message_t msg;
if (twai_receive(&msg, pdMS_TO_TICKS(1000)) == ESP_OK) {
Serial.printf("ID 0x%03X [%d] ", msg.identifier, msg.data_length_code);
for (int i = 0; i < msg.data_length_code; i++)
Serial.printf("%02X ", msg.data[i]);
Serial.println();
}
} Запусти с заведённым двигателем — увидишь поток кадров: каждый блок «болтает». Осталось запросить конкретные значения.
Как запросить значение — OBD-II PID
OBD-II — это слой «запрос/ответ» поверх CAN. Отправляешь запрос на ID 0x7DF (например,
режим 01, PID 0x0C = обороты), и ЭБУ отвечает на 0x7E8. Обороты
считаются как (A*256 + B) / 4 из байт ответа. Подставь другой PID — 0x05
(температура ОЖ), 0x0D (скорость) и т.д., список PID стандартный. Для грузовиков и
спецтехники поверх CAN живёт J1939 — та же физическая шина.
Безопасность и грабли
- Оставайся в listen-only, пока точно не знаешь, что делаешь. Запись в живую шину авто может сбить блоки — никогда не экспериментируй на едущей машине.
- Скорость должна совпадать — 500 кбит/с для большинства OBD-II; не та скорость = ноль кадров или шторм ошибок.
- Трансивер обязателен — не подключай CAN-H/L напрямую к GPIO.
- Никаких лишних терминаторов на порту OBD — машина их уже даёт.
- Фильтруй только нужные ID, когда всё заработает — сырая шина загружена.
Отсюда рукой подать до собственного борткомпьютера: заведи расшифрованные значения в пару виджетов — и ESP32 отдаёт живую приборку по Wi-Fi, без облака и приложения.
Посмотри, как арбитраж CAN (доминант/рецессив) гонит байт, вживую.