Arduino can шина автомобиля
Изучаем CAN-шину при помощи Arduino. Первые шаги.
Автомобильная электроника уже давно перешла на цифру. А значит придется изучать цифровые шины передачи данных. В качестве подопытного у меня был тахограф от автомобиля МАЗ как источник кодов и комбинация приборов ЩП8151-1 в роли исполнительного устройства. Работают они по протоколу J1939 на скорости 250КБит.
Так же была куплена плата Arduino Uno и контроллер CAN-шины MCP2515.
Была установлена программа Arduino IDE 1.6.0 для написания скетчей. Пришлось немного изучить C++. В молодости я изучал Pascal, поэтому пришлось немного помучиться.
Первая задача была — это подключиться к тахографу и посмотреть что он вещает. А после этого научиться отправлять коды в шину что бы щиток приборов что-то показал.
Что касается написания скетча, то за основу брал вот этот блог www.drive2.ru/l/498541387973656626/.
Правда с первого раза ничего не заработало. Пришлось долго и упорно разбираться, изучая и саму программу и библиотеки. В итоге нашел несколько моментов из-за которых программа не принимала пакеты.
2. в библиотеке mcp_can.cpp в mcp2515_init надо установить прием всех сообщений.
Вот этот кусок:
Вот основная программа:
Теперь вгружаем ее и смотрим монитор последовательного порта.
В идентификаторе 0CFE6CEE, первый байт 0C — это приоритет сообщения, далее два байта FE6C — номер группы параметров (скорость автомобиля), и последний байт EE — это источник (тахограф).
Теперь пробуем отправлять данные в шину. Для этого используем следующую программу:
Подключаем щиток приборов и получаем скорость и пробег:
Эксперименты с Arduino. Часть 3. Идеи нового проекта с использованием CAN шины
в последнем блоге по ардуино я написал, что у меня появилась задумка выводить все данные не на сторонний экран, а на экранчик приборки машины. Идея вовсе не утопическая, а уже однажды реализованная одним человеком в 2011 году:
Я уже делал блог несколько лет назад, однако тогда у меня не было совсем никаких знаний, как такое можно сделать. Я связывался с этим человеком, однако ни мне, ни другим (а это видно в комментариях) этот человек отвечать не хочет. Непонятно, какую цель он преследует. Нашей машине уже почти десяток лет, она уже явно не так интересует народ, как раньше и надеяться на то, что его ноу-хау принесет ему крупные деньги…это как-то глупо. Но каждый выбирает свой путь…
Мы же пойдем своим, благо появились возможности попытаться замахнуться на собственную реализацию чего-то подобного. Итак…
Сначала немного теории.
Многие из вас пользовались устройством ELM-327 для диагностики авто. Многие знают, что стандартный EML позволяет читать такие данные машины, как скорость, обороты, положение дрос. заслонки, температура впуска, показания лямбд, давление и прочее-прочее-прочее. Все эти данные наши программы получают, использую протокол диагностики OBD-II, который грубо говоря является оберткой вокруг других протоколов, в частности работы с CAN-шиной.
В наших фиатах существует две CAN-шины. Если вы посмотрите в диагностический разъем, то увидите, что у нас есть контакты на следующие пины: 1,9, 4, 5, 6, 14, 16.
Несколько лет назад, когда я вешал свой чип-тюнинг на провода 4, 16, 6, 14 я не задумывался, а за что они отвечают. Итак, 4, 5 и 16 — это «земли» и 12В соотвественно. 6 и 14 — это так называемая шина C-CAN. Шина имеет скорость 500 kbps и считается скоростной, отвечает за работу двигателя, abs и других критически важных узлов машины. Именно с ней работает хорошо нам известный ELM 327.
А что же 1 и 9. Эти пины стандартом OBD-II относятся к тем, которые могут использоваться производителем в своих целях. Фиат использует их для диагностики шины B-CAN. Это так называемая шина комфорта. Скорость ее работы 50 kbps.
На ней висят приборка, боди и прочие вещи.
Внимание, именно здесь кроется необходимость использования так называемых переходников для работы с multiecuscan и прочими для диагностики остальных узлов, кроме двигателя.
Если вы посмотрите внимательно, то увидите, что «желтый» переходник это ничто иное как перемыкание ножек разъема с шины C-CAN на выходы B-CAN:
Этот же мод можно сделать и внутри ELM 327, просто перепаяв выходы на нужные ножки OBD разъема и убрав терминирующий резистор на 120 ОМ, если он есть
Как вы уже поняли, меня интересует именно возможность управления приборной панелью.
Итак, в первой стадии проекта мне нужно научиться просто соединяться с CAN шиной комфорта и хотя бы читать сообщения, которые гуляют по сети. Что нам для этого нужно. Поскольку я решил все делать на ардуино, то для работы с CAN шиной нам сильно поможет CAN шилд. Купить в Донецке такое нереально сейчас, но один добрый человек предложил мне сделать его самостоятельно. Неделя ожидания и имеем такой вот бутерброд:
Сразу встал вопрос, а как им пользоваться ) Первым делом решил подсоединиться к проводам шины, выведенной в диагностический разъем OBD, поскольку к ним подобраться легче всего.
Сказано-сделано. Однако открыв логи Serial порта на ноуте увидел пустоту. Сразу возникли мысли, что шилд нерабочий. Или простой код, вычитывающий все сообщения из CAN шины, неверный…День ушел на поиски причины и оказалось все банально просто. Нужно было просто соединить землю машины с землей ардуины. И вот тут вот начались чудеса:
Приборка запищала, затрещала. Появилась ошибка питания усилителя руля, он выключился, появилась ошибка подушки безопасности водителя и пассажира. Пропала температура за бортом. Короче, весело. Но при этом сообщения из CAN шины посыпались как из рога изобилия )) :
О структуре сообщений расскажу в последующих главах, если смогу с ними разобраться ). Но первая стадия вроде бы достигнута. Но какой ценой…
Полез я в multiecuscan и ужаснулся. По всем абсолютно узлам куча ошибок, машина на скорости иногда при разгоне тупо блокирует его… Короче, срочно взял и все почистил и понял, что что-то делаю не так. Начал рыть инет.
Информации в сети ноль по фиатам. Однако косвенно понял, что многие не зря «садятся» на шину не в диагностическом разъеме, а непосредственно в самом интересуемом узле. Итак, что у нас есть в приборке.
А есть у нас там следующее:
Пришлось ставить eLearn и искать распиновку разъема. С трудом, но нашел:
Нас интересуют пины 1, 5, 6. 1-ый это земля, 5 и 6 — это некие шины CAN-A, CAN-B. Они то нам и нужны.
Ничего не обрезая просто присоединился к нужным мне проводам и вывел в удобное мне место 3 провода и подсоединил их для теста на шилд. И о чудо, никаких ошибок приборки, машины и прочего.
Таким образом своей цели я достиг и смог спокойно без проблем для машины читать сообщения из CAN шины комфорта.
Что дальше. А дальше нужно понять, что означают эти цифры:
А представляют они собой сообщения CAN шины, то, что посылается от body компьютера на приборку и то, что собственно отрисовывается приборкой на экранчике. Многие автолюбители методом проб и ошибок и анализа чудовищного потока информации смогли выделять для машин VAG, Mazda нужные сообщения, смогли определить вариацию стандарта, используемого для формирования CAN сообщений. Таким образом, узнав нужные сообщения появляется возможность «перехвата» и «подмены». Таким образом на нужный экран можно будет смело выводит вместо, допустим моментального расхода что-то нужное и более полезное.
У меня к вам просьба. Если кто-то сталкивался или видел подобную информацию или кто-то имеет опыт реверс инженерига CAN сообщений, а в идеале имеет опыт с фиатами, то прошу вас помочь. Я не видел нигде информации по фиатам, но это реально очень интересная тема, которая позволит придумать в будущем интересные штуки. Я же сам планирую попытаться, используя схожие сценарии других автолюбителей, разобраться с сообщениями и расшифровать их структуру. Оставайтесь на связи!
Arduino — постигаем CAN BUS
Приветствую всех! Некоторое время назад, я сделал запись о своих опытах с шиной LIN BUS. Но прогресс не стоит на месте, и я добрался до шины CAN.
А так, как прошлая запись многих заинтересовала, сейчас попробую описать, что у меня получилось с шиной CAN.
Итак, CAN шина — это линия связи(обычно 2х проводная), при помощи которой различные блоки нашего автомобиля обмениваются информацией. У нас в машине есть несколько CAN шин работающих на разных скоростях. Я решил подключиться к шине CONFORT, которая объединяет такие блоки, как BSI, магнитола, дисплей, блок кнопок двери водителя. Работает эта шина на скорости 125 кбит/сек.
Для подключения шины к популярной сейчас ARDUINO, необходимо использовать CAN модуль, например такой: CAN модуль MCP2515, стоит он около 2$. Далее необходимо импортировать в Arduino IDE библиотеку для связи с этим модулем. Я взял вот эту : Библиотека. В комплекте с библиотекой, есть пример чтения шины, загрузив который в ардуино, мы сможем видеть пакеты, присутствующие в шине. На основе этого примера, я написал программу, которая не только читает шину, но и посылает в неё команды.
Программа выполняет три задачи:
1) Включение 5го выхода ардуино, если скорость автомобился больше 60 км/ч. Этот выход я подключил к транзистору, который отключает пищалку в радар-детекторе. Теперь, в городе, я его практически не слышу. Раздражало его пищание на двери супермаркетов, например.
2) При нажатии на кнопку НАЗАД(с левой стороны руля), на дисплей выводится температура двигателя, вместо температуры окружающего воздуха. Температура двигателя отображается, только, пока нажата кнопка.
3) Автоматическое закрытие стекол, после того, как заглушил двигатель.
Кстати, я использовал ARDUINO NANO, прилагаю схему подключения к модулю CAN.
К CAN шине подключился на блоке BSI, черный разъем( CAN-H: пин №8 желтый, CAN-L: пин №10 фиолетовый)
Много информации почерпнул на этом форуме ФОРУМ
Какие пакеты ходят по шине, можно посмотреть ЗДЕСЬ
Спасибо за внимание!) Если есть вопросы, спрашивайте!
Напоследок, прилагаю саму программу для ARDUINO NANO:
CAN-bus Arduino адаптер руля Citroen C4B7. Подключаем 2din к шине CAN. Часть 1.
Значит делать было нечего и решил я заменить китайское незнамо что хорошей 2din магнитолой (JVC KW-M560BT). За время использования Teyes я понял что это невообразимой глубины бездна багов, лагов и пользоваться этой отрыжкой it-индустрии я больше не могу. Тем более основное что мне надо от этой штуки, как оказалось, это музыка и навигация через CarPlay.
Как я подключил 2din, наверное, в другой раз опишу и работает она идеально — музыка льется как мед для ушей, а CarPlay работает лучше самого телефона. Но сейчас вкратце и по верхам поделюсь как сделать так что бы кнопки руля которые работают по can-шине доходили до магнитолы в виде «резистивных сигналов».
Сразу скажу что это первый опыт, я аматор, новичок и просто делаю это в свое удовольствие в обед и вечерком между рабочими делишками.
Как работает canbus в двух словах: по определенным проводам машины постоянно летают сигналы о состоянии разных агрегатов и механизмов, например что включено и что нет, скорость, нажатие кнопок и тд.
Например если кнопка громкости не нажата, то в определенных пакетах данных каждые 100 миллисекунд приходит значение 0, а если нажата то те же 100 миллисекунд приходит значение 64.
Больше инфы и деталей по CAN Citroen C4 тут. Там же достаточно информации что бы собрать свой CanHacker для исследования сообщений на шине.
Теперь задача состоит в том что бы отловить эти пакеты данных, проверить что в них, перевести это в понятный для магнитолы язык и отправить ей. Магнитолы обычно имеют несколько проводов для резистивного управления с руля — GND, KEY1, KEY2. Меняя сопротивление между KEY1/KEY2 и GND мы говорим магнитоле что нажата определенная кнопка.
Для тестирования на столе пришлось собрать 12 физических кнопок что бы имитировать машину и еще одно can устройство которое бы имитировало активность в кан-шине.
Какие материалы нужны:
1️⃣ Arduino Nano / ATMEGA 328p — мозг этого всего устройства.
2️⃣ mcp2515 tja1050 модуль — модуль которые переводит в понятный для ардуино язык сигналы canbus.
3️⃣ ULN2803APG — микросхема которая в этом устройстве работает как реле, виртуально нажимая резистивные кнопки, то есть посылает сигналы в магнитолу что нажата некая кнопка на руле.
4️⃣ Набор резисторов (220, 470, 680… и другие, но кажется это должно подбираться индивидуально под магнитолу, каждые резистор — другая виртуальная кнопка)
5️⃣ Паяльник, припой, макетки, куча проводов и все остальное что бы превратить квартиру в гараж и мастерскую )
Схему я рисовал впервые, поэтому вышло как вышло, по крайней мере пару таких устройств по ней я собрал и всё работает ) Использовал юзерфрендли прогу Fritzing, интуитивно понятная, легко разобраться.
Схема нарисована для голого чипа Atmega328p, но по ней легко понять как заменить микросхему на готовую Arduino Nano. Предполагается что питание каким-то модулем конвертируется из 12 в 5, модулей разных огромная куча.
Суть работы устройства: mcp2515 переводит сигналы кан-шины в понятный для atmega328p/arduino язык, на atmega328p/arduino мы пишем код который отлавливает нужные нам сигналы и передает их в ULN2803APG.
ULN2803APG — это такое себе, если сильно грубо сказать — реле, на одну ногу мы подаем +5в, а на другой открывается канал к которому и подключен нужный резистор и KEY1/KEY2 магнитолы. Дальше магнитола определяет сопротивление и считает что нажата кнопка руля.
Всего в ULN2803APG есть 8 транзисторных пар, но кнопок магнитола может захотеть и 10 и 12 (как в моем случае) с этим проблем нет — просто открываем сразу несколько транзисторных пар и получаем новое сопротивление.
К машине это подключается через quadlock разъем. Он продается в любых авто- и радио- магазинах, через него и питание и CAN-шина.
CAN sniffer
CAN шина
Описывать технические подробности CAN шины в деталях — удел документации. В данной статье достаточно знать, что она:
Подключаюсь в диагностический разъём OBD (контакты 6 и 14) и смотрю осциллографом, что там имеется. После поворота ключа зажигания начинают бегать пакеты с амплитудой до 2,5 В. Ставлю паузу на осциллографе и смотрю на пакет.
Заметны стартовые и стоповые биты, какие-то данные в пакете. На тот момент я уже знал, что скорость передачи данных ожидается 500 кбит/с, как наиболее частая для моторной CAN шины. Длительность пакета получается около 230 мкс и перед пакетом наблюдается довольно большая пауза в передаче данных. Масштабирую время и вижу три пакета и паузы между ними.
Если сложить длительность передачи данных и паузу между пакетам получается, что передача одной порции данных занимает около 1 мс.
К чему я это всё вывожу? А вопрос чисто практический: хватит ли скорости последовательного порта для передачи всех данных? И исходя из увиденного, можно сделать вывод, что скорость 500 кбит/с развивается внутри пакета, который занимает примерно четверть времени на передачу. Значит средняя скорость передачи будет вчетверо меньшей. На тот момент я ещё не располагал тестами скорости последовательного интерфейса Arduino и забегая вперёд скажу, что даже с самым распространённым преобразователем Serial to USB CH340 стабильно работает скорость в 2 Мбит/с.
CAN scanner на Arduino
Первый прибыл шилд для классической Arduino UNO. Да он стоит значительно дороже своих более мелких собратьев, но он имеет на борту всё необходимое и даже две кнопки.
Именно с ним я и начал все эксперименты. Собрал простую схему с этим шилдом и жидкокристаллическим двухстрочным экраном. Цель была — вывести на экран хоть какие-то данные. Перебирал различные библиотеки для работы с CAN шиной на Arduino (сразу скажу, что правильная и рабочая библиотека называется CAN-BUS Shield by Seeed Studio с заголовочным файлом mcp_can.h), поменял кварцевый резонатор на шилде на 16 МГц (изначально стоял 8 МГц) — данных не было.
На шилде установлены две микросхемы: контроллер CAN шины MCP2515 и драйвер CAN шины TJA1050. Почитав документацию и различные форумы, решил поменять TJA1050 на более каноничный драйвер MCP2551 и данные появились. Возможно TJA1050 была изначально неисправна, так как с её подключением двумя проводками ошибиться было очень сложно, к тому же я использовал OBD и DB9 разъёмы для подключения.
За пару часов был написан простой CAN scanner, который выводил на жидкокристаллический дисплей номер захваченного пакета, его ID и до 8 байтов данных этого пакета.
Вот тут и пригодились кнопочки на шилде, которыми я реализовал переключение между номером отображаемого пакета.
Начало было положено, надо переходить к более интересной реализации.
CAN sniffer на Arduino
Задача стояла достаточно простая:
Для того, чтобы отправляемые данные корректно обрабатывались на стороне компьютера, перед каждой очередной порцией данных в поток вставляется префикс из четырёх байтов 0xAA55AA55 (почему-то вспомнились эти байты по последним двум байтам загрузочного сектора DOS, только они там были в другом порядке). Логика такая:
Так же я написал простой генератор пакетов данных для отладки, чтобы отлаживаться дома — он просто отправляет в последовательный порт пакеты со случайными данными, что позволяет отлаживать приложение на компьютере в комфортных условиях.
Примерно в это же время прибыли более миниатюрные компоненты Arduino Nano и Mini CAN shield.
Я спроектировал небольшой корпус, распечатал его и разместил внутри все компоненты.
Снаружи с одной стороны OBD разъём, с другой — Mini USB. Внутри имеется переключатель для терминирующего резистора.
CAN sniffer на PC с использованием wxWidgets
Ранее я в нескольких проектах использовал библиотеку wxWidgets и о ней у меня только приятные впечатления. Она легковесная, нет необходимости тащить с собой различные библиотеки и даже кросс-платформенная, что вселяет надежду, что интерфейсную часть кода можно перенести без значительных переделок на другие платформы. В конце статьи будет ссылка на скомпилированную программу, если возиться со всем этим не будет желания.
Можно скачать и посмотреть видео (менее восьми минут), а можно выполнить 6 шагов по описанию ниже.
Установка и компиляция wxWidgets:
1. Скачать и установить wxWidgets если это установщик, либо распаковать, если это архив
2. Создать переменную окружения WXWIN указывающую на папку, куда установили или распаковали (например C:\wxWidgets):
3. Из папки C:\wxWidgets\build\msw открыть файл решения под соответствующую Visual Studio (wx_vc16.sln для Visual Studio 2019)
4. В Solution Expolorer, с помощью клавиши Shift, выделить все проекты, кроме _custom_build и зайти в Properties проектов.
Для конфигурации Debug выбрать /MTd
Для конфигурации Release выбрать /MT
6. Скомпилировать библиотеки wxWidgets по очереди для Debug и Release конфигураций.
Пробное приложение и настройка проекта в Visual Studio (для проверки)
1. В Visual Studio создать Empty Project с указанием типа приложения Desktop Application (.exe)
3. Создать файл main.cpp и скопировать в него содержимое файла:
Runtime Library для конфигурации Debug: /MTd
Runtime Library для конфигурации Release: /MT
UAC Execution Level: requireAdministrator
6. Для добавления иконки exe-файлу надо добавить ресурсный файл со следующим содержимым:
#include «wx\msw\wx.rc»
wxicon icon app_icon.ico
Первый реализованный прототип на C++ и wxWidgets показал, что даже нетбук справляется с отображением данных в таблице и я приступил к разработке задуманного.
Архитектурно программа состоит из двух потоков: интерфейсный и поток работы с последовательным портом. Никаких невероятно интересных алгоритмов не применялось. Код обильно снабжён комментариями и должен быть довольно понятен. Ссылка на исходники будет в конце статьи.
Первое что было сделано — раскраска ячеек данных в таблице по давности получения этих данных. Уже в первом прототипе, глядя на 17 строк данных меняющихся непрерывно значений, я понял, что надо как-то различать свежие данные и данные, которые не изменяются или меняется редко. Сделал раскраску в два этапа:
Далее мне захотелось всё-таки проверить, справляется ли последовательный порт с потоком данных. Для этого я на стороне Arduino добавил счётчики количества принятых пакетов и счетчик байтов в пакете. Эти счётчики отправляются на компьютер в пакете с идентификатором 0x000. Программа при получении этих данных не выводит их в таблицу, а отображает в отдельных информационных полях сверху. Полученные результаты даже весьма понравились. В среднем принимается до 750 пакетов/с со скоростью до 9,5 кБ/с, а это где в районе до 80 кбит/с, что вполне по силам последовательному порту. Но всё равно, обмен данными настроен по умолчанию на 500 кбит/с, пусть лучше будет запас.
Добавление возможности записи данных в журнал появилось после того, как подключил параллельно к OBD интерфейсу диагностический адаптер ELM327 и связав его с телефоном, попробовал читать различные данные. Данные пробегали настолько быстро, что увидеть их невозможно. Записав всё это в журнал, можно потом спокойно сесть и посмотреть передаваемые данные. Для этого в журнал могут записываться даже ASCII текстовые данные. Так же можно выбирать тип файла, символ разделитель и настроить фильтр пакетов кликом в таблице по указанному идентификатору пакета и нажатию кнопки «Добавить ID в фильтр» (по умолчанию записываются все данные), если запись всех данных избыточна.
Именно тогда пришло осознание, что все приложения для телефона, которые производят всякую «диагностику» через связку ELM327 и телефон, не общаются напрямую с CAN шиной автомобиля. Они всего лишь используют функционал диагностики OBD через CAN шину посредством обращения к CAN ID 0x7E0. Обычно это адрес контроллера мотора (ЭБУ), ответ же от него приходит в пакете с идентификатором 0x7E8. А вот все остальные пакеты данных — это так называемый Vendor Specific и ни один производитель так просто их не раскроет (хотя есть пример: Ford выпустил SDK для своих автомобилей).
Продолжая изучать что же передаётся в этих пакетах пришёл к ещё одной идее: при клике на ячейку в таблице, в окне программы справа выводить двоичное и десятичное значение этого байта, а так же брать следующий байт и дополнять до слова. Далее это слово умножать на некий коэффициент и получить десятичный результат. Звучит не очень понятно, но вот в связи с чем это делалось: обороты мотора приходят в пакете CAN ID 0x180, в первых двух байтах. Эти два байта дают некое слово, которое пропорционально оборотам. Если значение этого слова разделить на 8, то получатся текущие обороты. Поэтому указывается множитель 0,125, как обратная величина от 8. Далее это слово визуализируется в графике с динамической подстройкой по амплитуде. В принципе, множитель можно искать в обратной последовательности: нашёл ячейки, которые по графику очень похожи на обороты мотора или ещё что-то искомое, после чего подгоняется множитель для получения действительных значений.
Ну а двоичное представление позволяет искать различные битовые индикаторы. Например поиск индикаторов указателей поворота сводится к тому, чтобы включить их и наблюдать какая ячейка начинает изменяться, в примере ниже это CAN ID 0x481 байт 2. После чего клик по ячейке приводит к отображению её двоичного значения в соответствующем поле, где уже видны переключающиеся младшие два бита (левый, правый и если вместе — аварийная сигнализация).
И напоследок мне понадобилось сделать отправку некоторых управляющих данных в CAN шину и посмотреть реакцию на эти команды. В программу на Arduino был добавлен код, который принимает данные со стороны компьютера и передаёт в CAN шину. Именно на этом этапе пришлось отказаться от CyberLib, так как у неё не было поддержки прерывания поступления данных в буфер последовательного порта. В программе на компьютере добавил несколько текстовых полей, в которые можно ввести различные параметры и таблицу для просмотра ответа исполнительного устройства. В примере ниже показаны команды управления включить/отключить первую скорость вентилятора охлаждения (0x0A) и включить/отключить муфту кондиционера (0x0B).
Практически нигде не найти полные расшифровки данных производителей, тем более официальных. В лучшем случае это будут чьи-то изыскания в рамках реализации какой-то дополнительной функции. CAN sniffer может помочь в поиске этих данных. Я смог найти порядка 40 различных параметров автомобиля и ради эксперимента, на базе полученных данных, я сделал собственное управление вентилятором охлаждения.
































