Как и многие я любитель слушать музыку с различных интернет радиостанций. И давным-давно задумал себе сделать wifi-радио. Сначала его заменяли смартфоны, планшеты, но хотелось чего-то стационарного, оригинального, своего. Плюс хотелось чего-то лампового и с linux. Такого в продаже, конечно же, нет. Тогда и пришла идея запилить такое радио самому.
Ремарка. Хочется сразу отметить, что эта серия статей невероятный долгострой. По ряду причин никак не могла выйти в свет в течение двух лет. Поэтому не пугайтесь дат. К счастью я нашёл в себе силы, энергию и энтузиазм таки её выложить. И искренне надеюсь, что это будет не последняя часть.
После моего поста о написании драйвера для lcd-дисплея на lpt-порт habrahabr.ru/post/206148 я заболел дисплеями. Однако хитачевский дисплей, который я использовал в том посте, совершенно устарел и уже совершенно не интересен. Поэтому изготавливать на нём уникальное устройство было бы глупо. В очередной раз, в поисках вдохновения плутал по ebay, разглядывая конструкции старинных приёмников и дисплеев. И внезапно наткнулся на VFD (Vacuum fluorescent display — Вакуумно-люминесцентный индикатор (ВЛИ)), просто за безумные деньги (что-то типа 500 долларов США). Платить такую сумму я был не готов, но уже тогда влюбился данные экранчики. В дальнейшем от goodic я узнал, что данные экраны используются в кассовых аппаратах и называются «Дисплеи покупателя». Стало ясно чего хотеть и искать.
Дисплей покупателя
Долго рыская по интернетам, и читая различную документацию, я таки определился, чего же на самом деле хочу. Мой выбор пал на дисплеи компании «Posiflex.». Лично я остановился на двух моделях: PD-2600 и PD-2800. Воспользуюсь случаем и принесу слова благодарности компании «АТОЛ» за данные модели. Главное их отличие между собой в способе подключения к компьютеру и блоке питания. Для работы первого дисплея требуется внешний блок питания, и подключается он через СОМ-порт компьютера. Второй же дисплей подключается по USB и от него же берёт питание. В остальном отличие у них заканчивается. Не смотря на USB-интерфейс – этот дисплей не отличается по принципу работы от PD-2600. USB-интерфейс данного дисплея – это просто обёртка виртуального СОМ-порта и питания.
Следует отметить, что цвет свечения у данных дисплеев разный. У меня один был зелёный, другой голубой. Как оказалось, что цвет дисплея определяется только светофильтром из оргстекла. В нормальном виде (без светофильтра) он светит почти белым (с зеленоватым отливом).
Слева кусок оранжевого оргстекла, посередине естественный цвет экрана, справа родной синий светофильтр.
Дисплеи появились у меня под Новый Год (с 2013 на 2014), по этому я не преминул воспользоваться возможностью и вывести поздравление на них :)
Разница внешнего вида дисплеев PD-2600 и PD-2800. Надпись – это дань традиции, зарождённой во время чтения и работы в журнале “Хакер”. Прошу простить :)
Разумеется, всё это было мерзким читерством для пробы дисплеев я ничего не особенного не делал. А просто воспользовался готовой операционной системой для касс на базе Линукс, запущенную на виртуальной машине:
Операционка на виртуалке
Но, выводить надписи через сторонние приложения, было скучно и я начал разбираться, как же с ним можно дружить.
Как же работать с этим зверьком?
Когда готовишь статью, то эпизодически рыскаешь в поисках лучшего описания своей задачи. И на хабре наткнулся на статью, где кратенько рассказывается о том, как автор загружал свои шрифты на дисплей. Однако, совершенно не говорится ни о модели, ни о том, что же эти команды на самом деле делают. Поэтому я постараюсь описать человеческим языком, что и почему мы делаем, но данный пост не является кратким пересказом мануалов (RTFM!). Так же отмечу, что тема столь обширная, дабы не разжёвывать каждый шаг, будет формат матана: «очевидно, что...».
Даю сразу ссылку на документацию: ДОКУМЕНТАЦИЯ Обращаю внимание, что документацию я искал долго и упорно, нашёл на каком-то американском сайте Posiflex. Сейчас она есть на сайте «АТОЛ» (Российского представительства компании Posiflex). Документация от других дисплеев, увы, не подойдёт или подойдёт, но не во всех вопросах (Не все йогурты одинаково полезны). Ниже объясню почему.
Итак, перейдём к вкусняшкам. После включения любого из дисплеев, он нас будет приветствовать таким образом:
Это сообщение говорит нам о том, что данный дисплей находится в режиме команд, совместимым со стандартом Epson. Этот режим задаётся переключателями на корпусе дисплея, и как правило по умолчанию на всех дисплеях покупателя стоит именно он.
Задаём режим работы дисплея
Обращаю внимание, что существует множество режимов работы. Мы будем использовать систему команд, совместимую с дисплеями Epson. В документации это раздел EPSON EMULATION MODE. «Дитям мороженое, бабе цветы. Смотри не перепутай»(с)
В данном режиме дисплей управляется ESC-последовательностями почти как vt52-терминал (однако совместимость не полная).
Пару слов об интерфейсе
Чтобы упростить понимание, что же мы делаем и зачем, я напомню, что это весьма детально описывал в своей статье «Создание собственных драйверов под Linux». Там есть спойлер FAQ (найдите через поиск), и там красиво в картинках показано что и как работает, и для чего какие команды. Чтобы было понятно в той статье «\033» эквивалентно записи «\x1B» в данной статье (одна в восьмеричной системе, вторая в шестнадцатеричной)
Давайте поиграемся с дисплеем из командной строки. Не будем подключать большого программирования. Для сегодняшней статьи этого будет с головой. Будем считать, что дисплей PD-2600 у нас подключён через USB-переходник и видится системой как /dev/ttyUSB0. То же самое будет работать с дисплеем PD-2800, только он будет у нас определяться как /dev/ttyACM0.
Для начала выставим скорость работы. По умолчанию скорость работы СОМ-порта (на обоих дисплеях) 9600. Эта скорость также задаётся переключателями.
stty 9600 < /dev/ttyUSB0
И уже после этой «весьма сложной команды» мы можем протестировать.
echo -en "Hello world" > /dev/ttyUSB0
Суровый аппаратный привет миру.
Всё, на этом повествование можно заканчивать. Привет мир удался. Но на самом деле не всё так просто. Данный дисплей поддерживает Великий и Могучий русский язык. Но делает это весьма своеобразно. Для работы с русским языком, согласно документации требуется выбрать кодовую таблицу. Если этого не сделать, то при выводе будет вот такая петрушка.
echo -en "Привет Хабру\nот dlinyj" > /dev/ttyUSB0
Чтобы включить кодовую страницу с русской кириллицей следует отдать следующую команду:
echo -en "\x1B\x74\x06" > /dev/ttyUSB0
После чего пробуем вывести снова наш текст
echo -en "Привет Хабру\nот dlinyj" > /dev/ttyUSB0
И-и-и-и, вновь нас ждёт облом…
Так в чём же дело? Проблема оказалось простой, но мне потребовалось два дня, чтобы до этого дотукать. Всё элементарно — проблема кодировок. Хвала камраду goodic за то, что мне подсказал верную кодировку. В результате получаем многострадальную команду, которая нам таки перекодирует наш текст в русский и выведет на экран.
echo -en "Привет Хабру\nот dlinyj" | iconv -f UTF-8 -t CP866 > /dev/ttyUSB0
На самом деле я опустил деталь, что каждый раз я отсоединял питание дисплея, заново инициализировал СОМ-порт и давал эти команды. Но существует ещё множество вкусных команд. Таких как: сдвиг курсора, очистка экрана, помещение курсора домой и т.п. Часть команд совместимо с vt52. Если привести весь список команд из документации, то он будет выглядеть вот так:
Теперь, по науке, чтобы вывести «Привет хабру», надо сделать следующее. На английском подписи соответствует названию команды в таблице выше, для удобства.
stty 9600 < /dev/ttyUSB0 #устанавливаем скорость СОМ-порта
echo -en "\x1B\x74\x06" > /dev/ttyUSB0 # Select character code page table. Включаем кодовую страницу с поддержкой русских шрифтов (страница№6).
echo -en "\x1B\x40" > /dev/ttyUSB0 #Initialize display. Инициализация дисплея. Очищает экран и помещает курсор домой (левый верхний угол).
echo -en "Привет Хабру\nот dlinyj" | iconv -f UTF-8 -t CP866 > /dev/ttyUSB0 #iconv в данном случае осуществляет перекодировку из UTF-8 в CP866.
Как мы видим, команды позволяют делать различные очень вкусные вещи. Например, можно с помощью команд включать и выключать запятую (точку) на экране. Например.
echo -en "\x1F," > /dev/ttyUSB0 #вывести запятую
echo -en "\x1F." > /dev/ttyUSB0 #вывести точку
У неё есть отдельное место. Но я ни разу не видел, чтобы кто-то пользовался этой возможностью. Как правило, все просто используют под точку отдельное знакоместо. Так же есть символ подчёркивания. В общем, дисплей разве что щи не варит. Демонстрировать все возможности дисплея в фотографиях я не буду, тем более что задача эта не благодарная. В посте про драйвера, этот громадный спойлер прочитало лишь несколько человек.
Для меня самое главное в данных дисплеях, это загрузка пользовательских шрифтов. О них и поговорим ниже.
Подключаем тяжёлую артиллерию. Пользовательские шрифты.
Самое крутое в данных дисплеях — это поддержка пользовательских шрифтов. Однако, могу разочаровать, что дальнейшее описание подходит только к PD-2600 и PD-2800 моделям дисплея. Даже в рамках одной фирмы отличается синтаксис команд загрузки шрифтов. И лично поимел немало граблей, используя документацию на ранние версии дисплеев данной фирмы. К сожалению, не понимаю, почему в таком простом месте каждый изобретает велосипед, а не примут какой-то единый стандарт, даже хотя бы в рамках одного предприятия.
Проблема поиска документации разработчика на данные дисплеи стояла очень остро. Общей информации очень много, но вот документации разработчика найти было очень сложно (2013-2014 год). Кратко опишу свой тернистый путь, быть может, кто-то по нему пройдёт.
Изначально, документация, программиста, которую удалось найти — это была документация на дисплей PD2100/2200. Особенность загрузки символа заключается в том, что в символе множество точек, и выглядит карта символов следующим образом:
Карта символов
Согласно документации загрузка символа осуществляется командой: <1B> <26> ~ (режим Epson и далее говорим только о нём). Где ad — это номер загружаемого символа, а x1 — x5 это пять байт карты символов, согласно таблице:
Таблица точек в байте, для дисплея PD2100/2200
Опытным путём было установлено, что загрузка символов идёт (хоть на том спасибо), но данная таблица не соответствует дисплею PD-2600! Разработчики, обратите внимание, что дисплеи НЕ ВЗАИМОЗАМЕНЯЕМЫ с точки зрения команд! С большим трудом удалось найти документацию разработчика на дисплей PD-2600. Там таблица точек выглядит следующим образом:
Таблица точек в байте, для дисплея PD2600/2800
Перекодирование символа превращается в тот ещё ребус, но вполне решаемый.
Так же, оказалось, что можно загрузить только два пользовательских символа, если загружать больше, то предыдущие символы сбрасываются в значение по умолчанию! Единственное, что символ, выведенный на экран уже не меняет своих очертаний, так что можно выводить символы и перезагружать его новым значением (что весьма неудобно).
Перестаём ныть, и давайте рассмотрим пример вывода символа вертикальной черты. Нарисуем его и переведём согласно таблице.
Перекодировка символа
Получаем такую картину:
X1=0001 0000b=0x10
X2=0100 0010b=0x42
X3=0000 1000b=0x08
X4=0010 0001b=0x21
X5=0000 0100b=0x04
Посылка в СОМ-порт будет выглядеть следующим образом (данные в hex):
1B 25 01 разрешаем использование пользовательского символа (Set/cancel user-defined characters). 01 – символ 1.
1B 26 A0 10 42 08 21 04 загрузка пользовательского символа по адресу A0 (Define user defined characters), последние пять байт — битовая маска символа.
A0 — печатаем символ
Таким образом в консоли всё будет выглядеть следующим образом.
Для начала проинициализируем дисплей
echo -en "\x1B\x40" > /dev/ttyUSB0 #Initialize display.
Первое, это надо дать команду, разрешающую пользовательские шрифты
echo -en "\x1B\x25\x01" > /dev/ttyUSB0 # Set/cancel user-defined characters.
Далее загрузим символ вертикальной черты, следующей командой
echo -en "\x1B\x26\ xA0\x10\x42\x08\x21\x04" > /dev/ttyUSB0 # Define user defined characters
Символ загружен на позицию A0, выведем его:
echo -en "\xA0" > /dev/ttyUSB0
В результате получим:
Отрисованный символ
Можно даже завалить экран “забором”, для наглядности
Забор
Вообще с перезагрузкой символов можно делать весьма крутые штуки. Например, бегущую палочку, которая является перезагрузкой из пяти различных символов.
Для чего это всё нужно, поведаю в других статьях.
Заключение к первой части
В данной части мы рассмотрели работу дисплеев Posiflex PD-2600 и PD-2800. Этот пост претендует даже на самостоятельность, т.к. показывает пример работы с дисплеем покупателя. Вы даже можете теперь достать такой дисплей (или подобный), и сделать на нём вывод полезной для вас информации. Хоть сообщения твитера.
В дальнейшем будет ясно, для чего я сделал такой большой упор на дисплей, т.к. это будет ключевым звеном в дальнейшей поделке.
Один из этапов прототипа.
В следующих статьях мы рассмотрим программирование данного дисплея на тёплом ламповом си, работа с маршрутизатором, mpd и многие другие вкусности.
З.Ы. Убедительно прошу писать мне обо всех найденных ошибках, неточностях и т.п. личным сообщением. Постараюсь максимально оперативно исправлять все ошибки!!!