Метеопанель на 16x2 к концу сезона превратилась в ребус: T 21.5 H 47 на верхней строке, P 746 M- на нижней, а минимумы и максимумы показывались по очереди — по нажатию кнопки. Сокращения экономили место и убивали смысл: через месяц я сам не вспоминал, что M- означает минимум за сутки, а жена и подавно. Переезд на 20x4 занял вечер, и интерфейс раскрылся: по строке на метрику, отдельное место под мин-макс, заголовок больше не давит на показания. С тех пор панель 16x2 у меня живёт только в мелких приборах, а всё, что показывает погоду, начинается с четырёх строк.
Код при этом меняется минимально: размеры — в конструкторе LiquidCrystal_I2C lcd(0x27, 20, 4) либо в lcd.begin(20, 4) у параллельного. У параллельного, кстати, begin обязателен в setup и с маленькими экранами тоже — без него библиотека не знает, с чем работает. Столбцы теперь от 0 до 19, строки от 0 до 3, setCursor(0, 3) — левый нижний угол. То, что память дисплея раскладывает четыре строки по-своему и длинный текст уезжает не на соседнюю строку, а через одну, — отдельная история про DDRAM: её по адресам разбирает урок про адресацию строк 20x4. Здесь практический слой: как уложить метеосводку без тесноты, какие две ловушки съели мой вечер и чем 2004 отличается по железу.
Съели время вот что. Первая ловушка: если в конструкторе остались старые 16 и 2, экран работает наполовину — нижние строки молчат, хвосты строк срезаются, и выглядит это как брак панели, а не как ваша опечатка. Вторая: переходник на модулях 2004 чаще отвечает по адресу 0x3F, а не по привычному 0x27, — и это тоже не брак, а другая партия чипа на плате.
Раскладка: по строке на метрику
Раскладку метеосводки я держу такой: строка 0 — заголовок и время, строка 1 — температура с трендом, строка 2 — влажность, строка 3 — давление. Минимумы и максимумы температуры встают в правую часть своей строки: T 21.5 20.1/24.3 — двадцать столбцов как раз хватает, чтобы не городить четвёртую страницу. Столбцы под каждое значение назначьте заранее, на бумажке: цифра в шестнадцатом столбце, уехавшая на один вправо, ломает всё поле. Главное правило раскладки: у каждой величины — постоянное место, закреплённое навсегда. Глаз за неделю привыкает находить давление в левом нижнем углу, и любое перестроение сетки превращает прибор обратно в ребус.
Числа печатайте в поля фиксированной ширины. Сегодня влажность 47, утром была 9 — и без заполнителей на экране останется хвост: 9% от старой записи, прилипший к новой. Печать через пробелы-заполнители переписывает и число, и место под ним; механику таких полей с дробями и ведущими нулями я разбирал в уроке про числа на LCD. На практике полю хватает четырёх-пяти знаков: температура от минус двадцати до плюс сорока с десятыми — шесть, давление — три цифры и подпись. Двадцать столбцов прощают больше, чем шестнадцать, но ячейка LCD по-прежнему не стирается сама — дисциплина та же.
И не путайте простор с правом переписывать всё подряд. Восемьдесят знакомест — не восемьдесят записей за кадр: на I2C полный кадр с чисткой стоит десятки миллисекунд, точечный апдейт изменённых ячеек — единицы. Метеостанция из итогового проекта раздела живёт именно на точечных обновлениях, и на четырёх строках экономия становится только весомее: площадь выросла в два с половиной раза, а переписывать её целиком на каждом проходе цикла не хочется тем более.
Время в строке 0 — отдельная песня, и лучше отрепетировать её до переезда. Формат с двоеточиями и ведущими нулями я собирал в уроке про часы на millis — здесь про место в сетке. Столбцы 11-19 строки 0 — идеальное место под часы: заголовок сидит слева и не двигается, время обновляется раз в секунду в правом углу, и между ними никогда не возникает стыка. Печатать время чаще раза в секунду не нужно: дёрганье двоеточия на I2C видно глазом, а шина занята зря.
В левую часть заголовка, между названием и часами, хорошо встаёт состояние прибора: AUTO или MANUAL, признак связи с датчиком, режим работы. Один флаг — и экран объясняет половину вопросов, которые раньше решались подключением Serial. Только держите этот флаг в своём столбце постоянной ширины, как и всё остальное: состояние, прыгающее по строке, читается хуже, чем его отсутствие.
И проверьте арифметику ширины до вёрстки: 20 столбцов — это заголовок до десятого столбца и время из восьми знаков справа, не больше. Я по привычке прилипил дату после времени — и двоеточие секунд прыгало на новую строку через раз, пока не пересчитал знаки на бумажке. Всё то же правило полей: каждому обновляемому куску — своя ячейка постоянной ширины.
#include <Wire.h>#include <LiquidCrystal_I2C.h>#include <DHT.h> LiquidCrystal_I2C lcd(0x27, 20, 4); // размеры — здесь, не в beginDHT dht(4, DHT11); int tMn10 = 999, tMx10 = -999; // минимумы-максимумы, десятые градусаint hMn = 101, hMx = -1;unsigned long last = 0;int lastT10 = 9999, lastH = 9999; // кэш прошлого кадра void setup() { dht.begin(); lcd.init(); lcd.backlight(); // статичный каркас печатаем один раз lcd.setCursor(0, 0); lcd.print("METEO 20x4"); lcd.setCursor(0, 1); lcd.print("T --.- mn --.- mx --.-"); lcd.setCursor(0, 2); lcd.print("H --% mn --% mx --%"); lcd.setCursor(0, 3); lcd.print("P 746 mm BMP280 ");} void loop() { if (millis() - last < 2000) return; // DHT11 не чаще раза в 2 секунды last = millis(); float t = dht.readTemperature(); float h = dht.readHumidity(); if (isnan(t) || isnan(h)) return; // сбой чтения — кадр не трогаем int t10 = (int)(t * 10.0); int hi = (int)h; if (t10 < tMn10) tMn10 = t10; if (t10 > tMx10) tMx10 = t10; if (hi < hMn) hMn = hi; if (hi > hMx) hMx = hi; if (t10 != lastT10) { // пишем ячейку только при смене lastT10 = t10; lcd.setCursor(3, 1); lcd.print(t10 / 10); lcd.print("."); lcd.print(t10 % 10); lcd.print(" mn "); lcd.print(tMn10 / 10); lcd.print("."); lcd.print(tMn10 % 10); lcd.print(" mx "); lcd.print(tMx10 / 10); lcd.print("."); lcd.print(tMx10 % 10); } if (hi != lastH) { lastH = hi; lcd.setCursor(3, 2); lcd.print(hi); lcd.print("% mn "); lcd.print(hMn); lcd.print("% mx "); lcd.print(hMx); lcd.print("%"); }}Четыре строки меняют не только раскладку — они меняют класс интерфейсов, которые вы можете себе позволить. Первое, что стоит переехать: меню с человеческими подписями. На 16x2 пункт меню — это аббревиатура, потому что в шестнадцати столбцах не влезает ни название, ни пояснение; на 20x4 строка пункта дышит, а нижняя строка остаётся под подсказку — что именно нажатие сделает. Полноценное меню на большом экране с курсором и правкой собрано в уроке про меню устройств 20x4 — после переезда оно у меня появилось в каждом втором приборе.
Второй новый класс — журнал событий: дачный прибор, который сам записывает, когда качал воду и когда пропало питание. Четыре строки вмещают три-четыре последних записи, а листание делает кнопка. И предупреждение: большой экран провоцирует насытить всё сразу — подписи, значки, бар, часы. Каждый такой элемент — это записи в шину на каждом кадре; раскладка жива только на точечных обновлениях, иначе четыре строки стают вчетверо дороже по шине, а не в два с половиной раза.
Адрес 0x3F, аппетит и когда 16x2 честнее
Адрес переходника зависит от партии чипа на плате. Микросхемы PCF8574 и PCF8574A различаются тремя старшими битами адреса: первая отвечает по 0x27, вторая — по 0x3F. На модулях 16x2 чаще попадается T-партия, а вот в панелях 2004 A-партия — частый гость, поэтому у владельцев больших экранов первый адрес обычно 0x3F. Догадок здесь быть не должно: сканер шины решает вопрос за минуту, механику и генерацию адресов я разбирал в уроке про выбор между 0x27 и 0x3F. У адаптеров с программной настройкой адрес хранится в энергонезависимой памяти чипа и переезжает вместе с модулем, так что сканер нужен только один раз. Библиотеке всё равно — она гоняет байты на адрес, который вы ей дали.
С токами у 2004 честность такая: логика панели с переходником берёт порядка 1,4 миллиампера, а вот подсветка — от 25-60 мА у типовых модулей до сотни с лишним у отдельных партий с яркой синей засветкой. Двадцать знакомест в строке не означают двойной ток против 16x2 — ест не площадь, а светодиоды за стеклом. От USB это невидимо, в батарейном проекте — первый кандидат на экономию: механику сна и цифры бюджета я считал в уроке про подсветку и сон.
Теперь неудобное мнение, с которым можно спорить. Четыре строки нужны, когда показаний три и больше или когда на экране живёт меню с человеческими подписями — тут 80 знакомест против 32 окупаются мгновенно. Но если прибор показывает одну величину и статус, 16x2 честнее: меньше место в корпусе, меньше ток, меньше строк кода. Разница в цене — копейки, спорить надо не про деньги, а про габариты и батарейный бюджет; если ваш проект живёт на аккумах, лишние миллиамперы большого экрана обойдутся дороже лишних строк кода. Моё правило срабатывания: как только раскладку приходится сжимать аббревиатурами или листать страницы кнопкой — пора переезжать; до этого момента большой экран простаивает.
| Параметр | LCD 16x2 | LCD 2004 |
|---|---|---|
| Знакомест | 32 | 80 |
| Строки в setCursor | 0-1 | 0-3, до столбца 19 |
| Подсветка, типично | 20-25 мА | 25-60 мА, отдельные партии до 120 мА |
| Когда брать | одна-две величины и статус | метео, журналы, меню с описаниями |
- 1. Сколько знакомест видит ваша программа на экране 20x4?
- 2. Куда попадает курсор после lcd.setCursor(0, 3)?
- 3. Панель 2004 включилась, но нижние строки молчат. Что проверить первым?
- 4. Какой адрес чаще у переходников на модулях 2004?
- 5. Сколько берёт подсветка типичного модуля 2004?
- Переезд на 2004 — это размеры в конструкторе (0x27, 20, 4) или begin(20, 4): столбцы 0-19, строки 0-3
- Раскладка: по строке на метрику и постоянные места — глаз привыкает находить величину по углу
- Молчащие нижние строки и срезанные хвосты — забытые размеры 16x2, а не брак панели
- У 2004 чаще адрес 0x3F (партия PCF8574A), но решает сканер шины, а не чужие примеры
- 16x2 честнее для одной-двух величин: меньше ток, габариты и код; переезжайте, когда пошли аббревиатуры и страницы
Частые вопросы по теме урока
- Сколько знакомест видит ваша программа на экране 20x4?
- 20 столбцов на 4 строки — 80 знакомест, все видимы: у четырёхстрочной панели нет скрытой DDRAM, в отличие от 16x2. 80
- Куда попадает курсор после lcd.setCursor(0, 3)?
- Строки считаются сверху вниз от 0 до 3, столбцы слева направо от 0 до 19: (0, 3) — левый нижний угол. Левый нижний угол
- Панель 2004 включилась, но нижние строки молчат. Что проверить первым?
- Старые размеры — самая частая причина: библиотека сообщает контроллеру геометрию 16x2, и записи на строки 2-3 уходят мимо видимой области. Размеры в конструкторе или begin: не остались ли 16 и 2
- Какой адрес чаще у переходников на модулях 2004?
- Партия PCF8574A отвечает по 0x3F и в панелях 2004 попадается часто. Но решает не статистика, а сканер шины на вашей плате. 0x3F
- Сколько берёт подсветка типичного модуля 2004?
- Логика панели с переходником — около 1,4 мА, а подсветка ест 25-60 мА и больше. Ест светодиод, а не площадь экрана. 25-60 мА, отдельные партии до 120 мА