ПИУ-2: Воскрешаем плазменный текстовый индикатор из СССР

Приветствую всех!
Месяц с небольшим назад я рассказывал о таком девайсе как МС6205. Тема подобных экранов меня заинтересовала, и вот ко мне в руки попал другой экземпляр, однострочный и с более простым управлением. Тем не менее, несмотря на схожий вид, внутри он устроен совершенно иначе — если в МС6205 был матричный индикатор, то тут используется панель с самосканированием. Как же оно работает и как это запустить? Давайте разбираться.

ПИУ-2: Воскрешаем плазменный текстовый индикатор из СССР

Итак, в сегодняшней статье поговорим о семействе советских текстовых индикаторов ПИУ. Узнаем, как они устроены и как работают. Попутно поговорим о текстовых газоразрядных дисплеях с самосканированием. Традиционно будет много интересного.

Суть такова

Началась эта история ещё в 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 показаны внутренности моего ПИУ. Этими фотографиями я поделился в чатике давным-давно, и вот они наконец пригодились.

Подключение

Так уж вышло, что детального описания работы ПИУ практически нигде нет. Есть, конечно, документация (причём сразу в двух версиях), но на этом всё. Поэтому сейчас я расскажу о том, как же вообще работает эта штука с точки зрения программиста микроконтроллеров.

Начнём, конечно же, с разъёма. Предыдущая ответная часть ушла вместе с неисправной панелью, пришлось намутить другой. Как оказалось, за минувший год такие разъёмы в местном магазине радиодеталей кончились, пришлось купить у сборщика металла. На этот раз он уже был частью какого-то жгута (если вдруг это условное обозначение вам о чём-то говорит, напишите в комментариях).

Разбираем разъём и выпаиваем остатки проводов. Их, разумеется, не выкидываем — ещё пригодятся.
Теперь можно перейти к распиновке самого блока. Она здесь оказалась вот такая:

  1. X8
  2. Первая строка
  3. X7
  4. Вторая строка
  5. X6
  6. Третья строка
  7. X5
  8. Четвёртая строка
  9. X4
  10. Пятая строка
  11. X3
  12. Шестая строка
  13. X2
  14. Седьмая строка
  15. X1
  16. Ничего
  17. Гашение
  18. Синхросигнал
  19. Запись/индикация
  20. Импульсы сброса
  21. Строб
  22. Ничего
  23. Сброс
  24. 5 В
  25. Управление яркостью
  26. -12,6 В
  27. Ничего
  28. Ничего
  29. Ничего
  30. Земля
  31. Ничего
  32. Масса

Для питания требуется два напряжения — +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 с синей подсветкой».

Такие дела.


Возможно, захочется почитать и это:

Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале

 

Источник

Читайте также