Пару месяцев назад я в очередной раз прогуливался по комиссионкам, и моё внимание привлёк стоящий на полке агрегат, чем-то похожий на музыкальный центр Bose.
Однако, взяв его с полки, я обнаружил, что это табло-бегущая строка!
Поначалу я подумал, что оно светодиодное, а зачем оно такое мне? Тем более, что у меня уже есть шикарные плазменные часы дома. Ну и поставил было его на полку обратно. Раздавшийся в этот момент громкий звон дал понять — внутри есть струны, а значит, это самый что ни на есть настоящий ВЛИ!
Поэтому я быстренько подыскал на соседнем стеллаже подходящий кабель питания, проверил, что экран загорается, и потопал на кассу, пока кто-то это чудо не перехватил.
❯ Первое включение
Приносим домой, втыкаем в розетку — убеждаемся, что делает оно всё то же, что и на тестовом стенде в комиссионке. Ну, хотя бы по пути не разбили, значит %)
Включается, говорит, что версия 1.12, а затем в цикле жалуется, что никаких сообщений нет. Значит, надо их как-то туда запихать.
❯ Что это за зверь
Шильдик на задней панели гласит, что девайс произведён Nagano Japan Radio Co. Ltd., и имеет модель NJE-105. Отдельная наклейка поверх утверждает, что версия прошивки — та самая, 1.12.
Сзади есть только выключатель и вход питания, а также некий отсек, закрытый пластиковой крышкой.
Если заглянуть внутрь отсека — там мы находим как раз интерфейсный разъём. С одного конца аж целый DB-25:
А вот с противоположного — нечто, с опознанием чего я затрудняюсь.
Долгие попытки разобраться, что же это за девайс и для чего он предназначался, привели к хитросплетению уже недоступных японских сайтов. Однако, на одном из них он был показан таки "в дикой природе", и оказалось, что этот дисплей... для пейджера!
Продавал такой набор оператор NTT Docomo. То есть, если вам нужно было, например, постоянно в офисе видеть свежие новости — вы покупали пейджер с таким табло и подключали на него подписку на нужные вам каналы. Как только на пейджер придёт сообщение — оно сразу начнёт отображаться на табло.
Или если у вас, к примеру, сеть автобусных остановок — просто устанавливаете такие табло, а пейджеры привязываете к одинаковым номерам, группируя по маршрутам или районам. Затем, в случае какого-то форс-мажора на маршруте, просто отправляете на этот номер сообщение — и все табло сразу начинают отображать его.
В какой-то момент производитель начал продавать табло сам, просто как бегущую строку для компьютера — но софт, судя по всему, нигде не сохранился.
Но, к счастью, обладатель пейджера записал хотя бы часть протокола, вот в такой суровой обстановке :-)
❯ Нужно больше ламповой теплоты!
Снимем переднюю панель и посмотрим, что там внутри.
Чутьё не подвело — это действительно огромный вакуумно-люминисцентный индикатор. Под ним находится лишь блок питания и вентилятор, включённый через термопереключатель на 45 градусов.
Сам дисплей производства фирмы Futaba — они, к сожалению, свернули производство ВЛИ в конце 2021 года.
Второй бит у DIP-переключателя непонятно зачем, а вот первый включает какой-то режим тестирования — скорее всего, для проверки на заводе:
Трёхцветность экрана достигается треугольными субпикселями двух цветов — оранжевого и зелёного:
Оттенки этого дисплея напоминают мне те, что устанавливали в поездах и на станциях, чем он мне и приглянулся.
❯ Протокол
Дальнейший поиск привёл, разве что, к упоминанию о том, что какая-то программа когда-то существовала, но автор удалил её с сайта. К счастью, в интернет-архиве сохранилась другая страница, автор которой смог записать многие управляющие последовательности с оригинального пейджера. Ради сохранения этой информации, ниже привожу вольный перевод описания протокола:
Судя по всему, распиновка идентична обычному RS-232 25-pin, разве что логические уровни здесь TTL. Изначальный автор применил два инвертера 7414 в качестве буфера, но я бы не рисковал и поставил MAX232. Хотя зачем оно вообще в наше время, когда переходники с TTL UART на USB продаются за сущие копейки :-) — прим. авт.
Передача идёт на скорости 9600 бод, 8N1.
Каждый пакет начинается с \r\n . Дальше идёт текущая дата и время в формате MMDDHHmm (ASCII), например, для 9 марта 16:39 это будет 03091639(hex: 30 33 30 39 31 36 33 39). Зачем это используется, кроме синхронизации внутренних часов табло — непонятно.
После этого — до 128 байт текста в кодировке Shift-JIS. В конце — ещё раз \r\n.
Атрибуты текста задаются в виде двух букв, указывающих цвет и эффект. Если атрибуты вставляются посреди текста, то отбиваются тильдами, например: ~AW~.
Большинство команд, будучи распознанными табло, сопровождаются выводом сообщения на экран.
❯ Вывод сообщений
Изначально я купил этот дисплей в расчёте на то, чтобы заменить им кассовый дисплей покупателя, который использую сейчас в диджейских стримах: (сверху на музыкальном центре на фоне, основной движ примерно с 9:48)
Всё же кассовый дисплей для такого слишком маловат.
Однако, как оказалось из описания протокола, этот дисплей работает не как тупой терминал, а буферизует сообщения и показывает их поочерёдно. Поэтому такие анимации создавать уже не получится, а посему идея была заброшена, и решено было сделать очередные часы-метеостанцию.
Так как приковывать табло к столу с компом не хотелось, то в ход пошла очередная ESP32. К сожалению, выход 5 вольт на DB25 не имеет запаса по току, поэтому пришлось вывести наружу 24 вольта с блока питания и преобразовать их самому.
Также оказалось, что на ESP32 не работает функция iconv() — но, к счастью, для Shift-JIS есть отдельная библиотека. На базе этого получилось написать простейшую функцию для отправки пакетов на табло.
Как отображаются произвольные сообщения, записанные просто как текст в порт, мне не понравилось: сначала экран инвертируется, и текст прокручивается один раз, затем прокручивается второй раз уже нормально.
Команды для получения сообщений же позволяют хранить их прямо в памяти табло. Однако, для этого прошивке надо будет знать, какие "слайды" уже заняты, а какие нет.
Поэтому, пишем простенькое подобие "аллокатора" сообщений :-) Таким образом, каждый "виджет" сможет зарезервировать себе "слайд":
mid.number = mgr->reserve(mid.kind);
А когда тот уже не нужен — освободить:
В остальном про код мало что можно рассказать — в отличие от тех же плазменных часов, где пришлось свою графическую библиотеку писать, здесь же просто работа с текстом.
Из того, что показывать, было решено вывести:
Погоду
"Слово дня" на английском
Дату и время
Текущий играющий трек в Foobar2000
Отправителя и тему входящей почты (IMAP)
Также добавлен проброс с USB-UART у ESP32 напрямую на табло, чтобы впоследствии всё равно хоть как-то интегрировать его с Traktor-OBS-Relay.
Хотелось добавить ещё и свежие твиты для одного из списков в твиттере, чтобы видеть новости от локально живущих товарищей. Однако кое-кто сделал бесплатное АПИ write-only, а для чтения нужно платить 100 баксов в месяц, поэтому идея была отложена в чёрный ящик :-)
До кучи на скорую руку была слеплена и вебморда. Для неё я использовал библиотеку GyverPortal:
(так забавно в ридми у неё смотрится реклама новой версии, отмечающая, что новая работает через интернет и приложение для телефона — как будто это плюсы какие-то)
Дата и время
Ну, тут всё элементарно — резервируем "слайд", и форматируем на него текущее время. Всего кода на 60 строк, и проще его привести здесь, чем описывать.
Единственный подводный камень — в заголовке сообщения атрибут "Статичное отображение" использовать нельзя, табло почему-то просто вешается намертво, а после сброса жалуется на повреждение оперативной памяти. Поэтому пришлось этот атрибут вставить напрямую в текст сообщения.
Погода
Тут тоже всё было довольно элементарно — нужно было просто угнать код для обращения к OpenWeatherMap из часов, которые я делал раньше :-)
Так же как и дату-время, просто форматируем и выдаём на зарезервированный под это дело слайд.
Ключ доступа к АПИ тоже взял из часов — в бесплатном тарифе там столько доступов даётся, что мне одного ключа хватает на все устройства, включая два смартфона и смарт-часы.
Foobar2000
Здесь уже пришлось повозиться — единственным плюс-минус удобным способом вытягивать метаданные из fb2k оказался плагин foo_controlserver.
Был написан простенький клиент, в цикле долбящийся на заданный айпишник и порт. Если подключиться получилось, то он бесконечно слушает входящие строки, и вытаскивает из них события воспроизведения/паузы и название трека.
Формат там напоминает CSV, только разделителем является вертикальная черта. Соответственно, если она есть в названии трека или исполнителя, парсинг развалится и на экране будет чёрт знает что. Не идеально, но и не критично.
Слово дня
Это такая странная вещь, показывающая каждый день случайно выбранное словарное определение. Раньше у меня такой скринсейвер на маке был, вот привычка и осталась.
Недолгие поиски привели к Wordnik API. Дальше всё было тоже элементарно — получаем JSON, парсим его, выводим на экран.
Почта по IMAP
Вносить лишние сущности я не люблю, дома не держу ни сервера, ни даже Разберипай, поэтому и получение почты было решено возложить прямо на микроконтроллер — безо всяких MQTT и прочих промежуточных звеньев.
Казалось бы — протокол древний, строго описанный в RFC, плейнтекстовый: должна быть туча реализаций разного качества, от наколенных поделок до полноценных модулей-комбайнов.
Вот тут-то меня и поджидали анальные пирогенные боли и прочие мозговые страдания!
Первом сюрпризом то, что единственная "микроконтроллерная" библиотека для электронной почты вся кривая, косая и тащит за собой драйвера внешнего флеша, карт памяти, десятка разных видов контроллеров сети, и ещё тучу всякого хлама. Да что там, просто после добавления в проект она даже не собиралась!
Поэтому пришлось интенсивно высирать 600 строк, которые упадут при первой же возможности — но вроде пока что работают.
Дальше просто по колбеку ловим новые заголовки и создаём под каждое письмо новый слайд, а когда оно становится прочитанным или удалённым — удаляем и его.
Вторым сюрпризом оказался всё тот же нерабочий iconv. Я-то думал, что там просто не включили поддержку SJIS, но нет — он мёртвый совсем, даже при попытках конвертации из ASCII в ASCII выдаёт дулю. Поэтому заголовки сообщений поддерживаются только в виде UTF-8, а остальные замещаются просто на текст "Новое сообщение".
❯ Итоговый результат
В остальном исходники можно посмотреть на гитхабе, а пока полюбуемся на готовый результат:
Я считаю, получилось неплохо! Хотя и муторно выключать его руками каждый раз, поэтому, датчик движения, наверное, когда-то таки добавлю.
А дойдут ли до этого у меня руки вы сможете узнать — среди тонн фоток еды, Мику, и прочего хлама из комиссионок — в моём телеграме :-)
Написано специально для Timeweb Cloud и читателей Пикабу. Больше интересных статей и новостей в нашем блоге на Хабре и телеграм-канале.
Хочешь стать автором (или уже состоявшийся автор) и есть, чем интересным поделиться в рамках наших блогов — пиши сюда.
Облачные сервисы Timeweb Cloud — это реферальная ссылка, которая может помочь поддержать авторские проекты.