Панель теплицы обросла вторым экраном не от жадности: главный висит в шкафу рядом с реле, а второй я вынес к двери, чтобы видеть влажность, не заходя внутрь. Первая мысль была тянуть ко второму 16x2 четыре отдельных провода — и это ровно случай, когда I2C раскрывается по-настоящему: оба модуля садятся на те же две линии, SDA и SCL, и по шине их разводит только адрес. Загвоздка в том, что по умолчанию оба переходника отвечают на один и тот же адрес, и шина получает двух собеседников с одинаковым именем.
Разводятся они перемычками A0, A1 и A2 на плате адаптера — это три адресных входа микросхемы PCF8574, задающие младшие биты адреса. У T-партии сетка от 0x20 до 0x27, у A-партии — от 0x38 до 0x3F; как отличить партии и почему большинство модулей «из коробки» отвечают на 0x27, я разбирал в уроке про выбор между 0x27 и 0x3F. Здесь практика: развести адреса двух экранов, развести их в скетче и не наступить на классические грабли конфликта.
План урока: механика перемычек и сетка адресов целиком, скетч на два объекта LiquidCrystal_I2C, ловушка двух одинаковых адресов, при которой печать уходит в один экран, и неудобное мнение — когда вместо двух 16x2 честнее поставить один 20x4. В симуляторе движок поднимает только один экран, зато адресную карту перемычек он показывает честно: ползунок крутит биты, Serial печатает готовую строку конструктора.
Сетка адресов: что делают A0, A1, A2
Механика у PCF8574 прозрачная. Адрес состоит из двух частей: фиксированной старшей, зашитой в партию чипа, и трёх младших битов, которые берутся с ножек A2, A1, A0. Разомкнутая перемычка оставляет ножку подтянутой к питанию — единица; замкнутая посадкой на землю — ноль. Считаем: все три разомкнуты, T-партия — 0x27; замкнули A0 — ноль в младшем разряде, адрес 0x26; замкнули все три — 0x20. Восемь адресов на одну партию и восемь на вторую — до шестнадцати экранов на одной шине в теории, на практике двух-трёх хватает всем.
На плате адаптера перемычки — три пары контактов с маркировкой A0, A1, A2 у самого края. Большинство модулей приходит без джамперов, замыкать придётся перемычкой мама-мама, каплей припоя или чем под рука попадётся. После настройки я пишу адрес маркером прямо на плате — через полгода угадывать его заново сомнительное удовольствие, — и проверяю сканером до сборки корпуса: стенд диагностики из урока про молчащий экран начинается со сканера, и на шине с двумя экранами он напечатает две строки с двумя разными адресами.
В скетче каждый экран — свой объект с собственным адресом: LiquidCrystal_I2C lcd1(0x26, 16, 2) и lcd2(0x27, 16, 2). Объекты независимы: у каждого свой init, свой backlight и своя раскладка строк, библиотека держит их не смешивая. На шине всё честно: каждый print превращается в пакеты на адрес конкретного объекта, и второй экран их не видит — PCF8574 откликается только на свой. Как эти пакеты выглядят побайтово, можно подсмотреть в уроке про адаптер PCF8574.
Грабля, на которой я потерял вечер при переезде панели с макетки на постоянную плату: перемычку A0 перепаяли, а в скетче остался старый адрес. Симптом получается хитрее, чем конфликт одинаковых: сканер честно показывает два устройства, но не в том сочетании, на которое рассчитан код, и один объект печатает в пустоту. Арифметика тут помогает читать показания сканера без таблицы: каждая перемычка сдвигает адрес T-партии ровно на свой бит — A0 минус единица, с 0x27 до 0x26; A1 минус два, до 0x25; A2 минус четыре, до 0x23. У A-партии тот же сдвиг идёт от 0x3F вниз: 0x3E, 0x3D, 0x3B. Замкнули не там — сканер назовёт «не тот» адрес, и это готовая диагностика, а не поломка шины. Правило у меня теперь жёсткое: любое движение паяльником возле адаптера — и следом сканер, потом правка конструктора. Число в LiquidCrystal_I2C lcd1(0x26, 16, 2) — не память о разводке, а её копия, обязанная совпадать с перемычками на плате.
#include <Wire.h>#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd1(0x26, 16, 2); // экран у двери: замкнута A0LiquidCrystal_I2C lcd2(0x27, 16, 2); // главный: без перемычек void setup() { lcd1.init(); lcd1.backlight(); lcd2.init(); lcd2.backlight(); lcd1.setCursor(0, 0); lcd1.print("DVER"); lcd1.setCursor(0, 1); lcd1.print("H 47% T 21.4 C"); lcd2.setCursor(0, 0); lcd2.print("TEPLICA: GLAVNYI"); lcd2.setCursor(0, 1); lcd2.print("nasos VYKL 22:41");} void loop() { // каждый объект печатает на свой адрес: экраны не путаются delay(1000);}После разводки адресов соберите скетч-проверку на два объекта и печатайте на каждый экран отличительную подпись — «DVER» и «GLAVNYI» — раз и навсегда. Так перепутанные объекты в коде видны за десять секунд: подпись не на том экране — конструкторы поменяны местами, а не провода. На той же шине спокойно живут и другие устройства: часы DS3231 по 0x68, барометр по своему адресу — семибитная адресация вмещает 112 устройств, и два экрана это пространство даже не будят.
С двумя модулями следите за питанием и длиной линий. Оба адаптера едят от 5 В, и подсветка каждого — свои 20-25 мА, суммарно под пятьдесят: разводите питание толстыми проводами от одного узла, а не цепочкой от модуля к модулю. Второй экран на хвосте первого ловит просадки, и это выглядит как случайные артефакты на дальнем конце шины, — родня грабле с длинными проводами из урока про диагностику молчащего экрана: для двух модулей всё то же самое, только свидетелей больше.
Вилка по току при этом шире, чем привычные 20-25 мА: подсветка одного экрана берёт 25-60 мА — у 16x2 обычно ближе к нижней границе, у 20x4 и отдельных партий все шестьдесят, и разброс зависит от партии светодиодов, а не от библиотеки. На саму шину этот ток не влияет: по SDA и SCL бегут сигнальные миллиамперы, подсветка питается своей дорожкой от VCC, мимо PCF8574. Блок питания считается на оба экрана: в худшем случае два раза по шестьдесят — 120 мА только на подсветку, плюс логика обоих адаптеров и всё, что уже висит на 5 В. При питании от USB с его 500 мА запас выходит небольшой, и его легко съест реле или сервопривод по соседству. Тускнеющая подсветка и перезагрузка в момент старта второго экрана — не глюк шины, а просадка по питанию: лечится отдельным блоком питания, а не перепайкой перемычек.
Два 16x2 или один 20x4
Теперь мнение, с которым можно спорить. Два 16x2 оправданы, когда экраны нужны в разных местах: панель в шкафу и индикатор у двери, прибор и дублирующее табло над проходом. Это два независимых кадра в двух точках — один 20x4 такого не умеет ни за какие деньги, ему всё равно, где висеть, но он один. Второй случай — разделение режимов: главный экран показывает состояние, второй отдаёт меню настроек; физическая развязка честнее переключаемых страниц, потому что настройки видны, пока основной прибор продолжает показывать данные.
Но если оба экрана планировалось повесить рядом, мой выбор — один 20x4. Он даёт 80 знакомест против 64 у пары 16x2, один объект в коде вместо двух, одну инициализацию, один адрес в сканере и на 20-25 мА подсветки меньше, чем пара. Раскладка на четырёх строках гибче двух независимых двухстрочных, а цена модулей различается на пару сотен рублей. Полный разбор переезда с раскладкой по строке на метрику — в уроке про LCD 2004.
| Параметр | Два 16x2 | Один 20x4 |
|---|---|---|
| Знакоместа | 32 + 32 = 64, в двух местах | 80, в одном |
| Адреса на шине | Два: развести перемычками | Один |
| Подсветка суммарно | 40-50 мА | 25-60 мА |
| Объектов в скетче | Два: lcd1 и lcd2 | Один |
| Когда брать | Экраны в разных точках | Одна панель: раскладка, меню |
И последнее, что стоит знать до покупки второго модуля: партии бывают смешанными. Первый экран у вас уже работает на 0x27 — это T-партия; новый модуль из другой поставки легко оказывается A-партией с адресом 0x3F, и план «замкни A0 и получи 0x26» превращается в «разберись, почему адреса вообще другие». Сканер после каждого нового модуля — не паранойя, а минута, которая экономит вечер; тот же эффект ловят люди, докупающие второй модуль через год, когда поставщик сменился, а чеки не сохранились.
На одной шине с двумя экранами спокойно живут часы DS3231 по 0x68, барометр и модули датчиков — семибитная адресация вмещает 112 устройств, и шесть адресов на два экрана с часами — капля. Следите за двумя вещами: чтобы ни одно устройство с жёстко зашитым адресом не пересеклось с вашим экраном, и за трафиком, когда экранов становится больше. Точечная перерисовка, на которой живёт метеостанция из итогового проекта раздела, держит шину пустой даже с двумя панелями: механика обновления только изменённых ячеек разобрана в уроке про точечную перерисовку.
- 1. Оба адаптера без перемычек, партия PCF8574T. Какие адреса у модулей?
- 2. Замкнули перемычку A0 на модуле T-партии. Новый адрес?
- 3. У партии PCF8574A сетка адресов…
- 4. В скетче два объекта LiquidCrystal_I2C с адресом 0x27. Что увидите?
- 5. Когда пара 16x2 честнее одного 20x4?
- Перемычки A0-A2 задают три младших бита: замкнутая — ноль, разомкнутая — единица; T-партия 0x20-0x27, A-партия 0x38-0x3F
- Каждый экран — свой объект LiquidCrystal_I2C со своим адресом; у каждого свой init и backlight
- Два объекта на одном 0x27 печатают в один экран; сканер видит одно устройство — верный признак конфликта
- Партии бывают смешанными: сканер после каждого нового модуля экономит вечер
- Экраны в разных точках — два 16x2; одна панель — один 20x4: 80 знакомест, один объект, меньше тока
Частые вопросы по теме урока
- Оба адаптера без перемычек, партия PCF8574T. Какие адреса у модулей?
- Без перемычек все три адресных бита подтянуты к единице: у T-партии это 0x27. Два одинаковых адреса — конфликт, о котором ниже. Оба 0x27
- Замкнули перемычку A0 на модуле T-партии. Новый адрес?
- Замкнутая перемычка — ноль в своём разряде: 0x27 минус единица в младшем бите = 0x26. Проверяйте сканером, а не таблицей. 0x26
- У партии PCF8574A сетка адресов…
- A-партия отличается тремя старшими битами адреса: сетка 0x38-0x3F, из коробки обычно 0x3F. Панели 2004 с A-партией встречаются часто. 0x38-0x3F
- В скетче два объекта LiquidCrystal_I2C с адресом 0x27. Что увидите?
- Оба объекта печатают на один физический адрес, и подтверждают оба переходника: экраны показывают одинаковую кашу, а сканер находит одно устройство. Оба показывают одинаковую смесь печати
- Когда пара 16x2 честнее одного 20x4?
- Два экрана оправданы физическим разделением: панель в шкафу и индикатор у двери. Для одной панели 80 знакомест 20x4 выгоднее во всём. Когда экраны висят в разных точках