Общая сводка. На фото выше представлена 3D модель разработанной мной платы при помощи САПР Altium Designer. Основные характеристики и функционал:
- 10\100 Mb Ethernet
- RTC
- MicroSD (FAT12, FAT16, FAT32) 4GB
- RS232 \ RS485
- CAN
- Buzzer
- 3 User LED
- GPIO
- EEPROM 32 KB
- FLASH 2 MB
- I2C
- SPI
- UART
- SW \ JTAG
- USB serial (COM Port)
- Power: miniUSB 5V \ External 9..24V
Стоимость собранной платы ~ 5000 Р. Проект носит open source характер, исходники можно найти на github. То, что получилось в итоге, помимо основного функционала, можно считать неплохой отладочной платой для работы с микроконтроллером STM32.
А теперь к подробностям создания.
Hardware
Изучение данной задачи началось с поиска и оценки готовых решений. Основными требованиями были:
- преобразование поступающих CAN2.0B фреймов в TCP\IP пакеты и наоборот;
- невысокая стоимость, как следствие реализация устройства на базе микроконтроллера.
У коллег из Китая есть несколько промышленных решений, но не из дешевых, поэтому в наш офис на тест был доставлен представитель отечественного производства «Преобразователь интерфейсов ПИРС CAN-Ethernet». По описанным возможностям и характеристикам устройство удовлетворяло скромное Т.З., оставалось лишь проверить работоспособность на деле, чем я и занялся, вооружившись Wireshark’ом и осциллографом. По неизвестной причине при отправке в девайс TCP пакетов на выходе устройства, там, где должны были появляться CAN фреймы, выплёвывались последовательности с физическими уровнями CAN (диф. пара), но логическим протоколом интерфейса UART (со стартовыми и стоповыми битами). Вскрыв корпус, открыв документацию микросхем и прозвонив дорожки платы, я обнаружил, что, действительно, пины RX и TX (UART) микроконтроллера соединены с трансивером CAN и с него выведены на внешний разъем. Таким образом, никакой аппаратной поддержки стандарта CAN2.0B ожидать не приходилось.
Вот, что я увидел на выводе CANL «ПИРС CAN-Ethernet» при отправке двух байт данных [0xF0] и [0x0A] по TCP\IP:
Порядок бит перевернут, но с этим можно бороться программно, а вот со стартовыми и стоповыми битами через каждый байт что-то сделать на уровне приложения уже сложнее т.к. они вставляются аппаратно.
А вот как должен был выглядеть «истинный» CAN2.0B фрейм с теми же двумя байтами данных:
Как видно из осциллограммы, помимо байт данных в фрейме присутствует немало служебных бит протокола плюс биты стаффинга, а что самое главное – идут они непрерывно без всяких стартовых и стоповых! (Для тех, кому интересно, под спойлером детальное описание данной посылки).
Таким образом, решить проблему несоответствия CAN и UART фреймов программным способом мне не представлялось возможным и, окинув разочарованным взглядом промежуточные результаты исследований, было принято решение разработки собственного прототипа требуемого устройства.
В связи с тем, что теперь под контроль можно было взять более широкий спектр технических характеристик устройства, добавились следующие требования:
3. Возможность питания от 12-24 В в транспортных системах;
4. Наличие внешней памяти для хранения логов;
5. Размеры платы не более 86х80мм.
6. Рабочий диапазон температур -40..85 °С
В качестве мозга нового устройства была выбрана небезызвестная платформа STM32F407VET6 [2], обладающая аппаратной поддержкой всех необходимых интерфейсов и неплохим запасом RAM и FLASH памяти. Пошерстив интернет, в качестве PHY Ethernet был выбран трансивер DP83848IVV [3], имеющий хорошую, на мой взгляд, документацию и достаточно примеров схем с подключением и трассировкой. В качестве внешней энергонезависимой памяти для хранения логов я выбрал SPI FLASH 2 MB и SPI EEPROM для хранения разнообразных настроек. Кроме того была добавлена защита питания от перенапряжения, переполюсовки. Через N вечеров и M выходных были составлены принципиальная схема и трассировка печатной платы устройства первой версии. Т.к. места на плате было достаточно, а незадействованные ножки МК оставлять не хотелось, помимо основного функционала на плату были добавлены:
- средства для отладки SW, JTAG;
- переключатель 8-DIP Switch;
- micro-USB (USB Serial);
- RS-232;
- UART;
- I2C;
- GPIO
Идея была в том, чтобы при необходимости плата была готова к расширению функционала за счет монтажа дополнительных компонентов. Тем более на стоимость производства запасные посадочные места не влияют. На одной стороне, к сожалению, из-за этого уместить все не удалось, так что плата получилась двусторонняя 86х80мм, мин. ширина дорожки 0.25мм, мин диаметр отверстия 0.6мм.
Первая версия PCB-дизайна
Позже были заказаны и собраны два тестовых образца с полным набором периферии для исследований. В целях экономии плата была изготовлена без маски поэтому имеет такой нехарактерный цвет.
При помощи STM32CubeMX я набросал тестовую прошивку с проверкой работоспособности основных периферийный модулей устройства и, в первом приближении, заработало все, кроме запуска МК от внешнего кварца 8 МГц. Оказалось, из-за моей ошибки в составлении спецификации, были напаяны не те нагрузочные конденсаторы. Но это не помешало STM32F407 работать от внутреннего RC-генератора. Когда же я смог пропинговать свое устройство, радости было не сдержать т.к. с трассировкой PHY Ethernet я провозился, наверное, дольше всего. Затем в браузере я увидел свою тестовую http страницу и с тестированием успокоился.
Производство первых образцов плат заказывали в Зеленограде. И, несмотря на то, что стоимость «с» маской и «без» отличалась почти в два раза, не рекомендую так делать даже на стадии прототипа, потому что, как правило, как раз на этом этапе всплывают ошибки трассировки и приходится что-нибудь перепаивать. А паяться на «голых» дорожках крайне неприятно, денег сэкономите, а вот нервов – вряд ли. Да и гадать потом коротнулось ли где-то или трассировка неверная – такое себе удовольствие. Я, в силу неопытности, перепаивая кварцевый резонатор и нагрузочные конденсаторы, один образец таки убил.
К тому времени, на работе, в закромах нашлась железка способная решить поставленную задачу конвертации в текущем проекте, но, помимо крупных габаритов и стоимости, сев писать для нее прошивку, я столкнулся с проблемами связанными с объемом RAM и урезанным функционалом TCP\IP стека МК LPC2368. Так что желание сделать свое устройство только усиливалось.
Внимательно изучив недостатки первой версии, я, долго не думая, приступил ко второй. И снова захотелось добавить «задел на будущее», вместив в прежний форм-фактор следующие компоненты:
- поддержка RTC с батарейкой;
- RS-485;
- micro-SD;
- пищалка buzzer;
- возможность питания от USB;
- SPI на внешний разъем;
- питание 5V и 3.3V на внешний разъем.
Кроме прочего была добавлена защита питания по току и TVS диоды на пользовательские разъемы.
В итоге получился этакий dev-board с возможностью подключения внешних модулей. На этот раз плату заказал в Китае. Сборка производилась у нас.
Вторая версия платы
Ко второй версии я разобрался с 3D моделированием в Altium Designer, что очень помогло в избежании ошибок взаимного расположения компонентов по двум сторонам (оказалось, в интернете уже полно готовых моделек SMD компонентов [4]). Тем самым, все ошибки первой версии были исправлены, нововведения показали свою работоспособность, что очень меня порадовало.
Firmware
Описание кода выходит за рамки данной части, однако пару слов о программной составляющей сказать хочется. В своем устройстве я решил использовать связку FreeRTOS + LwIP стек. Статей про них в достаточном количестве, например, [5] и [6], поэтому прикрутить их к своему проекту не должно составить трудностей. Вкратце, LwIP – TCP\IP стек для встраиваемых систем, характеризующийся малым потреблением RAM и удобным API (есть даже BCD socket оболочка). Я использовал netconn API. Средствами FreeRTOS, вся работа TCP\IP стека помещается в поток отдельный от приложения. Помимо основной работы (соединение внешнего TCP-сервера с CAN шиной) в самостоятельном потоке крутится отдельный веб-сервер для доступа к настройкам устройства. Такой веб-интерфейс предназначен для мониторинга и конфигурации настроек устройства – установки разных режимов работы, скоростей передачи, адресов и т.д. Пока не знаю получится ли сделать и обновление прошивки через него.
Заключение
Это был мой первый (и надеюсь, что не последний) хардверный проект такой сложности и, несмотря на допущенные ошибки, вторую версию платы, думаю, можно считать успешной. На каждой итерации было множество сомнений, но, тем не менее, лишний раз убеждаюсь, что если не пробовать — получаться ничего точно не будет.
Используемые источники
1. Wikipedia/Controller_Area_Network
2. STM32F407VET6 datasheet
3. DP83848 datasheet
4. 3D Models
5. Введение в FreeRTOS
6. Введение в LwIP
Комментарии (34)
NordicEnergy
17.08.2019 23:50Уровень трассировки конечно трындец… Надеюсь это делал студент. Интересно, что там такого в эзернете долго разводилось, когда 100 Мбит поднимаются на макетке с МГТФом.
Кстати, если это открытый проект, то залейте его на github, а то писать/отвечать в личку и на почту это утомительно и вам и интересующимся.
bazooka_easter
18.08.2019 00:00Не могли бы Вы подробнее описать проблемы с трассировкой?
ClownMik Автор
18.08.2019 01:02Проблем как таковых не было, за исключением разнящейся и зачастую противоречащей друг другу информации в интернете о правильной трассировке диф. пар. В итоге старался следовать преимущественно рекомендациям к DP83848. Из-за желания расширить функционал и неправильного планирования часто приходилось переставлять многие модули на плате, что значительно замедляло разработку.
NordicEnergy
18.08.2019 08:23Какие вами рекомендации то нужны? Берете любой калькулятор типа SaturnPCB и считаете стек своей платы и узнаете параметры проводников для нужного импеданса, затем переносите его в правила altium designer и просто прокидываете 2 дифпары. Это базовые понятия, тут даже не нужно даташит от производителя открывать.
Inanity
18.08.2019 13:24+1Несколько замечаний и от меня:
1. Пожалуй наиболее важное замечание это использование 2-х слойной платы. Я ещё могу понять самодельщиков, которые из кожи лезут вон, чтобы уложиться в 2 слоя для удобства ручного изготовления ПП (сам был таким давно), но раз уж вы так или иначе связываетесь с производством, то тем более для такой платы просто необходимо было заложить 4 слоя. И отдать на внутренние два — питание с землёй. Шинное соединение питания и земли, как это сделано у вас, крайне не приветствуется. В данном случае сплошные полигоны значительно увеличили бы качество ПП и упростили бы разводку. К примеру, конденсаторы по питанию нужно устанавливать максимально близко к микросхеме. Это очень удобно и эффективно делать на 4-х слоях с обратной стороны компонента. Все расчёты импеданса дифф. пары, которые вы возможно делали скорее всего бесполезны, т.к. у вас нет опорного слоя, хотя и длина проводника (неоднородности) достаточно мала, чтобы на что-то сильно повлиять. Возможно вам покажется это избыточным, но для ваших будущих проектов, если частоты интерфейсов будут достигать >50-100МГц, то с подобным конструктивом питания и земли с большой вероятностью будут проблемы. Я понимаю, что оно и так работает. Собственно говоря, работает потому, что частоты небольшие и хорошо, если вы, понимая это, осознанно проектируете в двух слоях. Хотя для продакшена такой платы эта экономия опасна и может выйти боком, лучше иметь запас по качеству.
2. У Ethernet PHY под брюхом микросхемы есть термопад, который у вас, судя по всему никуда не подключён. Через этот пад чип рассеивает тепло. Если бы у вас была 4-х слойная плата, то соединив этот пад с внутренним полигоном земли вы могли бы максимально эффективно охлаждать чип под высокой нагрузкой.
КартинкаClownMik Автор
18.08.2019 16:21Большое спасибо за замечания и советы, учту на будущее. По пункту 3. — корпуса разъемов соединены с землей через 1 МОм резистор и 1 кВ конденсатор в параллель.
NordicEnergy
18.08.2019 08:191) Дороги выводятся из падов какими-то неимоверными способами. Там, где дорогу можно вывести из центра площадки и перпедикулярно, выводят под 45 градусов и от края пада… Ладно если бы это было в одном-двух местах, там вся плата такая. Этот вот классический «хуяк хуяк и в продакшен».
ПримерыClownMik Автор
18.08.2019 22:43В трассировке я действительно новичок и буду рад дельным советам. На github выложил.
NordicEnergy
18.08.2019 23:14Возможно будет интересно — читать.
А вообще нужно вырабатывать чувство прекрасного, чтобы все эти кривости-корявости самому глаз мазолили и хотелось делать аккуратно.
Еще тут вроде в комментариях видел Говарда Джонса «Начальный курс черной магии», можно для ознакомления прочитать бегло, там базовые вещи неплохо разжеваны, а дальше уже только опыт и ревью коллег.
ClownMik Автор
18.08.2019 22:45В трассировке я действительно новичок и буду рад дельным советам. На github выложил.
ktod
18.08.2019 06:39действительно, пины RX и TX (UART) микроконтроллера соединены с трансивером CAN и с него выведены на внешний разъем.
Серьезно? Кто то такое производит? Это же профанация. Или этому таки можно найти применение?ClownMik Автор
18.08.2019 13:10Тоже был очень удивлен. Как ответили разработчики, в каких-то промышленных счетчиках эл. энергии действительно используется такой канал связи.
GarryC
18.08.2019 13:49Меня просто потрясают подобные решения, особенно «недорого».
Про связку преобразователя со стандартной платой Вам уже написали, вот еще вариант.
Не для рекламы, хотя лично я эти модули использую и претензий к ним, ну не то, чтобы совсем нет, но немного zao-zeo.ru/catalog/sbc/118-tion-pro28 — 5830 рублей и это не STM, так какого фига?
dobrev
18.08.2019 13:57Если это не обман зрения, то на первой версии разъём microUSB, а на второй — miniUSB. Почему так?
ClownMik Автор
18.08.2019 14:12Все верно. Это не обман зрения. Заметил, что miniUSB разъемы доступнее в магазинах РЭИ (во всяком случае известных мне Чип-Дипе и Элитане) чем microUSB, да и кабелей таких много и габариты позволяют.
KonstantinSpb
18.08.2019 15:531. www.altium.com/live-conference/altiumlive-2018-annual-pcb-design-summit#The-Extreme-importance-of-PC-Board-Stack-up
2. High-Speed Digital Design: A Handbook of Black Magic
ianzag
18.08.2019 19:06+1Как-то мягко говоря дороговато — 5000 рублей — для такой в общем то немудреной вещи. Любой пай на A20 сделает все тоже самое, а стоить на али будет в два раза меньше. И это с точки зрения «а не прикрутить ли нам ещё XXX» будет совсем не STM.
checkpoint
18.08.2019 22:50С этого места поподробнее пожалуйста, какая такая «пай на A20» имеет CAN интерфейс? И что это такое «пай на A20»?
Недавно с коллегой прикупили комплект конвертеров Ethernet-CAN на Али (как раз по 5000 руб за штуку) с целью «удлинить» OBD II от Nissan Leaf. Искомый результат не достигнут, так как инкапсуляция CAN фрэймов в UDP выполнена с достаточно высокой задержкой (как мне это показалось), точнее вообще непонятно как она выполнена — Leaf Spy обрывает соединение где-то в середине попытки получить данные о состоянии автомоильной батареи.ianzag
19.08.2019 00:00Под A20 имеется виду платы на базе SoC Allwinner A20. У него на борту уже есть CAN контроллер (описан в A20 User Guide). Возьмем к примеру первую попавшуюся Xunlong Orange Pi Mini. На 40pin гребенке я вижу CAN_RX/TX. Да, там нет видимо опторазвязки и ещё каких приятных ништяков, но на сколько я могу судить это вполне себе обычный CAN.
Далее идем на али и ищем похожие поделки. Почти уверен, что даже с учетом пересылки уложитесь в 2000 рублей.checkpoint
19.08.2019 00:09Простите, а кто софт писать будет для этого «пай на A20» непосредственно инкапсуляции и декапсуляции CAN в TCP или UDP? Или вы думаете, что CAN это почти как UART который можно перенаправить командой cat из shell-а?
Как я написал, одну поделку мы уже купили, 10 тыр на ветер. Теперь хочу увидеть опробованное решение.KonstantinSpb
19.08.2019 01:01Xunlong Orange Pi Mini и отдельные копеечные CAN трансиверы за 60р
SN65HVD230 CAN bus transceiver
www.aliexpress.com/item/32686393467.html
Простите, а кто софт писать будет для этого «пай на A20» непосредственно инкапсуляции и декапсуляции CAN в TCP или UDP?
Всё уже придумано до нас и гуглится на раз, есть готовое софтверное решение github.com/mguentner/cannelloni или rtime.felk.cvut.cz/can/can-eth-gw.pdf
ianzag
19.08.2019 09:26> Простите, а кто софт писать будет для этого «пай на A20» непосредственно инкапсуляции и декапсуляции CAN в TCP или UDP? Или вы думаете, что CAN это почти как UART который можно перенаправить командой cat из shell-а?
Берем can4linux и пишем? Навскидку не вижу в этом ровным счетом ничего сложного. Если вдруг A20 или его аналога нет в can4linux дописываем поддержку (тоже тривиально).
И таки вспоминаем, что CAN конечно CANом, но это ещё и сетевое устройство. Которое каким то образом должно интегрироваться в локальную сеть. Со всеми вытекающими из этого мелкими геморроями типа настройка/получение IP адреса, если адрес получается динамически то поиск устройства в сети и вот это вот все. И для таких развлечений IMHO куда приятнее работать с обычной линуксой.
Hewdin
19.08.2019 12:24+2Я когда-то тоже делал подобное устройство. Далее прототипа не пошло, т.к. софт не осилил. Пошел по пути изготовления «свистка» UART-CAN. Независимость от платформы и работа в терминале, в том числе.
KonstantinSpb
19.08.2019 00:01В Ethernet могут быть задержки в силу работы доступа к среде передачи и эти задержки перед доступом к среде носят случайный характер. CSMA/CD
checkpoint
19.08.2019 00:14Разумеется, но не более 0.5мс. Более того, сборка/разборка TCP добавит еще задержку особенно при загруженной сети. Но мы все это знаем и понимаем. Купленные девасы не достигают эффекта даже будучи воткнуты друг в друга метровым кабелем.
checkpoint
18.08.2019 22:57+1Скажите, вы продаете это изделие или оно «open source»? Если последнее, то не могли бы Вы выложить исходники (схему, гербера, исходники прошивки). Хотим повторить ваш опыт для одного хоббийного проекта с участием электрокара Nissan Leaf.
Достаточно схемы и исходников прошивки. Плату накидаем свою под размеры корпуса.ClownMik Автор
19.08.2019 00:14Выложил исходники на github, обновил статью. Прошивка еще не до конца дописана, но в том что есть, думаю, найдете много полезного. Буду постепенно обновлять. Любопытно как у вас получится, пишите.
IronHead
20.08.2019 17:25Из аналогов есть еще spb.terraelectronica.ru/product/1048019
По моему они скопипастили эту плату с какой то olimex, то есть при желании можно купить за те же деньги уже готовую плату с Eth и CAN
da-nie
Мы такое на отечественных контроллерах (от Миландра) и микросхемах делали. :)