В предыдущей статье я рассмотрел решение по созданию недорогого варианта для открывания шлагбаума. После нескольких месяцев тестирования в посёлке были выявлены проблемы, исправлены ошибки. Статья повторяет первую, но основана на практическом опыте, в ней много фотографий, ссылки на исходники. Информации должно быть достаточно, чтобы каждый смог это быстро повторить.
Общая концепция
На автомобили наклеиваются метки, на КПП вешаются считыватели меток, которые по wifi передают коды на роутер, роутер генерирует wiegand посылки, которые передаются в СКУД. СКУД принимает решение об открытии шлагбаума.
Первоначально я хотел использовать пароли, зачитывать один раз TID, второй раз по паролю. Как выяснилось в боевых условиях, ручное зачитывание (ReadCard) меток происходит достаточно долго, метка может считываться с ошибками, а значит надо делать множество попыток повторного чтения. Суммарно всё это приводило к долгому ожиданию перед открытием шлагбаума. Первым этапом был отказ от паролей, вторым - перевод считывателя в Active Mode, что значительно ускорило реакцию на метку: за секунду считыватель зачитывает больше 5 меток. Вариант включать пароли в Active Mode не проверял.
Сами считыватели можно купить с уже запаянными wifi модулями, которые отправляют в сеть информацию по меткам, так что если нет желания заморачиваться, можно купить готовый, написав только wiegand генератор на роутере.
Считыватели RU5306 отлично работают на всех автомобилях с обычным стеклом. Если же стекло с электроподогревом, качество считывания сразу очень сильно падает, в итоге я выставил RU5306 на продажу и купил RU5312. В этих моделях разница только в размере антенны и наличии светодиода, контроллеры совершенно одинаковые.
Модификация считывателей CF-RU5312
![Прям вспомнилось начало первого фильма про Эйса Вентуру Прям вспомнилось начало первого фильма про Эйса Вентуру](https://habrastorage.org/getpro/habr/upload_files/8e2/585/023/8e258502356143f4a713dbc4bd6a4aea.jpg)
Мне привезли заказ - две большие коробки со считывателями. Первая в отличном состоянии, второй считыватель оказался помят. К счастью дефект не повлиял на работоспособность. В коробке со считывателем не оказалось блока питания, что несколько испортило моё отношение к продавцу. По просьбе читателей я решил разобрать все считыватели и устроить фотосессию с обнажёнкой. В RU5312 крышка, скрывающая антенну, оказалась приклеена на силикон или что-то подобное. В RU5306 используются прокладки, что позволяет ничего не отдирать.
![Антенна считывателя RU5312 Антенна считывателя RU5312](https://habrastorage.org/getpro/habr/upload_files/1e8/d56/1e3/1e8d561e37d9d710158788b644434e8b.jpg)
К сожалению, у меня крайне мало опыта в антеннах, так что никаких комментариев дать не смогу.
![](https://habrastorage.org/getpro/habr/upload_files/9b9/622/159/9b96221595fd24739100ad0d982771ce.jpg)
К считывателю добавляем модуль ESP8266, прошивку можно взять из форка Tasmota https://github.com/BASM/Tasmota/ ветка uhf_nopass. Перед сборкой следует создать файл tasmota/mypass.inc, в котором указать логин/пароль от wifi, к которому будет подключаться модуль:
#define STA_SSID1 "uhfbarrer"
#define STA_PASS1 "zpubpR78T"
#define STA_SSID2 "reserve"
#define STA_PASS2 "pXNWo3Bmn"
#define WIFI_AP_PASSPHRASE "gR8I81mHC0"
Стоит заметить, что tasmota в каких-то случаях начинает пытаться получить время и дату по NTP и делает это крайне неоптимальным способом. Если же до NTP сервера достучаться не получается, считыватель переводится почти в неработоспособное состояние, постоянно "подвисает". Я сделал грязный хак, отключающий этот функционал. Если вам нужна правильная дата, сделайте revert этого коммита.
Для сборки нужно воспользоваться инструментарием platformio, для упрощения я добавил Makefile, так что достаточно набрать make для сборки. После сборки будет создано две прошивки: tasmota-minimal и tasmota-sensors. Прошивки архивируются.
![Не самый правильный, но самый простой способ перевести ESP8266 в режим программирования. Не самый правильный, но самый простой способ перевести ESP8266 в режим программирования.](https://habrastorage.org/getpro/habr/upload_files/06b/0b2/309/06b0b23094c57c2ba86a30de2ca1ca4b.png)
Для записи в ESP8266 нужно загрузить МК в режим программирования, это можно сделать, запаяв провода как на картинке. Для прошивки можно набрать "make flash", будет зашита прошивка tasmota-sensors. Перед прошивкой рекомендуется очистить память, это можно сделать командой "make flashclean". Если память не почистить, то области, где находятся настройки tasmota, не будут перетёрты, а значит могут возникнуть проблемы.
После прошивки нужно отпаять все провода кроме питания, а затем подать питание. Модуль подключится к wifi. Если это произошло, модуль можно запаивать, т.к. дальнейшее обновление можно делать через web-интерфейс. Из-за малого количества памяти на микроконтроллере обновление в tasmota сделано в два этапа: необходимо отправить сжатый образ minimal, после прошивки ещё раз перепрошить уже sensors версией.
![Запайка ESP8266 в штатный разъём на ножки. Запайка ESP8266 в штатный разъём на ножки.](https://habrastorage.org/getpro/habr/upload_files/cbe/ebf/e73/cbeebfe73574e8bb1d28e2381d2c4a4d.png)
Можно запаять модуль прямо на штатный разъём, но (при необходимости) выпаять его будет крайне сложно. Если припаять на ножки, то это значительно облегчит задачу.
В стандартной схеме ESP модуль UART-ом подключён к управляющему микроконтроллеру и является ведомым устройством. Мы сделаем его главным, для этого мы подключаем выход UART считывателя к ESP модулю. UART подпаиваем прямо в параллель к RS-232 драйверу, ножка 12 (удобнее запаять к стабилитрону) и 11. Идеально было бы, конечно, переписать прошивку управляющего микроконтроллера, но я пошёл более топорным вариантом.
Считыватель можно настраивать в разные режимы работы, нас интересует режим считывания TID и выдача его в UART. Делается это с помощью программы Reader Software, которую можно скачать с сайта фирмы chafon. В идеальном случае настраивать считыватель нужно из ESP модуля, но я так и не заставил себя дописать этот функционал в прошивку.
![Модификация закончена. Модификация закончена.](https://habrastorage.org/getpro/habr/upload_files/d0a/11c/691/d0a11c69155b9b0d09959a032ca5758a.png)
Из считывателя выходит масса проводов: питание, RS-232, wiegand, выход на реле и т.п. В нашем случае реально задействован будет только один - провод питания. Я установил на считыватель дополнительный 12v разъём питания и убрал все остальные провода. В большом считывателе RU5312 есть двухцветный светодиод, он очень помогает при анализе проблем, в RU5306 его не подключают, при кастомизации очень советую его добавлять. Разъём с бело-чёрно-красным проводом отвечает за него. Если на считывателе есть питание - горит красный светодиод, если считыватель зачитывает данные с метки - загорается зелёный светодиод. Причём загорается он, даже если данные были зачитаны с ошибкой (crc не совпала).
Делаем wiegand генератор на роутере
![](https://habrastorage.org/getpro/habr/upload_files/937/805/3eb/9378053eb7fd5b8e949bb69c4fd1a8e2.png)
Вариантов открыть шлагбаум, получив правильную UDP посылку, можно предложить массу. Наш вариант - прошить OpenWRT на роутер и вставить туда silabs cp2104, который с помощью PIO будет генерировать wiegand посылки. У меня старый роутер, куда устанавливается только старая версия OpenWRT, где старое ядро со старым драйвером cp2104, которое не поддерживает PIO. Наиболее простой выход из ситуации для использования PIO использовать libusb библиотеку. На радость такую библиотеку уже написал Андрей (nekromant): https://github.com/nekromant/pl2303gpio
Саму утилиту можно скачать тут: https://github.com/BASM/ufhudp2wiegand.git, команда make соберёт утилиту. Я не вижу особого смысла писать ещё одну подробную инструкцию, как заставить утилиту запускаться на роутере. Так что лишь кратко опишу, куда двигаться: скачиваем кросскомпилятор с проекта OpenWRT под ваш роутер, исправляем Makefile, указывая кросскомпилятор, собираем командой make, при желании проверяем с помощью qemu-mips (qemu-user позволяет запускать утилиты, собранные под другую архитектуру, на инструментальной машине), копируем на роутер, добавляем в автозапуск. Наиболее простой способ добавить в автозапуск - это поправить скрипт в /etc/rc.local, не забыв про знак "&", чтобы не блокировать скрипт /etc/rc.local.
Утилита для компьютера
![LJYNZ-105 LJYNZ-105](https://habrastorage.org/getpro/habr/upload_files/53e/dfe/842/53edfe8424c0b60b05537c575a69ed51.jpg)
Настольных считывателей я в общей сложности купил два, один Chafon CF-RU5102, второй LJYNZ-105, так как на него появилась очень хорошая скидка. Оба считывателя имеют совершенно одинаковые интерфейсы, даже документация отличалась только первой страницей. Но внутренности оказались немного разные.
В LJYNZ-105 были заботливо затёрты все наименования чипов, в CF-RU5102 затёрт только чип, отвечающий за управление. Для RF используется ADF7020, для USB Silabs CP2101. С точки зрения общей схемы считыватели крайне похожи, это USB<->Uart преобразователь, микроконтроллер, реализующий интерфейс общения, и RF контроллер. В LJYNZ-105 была обнаружена незначительная проблема, при включении и выключении бизера он продолжал очень тихо пищать. Прошу прощения за качество фотографии CF-RU5102, заметил это после того как уже отдал оборудование.
Я припаялся к DTR и RTS, тем самым получил возможность генерировать wiegand посылки из системы, куда подключён считыватель.
К сожалению, библиотек для работы со считывателем для языка C я найти не смог, поэтому решил написать свою. Я её разместил тут: https://github.com/BASM/UHFreader: библиотека и пример использования. Пример - это программа, которая решает две задачи: устанавливает пароли на метки (если метки поддерживают), что позволяет защитить метки от уничтожения, и позволяет внести код метки в СКУД, не вставая со стула. Ещё на метку в EPC записывается содержимое TID, использовалось в период тестирования, я решил не убирать эту функциональность.
Какие метки использовать
![](https://habrastorage.org/getpro/habr/upload_files/04e/b24/e1e/04eb24e1e67becf5c9d54dc6b47aa5a0.png)
Я накупил разных видов меток. Метки вида (2) работали крайне плохо, они имеют малый радиус и при чтении постоянно не совпадает CRC; лучше всего ловит (1), которые продаёт сам chafon. После того как был выявлен лидер, жителям по умолчанию выдавались метки вида (1). Было создано 3 тестовых комплекта, состоящих из всех видов, любой желающий мог взять его, протестировать и составить отчёт. Но к сожалению кроме меня этим никто не занялся. Так что по субъективным оценкам (3), (4) и (6) работают несколько хуже, чем (1), но лучше, чем (2). Метка (5) ко мне приехала в единственном экземпляре в качестве "пробника", я её наклеил на машину соседу и в целом дать оценку её работы не могу.
![](https://habrastorage.org/getpro/habr/upload_files/6cc/1ce/3c1/6cc1ce3c1b3a58299600f2ffa7e38042.png)
Если зайти в магазин Decatlon, то можно заметить, что там используется UHF для отслеживания и пробивания товара на кассе. Метки фирмы NXP, но модель отсутствуют в базе gs1.org. В метках выставлен пароль на запись. Их TID успешно считывается и потенциально может использоваться для открытия шлагбаума если вы, например, выезжаете на велосипеде. Практических опытов не проводилось.
А можно обойтись без модификаций считывателя?
Я пытался написать эту статью с минимумом теоретических рассуждений и воды, но всё же не смог удержаться. Я немного опишу, как можно было сделать систему без модификации считывателя, и расскажу о проблемах, которые могут возникнуть.
Помимо проводов питания необходимо будет тянуть провода для данных, будь то wiegand или UART. Либо можно заказать считыватели сразу с запаянным wifi модулем, проверить на практике такое решение у меня не было возможности.
Если настроить считыватель на выдачу кодов по wiegand, мы ограничиваемся размером wiegand посылок 24 или 32 бита. TID состоит из 96 бит: сначала идёт информация по протоколу, модели метки и т.п., в конце - уникальный идентификатор. Размер этого идентификатора больше 32 бит. Сначала я возвращал последние 32 бита TID для меток (1) и это работало правильно, но после тестирования меток Monza R6 (2) выяснилось, что метки изменяют старшую часть идентификатора. Специально для них пришлось делать XOR последних двух 32 битных блоков TID, чтобы от метки к метке у нас не совпадали номера.
Другой проблемой оказалась невозможность считывателя возвращать нужное смещение в TID, несмотря на явную возможность это задать в параметрах конфигурирования. При выдаче в wiegand всегда возвращалась начальная часть TID, которая совпадает для меток одинаковых моделей. Т.е. единственный вариант - это зачитывать EPC, а как известно, EPC является открытой для записи памятью, и любой желающий может записать туда любое значение, а значит легко сделать копию метки.
Ещё она проблема, это таксисты. Почти у любого таксиста есть метка; когда он паркуется у КПП в ожидании клиента, считыватель начинает посылать массу сообщений о том, что метка найдена. СКУД конечно не знает этой метки и не открывает шлагбаум, но сообщает об этом в журнал. Считыватель может зачитывать по несколько меток в секунду, из-за чего журнал сильно замусоривается. Можно включить ограничение на скорость считывания, но тогда если в зоне чтения больше двух меток, ожидаемая метка может быть прочитана с большой задержкой. В своей прошивке я обошёл эту проблему созданием буфера прочитанных меток. Считыватель выдаёт метки с максимальной скоростью, если метки нет в буфере; её код выдаётся в wiegand и записывается в буфер. Если метка в буфере есть, ничего не происходит. Алгоритм, в свою очередь, следит, чтобы коды, попавшие в буфер, удалялись оттуда через 3 секунды. В результате скорость реакции на правильную метку оказывается максимально высокой, даже если вокруг находятся другие метки.
Использование считывателя без СКУД
На считывателях есть реле, его можно замыкать с помощью управляющего контроллера. Если это реле подключить к шлагбауму, можно открывать по какой-то логике. Наиболее простой вариант - это считывать TID, делать какое-либо преобразование и результат сверять с EPC. Это позволит организовать открывание шлагбаума только на основании специально созданных меток без использования СКУД.
Заключение
Запуск системы был сделан в апреле 2021, система работала успешно у 80-90% жителей. К августу работоспособность доведена до 100%. Последний тест покажет, будут ли проблемы в зимний период.
Мы встретили метку с другого объекта, при попытке добавить эту метку в нашу систему оказалось, что пароль на метке не выставлен. Наше оборудование заботливо переписало EPC и установило пароль на метку, в результате чего на том объекте она работать перестала. Если метка наклеена на вашу машину, следует осознавать, что потенциально к ней имеет доступ любой человек, который может подойти на расстояние в 10 метров, а значит оставление метки без пароля является грубой ошибкой. Рано или поздно её кто-нибудь затрёт, будь то моя заботливая программа или школьник-радиолюбитель.
В российском интернет-магазине мне удалось найти в продаже метки с открытой на запись TID, цена таких меток около 800 рублей. Если требуется использовать действительно защищённую систему, следует рассмотреть метки с AES, например, NXP DNA.
К сожалению, моя статься затрагивает в основном одного производителя, сравнить работоспособность разных считывателей не удалось из-за отсутствия времени и бюджета. Статей, подобных этой, крайне мало, так что я буду очень рад увидеть аналогичные статьи с опытом использования считывателей от других производителей.
Первоначально я назвал статью "Бюджетное решение", но цена этого проекта перевалила за $1300, наверное, назвать это бюджетным будет не очень корректно. В целом если убрать из этой цены все мои ошибки, найти способы сэкономить на доставке (стоимость доставки соразмерна цене самого считывателя), то вполне реально выйти в бюджет $250-500.