Подключение символьного ЖК-дисплея 16×2 к Arduino
Хотя монитор последовательного порта — удобный способ отладки и отображения данных, он не всегда самое удобное или портативное решение. Вот тут на помощь приходят символьные ЖК-дисплеи! Эти простые экраны идеально подходят для отображения данных в реальном времени, статусов системы или просто для придания индивидуальности вашему проекту.
В этом руководстве мы покажем вам, как подключить символьный ЖК-дисплей 16×2 к Arduino. И не волнуйтесь — если у вас другой размер, например 16×1, 16×4 или даже 20×4, основные шаги и идеи, которые мы рассмотрим, подойдут и для них.
Независимо от того, являетесь ли вы полным новичком или просто освежаете знания, мы проведём вас шаг за шагом. Так что берите ваш Arduino, ЖК-дисплей и горсть соединительных проводов — давайте зажжём несколько пикселей!
Знаете ли вы?
Жидкокристаллический дисплей (ЖК) работает путём тщательного управления светом с использованием жидких кристаллов для создания изображений или текста на экране.
Внутри каждого ЖК-дисплея есть подсветка, обеспечивающая стабильный источник света. Специальные жидкие кристаллы расположены между двумя слоями поляризованного стекла.
Когда электричество проходит через жидкие кристаллы, они меняют своё расположение. Это расположение влияет на то, как свет проходит через них.
Свет сначала проходит через первый слой поляризованного стекла, затем через выровненные жидкие кристаллы, которые поворачивают свет под определённым углом. Второй слой поляризованного стекла затем либо пропускает этот повёрнутый свет, либо блокирует его, в зависимости от угла поворота.
Точно управляя электрическим током к различным секциям (или пикселям) жидких кристаллов, ЖК-дисплей может избирательно пропускать или блокировать свет в определённых областях. Так создаются изображения, числа или текст, которые вы видите на экране.
Обзор оборудования
Символьные ЖК-дисплеи специально разработаны для отображения букв, цифр и символов. Например, символьный ЖК-дисплей 16×2 может показать 16 символов в каждой строке, всего две строки.
Если вы посмотрите очень внимательно на экран, вы заметите маленькие прямоугольные ячейки для каждой позиции символа. Внутри каждого прямоугольника находится сетка из 5×8 крошечных точек или пикселей. Эти пиксели загораются в разных паттернах для формирования различных букв, цифр или символов.
Мозгом этих дисплеев является специальная микросхема — контроллер Hitachi HD44780. Эта микросхема выполняет всю сложную работу по отправке правильных сигналов для управления жидкими кристаллами и управляет тем, что отображается на экране.
Символьные ЖК-дисплеи бывают разных размеров и цветовых комбинаций. Вы можете найти их в форматах 16×1, 16×4 или 20×4. Они также бывают с разными цветовыми вариантами: белый текст на синем фоне, чёрный текст на зелёном фоне и многие другие!
Одно из лучших преимуществ использования этих дисплеев в проектах — возможность их лёгкой замены. Если вы решите, что хотите другой размер или цвет ЖК-дисплея, вы можете заменить его без необходимости перекоммутации. Хотя может потребоваться внести небольшие изменения в код, подключение останется прежним!
Распиновка символьного ЖК-дисплея 16×2
Прежде чем перейти к подключению и примеру кода, давайте рассмотрим распиновку стандартного символьного ЖК-дисплея, который имеет 16 выводов:
GND — это вывод заземления.
VCC — это вывод питания, обычно подключается к источнику 5 В.
V0 управляет контрастностью экрана ЖК-дисплея. Обычно подключается к среднему выводу потенциометра, а два других вывода потенциометра — к 5 В и земле. При повороте потенциометра изменяется напряжение на V0, что регулирует контрастность.
RS (Register Select) определяет, как интерпретируются данные, отправленные на ЖК-дисплей: как команда или как символьные данные. Когда RS = 0: ЖК-дисплей воспринимает данные как команду (например, «очистить экран» или «переместить курсор»). Когда RS = 1: ЖК-дисплей воспринимает данные как символы для отображения (буквы или цифры).
R/W (Read/Write) определяет, отправляете ли вы данные на ЖК-дисплей или получаете данные от него: Когда RW = 0: Режим записи, отправка информации на ЖК-дисплей. Когда RW = 1: Режим чтения, получение информации от ЖК-дисплея. В большинстве случаев нам нужно только отправлять информацию на ЖК-дисплей, поэтому вывод RW обычно постоянно подтянут к LOW (0).
E (Enable) используется для сообщения ЖК-дисплею, когда считывать данные с линий данных (D0-D7). Чтобы ЖК-дисплей принял данные, нужно кратковременно подать импульс на этот вывод с HIGH на LOW, что говорит ЖК-дисплею зафиксировать данные в памяти.
D0-D7 (линии данных) — это восемь выводов, по которым передаются фактические данные или команды на ЖК-дисплей. В 8-битном режиме используются все восемь выводов (D0-D7). В 4-битном режиме используются только старшие четыре (D4-D7), а младшие четыре (D0-D3) остаются неподключёнными.
A (анод) и K (катод) питают светодиод подсветки, освещающий дисплей. Анод подключается к положительному напряжению (обычно 5 В), а катод — к земле. Иногда добавляется резистор для ограничения тока и защиты светодиода подсветки, если ваш ЖК-дисплей не имеет встроенного резистора.
Тестирование символьного ЖК-дисплея
Теперь наступает волнующий момент: тестирование ЖК-дисплея!
Сначала подключите выводы 5V и GND Arduino к шине питания макетной платы и аккуратно вставьте ЖК-дисплей в макетную плату.
ЖК-дисплей фактически нуждается в питании в двух местах: одно подключение питает сам ЖК-дисплей (выводы 1 и 2), а другое — подсветку (выводы 15 и 16). Подключите выводы 1 и 16 ЖК-дисплея к GND (земля), а выводы 2 и 15 — к 5V.
Некоторые ЖК-дисплеи поставляются со встроенным резистором для подсветки — вы можете увидеть его на обратной стороне ЖК-дисплея около вывода 15. Этот резистор защищает подсветку от чрезмерного тока. Если на вашем ЖК-дисплее нет этого резистора (или вы не уверены), безопаснее добавить его самостоятельно между 5V и выводом 15. Резистор 220 Ом подойдёт хорошо, хотя подсветка может быть немного тусклой. Для лучшей яркости проверьте техническое описание ЖК-дисплея, чтобы найти максимальный ток подсветки и рассчитать идеальное значение резистора.
Далее нужно настроить контрастность, чтобы видеть символы. Подключите потенциометр 10 кОм к дисплею: один конец к 5V, другой к GND, а средний вывод (движок) — к выводу 3 ЖК-дисплея.
На этом базовая настройка завершена! Теперь включите Arduino. Вы должны увидеть, как загорается подсветка, и при медленном повороте ручки потенциометра вы увидите, как на экране появляется первый ряд прямоугольников. Эти прямоугольники — места, где будут отображаться символы. Если вы видите эти прямоугольники чётко — поздравляем, ваш ЖК-дисплей работает и готов к отображению текста!
Схема подключения символьного ЖК-дисплея 16×2 к Arduino
Давайте завершим подключение ЖК-дисплея к Arduino.
Вы можете подумать, что нужно подключить все восемь выводов данных на ЖК-дисплее для отправки информации. Но вот что интересно: ЖК-дисплеи на базе HD44780 достаточно умны, чтобы общаться с ними, используя только четыре вывода данных вместо восьми! Это называется «4-битный режим» (с четырьмя выводами) вместо «8-битного режима» (с восемью выводами). Этот приём экономит четыре вывода Arduino, которые можно использовать для других частей проекта!
Для подключения ЖК-дисплея в 4-битном режиме потребуется всего шесть выводов Arduino: RS, EN и четыре вывода данных (D7, D6, D5 и D4). Вот как их подключить:
Подключите четыре вывода данных ЖК-дисплея (D4, D5, D6 и D7) к цифровым выводам 5, 4, 3 и 2 на Arduino.
Подключите вывод EN (Enable) к цифровому выводу 11 на Arduino.
Подключите вывод RS (Register Select) к цифровому выводу 12 на Arduino.
Полная схема подключения показана на изображении ниже.
Помните, что мы уже подключили выводы питания, земли и регулировки контрастности в предыдущей настройке. С этими дополнительными подключениями ваш ЖК-дисплей полностью подключён к Arduino и готов к отображению сообщений после загрузки кода!
4-битный и 8-битный режимы
Основное различие между 4-битным и 8-битным режимами символьного ЖК-дисплея — способ передачи информации от Arduino (или другого микроконтроллера) к экрану ЖК-дисплея.
В 8-битном режиме используются все 8 выводов данных (D0–D7). Это позволяет передавать полный байт (8 бит) информации за один раз. Это как отправить целое слово за один раз, что делает связь быстрее. Недостаток — нужно подключить все 8 выводов, что занимает больше ограниченных выводов ввода/вывода Arduino.
В 4-битном режиме используются только 4 вывода данных (D4–D7). При отправке информации каждый байт разбивается на два меньших фрагмента (называемых «полубайтами»), которые передаются последовательно. Это как разбить слово пополам и отправить в два приёма. Это немного медленнее, так как данные отправляются в два этапа вместо одного, но нужно в два раза меньше выводов Arduino.
Подводя итог: 8-битный режим быстрее, но требует больше выводов, а 4-битный режим немного медленнее, но экономит ценные выводы для других частей проекта. Для большинства простых проектов разница в скорости незаметна, поэтому 4-битный режим используется чаще.
Пример кода Arduino
Пример скетча ниже выводит «Hello World» на ЖК-дисплей. Попробуйте сначала запустить скетч, а затем мы разберём его подробно.
// include the library
#include <LiquidCrystal.h>
// Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Clears the LCD screen
lcd.clear();
}
void loop() {
// Print a message to the LCD.
lcd.print(" Hello world!");
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// Print a message to the LCD.
lcd.print(" LCD Tutorial");
}
Если всё подключено правильно и контрастность отрегулирована потенциометром, вы должны увидеть «Hello world!» в первой строке и «LCD Tutorial» во второй строке.
Объяснение кода
Скетч начинается с подключения библиотеки LiquidCrystal, которая необходима для управления ЖК-дисплеями на базе контроллера Hitachi HD44780. Эта библиотека предустановлена в Arduino IDE.
// include the library code:
#include <LiquidCrystal.h>
Далее мы создаём объект класса LiquidCrystal, указывая номера выводов, подключённых к RS (Register Select), EN (Enable) и четырём выводам данных (D4, D5, D6, D7) ЖК-дисплея. Этот объект позволяет управлять ЖК-дисплеем.
// Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
В функции setup мы вызываем две важные функции. Первая — begin(). Она инициализирует интерфейс с экраном ЖК-дисплея и задаёт его размеры (столбцы и строки). Поскольку мы используем ЖК-дисплей 16×2, указываем 16 и 2. Если у вас дисплей другого размера, например 20×4, используйте 20 и 4.
Вторая функция — clear(). Она очищает экран ЖК-дисплея и устанавливает курсор в верхний левый угол.
lcd.begin(16, 2);
lcd.clear();
В функции loop мы используем функцию print() для отображения текста «Hello world!» на ЖК-дисплее. Помните, что текстовые строки нужно заключать в кавычки (" "). Однако кавычки не нужны при выводе чисел или переменных.
// Print a message to the LCD.
lcd.print(" Hello world!");
После вывода первого сообщения мы хотим перейти на вторую строку для вывода другого сообщения. Для этого используем setCursor(0, 1). Первое число (0) означает крайний левый столбец, а второе число (1) — вторую строку. (Помните, в программировании мы часто начинаем счёт с 0, а не с 1, поэтому строка 0 — первая, а строка 1 — вторая!)
lcd.setCursor(0, 1);
lcd.print(" LCD Tutorial");
Пример прокрутки текста
Если ваше сообщение длиннее 16 символов или вы хотите создать эффект бегущей строки, можно использовать функции scrollDisplayLeft() или scrollDisplayRight() в цикле для перемещения текста по экрану.
Код Arduino
Скетч ниже показывает, как непрерывно прокручивать сообщение влево:
#include <LiquidCrystal.h>
// Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Clears the LCD screen
lcd.clear();
// Print a message to the LCD.
lcd.print("Scrolling Text Demo");
delay(1000); // pause to read the message initially
}
void loop() {
lcd.scrollDisplayLeft(); // scroll everything to the left by one position
delay(300); // small delay for visible scrolling speed
}
Когда вы загрузите этот код на Arduino, ваш ЖК-дисплей покажет что-то подобное:
Объяснение кода
В этом примере мы выводим сообщение длиной 19 символов («Scrolling Text Demo») на ЖК-дисплей. Поскольку дисплей может показать только 16 символов за раз, изначально будут видны только первые 16 символов.
// Print a message to the LCD
lcd.print("Scrolling Text Demo");
В функции loop() мы вызываем lcd.scrollDisplayLeft(), которая сдвигает всё содержимое дисплея на одну позицию влево. Повторяя это с короткой задержкой между каждым сдвигом, сообщение плавно перемещается по экрану.
void loop() {
lcd.scrollDisplayLeft(); // scroll everything to the left by one position
delay(300); // small delay for visible scrolling speed
}
По мере прокрутки текста символы, уходящие за левый край, исчезают, а пустые места появляются справа. Если вы хотите, чтобы сообщение непрерывно повторялось, нужно добавить код, который периодически повторно выводит сообщение.
Для прокрутки в противоположном направлении (справа налево) можно использовать lcd.scrollDisplayRight().
Другие полезные функции библиотеки LiquidCrystal
Объект LiquidCrystal предоставляет множество полезных функций для управления ЖК-дисплеем. Вот некоторые из наиболее полезных:
lcd.home()перемещает курсор обратно в верхний левый угол ЖК-дисплея (первая позиция первой строки). В отличие отclear(), она не стирает то, что уже на экране — просто перемещает курсор в начальную позицию.lcd.blink()иlcd.noBlink()включают или выключают мигающий блочный курсор. При включении с помощьюblink()вы увидите сплошной блок, мигающий на текущей позиции курсора. Это отлично для привлечения внимания пользователя. Если вы не хотите этот мигающий блок, используйтеnoBlink().lcd.cursor()иlcd.noCursor()управляют отображением подчёркивания (_) в позиции, где будет записан следующий символ.cursor()показывает эту линию, аnoCursor()скрывает её. Это отличается от мигающего блока — это просто линия, показывающая, где появится следующий символ.lcd.display()иlcd.noDisplay()позволяют включать и выключать весь дисплей без стирания данных. Когда вы используетеnoDisplay(), экран гаснет, но весь текст остаётся в памяти ЖК-дисплея. Когда вы снова вызоветеdisplay(), всё появится снова! Это идеально для создания эффектов мигания или экономии энергии.
Попробуйте поэкспериментировать с этими функциями в своём коде. Они помогут создать более интерактивные и динамичные дисплеи для ваших проектов!
Создание пользовательских символов для символьного ЖК-дисплея 16×2
Иногда вам может понадобиться отобразить специальные символы, не входящие в стандартный алфавит или набор цифр — например, смайлик, символ градуса (°) для показаний температуры или забавные иконки вроде сердечек, нот или стрелок.
Хорошая новость — ЖК-дисплеи на HD44780 позволяют создавать до 8 пользовательских символов собственного дизайна! Как мы узнали ранее в этом руководстве, каждый символ на ЖК-дисплее отображается с помощью сетки пикселей размером 5×8 (5 пикселей в ширину и 8 в высоту). Для создания собственного символа нужно определить, какие из этих точек должны быть включены, а какие — выключены.
Для создания пользовательского символа сначала нужно создать массив из 8 байт в коде. Каждый байт представляет одну горизонтальную строку символа, начиная с верхней и заканчивая нижней. Для каждого байта биты (1 и 0 в двоичной системе) указывают, какие пиксели должны быть включены (1), а какие — выключены (0). Используются только первые 5 бит каждого байта, поскольку символ имеет ширину 5 пикселей.
После того как вы спроектировали символ, настроив массив, используйте функцию createChar() для сохранения пользовательского символа в CGRAM ЖК-дисплея (Character Generator RAM) — специальной области памяти для хранения пользовательских символов.
Теперь давайте создадим крутые пользовательские символы для ваших проектов!
CGROM и CGRAM
Все ЖК-дисплеи на базе контроллера Hitachi HD44780 имеют два типа памяти: CGROM (постоянная память генератора символов) и CGRAM (оперативная память генератора символов).
CGROM — это энергонезависимая память, которая сохраняет данные даже при отключении питания. Она хранит предопределённые точечные паттерны для стандартных ASCII-символов: букв, цифр и общих символов. Когда вы приказываете ЖК-дисплею показать «A», контроллер ЖК-дисплея ищет паттерн для «A» в CGROM и отображает его. Это делает показ обычных символов очень быстрым и простым!
CGRAM — это энергозависимая память, которая теряет данные при отключении питания. Эта память гибкая и позволяет хранить пользовательские паттерны, не входящие в встроенный набор. Например, вы можете создать собственные символы, иконки или уникальные символы для проекта. Однако объём CGRAM ограничен — всего 64 байта. На стандартном ЖК-дисплее с пикселями 5×8 это означает возможность хранения только 8 пользовательских символов (поскольку каждый символ требует 8 байт). На ЖК-дисплее с пикселями 5×10 можно хранить только 4 пользовательских символа, так как каждый требует больше памяти.
Итого: CGROM — только для чтения с фиксированными паттернами символов, которые нельзя изменить, а CGRAM — для записи, позволяющая создавать и сохранять пользовательские символы по мере необходимости.
Генератор пользовательских символов
Создание пользовательских символов ещё никогда не было таким простым! Мы разработали полезный инструмент — Генератор пользовательских символов. Видите синюю сетку ниже? Вы можете щёлкнуть по любому пикселю, чтобы включить или выключить его, и по мере этого код для вашего символа автоматически создаётся рядом с сеткой. Вы можете скопировать этот код прямо в ваш скетч Arduino.
пиксели
| byte Character[8] = |
| { |
| 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000 |
| }; |
Скопируйте
код в скетч
Возможности для творчества практически безграничны! Вы можете создать стрелки, простых животных, игровых персонажей, символы погоды или любые маленькие иконки, которые помещаются в сетку 5×8. Единственное ограничение — библиотека LiquidCrystal позволяет использовать одновременно только восемь пользовательских символов. Но не волнуйтесь — восьми различных пользовательских символов всё ещё достаточно, чтобы сделать ваш проект уникальным и интересным!
Пример кода Arduino
Скетч ниже показывает, как отобразить пользовательские символы на ЖК-дисплее:
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// make some custom characters:
byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
byte Bell[8] = {
0b00100,
0b01110,
0b01110,
0b01110,
0b11111,
0b00000,
0b00100,
0b00000
};
byte Alien[8] = {
0b11111,
0b10101,
0b11111,
0b11111,
0b01110,
0b01010,
0b11011,
0b00000
};
byte Check[8] = {
0b00000,
0b00001,
0b00011,
0b10110,
0b11100,
0b01000,
0b00000,
0b00000
};
byte Speaker[8] = {
0b00001,
0b00011,
0b01111,
0b01111,
0b01111,
0b00011,
0b00001,
0b00000
};
byte Sound[8] = {
0b00001,
0b00011,
0b00101,
0b01001,
0b01001,
0b01011,
0b11011,
0b11000
};
byte Skull[8] = {
0b00000,
0b01110,
0b10101,
0b11011,
0b01110,
0b01110,
0b00000,
0b00000
};
byte Lock[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000
};
void setup()
{
// initialize LCD and set up the number of columns and rows:
lcd.begin(16, 2);
// create a new character
lcd.createChar(0, Heart);
// create a new character
lcd.createChar(1, Bell);
// create a new character
lcd.createChar(2, Alien);
// create a new character
lcd.createChar(3, Check);
// create a new character
lcd.createChar(4, Speaker);
// create a new character
lcd.createChar(5, Sound);
// create a new character
lcd.createChar(6, Skull);
// create a new character
lcd.createChar(7, Lock);
// Clears the LCD screen
lcd.clear();
// Print a message to the lcd.
lcd.print("Custom Character");
}
// Print All the custom characters
void loop()
{
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.setCursor(2, 1);
lcd.write(byte(1));
lcd.setCursor(4, 1);
lcd.write(byte(2));
lcd.setCursor(6, 1);
lcd.write(byte(3));
lcd.setCursor(8, 1);
lcd.write(byte(4));
lcd.setCursor(10, 1);
lcd.write(byte(5));
lcd.setCursor(12, 1);
lcd.write(byte(6));
lcd.setCursor(14, 1);
lcd.write(byte(7));
}
Когда вы загрузите этот код на Arduino, ваш ЖК-дисплей покажет что-то подобное:
Попробуйте и поэкспериментируйте с созданием собственных уникальных символов!
Объяснение кода
После подключения библиотеки LiquidCrystal и создания объекта ЖК-дисплея код определяет специальные массивы для наших пользовательских символов. Каждый массив содержит ровно 8 байт, и каждый байт управляет одной строкой точек в нашей сетке символа 5×8.
Пример включает восемь различных пользовательских символов. Рассмотрим массив Heart[8]:
byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
Каждая строка представляет одну строку пикселей, начиная с верхней части символа. «0b» в начале просто говорит Arduino, что это двоичное число (состоящее из 0 и 1). Каждый 0 означает «пиксель выключен», а каждая 1 — «пиксель включен». Если вы внимательно посмотрите на паттерн, можно увидеть, как единицы формируют форму сердца!
В разделе setup мы используем функцию createChar() для сохранения пользовательского символа в памяти ЖК-дисплея. Эта функция требует две части информации: номер от 0 до 7 (который указывает ЖК-дисплею, какую из восьми доступных ячеек памяти использовать) и имя массива с дизайном символа.
Код ниже сохраняет дизайн сердца в ячейку 0 памяти CGRAM ЖК-дисплея.
// create a new character
lcd.createChar(0, Heart);
Наконец, в разделе loop мы отображаем пользовательский символ с помощью функции write(). Мы указываем, какой символ отображать, передавая номер ячейки памяти:
// byte(0) represents Heart character.
lcd.write(byte(0));