Библиотека LiquidCrystal I2C для дисплеев LCD 1602 и 2004
Обновлено
- В менеджере библиотек
- LiquidCrystal I2C by Frank de Brabander
- Версия
- 1.1.2 · всего 2 версии, первая — 1.1.1
- Платы
- AVR — UNO, Nano, Mega, Pro Mini
Архивы — копии из официального индекса Arduino, контрольная сумма совпадает. Сверено 19.10.2026.
Те же дисплеи 1602 и 2004, но через переходник I2C на PCF8574: два провода вместо шести.
Почти все дисплеи 1602 сейчас продаются с припаянным переходником, и подключаются они четырьмя проводами: питание, земля, SDA и SCL. Методы вывода те же, что у обычной LiquidCrystal, добавляется управление подсветкой и обязательная инициализация init().
Одноимённых библиотек в менеджере несколько, и у них разные конструкторы. Здесь описана самая распространённая — Frank de Brabander; если у вашей нет init(), это другая, и она ждёт begin().
Как скачать и установить
- Через менеджер — самый простой путь. В Arduino IDE: Инструменты → Управлять библиотеками (Ctrl+Shift+I). Введите
LiquidCrystal I2Cи найдите в списке строку «LiquidCrystal I2C by Frank de Brabander» — одноимённых библиотек бывает несколько, отличаются они автором. Нажмите «Установить». - Конкретная версия — если в чужом проекте указана не последняя. В той же карточке менеджера рядом с кнопкой есть выпадающий список версий: выберите нужную и нажмите «Установить».
- Из архива — если нет интернета на рабочем компьютере или менеджер не открывается. Скачайте ZIP выше, затем Скетч → Подключить библиотеку → Добавить .ZIP библиотеку и укажите файл. Распаковывать не нужно.
Файл LiquidCrystal_I2C.h отдельно не скачивают: он внутри библиотеки и появляется после установки. Если среда пишет LiquidCrystal_I2C.h: No such file or directory — библиотека не установлена или установлена не та. Как устроен менеджер и куда складываются файлы — в общей статье про библиотеки.
Строка подключения:
#include <LiquidCrystal_I2C.h>Создание объекта — обычно до setup():
LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес, столбцов, строк
lcd.init(); // в setup()
lcd.backlight(); // иначе экран тёмныйПодключение и адрес
Переходник на микросхеме PCF8574 припаян к гребёнке дисплея, и от платы идут четыре провода: GND, VCC к 5 В, SDA и SCL. На UNO и Nano это A4 и A5 или отдельные гнёзда SDA и SCL у AREF — одни и те же линии; на других платах — по таблице в разборе Wire.
Адрес задаёт микросхема на переходнике и три перемычки A0–A2. Если сканер ничего не находит — дело в проводах; если находит, а экран пуст — в контрасте.

- PCF8574T
- Адрес:
0x270x20–0x27: до восьми дисплеев на одной шине
- PCF8574AT
- Адрес:
0x3F0x38–0x3F
Контраст — подстроечником
Синий подстроечник на переходнике. С завода он часто выкручен так, что видна только подсветка или ряд пустых квадратов. Крутите на работающем скетче, пока не проступят буквы. Кодом контраст не меняется — setContrast() в библиотеке пустая.
Перемычка подсветки
Два штырька с джампером сбоку переходника. Снят джампер — подсветка не горит ни при каком backlight().
ESP32 и ESP8266
Дисплей питают от 5 В, а SDA и SCL подключают к ESP. Подтяжка на переходнике тянет линии к его VCC, то есть к 5 В, хотя выводы ESP рассчитаны на 3,3 В. На практике обычно работает, но надёжно — через преобразователь уровней на линиях шины.
Русские буквы на 1602
В памяти обычного дисплея 1602 — латиница, цифры и японская катакана, русских букв там нет. Поэтому lcd.print("Привет") выводит набор закорючек. Буквы, похожие на латинские — А, В, Е, К, М, Н, О, Р, С, Т, Х, — выводят латинскими, остальные рисуют сами через createChar(). Своих символов у дисплея восемь, и это главный предел: на экране одновременно помещается не больше восьми русских букв, не похожих на латинские.
| Способ | Что нужно | Предел |
|---|---|---|
| Свои символы вручную | createChar() этой же библиотеки — пример «ПРИВЕТ» ниже | 8 разных нелатинских букв на экране |
| I2C_LiquidCrystal_RUS (Alash Electronics) | поставить из менеджера, в скетче — #define _LCD_TYPE 1 и свой класс | те же 8: буквы подгружаются сами |
| GyverLCD (AlexGyver) | поставить из менеджера, класс GyverLCD_UTF8, print("Привет") работает как есть | 8 в программном режиме; с дисплеем с кириллицей — без предела |
| Дисплей с кириллицей в памяти | другой дисплей: продавец указывает «с русскими буквами» | нет, но коды букв — по таблице конкретного дисплея |
Методы
Только то, что нужно в обычном скетче. Сигнатуры сверены с версией 1.1.2.
Запуск
LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows)
Создать дисплей. Шину и сам дисплей конструктор не трогает — это делает init().
- lcd_Addr
- адрес переходника: 0x27 или 0x3F, точно — сканером.
- lcd_cols
- столбцов: 16 для 1602, 20 для 2004.
- lcd_rows
- строк: 2 или 4.
LiquidCrystal_I2C lcd(0x27, 16, 2);
void init()
Запустить шину I2C и сам дисплей. Обязательно в setup(), до любого вывода. Подсветку не включает.
lcd.init();
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS)
То же, что init(), но размер передаётся ещё раз, а шину Wire надо запустить самому. Есть ради совместимости с обычной LiquidCrystal; в новых скетчах берут init().
- cols, rows
- столбцы и строки.
- charsize
- LCD_5x8DOTS; режим 5×10 у 1602 почти не встречается.
Wire.begin(); lcd.begin(16, 2);
Подсветка
void backlight()
Включить подсветку. Без неё текст есть, но почти не виден — частая причина «экран пустой».
lcd.backlight();
void noBacklight()
Выключить подсветку — она потребляет больше всего в модуле, и её гасят, когда на дисплей никто не смотрит.
lcd.noBacklight();
void setBacklight(uint8_t new_val)
Включить или выключить подсветку одним вызовом. Яркость не регулирует: 0 — выключить, любое другое — включить.
lcd.setBacklight(motion ? 1 : 0);
Вывод текста
print(...)
Вывести текст или число с позиции курсора — как Serial.print(): строки, целые, дробные с точностью, F("...") из флеш-памяти. Старое содержимое не стирается, а перезаписывается поверх.
- ...
- что угодно, что умеет
Serial.print; для дробных второй аргумент — знаков после запятой.
Возвращает: сколько символов выведено.
lcd.print(t, 1);
lcd.print(F(" C"));size_t write(uint8_t value)
Вывести один символ по коду: свой символ из createChar() (0–7) или любой из встроенной таблицы дисплея.
Возвращает: 1.
lcd.write(0); // свой символ №0 lcd.write(0xDF); // знак градуса из таблицы дисплея
void setCursor(uint8_t col, uint8_t row)
Поставить курсор: куда пойдёт следующий print().
- col
- столбец с нуля: 0–15 у 1602.
- row
- строка с нуля: 0 или 1.
lcd.setCursor(6, 0);
void clear()
Очистить экран и вернуть курсор в начало. Медленная — около 2 мс; в цикле вместо неё перезаписывают нужное место пробелами, иначе экран мерцает.
lcd.clear();
void home()
Курсор в начало, экран не стирается.
lcd.home();
Свои символы
void createChar(uint8_t location, uint8_t charmap[])
Нарисовать свой символ 5×8 точек: значок, букву, деление шкалы. Ячеек восемь, 0–7. Загружают после init(), а после загрузки курсор сбивается — поставьте его заново setCursor().
- location
- номер ячейки 0–7.
- charmap
- восемь байт, по байту на строку сверху вниз; младшие пять битов — точки слева направо.
lcd.createChar(0, heart); lcd.setCursor(0, 0); lcd.write(0);
Курсор и экран
void cursor()
Показать курсор-подчёркивание. noCursor() — спрятать.
lcd.cursor();
void blink()
Мигающий прямоугольник на месте курсора — например, при вводе с клавиатуры. noBlink() — выключить.
lcd.blink();
void noDisplay()
Погасить символы, не стирая их: display() вернёт всё как было. Подсветка при этом остаётся.
lcd.noDisplay(); delay(500); lcd.display();
void scrollDisplayLeft()
Сдвинуть всё содержимое на символ влево — обе строки разом. scrollDisplayRight() — вправо. Память дисплея — 40 символов на строку, поэтому длинный текст так прокручивается без перерисовки.
lcd.scrollDisplayLeft();
void autoscroll()
Режим «бегущей строки справа»: каждый новый символ сдвигает весь экран. noAutoscroll() — выключить.
lcd.autoscroll();
void leftToRight()
Направление вывода: слева направо, как обычно. rightToLeft() — справа налево, для выравнивания чисел по правому краю.
lcd.rightToLeft();
void command(uint8_t value)
Отправить дисплею команду контроллера HD44780 напрямую — для того, чего нет в библиотеке.
- value
- код команды из даташита HD44780.
lcd.command(0x01); // то же, что clear()
Заглушки
void setContrast(uint8_t new_val)
Объявлена, но пустая — ничего не делает. Контраст у переходника только подстроечником. Так же пусты on(), off(), status() и функции графиков: скетч с ними собирается, но они не работают.
// контраст — отвёрткой, не кодом
Примеры
Термометр на LM35
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // если экран пуст — попробуйте 0x3F
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
}
void loop() {
float t = analogRead(A0) * 5.0 / 1023 * 100; // датчик LM35 на A0: 10 мВ на градус
lcd.setCursor(6, 0);
lcd.print(t, 1);
lcd.print(" C "); // пробелы затирают хвост от прошлого, более длинного числа
delay(500);
}Температура с датчика LM35 на A0 обновляется раз в полсекунды. Пробелы после числа нужны: когда 10,0 сменяется на 9,5, хвост от прошлого значения иначе останется на экране. Вместо clear() в цикле — перезапись одного места: так экран не мерцает.
Бегущая строка
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const char text[] = "Niro Electronics: I2C LCD scroll demo";
void setup() {
lcd.init();
lcd.backlight();
}
void loop() {
// бегущая строка по нижней строке: окно в 16 символов сдвигается по тексту
int len = strlen(text);
for (int start = 0; start <= len; start++) {
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
int k = start + i;
lcd.print(k < len ? text[k] : ' ');
}
delay(300);
}
}Длинный текст проезжает по нижней строке, верхняя стоит на месте. scrollDisplayLeft() так не умеет — она двигает обе строки сразу, поэтому окно в 16 символов сдвигается по тексту вручную.
Шкала с потенциометра на своих символах
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// пять символов: заполнено 1, 2, 3, 4 и 5 столбиков из пяти
byte level[5][8];
void setup() {
for (int n = 0; n < 5; n++) {
byte row = (0b11111 << (4 - n)) & 0b11111; // n+1 столбиков слева
for (int r = 0; r < 8; r++) level[n][r] = row;
}
lcd.init(); // символы загружают после init()
for (int n = 0; n < 5; n++) lcd.createChar(n, level[n]);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Level:");
}
void loop() {
// потенциометр на A0 → полоса из 16 клеток по 5 столбиков: 80 делений
int filled = map(analogRead(A0), 0, 1023, 0, 80);
lcd.setCursor(0, 1);
for (int cell = 0; cell < 16; cell++) {
int rest = filled - cell * 5;
if (rest >= 5) lcd.write(4); // клетка целиком
else if (rest > 0) lcd.write(rest - 1); // часть клетки
else lcd.print(' ');
}
delay(50);
}Нижняя строка — полоса уровня с точностью до столбика: 16 клеток по 5 столбиков, 80 делений. Пять своих символов — клетки, заполненные на один, два, три, четыре и пять столбиков.
«ПРИВЕТ» русскими буквами
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// у дисплея нет русских букв; похожие на латиницу берём латинские,
// а П и И рисуем сами — матрица 5×8, по строке на байт
byte letterP[8] = { 0b11111, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b00000 };
byte letterI[8] = { 0b10001, 0b10001, 0b10011, 0b10101, 0b11001, 0b10001, 0b10001, 0b00000 };
void setup() {
lcd.init();
lcd.backlight();
lcd.createChar(0, letterP); // своих символов у дисплея всего восемь: 0–7
lcd.createChar(1, letterI);
lcd.setCursor(5, 0);
lcd.write(0); // П
lcd.print("P"); // Р — латинская P
lcd.write(1); // И
lcd.print("BET"); // В, Е, Т — латинские B, E, T
}
void loop() {}Р, В, Е и Т выводятся латинскими P, B, E, T, а П и И нарисованы через createChar(). На экране — «ПРИВЕТ». Так же собирается любое слово, пока нелатинских букв в нём не больше восьми.
Таблица символов, встроенных в дисплей
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
}
void loop() {
// вся встроенная таблица: 8 страниц по 32 кода, по 16 на строку.
// Коды 0–7 — ваши символы из createChar(), 32–127 — латиница и знаки,
// выше — то, что зашито в конкретный дисплей: обычно катакана
for (int page = 0; page < 8; page++) {
int first = page * 32;
Serial.print("Коды ");
Serial.print(first);
Serial.print("–");
Serial.println(first + 31);
for (int row = 0; row < 2; row++) {
lcd.setCursor(0, row);
for (int col = 0; col < 16; col++) lcd.write(first + row * 16 + col);
}
delay(4000);
}
}Дисплей по очереди показывает все 256 кодов, в монитор порта пишется, какие коды сейчас на экране. Так видно, что зашито именно в ваш дисплей: на большинстве после латиницы идёт японская катакана, на редких — кириллица или европейские буквы. Отсюда же берут коды для write(): 0xDF — знак градуса, 0x7E и 0x7F — стрелки.
Монитор порта:
Коды 0–31\nКоды 32–63\nКоды 64–95\n…\nКоды 224–255
Два дисплея на одной шине
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// два дисплея на одной шине: у второго на переходнике запаяна перемычка A0,
// и его адрес сдвинулся с 0x27 на 0x26
LiquidCrystal_I2C lcdA(0x27, 16, 2);
LiquidCrystal_I2C lcdB(0x26, 16, 2);
void setup() {
lcdA.init();
lcdB.init();
lcdA.backlight();
lcdB.backlight();
lcdA.print("Display A");
lcdB.print("Display B");
}
void loop() {
lcdA.setCursor(0, 1);
lcdA.print(millis() / 1000);
lcdB.setCursor(0, 1);
lcdB.print(analogRead(A0));
lcdB.print(" ");
delay(200);
}На переходнике второго дисплея запаяна перемычка A0, и его адрес стал 0x26. Оба дисплея висят на тех же четырёх проводах, каждый отвечает только на свой адрес. Сколько их и с какими адресами, покажет сканер.
На чём попадаются
LiquidCrystal_I2C.h: No such file or directory
Библиотека не установлена. В менеджере нужна строка «LiquidCrystal I2C by Frank de Brabander».
Подсветка горит, текста нет
Контраст: крутите подстроечник на переходнике на работающем скетче. Если не помогает — неверный адрес: 0x27 против 0x3F, проверьте сканером.
Ошибка: нет init() или no matching function for begin
Под именем LiquidCrystal I2C ходят разные библиотеки. В версии 1.1.2 из менеджера есть и init(), и begin(16, 2). В одноимённой с GitHub init() нет, а begin() — без параметров. Удалите лишние копии из папки libraries и поставьте версию из менеджера.
На ESP32: «may be incompatible with your current board»
В карточке библиотеки указано «только AVR», и среда честно предупреждает. На ESP32 и ESP8266 библиотека работает — предупреждение можно не слушать.
Вместо русских букв — иероглифы
В памяти дисплея нет кириллицы. Способы — в разделе «Русские буквы на 1602».
Свой символ не появляется или текст уехал
createChar() вызвали до init() — символы не загрузятся. Или после createChar() не поставили курсор заново: он сбивается, и следующий print() пишет не туда.