ПИУ-2. Оживляем плазменный текстовый индикатор из СССР
Средний 17 мин Блог компании Timeweb Cloud Программирование микроконтроллеров *Схемотехника *Компьютерное железо Старое железо Туториал Приветствую всех!
Месяц с небольшим назад я рассказывал о таком девайсе как МС6205. Тема подобных экранов меня заинтересовала, и вот ко мне в руки попал другой экземпляр, однострочный и с более простым управлением. Тем не менее, несмотря на схожий вид, внутри он устроен совершенно иначе — если в МС6205 был матричный индикатор, то тут используется панель с самосканированием. Как же оно работает и как это запустить? Давайте разбираться.
Итак, в сегодняшней статье поговорим о семействе советских текстовых индикаторов ПИУ. Узнаем, как они устроены и как работают. Попутно поговорим о текстовых газоразрядных дисплеях с самосканированием. Традиционно будет много интересного.
Содержание статьи:
- 1 ❯ Суть такова
- 2 ❯ Обзор оборудования
- 3 ❯ Как работает ПИУ
- 4 ❯ В чём разница между ПИУ-1 и ПИУ-2
- 5 ❯ Первый запуск
- 6 ❯ Подключение
- 7 ❯ Синхронный и асинхронный режим
- 8 ❯ Пишем первую программу
- 9 ❯ Немного про ГТИ и внешний знакогенератор
- 10 ❯ Управление яркостью
- 11 ❯ Неожиданные глюки
- 12 ❯ Библиотека для Arduino
- 13 ❯ Вот как-то так
❯ Суть такова
Началась эта история ещё в 2022 году, когда я услышал про существование такого устройства как ПИУ-2 и немедленно захотел себе такой экземпляр. Девайс был куплен без промедления, интереса ради. Далее последовали выпившие немало моей крови попытки его подключения, которыми я наконец и решил поделиться.
ПИУ-1 и ПИУ-2 — две модели индикаторных приборов, использовавшихся в неком оборудовании (мне так и не удалось выяснить, где именно, но, по слухам, стояли такие где-то на ЖД). Оба этих девайса имеют схожую конструкцию и отличаются лишь кодовой таблицей. Так что практически всё, что будет сказано тут, применимо и к ПИУ-1.
❯ Обзор оборудования
Так уж вышло, что в моих руках побывали два ПИУ — ранней и поздней версии.
Общий вид первого экземпляра. Здесь только индикаторный модуль. Также по бокам должны были располагаться два крепёжных ушка, но у моего прибора они замяты.
На обратной стороне разъём, клемма заземления, крепёжные винты (один из которых под пломбой) и заводская табличка. Как и практически все интересные и необычные советские приборы индикации, выпускался девайс на ровненском «Газотроне».
Снимем кожух. Внутри металлическая рама, к которой прикручены плата, панель и разъём.
С обратной стороны ничего интересного.
Плата. На ней вся электроника — чипы логики, память, ПЗУшка с таблицей символов и импульсный преобразователь для питания панели.
Разъём, связывающий панель с внешним миром. Почему-то очень сложно было найти какую-то информацию на этот счёт, так что оставлю тут для потомков: ответная его часть называется 2РМ30КПН32Г5В1В.
Панель представляет собой законченный модуль, соединённый с платой разъёмом МРН. Состоит он из стеклянного индикатора, рамки и платы, к которой он подключается.
Интересно то, как подключается непосредственно стеклянная колба к плате — тоненькими проволочками-волосинками, которые легко сминаются и рвутся. Для защиты от жизненных ударов щели заклеены полоской липкой ленты.
А вот более старая панель. Внешне отличия заметны не особо…
С обратной стороны отличие лишь в годе выпуска — 1983. Также видно, что изолятор в разъёме на этот раз карболитовый.
Вскрываем. Внутри это совершенно иное устройство, построенное уже на двух платах. Эти платы вставляются в слоты, позволяющие при необходимости вытащить какую-либо из них без паяльника.
Первая плата — низковольтная. На ней расположена управляющая логика и ПЗУшки.
Вторая — высоковольтная. Здесь преобразователь, выдающий все необходимые для питания панели напряжения, а также транзисторные сборки, призванные управлять анодами и катодами индикатора. Интересное схемотехническое решение в виде дорожки-спиральки — явно какая-то катушка низкой индуктивности.
Шасси со снятыми платами.
Оба модуля втыкаются в расположенную на боковой стенке кросс-плату. От неё же расходятся жгуты проводов к разъёму и индикатору. К слову, о разъёме. Вместо ОНЦ здесь стоит другой разъём — 2РМ30Б32Ш5В1В. Впрочем, ответная часть к нему та же самая.
Те самые слоты.
Разъём МРН, через который подключается индикатор.
Индикатор отдельно. От рассмотренного ранее он не отличается ничем.
❯ Как работает ПИУ
Вообще, по своей структуре ПИУ во многом схож с МС6205 — здесь тоже есть преобразователь питания, генератор импульсов, знакогенератор, блок интерфейса и подобная логика. Но вот индикаторы тут стоят совершенно иные. Это так называемые газоразрядные индикаторы с самосканированием.
Вообще, если вы никогда не интересовались подобным железом, то вид матричного индикатора, способного работать всего по двенадцати проводам, уже способен заинтересовать. А уж упоминание того, что прибор этот не содержит ни единого полупроводника, и вовсе поставит в ступор обывателя.
Наиболее доходчиво о работе таких ГРИ рассказывал товарищ radiolok. Я сам узнал об этих индикаторах, посмотрев этот ролик, после чего немедленно захотел себе какой-то законченный девайс на базе такой панели. Именно им и стал ПИУ.
Принцип работы таких панелей очень схож с декатронами, а также (немного) с газоразрядным индикатором ИН-33. Помимо обычных анодов и катодов девайс имеет вспомогательные аноды (аноды сканирования). Если последовательно подавать импульсы между группой анодов сканирования и одной из групп катодов, то можно получить разряд, последовательно проходящий все столбцы индикатора. Если в момент, когда разряд сканирования горит в некотором положении (которое можно однозначно отсчитать благодаря наличию отдельно выведенного катода сброса, с которого начинается прохождение разряда по столбцам), подать импульс на анод сканирования, то в выбранной строке этого столбца загорится точка. Таким образом, для работы индикатора необходима схема сканирования, которая постоянно будет проходить по всей панели, и схема индикации, которая, зная, где сейчас находится разряд (благодаря работе от того же тактового генератора) может включать и выключать аноды индикации.
❯ В чём разница между ПИУ-1 и ПИУ-2
Изначально я думал, что эти две модели — разные ревизии одного и того же прибора. Но всё оказалось куда интереснее. Первая и вторая версия отличаются кодовой таблицей.
У ПИУ-1 она такая.
А у ПИУ-2 — вот такая.
По просторам гуляют две документации: одна называется «ПИУ-1: паспорт, техническое описание и руководство по эксплуатации», другая — «Приборы индикаторные универсальные ПИУ-1, ПИУ-2: паспорт, техническое описание и руководство по эксплуатации». При этом они описывают по сути два совершенно разных по схемотехнике устройства. Первая рассказывает про более старую версию, имеющую внутри два слотовых модуля и кросс-плату, вторая — про поздний вариант, собранный на одной плате. Помимо этого в первой инструкции детально описаны некоторые аспекты работы устройства в синхронном и асинхронном режимах (в документации к ПИУ-2 эти моменты скромно опущены). Чтобы вам не пришлось искать эти архивы среди кучи битых, ссылку на них я дам чуть позже.
❯ Первый запуск
Итак, самое время приступить к экспериментам.
Берём ответную часть разъёма и припаиваем провода. Распиновка есть в документации.
Но, увы, при попытке что-то вывести меня ждала неудача — на экране отображался один и тот же символ. Последующие проверки показали, что в индикаторе, судя по всему, вылетела ПЗушка, так как адресный счётчик работал исправно. Я понятия не имею, где взять такую же, чем её прошить и какой прошивкой, так что разбирательства с этим индикатором я забросил, а через полгода его лежания у меня и вовсе продал.
Также именно упомянутый экземпляр успел засветиться в ролике всё того же radiolok, где на 2:37 показаны внутренности моего ПИУ. Этими фотографиями я поделился в чатике давным-давно, и вот они наконец пригодились.
❯ Подключение
Так уж вышло, что детального описания работы ПИУ практически нигде нет. Есть, конечно, документация (причём сразу в двух версиях), но на этом всё. Поэтому сейчас я расскажу о том, как же вообще работает эта штука с точки зрения программиста микроконтроллеров.
Начнём, конечно же, с разъёма. Предыдущая ответная часть ушла вместе с неисправной панелью, пришлось намутить другой. Как оказалось, за минувший год такие разъёмы в местном магазине радиодеталей кончились, пришлось купить у сборщика металла. На этот раз он уже был частью какого-то жгута (если вдруг это условное обозначение вам о чём-то говорит, напишите в комментариях).
Разбираем разъём и выпаиваем остатки проводов. Их, разумеется, не выкидываем — ещё пригодятся.
Теперь можно перейти к распиновке самого блока. Она здесь оказалась вот такая:
- X8
- Первая строка
- X7
- Вторая строка
- X6
- Третья строка
- X5
- Четвёртая строка
- X4
- Пятая строка
- X3
- Шестая строка
- X2
- Седьмая строка
- X1
- Ничего
- Гашение
- Синхросигнал
- Запись/индикация
- Импульсы сброса
- Строб
- Ничего
- Сброс
- 5 В
- Управление яркостью
- -12,6 В
- Ничего
- Ничего
- Ничего
- Земля
- Ничего
- Масса
Для питания требуется два напряжения — +5 и -12,6 В. Взять их можно, разумеется, в компьютерном БП. Как показала практика, от -12 В он девайс тоже отлично стартует.
Если просто подать питание, девайс тоже должен запуститься — послышится тихое пищание преобразователя, а экран очень тускло засветится оранжевым — именно так выглядит процесс сканирования. Для примера фото я сделал в темноте при большой выдержке и почти полностью открытой диафрагме, в реальности увидеть это свечение получится только если приглядываться.
❯ Синхронный и асинхронный режим
Индикатор может работать в двух режимах — синхронном и асинхронном.
В асинхронном режиме ПИУ находится в одном из двух состояний. Когда на контакте 19 разъёма присутствует высокий уровень, управляющая схема ожидает поступления на вход данных. Когда напряжение снимается, прибор переходит в режим индикации.
В синхронном режиме контакт 19 всегда заземлён, а отображаемая информация обновляется сразу при поступлении новых данных. Именно этот режим мы и задействуем.
❯ Пишем первую программу
Памятуя о жёстких глюках неясной природы при подключении МС6205 напрямую к выводам МК, я решил и тут использовать сдвиговый регистр. Подключение, таким образом, очень простое — строб и сброс к выводам МК, X1…X8 — к Q0…Q7 регистра. В качестве управляющего девайса была взята всё та же тестовая ардуино.
Саму микросхему удалось уместить внутри разъёма.
Теперь о программе. Для начала необходимо сбросить экран (после чего он погаснет), после чего последовательно загрузить в регистр каждый символ, не забывая после этого дёргать строб. У ПИУ нет шины адреса как у МС6205, он работает по сути как обычный дисплей 1602: выставляем на шине код, после чего даём высокий уровень на строб. Для программиста единственное отличие лишь в том, что у HD44780 строб по спаду сигнала, а также есть поддержка управляющих команд, тогда как единственная команда, которую знает ПИУ, — это считать код символа с восьмибитной шины и протолкнуть его в буфер. Программа для этого получилась вот такая:
#define CLOCK 5 //SH_CP #define DATA 6 //DS #define LATCH 7 //ST_CP #define STROBE 4 #define RESET 3 void setup() { pinMode(CLOCK, OUTPUT); pinMode(DATA, OUTPUT); pinMode(LATCH, OUTPUT); pinMode(STROBE, OUTPUT); pinMode(RESET, OUTPUT); digitalWrite(LATCH, HIGH); digitalWrite(STROBE, LOW); digitalWrite(RESET, LOW); delay(300); digitalWrite(RESET, HIGH); Serial.begin(115200); Serial.println(«test»); showString(«priwet, habr»); } void sendData(uint8_t toLCD) { digitalWrite(LATCH, LOW); shiftOut(DATA, CLOCK, MSBFIRST, toLCD); digitalWrite(LATCH, HIGH); delay(10); digitalWrite(STROBE, HIGH); delay(1); digitalWrite(STROBE, LOW); } void showString(String data) { for (int i = 0; i < data.length(); i++) { sendData(data[i]); } } void loop() { }
Прибор работает в кодировке КОИ-7, что тоже надо учитывать.
Остаётся только залить её, и, если ПИУ живой, на экране должно будет появиться примерно следующее:
Наконец-то оно работает!
❯ Немного про ГТИ и внешний знакогенератор
У индикатора имеется возможность управления полностью извне. Оно позволяет использовать ПИУ при отсутствии возможности подключить его по штатному интерфейсу, а также если встроенный знакогенератор сдох.
Для этого индикатор обладает выводами управления строками, ГТИ и импульсов сброса.
Контакты 2, 4, 6, 8, 10, 12, 14 служат для непосредственного включения или выключения пикселей в столбце. ГТИ — генератор тактовых импульсов, от которого работает схема сканирования. В момент смены уровня этого сигнала с высокого на низкий происходит считывание данных с выводов управления строками. Контакт импульсов сброса нужен для определения начала панели — на нём появляется низкий уровень в тот момент, когда сканирующий разряд проходит «нулевой» катод.
И при попытке запустить индикатор в таком режиме можно наглядно увидеть, насколько же всё-таки слабо работает Arduino! «Медленные» digitalWrite не справляются с таким переключением, отчего изображение размазывается.
Вот этот код работать не будет, как бы вы ни пытались const uint8_t System5x7C[156][5] = { {0x00, 0x00, 0x00, 0x00, 0x00},// (space) {0x00, 0x00, 0x5F, 0x00, 0x00},// ! {0x00, 0x07, 0x00, 0x07, 0x00},// » {0x14, 0x7F, 0x14, 0x7F, 0x14},// # {0x24, 0x2A, 0x7F, 0x2A, 0x12},// $ {0x23, 0x13, 0x08, 0x64, 0x62},// % {0x36, 0x49, 0x55, 0x22, 0x50},// & {0x00, 0x05, 0x03, 0x00, 0x00},// ‘ {0x00, 0x1C, 0x22, 0x41, 0x00},// ( {0x00, 0x41, 0x22, 0x1C, 0x00},// ) {0x08, 0x2A, 0x1C, 0x2A, 0x08},// * {0x08, 0x08, 0x3E, 0x08, 0x08},// + {0x00, 0x50, 0x30, 0x00, 0x00},// , {0x08, 0x08, 0x08, 0x08, 0x08},// — {0x00, 0x60, 0x60, 0x00, 0x00},// . {0x20, 0x10, 0x08, 0x04, 0x02},// / {0x3E, 0x51, 0x49, 0x45, 0x3E},// 0 {0x00, 0x42, 0x7F, 0x40, 0x00},// 1 {0x42, 0x61, 0x51, 0x49, 0x46},// 2 {0x21, 0x41, 0x45, 0x4B, 0x31},// 3 {0x18, 0x14, 0x12, 0x7F, 0x10},// 4 {0x27, 0x45, 0x45, 0x45, 0x39},// 5 {0x3C, 0x4A, 0x49, 0x49, 0x30},// 6 {0x01, 0x71, 0x09, 0x05, 0x03},// 7 {0x36, 0x49, 0x49, 0x49, 0x36},// 8 {0x06, 0x49, 0x49, 0x29, 0x1E},// 9 {0x00, 0x36, 0x36, 0x00, 0x00},// : {0x00, 0x56, 0x36, 0x00, 0x00},// ; {0x00, 0x08, 0x14, 0x22, 0x41},// < {0x14, 0x14, 0x14, 0x14, 0x14},// = {0x41, 0x22, 0x14, 0x08, 0x00},// > {0x02, 0x01, 0x51, 0x09, 0x06},// ? {0x32, 0x49, 0x79, 0x41, 0x3E},// @ {0x7E, 0x11, 0x11, 0x11, 0x7E},// A {0x7F, 0x49, 0x49, 0x49, 0x36},// B {0x3E, 0x41, 0x41, 0x41, 0x22},// C {0x7F, 0x41, 0x41, 0x22, 0x1C},// D {0x7F, 0x49, 0x49, 0x49, 0x41},// E {0x7F, 0x09, 0x09, 0x01, 0x01},// F {0x3E, 0x41, 0x41, 0x51, 0x32},// G {0x7F, 0x08, 0x08, 0x08, 0x7F},// H {0x00, 0x41, 0x7F, 0x41, 0x00},// I {0x20, 0x40, 0x41, 0x3F, 0x01},// J {0x7F, 0x08, 0x14, 0x22, 0x41},// K {0x7F, 0x40, 0x40, 0x40, 0x40},// L {0x7F, 0x02, 0x04, 0x02, 0x7F},// M {0x7F, 0x04, 0x08, 0x10, 0x7F},// N {0x3E, 0x41, 0x41, 0x41, 0x3E},// O {0x7F, 0x09, 0x09, 0x09, 0x06},// P {0x3E, 0x41, 0x51, 0x21, 0x5E},// Q {0x7F, 0x09, 0x19, 0x29, 0x46},// R {0x46, 0x49, 0x49, 0x49, 0x31},// S {0x01, 0x01, 0x7F, 0x01, 0x01},// T {0x3F, 0x40, 0x40, 0x40, 0x3F},// U {0x1F, 0x20, 0x40, 0x20, 0x1F},// V {0x7F, 0x20, 0x18, 0x20, 0x7F},// W {0x63, 0x14, 0x08, 0x14, 0x63},// X {0x03, 0x04, 0x78, 0x04, 0x03},// Y {0x61, 0x51, 0x49, 0x45, 0x43},// Z {0x00, 0x00, 0x7F, 0x41, 0x41},// [ {0x02, 0x04, 0x08, 0x10, 0x20},// «» {0x41, 0x41, 0x7F, 0x00, 0x00},// ] {0x04, 0x02, 0x01, 0x02, 0x04},// ^ {0x40, 0x40, 0x40, 0x40, 0x40},// _ {0x00, 0x01, 0x02, 0x04, 0x00},// ` {0x20, 0x54, 0x54, 0x54, 0x78},// a {0x7F, 0x48, 0x44, 0x44, 0x38},// b {0x38, 0x44, 0x44, 0x44, 0x20},// c {0x38, 0x44, 0x44, 0x48, 0x7F},// d {0x38, 0x54, 0x54, 0x54, 0x18},// e {0x08, 0x7E, 0x09, 0x01, 0x02},// f {0x08, 0x14, 0x54, 0x54, 0x3C},// g {0x7F, 0x08, 0x04, 0x04, 0x78},// h {0x00, 0x44, 0x7D, 0x40, 0x00},// i {0x20, 0x40, 0x44, 0x3D, 0x00},// j {0x00, 0x7F, 0x10, 0x28, 0x44},// k {0x00, 0x41, 0x7F, 0x40, 0x00},// l {0x7C, 0x04, 0x18, 0x04, 0x78},// m {0x7C, 0x08, 0x04, 0x04, 0x78},// n {0x38, 0x44, 0x44, 0x44, 0x38},// o {0x7C, 0x14, 0x14, 0x14, 0x08},// p {0x08, 0x14, 0x14, 0x18, 0x7C},// q {0x7C, 0x08, 0x04, 0x04, 0x08},// r {0x48, 0x54, 0x54, 0x54, 0x20},// s {0x04, 0x3F, 0x44, 0x40, 0x20},// t {0x3C, 0x40, 0x40, 0x20, 0x7C},// u {0x1C, 0x20, 0x40, 0x20, 0x1C},// v {0x3C, 0x40, 0x30, 0x40, 0x3C},// w {0x44, 0x28, 0x10, 0x28, 0x44},// x {0x0C, 0x50, 0x50, 0x50, 0x3C},// y {0x44, 0x64, 0x54, 0x4C, 0x44},// z {0x00, 0x08, 0x36, 0x41, 0x00},// { {0x00, 0x00, 0x7F, 0x00, 0x00},// | {0x00, 0x41, 0x36, 0x08, 0x00},// } {0x08, 0x08, 0x2A, 0x1C, 0x08},// -> {0x08, 0x1C, 0x2A, 0x08, 0x08}, // <- {0x7E, 0x11, 0x11, 0x11, 0x7E},// A {0x7F, 0x49, 0x49, 0x49, 0x30},// Б {0x7F, 0x49, 0x49, 0x49, 0x36},// B {0x7F, 0x01, 0x01, 0x01, 0x01},// Г {0x60, 0x3F, 0x21, 0x3F, 0x60},// Д {0x7F, 0x49, 0x49, 0x49, 0x41},// E {0x63, 0x14, 0x7F, 0x14, 0x63},// Ж {0x49, 0x49, 0x49, 0x49, 0x36},// З {0x7F, 0x10, 0x08, 0x04, 0x7F},// И {0x7F, 0x10, 0x09, 0x04, 0x7F},// Й {0x7F, 0x08, 0x14, 0x22, 0x41},// К {0x40, 0x3F, 0x01, 0x01, 0x7F},// Л {0x7F, 0x02, 0x04, 0x02, 0x7F},// М {0x7F, 0x08, 0x08, 0x08, 0x7F},// H {0x3E, 0x41, 0x41, 0x41, 0x3E},// O {0x7F, 0x01, 0x01, 0x01, 0x7F},// П {0x7F, 0x09, 0x09, 0x09, 0x06},// P {0x3E, 0x41, 0x41, 0x41, 0x22},// C {0x01, 0x01, 0x7F, 0x01, 0x01},// T {0x63, 0x14, 0x08, 0x04, 0x03},// У {0x3E, 0x41, 0x7F, 0x41, 0x3E},// Ф {0x63, 0x14, 0x08, 0x14, 0x63},// X {0x3F, 0x20, 0x20, 0x3F, 0x60},// Ц {0x07, 0x08, 0x08, 0x08, 0x7F},// Ч {0x7F, 0x40, 0x7F, 0x40, 0x7F},// Ш {0x3F, 0x20, 0x3F, 0x20, 0x7F},// Щ {0x01, 0x7F, 0x48, 0x48, 0x30},// Ъ {0x3C, 0x41, 0x42, 0x20, 0x7C},// ѝ {0x7F, 0x08, 0x3E, 0x41, 0x3E},// Ю {0x46, 0x29, 0x19, 0x09, 0x7F},// Я {0x20, 0x54, 0x54, 0x54, 0x78},// а {0x7E, 0x49, 0x45, 0x45, 0x39},// б {0x7C, 0x54, 0x54, 0x58, 0x20},// в {0x7C, 0x04, 0x04, 0x04, 0x04},// г {0x08, 0x14, 0x54, 0x54, 0x3C},// д {0x38, 0x54, 0x54, 0x54, 0x18},// е {0x44, 0x28, 0x7C, 0x28, 0x44},// ж {0x54, 0x54, 0x54, 0x54, 0x28},// з {0x3C, 0x40, 0x40, 0x20, 0x7C},// и {0x3C, 0x41, 0x42, 0x21, 0x7C},// й {0x00, 0x7C, 0x10, 0x28, 0x44},// к {0x40, 0x3C, 0x04, 0x04, 0x7C},// л {0x7C, 0x08, 0x10, 0x08, 0x7C},// м {0x00, 0x7C, 0x10, 0x10, 0x7C},// н {0x38, 0x44, 0x44, 0x44, 0x38},// о {0x00, 0x7C, 0x04, 0x04, 0x7C},// п {0x7C, 0x14, 0x14, 0x14, 0x08},// р {0x38, 0x44, 0x44, 0x44, 0x20},// с {0x04, 0x04, 0x7C, 0x04, 0x04},// т {0x0C, 0x50, 0x50, 0x50, 0x3C},// у {0x38, 0x44, 0x7C, 0x44, 0x38},// ф {0x44, 0x28, 0x10, 0x28, 0x44},// х {0x3C, 0x20, 0x20, 0x3C, 0x60},// ц {0x00, 0x0C, 0x10, 0x10, 0x7C},// ч {0x7C, 0x40, 0x7C, 0x40, 0x7C},// ш {0x3C, 0x20, 0x3C, 0x20, 0x7C},// щ {0x04, 0x7C, 0x50, 0x50, 0x30},// ъ {0x00, 0x7C, 0x50, 0x50, 0x30},// ь {0x7C, 0x10, 0x38, 0x44, 0x38},// ю {0x48, 0x34, 0x14, 0x14, 0x7C} // я }; #define PANEL_RESET 2 #define PANEL_CLK 3 #define PANEL_D0 47 #define PANEL_D1 45 #define PANEL_D2 43 #define PANEL_D3 41 #define PANEL_D4 39 #define PANEL_D5 37 #define PANEL_D6 35 volatile uint8_t n = 0; volatile uint8_t lines[111]; void changeN() { n++; panelWrite(lines[n]); } void panelInit() { n = 0; panelWrite(0x00); } void panelWrite(uint8_t toPanel) { digitalWrite(PANEL_D0, (toPanel >> 0) & 1); digitalWrite(PANEL_D1, (toPanel >> 1) & 1); digitalWrite(PANEL_D2, (toPanel >> 2) & 1); digitalWrite(PANEL_D3, (toPanel >> 3) & 1); digitalWrite(PANEL_D4, (toPanel >> 4) & 1); digitalWrite(PANEL_D5, (toPanel >> 5) & 1); digitalWrite(PANEL_D6, (toPanel >> 6) & 1); } void setup() { // put your setup code here, to run once: pinMode(31, OUTPUT); pinMode(47, OUTPUT); pinMode(35, OUTPUT); pinMode(37, OUTPUT); pinMode(39, OUTPUT); pinMode(41, OUTPUT); pinMode(43, OUTPUT); pinMode(45, OUTPUT); for (int i = 0; i < 111; i++) lines[i] = 0x00; Serial.begin(115200); String s = «»; while(!Serial.available());; s = Serial.readStringUntil(‘r’); Serial.println(s); int index = 3; for(int i = 0; i < s.length(); i++) { for(int t = 0; t < 5; t++) { lines[index] = System5x7C[s[i] — 0x20][t]; index++; } index += 3; } for(int i = 0; i < 111; i++) Serial.println(lines[i],HEX); attachInterrupt(digitalPinToInterrupt(3), changeN, FALLING); attachInterrupt(digitalPinToInterrupt(2), panelInit, FALLING); } void loop() { // put your main code here, to run repeatedly: }
А вот этот — пожалуйста const uint8_t System5x7C[156][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00},// (space)
{0x00, 0x00, 0x5F, 0x00, 0x00},//!
{0x00, 0x07, 0x00, 0x07, 0x00},// «
{0x14, 0x7F, 0x14, 0x7F, 0x14},// #
{0x24, 0x2A, 0x7F, 0x2A, 0x12},// $
{0x23, 0x13, 0x08, 0x64, 0x62},// %
{0x36, 0x49, 0x55, 0x22, 0x50},// &
{0x00, 0x05, 0x03, 0x00, 0x00},// ‘
{0x00, 0x1C, 0x22, 0x41, 0x00},// (
{0x00, 0x41, 0x22, 0x1C, 0x00},// )
{0x08, 0x2A, 0x1C, 0x2A, 0x08},// *
{0x08, 0x08, 0x3E, 0x08, 0x08},// +
{0x00, 0x50, 0x30, 0x00, 0x00},//,
{0x08, 0x08, 0x08, 0x08, 0x08},// — {0x00, 0x60, 0x60, 0x00, 0x00},//.
{0x20, 0x10, 0x08, 0x04, 0x02},// /
{0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
{0x00, 0x42, 0x7F, 0x40, 0x00},// 1
{0x42, 0x61, 0x51, 0x49, 0x46},// 2
{0x21, 0x41, 0x45, 0x4B, 0x31},// 3
{0x18, 0x14, 0x12, 0x7F, 0x10},// 4
{0x27, 0x45, 0x45, 0x45, 0x39},// 5
{0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
{0x01, 0x71, 0x09, 0x05, 0x03},// 7
{0x36, 0x49, 0x49, 0x49, 0x36},// 8
{0x06, 0x49, 0x49, 0x29, 0x1E},// 9
{0x00, 0x36, 0x36, 0x00, 0x00},//:
{0x00, 0x56, 0x36, 0x00, 0x00},//;
{0x00, 0x08, 0x14, 0x22, 0x41},// <
{0x14, 0x14, 0x14, 0x14, 0x14},// =
{0x41, 0x22, 0x14, 0x08, 0x00},// >
{0x02, 0x01, 0x51, 0x09, 0x06},//?
{0x32, 0x49, 0x79, 0x41, 0x3E},// @
{0x7E, 0x11, 0x11, 0x11, 0x7E},// A
{0x7F, 0x49, 0x49, 0x49, 0x36},// B
{0x3E, 0x41, 0x41, 0x41, 0x22},// C
{0x7F, 0x41, 0x41, 0x22, 0x1C},// D
{0x7F, 0x49, 0x49, 0x49, 0x41},// E
{0x7F, 0x09, 0x09, 0x01, 0x01},// F
{0x3E, 0x41, 0x41, 0x51, 0x32},// G
{0x7F, 0x08, 0x08, 0x08, 0x7F},// H
{0x00, 0x41, 0x7F, 0x41, 0x00},// I
{0x20, 0x40, 0x41, 0x3F, 0x01},// J
{0x7F, 0x08, 0x14, 0x22, 0x41},// K
{0x7F, 0x40, 0x40, 0x40, 0x40},// L
{0x7F, 0x02, 0x04, 0x02, 0x7F},// M
{0x7F, 0x04, 0x08, 0x10, 0x7F},// N
{0x3E, 0x41, 0x41, 0x41, 0x3E},// O
{0x7F, 0x09, 0x09, 0x09, 0x06},// P
{0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
{0x7F, 0x09, 0x19, 0x29, 0x46},// R
{0x46, 0x49, 0x49, 0x49, 0x31},// S
{0x01, 0x01, 0x7F, 0x01, 0x01},// T
{0x3F, 0x40, 0x40, 0x40, 0x3F},// U
{0x1F, 0x20, 0x40, 0x20, 0x1F},// V
{0x7F, 0x20, 0x18, 0x20, 0x7F},// W
{0x63, 0x14, 0x08, 0x14, 0x63},// X
{0x03, 0x04, 0x78, 0x04, 0x03},// Y
{0x61, 0x51, 0x49, 0x45, 0x43},// Z
{0x00, 0x00, 0x7F, 0x41, 0x41},// [
{0x02, 0x04, 0x08, 0x10, 0x20},// «»
{0x41, 0x41, 0x7F, 0x00, 0x00},// ]
{0x04, 0x02, 0x01, 0x02, 0x04},// ^
{0x40, 0x40, 0x40, 0x40, 0x40},// _
{0x00, 0x01, 0x02, 0x04, 0x00},// `
{0x20, 0x54, 0x54, 0x54, 0x78},// a
{0x7F, 0x48, 0x44, 0x44, 0x38},// b
{0x38, 0x44, 0x44, 0x44, 0x20},// c
{0x38, 0x44, 0x44, 0x48, 0x7F},// d
{0x38, 0x54, 0x54, 0x54, 0x18},// e
{0x08, 0x7E, 0x09, 0x01, 0x02},// f
{0x08, 0x14, 0x54, 0x54, 0x3C},// g
{0x7F, 0x08, 0x04, 0x04, 0x78},// h
{0x00, 0x44, 0x7D, 0x40, 0x00},// i
{0x20, 0x40, 0x44, 0x3D, 0x00},// j
{0x00, 0x7F, 0x10, 0x28, 0x44},// k
{0x00, 0x41, 0x7F, 0x40, 0x00},// l
{0x7C, 0x04, 0x18, 0x04, 0x78},// m
{0x7C, 0x08, 0x04, 0x04, 0x78},// n
{0x38, 0x44, 0x44, 0x44, 0x38},// o
{0x7C, 0x14, 0x14, 0x14, 0x08},// p
{0x08, 0x14, 0x14, 0x18, 0x7C},// q
{0x7C, 0x08, 0x04, 0x04, 0x08},// r
{0x48, 0x54, 0x54, 0x54, 0x20},// s
{0x04, 0x3F, 0x44, 0x40, 0x20},// t
{0x3C, 0x40, 0x40, 0x20, 0x7C},// u
{0x1C, 0x20, 0x40, 0x20, 0x1C},// v
{0x3C, 0x40, 0x30, 0x40, 0x3C},// w
{0x44, 0x28, 0x10, 0x28, 0x44},// x
{0x0C, 0x50, 0x50, 0x50, 0x3C},// y
{0x44, 0x64, 0x54, 0x4C, 0x44},// z
{0x00, 0x08, 0x36, 0x41, 0x00},// {
{0x00, 0x00, 0x7F, 0x00, 0x00},// |
{0x00, 0x41, 0x36, 0x08, 0x00},// }
{0x08, 0x08, 0x2A, 0x1C, 0x08},// ->
{0x08, 0x1C, 0x2A, 0x08, 0x08}, // < — {0x7E, 0x11, 0x11, 0x11, 0x7E},// A
{0x7F, 0x49, 0x49, 0x49, 0x30},// Б
{0x7F, 0x49, 0x49, 0x49, 0x36},// B
{0x7F, 0x01, 0x01, 0x01, 0x01},// Г
{0x60, 0x3F, 0x21, 0x3F, 0x60},// Д
{0x7F, 0x49, 0x49, 0x49, 0x41},// E
{0x63, 0x14, 0x7F, 0x14, 0x63},// Ж
{0x49, 0x49, 0x49, 0x49, 0x36},// З
{0x7F, 0x10, 0x08, 0x04, 0x7F},// И
{0x7F, 0x10, 0x09, 0x04, 0x7F},// Й
{0x7F, 0x08, 0x14, 0x22, 0x41},// К
{0x40, 0x3F, 0x01, 0x01, 0x7F},// Л
{0x7F, 0x02, 0x04, 0x02, 0x7F},// М
{0x7F, 0x08, 0x08, 0x08, 0x7F},// H
{0x3E, 0x41, 0x41, 0x41, 0x3E},// O
{0x7F, 0x01, 0x01, 0x01, 0x7F},// П
{0x7F, 0x09, 0x09, 0x09, 0x06},// P
{0x3E, 0x41, 0x41, 0x41, 0x22},// C
{0x01, 0x01, 0x7F, 0x01, 0x01},// T
{0x63, 0x14, 0x08, 0x04, 0x03},// У
{0x3E, 0x41, 0x7F, 0x41, 0x3E},// Ф
{0x63, 0x14, 0x08, 0x14, 0x63},// X
{0x3F, 0x20, 0x20, 0x3F, 0x60},// Ц
{0x07, 0x08, 0x08, 0x08, 0x7F},// Ч
{0x7F, 0x40, 0x7F, 0x40, 0x7F},// Ш
{0x3F, 0x20, 0x3F, 0x20, 0x7F},// Щ
{0x01, 0x7F, 0x48, 0x48, 0x30},// Ъ
{0x3C, 0x41, 0x42, 0x20, 0x7C},// ѝ
{0x7F, 0x08, 0x3E, 0x41, 0x3E},// Ю
{0x46, 0x29, 0x19, 0x09, 0x7F},// Я
{0x20, 0x54, 0x54, 0x54, 0x78},// а
{0x7E, 0x49, 0x45, 0x45, 0x39},// б
{0x7C, 0x54, 0x54, 0x58, 0x20},// в
{0x7C, 0x04, 0x04, 0x04, 0x04},// г
{0x08, 0x14, 0x54, 0x54, 0x3C},// д
{0x38, 0x54, 0x54, 0x54, 0x18},// е
{0x44, 0x28, 0x7C, 0x28, 0x44},// ж
{0x54, 0x54, 0x54, 0x54, 0x28},// з
{0x3C, 0x40, 0x40, 0x20, 0x7C},// и
{0x3C, 0x41, 0x42, 0x21, 0x7C},// й
{0x00, 0x7C, 0x10, 0x28, 0x44},// к
{0x40, 0x3C, 0x04, 0x04, 0x7C},// л
{0x7C, 0x08, 0x10, 0x08, 0x7C},// м
{0x00, 0x7C, 0x10, 0x10, 0x7C},// н
{0x38, 0x44, 0x44, 0x44, 0x38},// о
{0x00, 0x7C, 0x04, 0x04, 0x7C},// п
{0x7C, 0x14, 0x14, 0x14, 0x08},// р
{0x38, 0x44, 0x44, 0x44, 0x20},// с
{0x04, 0x04, 0x7C, 0x04, 0x04},// т
{0x0C, 0x50, 0x50, 0x50, 0x3C},// у
{0x38, 0x44, 0x7C, 0x44, 0x38},// ф
{0x44, 0x28, 0x10, 0x28, 0x44},// х
{0x3C, 0x20, 0x20, 0x3C, 0x60},// ц
{0x00, 0x0C, 0x10, 0x10, 0x7C},// ч
{0x7C, 0x40, 0x7C, 0x40, 0x7C},// ш
{0x3C, 0x20, 0x3C, 0x20, 0x7C},// щ
{0x04, 0x7C, 0x50, 0x50, 0x30},// ъ
{0x00, 0x7C, 0x50, 0x50, 0x30},// ь
{0x7C, 0x10, 0x38, 0x44, 0x38},// ю
{0x48, 0x34, 0x14, 0x14, 0x7C} // я
};
#define PANEL_RESET 2
#define PANEL_CLK 3
#define PANEL_D0 47
#define PANEL_D1 45
#define PANEL_D2 43
#define PANEL_D3 41
#define PANEL_D4 39
#define PANEL_D5 37
#define PANEL_D6 35
volatile uint8_t n = 0;
volatile uint8_t lines[111];
void changeN() {
n++;
PORTC = lines[n];
}
void panelInit() {
n = 0;
PORTC = 0x00;
}
void setup() {
// put your setup code here, to run once:
DDRC = 0xFF;
for (int i = 0; i < 111; i++) lines[i] = 0x00;
Serial.begin(115200);
String s = «»;
while(!Serial.available());;
s = Serial.readStringUntil(‘r’);
Serial.println(s);
int index = 3;
for(int i = 0; i < s.length(); i++) {
for(int t = 0; t < 5; t++) {
lines[index] = System5x7C[s[i] — 0x20][t];
index++;
}
index += 3;
}
for(int i = 0; i < 111; i++) Serial.println(lines[i],HEX);
attachInterrupt(digitalPinToInterrupt(3), changeN, FALLING);
attachInterrupt(digitalPinToInterrupt(2), panelInit, FALLING);
}
void loop() {
// put your main code here, to run repeatedly:
}
Смена «медленных» pinMode и digitalWrite на «быструю» работу с портами резко меняет ситуацию к лучшему.
❯ Управление яркостью
25 контакт разъёма — ещё один генератор импульсов, служащий для управления яркостью панели. Если подать высокий уровень на контакт 17, то индикатор погаснет. Но, само собой, если подавать на него сигнал случайной частоты и фазы, то индикатор будет мерцать. Чтобы этого не происходило, существует контакт управления яркостью: импульсы на контакт гашения подаются синхронно с таковыми на 25 выводе, а их длительность позволяет регулировать время горения столбца панели.
❯ Неожиданные глюки
В процессе опытов столкнулся с проблемой, что после прогрева девайсу плохеет — при выводе появляются фантомные символы, сброс не приводит к полному гашению экрана. Предположительно, всему виной электролиты, которые следует поменять все и полностью.
❯ Библиотека для Arduino
Я прекрасно понимаю, что большинство из заинтерсовавшихся, скорее всего, будут использовать ПИУ для сборки часов или другого подобного устройства. Специально для них я привёл все тестовые проги в нормальный вид и написал библиотеку для работы с этим прибором при помощи Arduino. Также в репозитории лежат обе версии документации, упомянутые ранее.
❯ Вот как-то так
При кажущейся простоте ПИУ оказался прибором, не менее интересным, что и МС6205.
По сравнению с цифровыми ГРИ или ВЛИ, проектов на подобных девайсах немного, но они всё же есть. На просторах удалось найти вот такой вот шикарнейший девайс. Индикатор очень круто выглядит и разбавляет уже приевшиеся проекты типа привычных «ИН-12 с синей подсветкой».
Такие дела.
Возможно, захочется почитать и это:
- ➤ Оживляем контроллер машиниста от ушедшего в историю электропоезда
- ➤ Старый добрый семисегментный индикатор
- ➤ Starting Electronics: руководство по веб-серверам на Arduino. Графический индикатор на веб-странице
- ➤ Timeweb Cloud CLI. Часть 1: S3
- ➤ Half-life через 25 лет. История серии
Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале ↩
Теги:
- timeweb_статьи
- пиу
- гипс
- игпс
- гри
- неоновые лампы
- индикатор
- avr
- arduino
- блок питания
- пзу
- преобразователь
- генератор
Хабы:
- Блог компании Timeweb Cloud
- Программирование микроконтроллеров
- Схемотехника
- Компьютерное железо
- Старое железо