Работа с текстом на графическом дисплее MT-12864J

MT-12864J-rus

 О том, как подключать ЖК-матрицу 128х64 точек MT-12864J и использовать ее для вывода изображений рассказывается в статье «Работа с ЖК-матрицей 128х64». Здесь мы подробнее остановимся на некоторых нюансах практического применения ЖК-матриц на основе контроллера KS-0108, а также рассмотрим вывод текста с помощью готовых шрифтов из библиотеки GLCD v3 и вопросы их модернизации для вывода кириллических символов.

Подключение MT-12864J

К сожалению, контроллер ks0108 имеет параллельный восьмибитовый интерфейс, и с учетом управляющих выводов, придется занять аж 13 функциональных контактов платы Arduino Uno. Число соединений можно сократить, если подключить ЖК-модуль через сдвиговый регистр или, что еще проще, дешифратор двоичного кода. В первом случае число линий данных сократится с восьми до одной плюс линия импульсов сдвига, во втором — до трех. Но в обоих случаях о стандартной библиотеке придется забыть, создавать свои схемы подключения и писать свои процедуры вывода.

Потому мы используем стандартный способ, но внесем в него некоторые изменения. Использовать именно те выводы Arduino, что предусмотрены библиотекой GLCD по умолчанию (см. таблицу в указанной статье или в описании библиотеки, где матрице MT-12864J соответствует вариант «Pinout A»), при таком их количестве не только неудобно, но часто просто невозможно. Не забудем, что ведь мы еще подключаем к контроллеру всякие другие устройства по стандартным коммуникационным портам, и стоит постараться не занимать их выводы по максимуму.

Модернизированная с учетом этого обстоятельства схема подключения к Arduino Uno приведена на рисунке ниже. Как видите, у нас оставлены свободными контакты D1 и D2 (RX и TX последовательного порта) и контакты А4-A5, участвующие в обмене через порт I²C. Одновременная работа со стандартным подключением SD-карты, требующим выводов интерфейса SPI (11, 12, 13, и, с некоторыми оговорками, 10) здесь уже оказывается невозможной.

glsdA

Обратим также внимание на резисторы R1 и R2, о которых почему-то авторы статей о графических матрицах часто забывают упомянуть. Переменный или подстроечный резистор R1 служит для регулировки контрастности индикатора. На схеме он подключен так, как рекомендуется в документации фирмы МЭЛТ, однако может подключаться и по схеме потенциометра: одним концом к «земле», другим к питанию 5 В, а средним выводом к контакту Vo индикатора. Номинал его выбирается в пределах 10-20 кОм, и в конечном продукте R1 можно заменить на постоянный резистор подобранного номинала.

Резистор R2 — токоограничивающий для LED-подсветки. В принципе его можно не устанавливать вовсе (и в документации он не упоминается), поэтому на схеме он обозначен пунктиром. Согласно документации МЭЛТ, ток подсветки тогда составит около 64 мА. Установить его следует в двух случаях: если вы хотите уменьшить ток (и, соответственно, пожертвовать яркостью подсветки) или если подсветка питается от отдельного источника с повышенным напряжением. Последний вариант обычно реализуется при смешанном питании, когда при подключении к сетевому источнику подсветка запитывается от нестабилизированного выхода адаптера питания 7-9 В, а при переключении на батарейку отключается вовсе — потребление контроллера модуля при выключенной подсветке составляет всего 4 мА (на подробностях реализации этого способа мы здесь останавливаться не будем). При указанном напряжении (7-9 В) резистор R2 должен погасить лишние 2-4 В, соответственно, его номинал должен составлять от 39 до 62 Ом.

Отмечу, что на свету при отсутствии подсветки дисплей MT-12864J выглядит даже лучше — больше контраст и углы обзора, а сама подсветка настолько тусклая, что при посторонней засветке экрана только снижает контраст, ухудшая различимость символов. То есть фактически она требуется только при эксплуатации экрана в темноте. Зато, вопреки ожиданиям, качество дисплея в отсутствии подсветки оказалось вполне на высоте.

Скачать библиотеку GLCD можно с официального ресурса, на момент написания этой статьи последняя версия носит номер 3. Распакуйте ее, как обычно, в папку libraries каталога Arduino. Так как мы меняли контакты, то для начала файл библиотеки, где обозначены выводы, придется причесать в соответствии с нашими потребностями. Для этого необходимо править файл ks0108_Arduino.h (папка libraries\glcd\config). Согласно схеме, установим следующие выводы (в листинге приводятся только строки файла, которые подлежат правке, закомментированы старые номера выводов):

#define glcdData0Pin 2 //8 – так было в оригинале
#define glcdData1Pin 3 //9
#define glcdData2Pin 4 //10
#define glcdData3Pin 5 //11
#define glcdData4Pin 6 //4
#define glcdData5Pin 7 //5
#define glcdData6Pin 8 //6
#define glcdData7Pin 9 //7
#define glcdCSEL1 10 //14
#define glcdCSEL2 11 //15
#define glcdRW 12 //16
#define glcdDI 13 //17
#define glcdEN 14 //18

Русификация модуля MT-12864J

Конечно, никакого специального текстового режима в модулях MT-12864J не существует. Текст в них выводится, просто, как картинка, для чего имеются таблицы шрифтов в виде специальной функции, вызываемой через оператор SelectFont. Чтобы русифицировать этот индикатор, для него придется создать шрифт с русскими символами. Причем создать руками: рекомендуемый конвертор шрифтов Windows, к сожалению, в упор не понимает ничего, кроме английских символов. Это объясняется не столько презрительным отношением англосаксов к иноязычным народам, сколько тем, что в UTF-8, принятой в качестве кодировки для файлов Arduino IDE, только английские символы однозначно автоматически переводятся в однобайтовую кодировку. Нет никаких сомнений, что авторы конвертора могли бы с этой проблемой справиться — но только представьте, какой объем работы им пришлось бы провернуть, чтобы охватить всего десяток-другой самых популярных языков? Так что простим их и вспомним, что все наших руках.

Для этого мы модернизируем имеющийся в комплекте библиотеки GLCD английский шрифт 57 точек, размещающийся в файле SystemFont5x7.h (папка fonts). В принципе никакие особые инструменты для этого не нужны: немного поразмыслив над приведенными там кодами (для наглядности каждый байт следует разложить в двоичное представление и записать все пять штук один над другим), вы легко разберетесь в принципе устройства таблицы и сможете ее менять и дополнять без какого-либо визуального редактора. Вот как, например, кодируется заглавная буква «P» в этой системе (последовательность 0x7F, 0×09, 0×09, 0×09, 0×06):

01111111 0x7F
00001001 0x09
00001001 0x09
00001001 0x09
00000110 0x06

Если еще не догадались, то мысленно поверните байтовый массив на 90 градусов влево, и вы увидите букву «Р», образованную единицами. Хитрость дополнения имеющейся таблицы состоит только в том, чтобы русские буквы соответствовали их кодам, получающимся при компиляции текстового файла с программой — вводить текст в программе через номера кодов не слишком удобно, приятнее писать его прямо по-русски.

Правила Arduino IDE для кодирования символов второй половины байтовой таблицы символов (т.е. с номерами более 127) соответствуют младшему байту кодировки UTF-8 (именно в ней сохраняется текстовый файл .ino). В русскоязычной части таблицы UTF-8 младшие байты кодов с 80h по 8Fh занимают строчные буквы от «р» до «я», далее идут подряд 32 заглавные от «А» до «Я» (исключая букву «Ё»), а в кодах от B0h до BFh размещены оставшиеся строчные от «а» до «п». Таким образом у нас еще остается в конце байтовой таблицы незадействованная часть массива кодов, размером в целых 64 символа (с кодами от C0h до FFh), куда можно при надобности втиснуть различные служебные символы, отсутствующие в оригинале (вроде степеней или индексов). При самостоятельном дополнении таблицы не забывайте, что номера символов должны идти подряд, начиная с указанного в заголовке функции System5x7 кода 0х20 (что соответствует пробелу во всех разновидностях кодировок, основанных на ASCII). А общее количество символов следует указать в последнем параметре функции — в оригинале там стоит 0×60 (96), у нас это число возрастает до 0xA0 (160).

Один из таких отсутствующих символов нам понадобится прямо в этом проекте: ни в системном английском шрифте, ни в доработанных разными умельцами вариантах не содержится значка градуса. Чтобы больше ничего не менять в заголовке файла, мы не будем дополнять таблицу, а подставим этот значок вместо одного из редко используемых символов. Закодированный в этой системе, символ градуса будет выглядеть, как 0×00, 0×00, 0x0F, 0×09, 0x0F. Для замены я выбрал знак «\» («обратный слэш»), номер которого в таблице равен 0x5C. Вместо значка градуса в операторе вывода тогда придется указывать либо его код (в среде Arduino IDE это удобнее делать в восьмеричном виде, как «\134»), либо просто двойной «обратный слеш», в соответствии с правилами синтаксиса языка C.

Кроме указанных изменений, в этом шрифте я исправил цифру 0: вместо перечеркнутого «0» скопировал для символа 0×30 строку для буквы «О» (символ 0x4F). Перечеркнутый ноль давно удален из всех шрифтов в пользовательских устройствах, что иногда даже бывает неудобно: например, когда требуется воспроизвести пароль с цифрами и буквами вперемешку. И только в таблицах шрифтов для подобных индикаторов он по инерции задержался с доисторических времен господства АЦПУ и алфавитно-цифровых терминалов, и в современном антураже выглядит довольно дико.

Архив с файлом русифицированного шрифта под именем SystemFont5×7R.h вы можете скачать с сайта автора по этому адресу. При его создании использованы наработки SkyFort с сайта Robocraft.ru, который и проделал основную работу по прорисовке русских символов и переводу их в hex-коды, используя какой-то хитрый софт (и, судя по его статье, все делал верно, однако, почему-то для скачивания разместил ошибочный результирующий файл).

Файлы шрифта можно размещать прямо в папке с библиотекой GLCD (там же, где размещается glcd.h) или в ее подпапке fonts. В последнем случае в директиве #include к имени файла придется добавлять название каталога (по образцу #include «fonts/SystemFont5x7.h»).

В том же архиве имеется файл тестовой программы-примера Proba_LCD.ino, который выводит подряд символы русского алфавита и цифр, значок градуса и в нижней строке — наименование дисплея «MT-12864J»:

#include <glcd.h> //подключим библиотеку
#include "SystemFont5x7R.h" // файл шрифта
void setup() {
GLCD.Init(); //инициализация
GLCD.ClearScreen();
}
void loop()
{
GLCD.SelectFont(System5x7); //выбираем шрифт
GLCD.CursorToXY(0,0); //установим курсор в начальную позицию
GLCD.println("АБВГДЕЖЗИЙКЛМНОП");
GLCD.println("РСТУФХЦЧШЩЪЫЬЭЮЯ");
GLCD.println("абвгдежзийклмноп");
GLCD.println("рстуфхцчшщъыьэюя");
GLCD.println("1234567890");
GLCD.CursorToXY(19*6,4*8); //установим курсор в предпоследнюю позицию 5-й строки
GLCD.print("\\C"); //градус С
GLCD.CursorToXY(4*6,7*8); //установим курсор в поз 4 строки 8
GLCD.print("MT-12864J");
}

Из текста примера понятно, как обращаться с текстом при выводе. Текстовая зона с данным шрифтом получается 21 символ на 8 строк. При выводе строки длиннее 21 символа, ее конец автоматически перейдет на другую строку . Для принудительного перевода строки используйте функцию println. Чтобы правильно позиционировать вывод текста, следует иметь в виду, что библиотечная функция CursorToXY рассчитана на графический экран 12864 точки. По этой причине при выводе текста указывать положение курсора удобно так, как показано в примере, с учетом того, что символ занимает 6 точек по ширине, а строка — 8 точек по высоте. Так как позиции в строке и сами строки нумеруются с нуля, то вывод символа в предпоследнюю (20-ю, т. е. номер 19) позицию пятой (т. е. номер 4) строки предваряем оператором CursorToXY(19*6,4*8).

Результат выполнения тестовой программы см. на фото (при выключенной подсветке — на снимке она была бы практически не видна).

автор Юрий РЕВИЧ