Символьные дисплеи LCD 1602 и 2004: подключение и русские буквы

Как устроены алфавитно-цифровые ЖК-дисплеи, чем удобен адаптер I2C и как вывести на экран кириллицу и собственные символы.
Что такое алфавитно-цифровой дисплей
Символьные, или алфавитно-цифровые, дисплеи показывают не произвольную картинку, а набор знаков, заранее записанных в их память: буквы, цифры, знаки препинания. Когда-то по такому принципу работало большинство мониторов, а сегодня эти индикаторы остались в малой электронике, прежде всего в проектах на Arduino и других микроконтроллерах. Их встречают и в готовой технике, от вендинговых автоматов до измерительных приборов.
В типичном жидкокристаллическом модуле каждый символ собран из 40 точек: 5 по горизонтали и 8 по вертикали. Название модели складывается из числа знаков в строке и числа строк: LCD 1602 вмещает 16 символов в 2 строках, LCD 2004 рассчитан на 20 символов в 4 строках. Первого хватает для большинства задач, второй берут, когда места мало. Кроме размера, модули различаются цветом подсветки (жёлтая, синяя, зелёная, красная, белая) и типом изображения: светлые знаки на тёмном фоне или наоборот. Работают и программируются все они одинаково, с одними и теми же библиотеками.
Два способа подключения
Прямое подключение предполагает, что каждый вывод дисплея соединён с отдельным выводом контроллера. Для полного управления может понадобиться до 12 пинов, причём одна только шина данных занимает 8. Для такого варианта есть стандартная схема, но проводов и занятых выводов получается много.
Второй способ опирается на адаптер, который принимает команды по двухпроводной шине I2C и сам формирует сигналы для дисплея. Плата адаптера припаивается прямо к модулю и лишь немного увеличивает его толщину. Со стороны контроллера остаются два сигнальных провода, а регулятор контрастности уже установлен на адаптере, так что отдельный переменный резистор не нужен. Этот вариант считается более удобным, и дальнейшие примеры относятся именно к нему.
Библиотека и базовые команды
Для работы через адаптер в скетч подключают библиотеку LiquidCrystal_I2C, а перед ней Wire.h, отвечающую за протокол I2C. Объект дисплея создаётся строкой вида LiquidCrystal_I2C lcd(0x27, 16, 2), где указаны адрес на шине, число символов и число строк. Дальше используется небольшой набор функций:
- lcd.init() запускает дисплей;
- lcd.backlight() и lcd.noBacklight() включают и выключают подсветку;
- lcd.clear() очищает экран;
- lcd.setCursor(позиция, строка) ставит курсор в нужное место;
- lcd.print() выводит текст.
Что записано в памяти дисплея
Набор знаков зависит от прошивки конкретного модуля. Латиница, цифры и часть стандартных символов есть всегда, а буквы других алфавитов встречаются не во всех версиях. По внешнему виду русифицированный дисплей не отличить, если производитель не указал это в маркировке, поэтому наличие кириллицы лучше уточнять заранее. Перепрошить знакогенератор самостоятельно на практике нельзя: микросхемы залиты компаундом.
Проверить содержимое памяти помогает простой скетч, который по кругу выводит все коды по 16 штук с паузой 4 секунды. В рассмотренном примере первые 16 позиций выглядят как случайный набор знаков, затем идут математические и пунктуационные символы, цифры, латинские буквы. Диапазон с 0x80 по 0xA0 пуст, а после него начинается кириллица. В ней нет букв, совпадающих по начертанию с латинскими (А, В, С, О и подобных): вместо них используют латинские. Несколько букв, у которых латинского двойника нет, вынесены в другое место таблицы, ближе к её концу, где расположены также дроби и специальные значки.
Вывод русского текста
Среда Arduino не позволяет напрямую печатать на таком дисплее русские буквы, поэтому каждую приходится задавать её кодом. Например, слово «Привет» собирается из кодов 0xA8, 0x70, 0xB8, 0xB3, 0x65, 0xBF, которые отправляются по одному функцией вывода байта, а латинская часть строки печатается обычным lcd.print(). Второй вариант записи состоит в том, чтобы сложить коды и обычные символы в массив байтов и вывести его в цикле. Читается он не легче, зато компактнее, занимает меньше памяти контроллера и выполняется быстрее.
Собственные символы
Знак, которого нет в памяти, можно нарисовать самостоятельно. Его описывают матрицей 5х8, где единица означает тёмную точку, а ноль светлую, оформляют как массив из восьми байтов и записывают в дисплей функцией lcd.createChar(1, sd), где первое число задаёт номер ячейки. После этого символ выводится как любой другой, например строкой lcd.print с кодом \1.
Пользовательские символы хранятся в самых первых ячейках таблицы; именно поэтому в начале проверки там виден беспорядочный набор знаков. Эта память не сохраняется при отключении питания, так что программа должна записывать свои символы заново при каждом запуске. В рассмотренном дисплее под них отведено 8 знакомест. Теоретически так можно дорисовать недостающие русские буквы, но на весь алфавит восьми ячеек не хватит. Если дисплей не русифицирован, остаются короткие подписи на английском либо подбор слов, в которых большинство букв совпадает с латинскими, а недостающие размещаются в пользовательских ячейках.
OLED-версии и расход энергии
Существуют внешне похожие модули с маркировкой OLED. Это такие же символьные дисплеи, но с OLED-матрицей: она ярче и контрастнее, лучше читается при сильном освещении и не оставляет шлейфов при быстрой смене изображения. Из минусов отмечают склонность к выгоранию и цену, которая выше примерно на порядок.
При питании от аккумулятора основная доля потребления ЖК-дисплея приходится на подсветку. Её имеет смысл гасить, когда на экран никто не смотрит, и включать кнопкой либо по сигналу датчика движения или приближения.