Сделай сам. Сканер J1939 на ESP32

По профессиональной своей деятельности случаются задачи по оперативной диагностике промышленной техники. В моем случае силовые агрегаты техники, как правило, дизельные двигатели самостоятельно или в паре с автоматической трансмиссией. Система управления силовых агрегатов построена на CAN шине и использует протокол J1939.

Поскольку по работе я не в ИТ, но по хобби давно и плотно с этим связан, то решил я собрать просмотрщик параметров сам. Импортозаместить, так сказать, готовые дорогие заморские решения.

Конечно правда жизни такова, что не использовать импортные компоненты и программные решения уже невозможно, и поэтому в конечном устройстве из отечественного - желание и время.. ну и денег немного. И даже исходники были выложены на “не наш” Github, но это из-за github pages для демонстрации веб интерфейса. В конце концов хватит работать в стол и пришло время тоже бесплатно что-то отдать обществу.

Продукт довольно нишевый и не предназначен для широких масс, но тем не менее я надеюсь, что мои наработки позволят кому нибудь получить ответы на какие-то свои вопросы или быстро стартануть свой проект, если возникнет необходимость использовать подобный стек. А стек здесь такой - в качестве сервера ESP32. В качестве языка backend - c++ в качестве фреймворка бэкенда - ESP-IDF. Для фронтенда использовал Vue3, Typescript, Vite…

Обзор устройства начну с конца, постепенно раскрывая детали:

Онлайн демо веб интерфейса

Комплектующие:

Корпус

Кабель

Контроллер

Преобразователь напряжения

Приемопередатчик CAN


Схема:

Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост

Прошивка:

Проект

Программа для прошивки


Железо и backend:

Код тут

По схеме тут все просто - используются готовые компоненты. Задача понижающего преобразователя напряжения - получить 5v из бортовой сети двигателя (24-28v). На плате Devkit ESP32 имеется свой преобразователь и он из 5v делает 3.3v, что и используется непосредственно ESP32. На входе преобразователя я еще дополнительно припаял диод как элементарную защиту от переполюсовки, хотя по идее можно поставить диодный мост и тогда по поводу перепутать плюс и минус можно не заморачиваться. А переполюсовка тут актуальная тема т.к. у разных производителей на одном и том же разъеме плюсы и минусы на тех же пинах, но поменяны местами. CAN трансивер необходим для преобразования физического уровня CAN шины для работы с обычными цифровыми пинами микроконтроллера.

Для создания программы для микроконтроллера использовался VS Code с установленным официальным расширением от Espressif - Espressif IDF. Может быть используя Arduino платформу какие то вещи можно было бы сделать удобнее, но был интерес въехать и потрогать немного FreeRTOS как бы непосредственно. Немного непривычно поначалу, но если разобраться, то все хорошо. Могу сказать, что система сборки у Espressif норм.

Микроконтроллер при старте инициализирует SPIFFS хранилище (аналог файлового хранилища, где хранятся файлы фронтенда), поднимает точку доступа, файловый сервер, websocket сервер, инициализирует CAN драйвер, начинает слушать CAN шину и при получении сообщений рассылать их всем websocket клиентам подключенным к серверу. Кстати CAN драйвер в ESP32 называется TWAI , что , как я понял , связано с какими-то лицензионными заморочками.

Особенностью файлового сервера является то, что при запросе клиентом файла он пытается отдать этот файл , а если его нет, то пытается отдать заархивированный файл {имяфайла}.{расширение}.gz и только если нет ни того ни другого отвечает ошибкой. Что касается протокола J1939, то на микроконтроллере реализовано только чтение обычных сообщений , широковещательных сообщений переданных по транспортному протоколу (более 8 байт) и отправка простых (8 байт) сообщений в шину. По задумке устройство может отправлять в шину только сообщения об очистке сохраненных ошибок, но тот же самый механизм используется при отправке сообщений для управления желаемой скоростью вращения двигателя и желаемой передачи АКПП. Расшифровка же сообщений происходит в браузере клиента.

Фото:

Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост
Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост
Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост
Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост

Frontend:

Код тут

Для веб интерфейса использовал современные инструменты веб разработки последних ревизий:

TypeScript

Vue3

Vite

VueUse

Echarts

AnimateCss

W3Css

FuseJs

AJV

IndexedDb


Проект веб приложения имеет 3 сценария сборки:


build_preview - собирает проект для предпросмотра на локальном сервере (preview)


build_embedded - собирает проект непосредственно для микроконтроллера. Генерируются только архивированные файлы gz. Разделение на части не производится т.к. опытным путем установлено, что файловый сервер ESP32 быстрее отдает один файл побольше чем несколько разделенных файлов. Весь проект в архивированном виде имеет размер 498kB и отлично помещается в памяти ESP.


build_deploy - этот сценарий добавлен недавно и создает файлы для публикации приложения на github pages. Пример настройки альтернативного именования файлов, поскольку сборка по умолчанию (preview) генерирует файл с символом “_” в начале, что в результате порождает ошибку при скачивании файла браузером.


Помню в начале знакомства с веб разработкой у меня было непонимание - где конкретно находятся файлы веб приложения и как они исполняются. И если у кого-то возникает такой вопрос, то работает это все так: При обращении из браузера (клиента) к какой-либо странице, сервер отвечает файлом index.html. В этом файле есть список файлов веб приложения и браузер запрашивает эти файлы с сервера, разархивирует и далее действует по инструкциям из этих файлов. Таким образом файлы веб приложения изначально находятся на сервере, скачиваются и выполняются браузером.

На веб приложение ушло больше всего времени. Изначально я сделал все с использованием замечательной библиотеки element-plus, но почему-то выловил жесткую утечку памяти и месяц бился с этим явлением. Постепенно заменяя компоненты из element-plus самописными.


Общий алгоритм работы приложения такой- приложение получает массив байт от микроконтроллера, далее этот массив декодируется с помощью данных из JSON файла. (Как я искал и парсил доступную инфу по J1939 - тема для отдельной статьи.)


Поскольку вся спецификация протокола довольно объемна, то хранить ее на мк не выйдет , по крайней мере в стандартной комплектации ESP32 Devkit с 4 Mb флеш памяти. В связи с чем решено было хранить данные для декодирования параметров и передаваемых ошибок на стороне клиента в браузере. При первой загрузке веб приложения эти файлы создаются автоматически, но имеют немного данных для декодирования и можно изменить данные в этом файле в текстовом редакторе или загрузить по указанным в приложении ссылкам.

При загрузке файлов правильность их структуры проверяется с помощью отличного AJV по схеме файла. Данные хранятся в памяти браузера и при использовании из другого браузера или с другого устройства надо опять подгружать файлы.

Поиск по параметрам осуществляется с помощью FuseJS через интеграцию VueUse. Вообще библиотека VueUse должна быть дефолтной частью проекта на Vue3 поскольку содержит огромное количество очень полезных функций, которые намного облегчают код и работают напрямую с реактивными объектами Vue.

В приложении есть возможность строить графики изменения параметров. Добавление параметра на график осуществляется включением соответствующего переключателя в меню параметра. Графики строятся используя гениальный Echarts и в коде в частности есть пример переключения темы графика “на лету”.


И все это дело собирается в 498Kb! По моему не плохо. Собранные файлы помещаются в папку spiffs_images проекта для микроконтроллера и сохраняются в его памяти при прошивке. Из этой области памяти файловый сервер ESP32 отдает файлы по запросу браузера.


Среди вопросов по работе остался момент периодической “заморозке” вебсокет сообщений, которые были замечены из браузеров на линуксе и на андройде, причем периодичность их появления не зависит ни от чего. Из браузеров виндовса подобная проблема ни разу не проявила себя, что наталкивает на мысль о какой-то глубокой малозаметной ошибке в реализации протокола либо на стороне ESP либо на клиентской стороне.

Вообще в целом реализация проекта подарила интересный опыт и полезные наработки, что, думаю, может пригодиться в будущем (если оно будет)).


Фото в “полях”:

Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост
Сделай сам. Сканер J1939 на ESP32 IT, Open Source, Esp32, Образование, Программирование, Can, Длиннопост

P.S. Поскольку я сам не в ит и для знакомых я занимаюсь непонятными делами и разговариваю непонятными словами, то мне была бы интересна обратная связь, замечания и предложения по коду и реализации проекта.

Лига программистов

1.5K поста11.3K подписчиков

Добавить пост

Правила сообщества

- Будьте взаимовежливы, аргументируйте критику

- Приветствуются любые посты по тематике программирования

- Если ваш пост содержит ссылки на внешние ресурсы - он должен быть самодостаточным. Вариации на тему "далее читайте в моей телеге" будут удаляться из сообщества