LiquidCrystal_I2C: библиотека для LCD 1602 — скачать, адреса, первый скетч
Экран куплен, четыре провода воткнуты, и тут начинается самое интересное: в менеджере библиотек по слову LiquidCrystal вываливается несколько почти одинаковых названий, скетчи с форумов отказываются собираться, а вместо приветствия — ряд закрашенных квадратов. Сам дисплей тут ни при чём: внутри у него контроллер HD44780, а на переходнике сзади сидит расширитель PCF8574, который растит шину из двух проводов до восьми линий управления панелью. Библиотека — переводчик между привычным print() и этим переходником, и половина странностей зависит от того, какой именно переводчик стоит у вас.
Ниже — маршрут без догадок: какую библиотеку из списка ставить и как отличить форки по строке авторов, сканер шины, который за полминуты печатает реальный адрес вместо перебора 0x27 и 0x3F наугад, минимальный скетч на lcd.init() и print(), синий подстроечник контраста и второй экран на той же паре проводов. Если вас интересует голая проводка без библиотечных подробностей, есть короткая карточка LCD I2C: подключение на четыре провода; здесь же я разбираю именно библиотеку — с местами, где спотыкался сам.
Какую библиотеку ставить: менеджер, авторы и форки
Самый короткий путь лежит через Arduino IDE: меню Скетч → Подключить библиотеку → Управлять библиотеками, в поиск — LiquidCrystal I2C, установка одной кнопкой. В строке авторов правильной библиотеки значится Frank de Brabander, а сопровождающим — Martin Kubovčík: это прямая родословная того самого кода, который десять лет перекочёвывает из блога в блог. Подводный камень в том, что имя не защищено: в списке живут одноимённые форки, один из них давно переехал на GitLab, другой тащит свои добавки поверх чужого API. Мой ориентир простой: если пример компилируется как есть — не трогайте то, что стоит; если компилятор не находит lcd.init() или ругается на begin() без аргументов, у вас другой форк, и дешевле переустановить правильную библиотеку, чем править каждый скетч под её вкусы. Без сети архив ZIP скачивается с репозитория и ставится через Добавить .ZIP библиотеку — результат тот же.
Четыре провода: куда идут SDA и SCL
Переходнику на спине дисплея нужны четыре соединения: VCC на 5 В, GND на землю, SDA и SCL на шину. На Uno и Nano шина живёт на A4 и A5, на Mega — на 20 и 21, платы вроде Leonardo или ESP32 несут отдельные подписанные ножки; раскладку по популярным платам я собрал в таблицу. Шестого провода не появится: питание подсветки и логика уже разведены на переходнике, а контраст задаётся подстроечником прямо на нём — потенциометр в схеме, как было при параллельном подключении, здесь не нужен.
| Плата | SDA | SCL | Замечание |
|---|---|---|---|
| Uno, Nano, Mini (ATmega328) | A4 | A5 | на R3 есть дублирующие SDA/SCL возле AREF |
| Mega 2560 | 20 | 21 | своя пара аппаратной шины |
| Leonardo / Micro | D2 | D3 | ножки подписаны на плате |
| ESP32 | 21 | 22 | умолчания Wire.begin(); можно переназначить |
| NodeMCU (ESP8266) | D2 | D1 | SDA/SCL подписаны шелкографией |
Одна тонкость, на которой я потерял вечер с ESP32: чип PCF8574 переваривает и 3,3 В, но сама жидкокристаллическая панель рассчитана на 5 В — при питании от 3,3 вольта подсветка горит, а символы не видны вовсе или проступают призрачно. Лечится подачей 5 В на VCC переходника; вопрос уровней на линии при смешанном хозяйстве стоит прогнать через урок про согласование 3,3 В и 5 В. А если каждый пин на счету, дисплей можно кормить через транзистор и гасить целиком между показами — механика в уроке про питание LCD от пина.
Адрес 0x27 или 0x3F: спрашиваем шину, а не форум
На переходнике стоит один из двух близнецов: PCF8574 с заводским адресом 0x27 или PCF8574A с 0x3F — различие в одном бите, а путаницы на годы вперёд. Рядом с чипом три площадки A0–A2: каждая, замкнутая каплей припоя, сдвигает адрес на шаг внутри своего диапазона — так на одну шину встаёт до восьми одинаковых экранов. Вместо того чтобы угадывать, я гоняю сканер: полминуты — и в мониторе напечатан точный адрес. Отдельная шпаргалка про сканер I2C держит этот скетч под рукой, а тонкости площадки за площадкой разобраны в уроке про адреса PCF8574.
| Чип на переходнике | Диапазон адресов | Заводской |
|---|---|---|
| PCF8574 | 0x20–0x27 | 0x27 |
| PCF8574A | 0x38–0x3F | 0x3F |
#include <Wire.h> void setup() { Serial.begin(9600); Wire.begin(); Serial.println("Proveryayu adresy 8..119..."); byte naydeno = 0; for (byte adr = 8; adr < 120; adr++) { Wire.beginTransmission(adr); if (Wire.endTransmission() == 0) { // ACK пришёл - тут кто-то живёт Serial.print("Ustrojstvo na adrese 0x"); if (adr < 16) Serial.print("0"); Serial.println(adr, HEX); naydeno++; } } if (naydeno == 0) { Serial.println("Tishina: provoda, pitanie, podtyazhki"); }} void loop() {}Тишина в ответ — тоже диагноз: шина не нашла ни одного устройства, значит смотреть провода, питание и подтяжки, а не код библиотеки. Как выжать из сканера максимум, когда адрес нашёлся, а модуль всё равно молчит, показано в уроке про сканер и диагностику; выбор между 0x27 и 0x3F с фотографиями обоих чипов — в уроке про адрес дисплея.
Минимальный скетч: lcd.init() и первые символы
API библиотеки нарочно повторяет классический LiquidCrystal: print, setCursor, cursor, blink — всё на привычных местах, поэтому скетчи с параллельного подключения переезжают почти без правок. Прибавляются две новинки: lcd.init(), которая через переходник прогоняет дисплей полный стартовый ритуал, и lcd.backlight() — включение подсветки (есть и noBacklight для пауз). Дальше обычный сценарий: курсор, строка, число.
#include <Wire.h>#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес из сканера, столбцы, строки void setup() { lcd.init(); // стартовый ритуал дисплея через PCF8574 lcd.backlight(); // подсветка включена lcd.setCursor(0, 0); lcd.print("LCD 1602 po I2C"); lcd.setCursor(0, 1); lcd.print("sekund: ");} void loop() { lcd.setCursor(8, 1); lcd.print(millis() / 1000); lcd.print(" s "); // хвост затирает остатки старых цифр delay(250);}Контраст: синий подстроечник на переходнике
На каждом I2C-переходнике есть маленький синий подстроечник — единственная ручка, которая двигает контраст. Крутить его нужно при включённом питании и после загрузки скетча: один край даёт пустое стекло, другой — сплошные блоки, рабочая точка лежит между ними и ловится на глаз за пару поворотов. Я привык сначала гонять минимальный скетч выше, а потом крутить: если текст выводится, но его не видно — виновата ручка, а не код. Перемычка рядом — про подсветку целиком, и на батарейных проектах она превращается в регулятор счёта за электричество; арифметика в уроке про экономию подсветки, а физика пустого экрана и чёрных квадратов — в уроке про контрастность.
Если адрес верный, скетч загружен, а стекло пустое в любом положении ручки — двигайтесь по шагам от питания до шины. Урок про молчащий LCD собирает такую диагностику в один маршрут, урок про чёрную строку — отдельно про случай, когда экран жирно закрашен, но букв нет.
Второй экран и соседи по шине
Два дисплея 1602 на одной паре проводов — штатная ситуация. У первого замыкаете площадку A0 — адрес сдвигается до 0x26, второй остаётся на 0x27; в скетче объявляете два объекта, каждому — свой адрес и свои setCursor'ы. Ещё проще, когда переходники на разных чипах: 0x27 и 0x3F живут рядом без пайки. Полную разборку с скетчем на два экрана ведёт урок про два LCD на шине. По соседству на тех же двух проводах спокойно уживаются часы и датчики: раскладка LCD плюс RTC — в уроке про несколько устройств на шине, а свежую карту адресов типовых модулей держите в закладки — таблица адресов I2C.
- библиотеку беру из менеджера, проверяю строку авторов — de Brabander / Kubovčík
- адрес в конструктор — только из вывода сканера, не из чужого скетча
- lcd.init() и lcd.backlight() в setup() — без них стекло пустое даже при верном адресе
- размер экрана в конструкторе: (0x27, 16, 2) или (0x27, 20, 4)
- контраст кручу при включённом питании — между пустотой и блоками
- второй экран — капля припоя на площадке A0, мультиплексор не нужен