- Хакаем CAN шину авто. Виртуальная панель приборов
- CAN сниффер из Arduino Uno
- Подслушиваем запросы с помощью диагностической системы VAG-COM (VCDS)
- Разработка панели приборов на основе Raspberry Pi и 7″ дисплея
- Софт панели приборов на Python и Kivy (UI framework)
- Видео работы цифровой панели приборов на базе Raspberry Pi
- Приложение на телефон Виртуальная панель приборов
- Цифровая приборная панель на автомобиль своими руками
- Схема
- Скетч (прошивка) для контроллера Arduino Mega
- Настройка ESP-8266
- Приложение «Приборная панель для планшета»
Хакаем CAN шину авто. Виртуальная панель приборов
В первой статье «Хакаем CAN шину авто для голосового управления» я подключался непосредственно к CAN шине Comfort в двери своего авто и исследовал пролетающий траффик, это позволило определить команды управления стеклоподъемниками, центральным замком и др.
В этой статье я расскажу как собрать свою уникальную виртуальную или цифровую панель приборов и получить данные с любых датчиков в автомобилях группы VAG (Volkswagen, Audi, Seat, Skoda).
Мною был собран новый CAN сниффер и CAN шилд для Raspberry Pi на базе модуля MCP2515 TJA1050 Niren, полученные с их помощью данные я применил в разработке цифровой панели приборов с использованием 7″ дисплея для Raspberry Pi. Помимо простого отображения информации цифровая панель реагирует на кнопки подрулевого переключателя и другие события в машине.
В качестве фреймворка для рисования приборов отлично подошел Kivy для Python. Работает без Иксов и для вывода графики использует GL.
- CAN сниффер из Arduino Uno
- Подслушиваем запросы с помощью диагностической системы VAG-COM (VCDS)
- Разработка панели приборов на основе Raspberry Pi и 7″ дисплея
- Софт панели приборов на Python и Kivy (UI framework)
- Видео работы цифровой панели приборов на базе Raspberry Pi
Под катом полная реализация проекта, будет интересно!
Водительская дверь открыта
CAN сниффер из Arduino Uno
Чтобы послушать, что отправляет VCDS в CAN шину я собрал сниффер на макетке из Arduino и модуля MCP2515 TJA1050 Niren.
Схема подключения следующая:
Для прослушивания трафика использовал анализатор CanHackerV2 и прошивку arduino-canhacker для Arduino, которая реализует API совместимое с этой программой. Прошивка в гите https://github.com/autowp/arduino-canhacker.
CanHackerV2 позволяет смотреть пролетающий трафик, записывать и проигрывать команды с заданным интервалом, что очень сильно помогает в анализе данных.
Подслушиваем запросы с помощью диагностической системы VAG-COM (VCDS)
Описание VCDS с официального сайта ru.ross-tech.com:
Программно-аппаратный сканер VCDS предназначен для диагностики электронных систем управления, устанавливаемых на автомобилях группы VAG. Доступ ко всем системам: двигатель, ACP, АБС, климат-контроль, кузовая электроника и т.п., считывание и стирание кодов неисправностей, вывод текущих параметров, активация, базовые установки, адаптация, кодирование и т.п.
Подключив сниффер к линиям CAN_L и CAN_H в диагностическом шнурке я смог увидеть какие запросы делает VCDS и что отвечает авто.
Особенность авто группы VAG в том, что OBD2 разъем подключен к CAN шине через шлюз и шлюз не пропускает весь гуляющий по сети трафик, т.е. подключившись в OBD2 разъем сниффером вы ничего не увидите. Чтобы получить данные в OBD2 разъёме нужно отправлять шлюзу специальные запросы. Эти запросы и ответы видно при прослушивании трафика от VCDS. Например вот так можно получить пробег.
В VCDS можно получить информацию почти с любого датчика в машине. Меня в первую очередь интересовала информация, которой вообще нет на моей приборке, это:
- температура масла
- какая именно дверь открыта
Скорость, обороты, температура ОЖ, пробег, расход, место в баке и другие запросы я тоже получил, для справки размещу.
Разработка панели приборов на основе Raspberry Pi и 7″ дисплея
В качестве аппаратной части я выбрал Raspberry Pi. Была идея использовать Android планшет, но показалось, что на Raspberry Pi будет проще и быстрее. В итоге докупил официальный 7″ дисплей, и сделал CAN шилд из модуля TJA1050 Niren.
OBD2 штекер использовал от старого ELM327 адаптера.
Используются контакты: CAN_L, CAN_H, +12, GND.
Тесты в машине прошли успешно и теперь нужно было все собрать. Плату дисплея, Raspberry Pi и блок питания разместил на куске черного пластика, очень удачно подобрал пластмассовые втулки, с ними ничего не болтается и надежно закреплено.
Местом установки выбрал бардачок на торпедо, которым я не пользуюсь. По примеркам в него как раз помещается весь бутерброд.
Напильником довел лист черного пластика до размера крышки бардачка, к нему прикрепил бутерброд и дисплей. Для прототипа сойдет, а 3D модель с крышкой для дисплея и всеми нужными крепежами уже в разработке.
Софт панели приборов на Python и Kivy (UI framework)
Параллельно со сборкой самой панели приборов я вел разработку приложения для отображения информации с датчиков. В самом начале я не планировал какой либо дизайн.
Первая версия панели приборов
По мере разработки решил визуализировать данные более наглядно. Хотел гоночный дизайн, а получилось, что-то в стиле 80-х.
Вторая версия панели приборов
Продолжив поиски более современного дизайна я обратил внимание какие цифровые приборки делают автопроизводители и постарался сделать что-то похожее.
Третья версия панели приборов
Ранее, я никогда не разрабатывал графические приложения под Linux поэтому не знал с чего начать. Вариант на вебе простой в разработке, но слишком много лишних компонентов: иксы, браузер, nodejs, хотелось быстрой загрузки. Попробовав Qt PySide2 я понял, что это займет у меня много времени, т.к. мало опыта. Остановился на Kivy — графический фреймворк для Python, простой в понимании с полной библиотекой графических элементов и дающий возможность быстро создать мобильный интерфейс.
Kivy позволяет запускать приложение без Иксов, прямо из консоли, в качестве рендера используется OpenGL. Благодаря этому полная загрузка системы может происходить за 10 секунд.
Алгоритм работы следующий, используется 3 потока:
- В главном потоке работаем с графическими элементы (спидометр, тахометр, часы, температуры и др) на экране
- Во втором потоке каждые 5 мс делаем опрос следующего датчика
- В третьем потоке слушаем CAN шину, получив ответ парсим его и обновляем соответствующий графический элемент
Работает стабильно, самый долгий процесс в разработке был связан с рисованием дизайна. На данный момент обкатываю решение и потихоньку пишу мобильное приложение для iOS, чтобы любой мог попробовать цифровую панель приборов.
Проект цифровой панель приборов открытый. Рад буду предложениям и комментариям!
Видео работы цифровой панели приборов на базе Raspberry Pi
Приложение на телефон Виртуальная панель приборов
Для телефона написал приложение — виртуальная панель приборов, данные от машины передаются через ELM327 Wi-Fi адаптер. Адаптер подключается в OBD2 разъем, делает запросы по CAN шине и возвращается ответы в приложение по Wi-Fi.
Приложение VAG Virtual Cockpit уже в AppStore. Пока, что только под iPhone/iPad, но Android версия планируется. Приложение решил сделать платным с минимальной символической стоимостью.
Если есть желание поддержать проект, то вот ссылка на приложение, принимаю любые замечания и предложения!
VAG Virtual Cockpit
Источник
Цифровая приборная панель на автомобиль своими руками
Для ее создания потребуются следующие комплектующие:
- Контроллер Arduino MEGA
- Планшет с операционной систем Androir
- Модуль Wi-Fi esp8266
- Преобразователь питания с 12 до 5 вольт (можно использовать любое автомобильное зарядное устройство для мобильных телефонов).
К контроллеру Arduino подключаются все датчики автомобиля. В нашем случае потребовалось еще установить датчик скорости в коробку передач вместо тросика привода спидометра. А так же завести провод в салон автомобиля от коммутатора зажигания, чтобы контроллер смог отображать обороты двигателя (это нужно было сделать, так как в ОКЕ не был установлен тахометр).
Схема
Датчики к контроллеру подключить необходимо по следующей схеме:
Скетч (прошивка) для контроллера Arduino Mega
Скачать готовый скетч в файле можете по этой ссылке.
unsigned long micros_sp = 0, micros_th = 0;
volatile int tz;
volatile int sz;
volatile int sp; //импульсы спидометра
volatile int th; //импульсы тахометра
int analogInput [15]; //массив аналоговых значений
int digitalInput[29]; //массив цифровых значений
String resultString = «»; //строка
int i; //счетчик циклов
//********************************************************************
void setup() <
for(i=0; i
digitalInput[i]=0;
>
for(i=0; i
analogInput[i]=0;
>
Serial.begin(115200);
Serial2.begin(115200); //инициализация ком порта
attachInterrupt(0, speedometr, RISING); //прерывание спидометра по фронтам импульса
attachInterrupt(1, tahometr, RISING); //прерывание тахометра по фронтам импульса
>
//********************************************************************
void loop() <
analogInput[0] = analogRead(0); // B13 напряжение
analogInput[1] = analogRead(1); // B24 топливо
analogInput[2] = analogRead(2); // B21 температура охлаждения
analogInput[3] = analogRead(8); //
analogInput[4] = analogRead(7); //
analogInput[5] = analogRead(3); //
analogInput[6] = analogRead(4); //
analogInput[7] = analogRead(9); //
analogInput[8] = analogRead(10); //
analogInput[9] = analogRead(11); //
analogInput[10] = analogRead(12); //
analogInput[11] = analogRead(13); //
analogInput[12] = analogRead(14); //
analogInput[13] = analogRead(15); //
analogInput[14] = analogRead(6); //
digitalInput[0] = digitalRead(4); // зажигание
// digitalInput[1] = digitalRead(5); //
//********************************************************************
digitalInput[2] = digitalRead(53) + //
digitalRead(51) * 2; //
//********************************************************************
digitalInput[3] = digitalRead(5) + // A14 левый поворот
digitalRead(6) * 2; // A13 правый поворот
//********************************************************************
digitalInput[4] = digitalRead(8) + // A18 ближний
digitalRead(9) * 2; // A17 дальний
//********************************************************************
digitalInput[5] = digitalRead(10) + // А16 птф передние
digitalRead(11) * 2; // A15 птф задний
//********************************************************************
digitalInput[6] = digitalRead(23); // A23 чек
digitalInput[7] = !digitalRead(21); // B 9 — уровень тж
digitalInput[8] = !digitalRead(31); // A19 — ручник
digitalInput[9] = digitalRead(25); // B 3 износ колодок
digitalInput[10] = !digitalRead(45); // B10 — лампа топлива
digitalInput[11] = !digitalRead(51); // B12 — уровень ож
digitalInput[12] = !digitalRead(47); // А24 — давление масла
digitalInput[13] = digitalRead(27); // A20 лампа вентилятора
digitalInput[14] = !digitalRead(29); // A23 зарядка
digitalInput[15] = digitalRead(33); // A 5 абс
digitalInput[16] = digitalRead(35); // A20 srs
digitalInput[17] = digitalRead(37); // A 3 ремень
digitalInput[18] = digitalRead(39); // B 1 двери
digitalInput[19] = 0;//digitalRead(22); // B 2 p
digitalInput[20] = 0;//digitalRead(24); // А22 r
digitalInput[21] = 0;//digitalRead(26); // A 7 n
digitalInput[22] = 0;//digitalRead(28); // B 6 d
digitalInput[23] = 0;//digitalRead(30); // B 5 s
digitalInput[24] = digitalRead(41); // A 8 резерв
digitalInput[25] = 0;//digitalRead(32); // A 9 резерв
digitalInput[26] = digitalRead(43); // A10 резерв
digitalInput[27] = 0;//digitalRead(34); // A11 резерв
digitalInput[28] = digitalRead(49); // B 4 резерв
resultString = String(resultString + sp);
resultString = String(resultString + «,»);
resultString = String(resultString + th*10);
resultString = String(resultString + «,»);
for(i=0; i
resultString = String(resultString + analogInput[i]);
resultString = String(resultString + «,»);
>
for(i=0; i
resultString = String(resultString + digitalInput[i]);
>
resultString = String(resultString + «:\n»);
// Serial2.print (resultString);
Serial.print (resultString);
resultString = String(«»);
tz = tz — 1;
sz = sz — 1;
if (tz == 0)
delay(50);
>
//********************************************************************
void speedometr() < //измеряем частоту на входе спидометра по прерыванию
sp=(900000.0/( micros() — micros_sp));
micros_sp = micros();
sz = 10;
>
//********************************************************************
void tahometr() < //измеряем частоту на входе тахометра по прерыванию
th=(2900000.0/( micros() — micros_th));
micros_th = micros();
tz = 10;
>
Настройка ESP-8266
Перед тем как подключать Модуль ESP8266 к схеме его нужно прошить и настроить в режиме прозрачного моста Tcp2uart (tcp to uart), чтобы полученные данные с ком-порта он передавал планшету по Wi-Fi.
Прошивать лучше через USB-UART преобразователь, который должен иметь выход источника 3.3V для питания ESP8266. Так же этот источник должен обеспечить необходимый ток не менее 200мА.
Готово! Теперь при подключении модуля ESP-8266 к ардуино он работает в режиме прозрачного моста и по Wi-Fi передает необходимые данные.
Приложение «Приборная панель для планшета»
Приложение можете скачать по ссылке.
Благодарим пользователя Frud портала Drive2 за опубликованную версию приложения и описание метода установки приложения:
После установки приложение уже будет работать. Для того чтобы включить его автозагрузку необходимо сделать следующее:
После установки необходимо зайти в настройки Андроид, в раздел «Домашний экран», выбрать приложение приборной панели VenatorLite2. Очень важный момент! Выйти в настройки Андроида из приложения приборной панели для возврата стандартного Launcher-a нельзя. Перед тем как установить приложение вместо Launcher-a необходимо убедиться что в настройки можно зайти из статусбара. Иначе вернуть стандартный лаунчер будет проблематично.
ПРИМЕЧАНИЕ! Перед установкой автозагрузки желательно настроить и отладить работу приложения.
После запуска приложения нужно зайти в настройки (нажать на значок шестеренки справа вверху). Тут надо указать ip-адрес и порт (В нашем примере этими значениями являются: адрес 192.168.4.1 и порт 3333).
Осталось все подключить и протестировать. Если все сделали правильно, то при вкючении устройства и подаче на 4-ый пин ардуино «плюса» приборная панель включится.
А вот как выглядит приборная панель, установленная в ОКУ:
Желаем успеха в реализации данного проекта
Источник