Первый LCD-экран я подключал к Uno «в лоб»: шесть сигнальных линий, питание, земля, потенциометр на контраст. Набежало двенадцать проводов, макетка превратилась в джунгли, и стоило задеть один из них — на экране вместо цифр вырастали кракозябры. Когда через неделю я захотел добавить к проекту часы реального времени, то честно сел считать свободные пины. Их оставалось три, а нужны были шесть.
Выход оказался стар как мир: шина I2C. Два сигнальных провода — и к ним цепляется десяток устройств, лишь бы у каждого был свой адрес. В этом уроке покажу, как шина устроена, куда на Uno втыкать SDA и SCL, зачем нужны подтяжки 4,7 кОм и как вывести текст на LCD1602 через переходник PCF8574, заняв всего два пина. Симулятор уже собрал схему за нас: экран висит на шине, можно печатать.
Что такое I2C: телефонная линия с громкой связью
I2C (Inter-Integrated Circuit, читается «и-квадрат-си») придумали в Philips в начале восьмидесятых, чтобы соединять микросхемы внутри телевизоров без пучков проводов. С тех пор шина стала стандартом де-факто для датчиков, экранов, часов и энергонезависимой памяти. За неё на Uno отвечает библиотека Wire — она встроена в Arduino IDE, ничего устанавливать не нужно: пишете #include <Wire.h> и работаете.
Участников на шине два сорта. Мастер — наша Arduino: она задаёт темп, генерирует тактовый сигнал и решает, с кем и когда говорить. Подчинённые (слейвы) — экраны, датчики, память: они молчат, пока мастер не обратится к ним по имени-адресу. Демократии здесь никакой: говорить одновременно двое не могут, поэтому слейв, которому есть что сказать, просто ждёт своей очереди.
Физически шина — это две линии. SDA (Serial Data) — по ней ходят сами данные, байт за байтом. SCL (Serial Clock) — такт: мастер «щёлкает» линией, и по каждому щелчку обе стороны фиксируют очередной бит. Обе линии двунаправленные: мастер может слать сам, а может слушать ответы. Завершается любая передача стоп-условием — особым перепадом уровней, который означает «разговор окончен»; в библиотеке Wire стоп ставит endTransmission().
Куда подключать: SDA = A4, SCL = A5
На Uno шина I2C сидит на двух аналоговых пинах: SDA — это A4, SCL — это A5. Питание и земля берутся с соседних гнёзд 5V и GND. На платах Uno R3 эти линии продублированы отдельными гнёздами SDA и SCL слева от AREF — втыкать туда удобнее, но электрически это одно и то же: A4 и A5 остаются занятыми.
Отсюда следствие, о котором забывают: пока на A4/A5 живёт шина, использовать их как обычные аналоговые входы нельзя. Я однажды повесил на A5 фоторезистор параллельно с SCL — и полдня лечил «случайно отваливающийся» экран, который отваливался ровно в тот момент, когда в комнате темнело.
| Линия | Пин Uno | Назначение |
|---|---|---|
| SDA | A4 | Данные: байты ходят в обе стороны |
| SCL | A5 | Такт: его генерирует только мастер |
| VCC | 5V | Питание модуля |
| GND | GND | Общий минус — обязателен для всех |
Адресация: от 0x03 до 0x77, у каждого своё имя
Чтобы мастер обращался к нужному устройству, у каждого слейва есть семибитный адрес. Классический диапазон, который перебирают все сканеры, — от 0x03 до 0x77, а строго «легальных» адресов ещё меньше: младшие номера зарезервированы стандартом под служебные цели. Теоретический потолок — сотня с лишним устройств на двух проводах; практический упирается не в адреса, а в ёмкость линий, поэтому на макетке больше пяти-шести модулей я бы не вешал без чтения даташитов.
Адрес прошит производителем, и у многих модулей его можно сдвинуть джамперами. Часы DS3231 всегда просыпаются на 0x68, OLED-экран SSD1306 обычно живёт на 0x3C, а LCD-переходник на PCF8574 — 0x20–0x27 или 0x38–0x3F, смотря какая партия микросхемы. Как узнать адрес своего модуля, не листая даташит, — тема следующего урока: там мы напишем сканер.
Минимальная церемония обмена выглядит так: мастер выставляет старт-условие, называет адрес и бит направления — пишем мы или читаем. Слейв, узнав свой адрес, подтверждает, что на месте. Дальше идут байты данных, и в конце — стоп-условие. Для нас вся эта церемония свёрнута в три вызова:
Wire.begin(); // Arduino становится мастеромWire.beginTransmission(0x27); // стучимся к экрану на адресе 0x27Wire.write('H'); // байт кладётся в буферWire.endTransmission(); // STOP: байты ушли, шина свободнаОбратите внимание: Wire.write() ничего не отправляет. Байты копятся в буфере, и только endTransmission() выстреливает их на шину одним пакетом и ставит стоп-условие. Если слейва по адресу 0x27 нет, endTransmission() вернёт не ноль — и именно на этой проверке построен сканер из следующего урока.
LCD1602 по I2C: четыре провода вместо двенадцати
Самый популярный модуль новичка — экран LCD1602 с переходником на PCF8574. Переходник втыкается в 16-контактную планку экрана, и дальше весь экран занимает на шине один адрес, чаще всего 0x27. Питание, земля, SDA и SCL — вот и вся схема. Управляет экраном библиотека LiquidCrystal_I2C: в симуляторе она уже подключена, на реальной плате её ставят через менеджер библиотек одной кнопкой.
Порядок инициализации жёсткий: сначала init(), потом backlight(), и только затем можно clear() и setCursor(). Я один раз напечатал текст до backlight() — Serial уверял, что всё отправлено, а экран стоял тёмный. Полчаса я думал, что сжёг переходник. Не повторяйте: сначала init, потом подсветка, потом печать.
В панели I2C симулятора видно каждый обмен: мастер объявляет адрес 0x27, отдаёт байты, ставит стоп. На настоящей плате кириллица в print() превратится в кракозябры — в знакогенераторе стандартного контроллера HD44780 русских букв нет, поэтому в реальных скетчах пишут латиницей или рисуют символы вручную. Симулятору это без разницы, но привычку к латинице я бы ставил с первого дня — если планируете переносить код на железо.
Эксперименты для закрепления
Теория без наигрыша выветривается за вечер. Три задачи — прямо здесь, в симуляторе:
- Выведите во вторую строку слово длиннее 16 символов. На настоящем экране хвост уедет в невидимую зону и без setCursor() не вернётся — проверьте это поведение, оно ещё не раз всплывёт.
- Поменяйте адрес в конструкторе с 0x27 на 0x3F и запустите. Панель I2C покажет передачу по новому адресу, а экран замолчит — так выглядит мой четырёхчасовой тупик с «молчащим» LCD, о котором подробно в следующем уроке.
- Соберите счётчик секунд: раз в секунду печатайте число секунд с запуска. Подсказка: переменная над setup(), инкремент в loop(), и дописывайте пробел в конце, чтобы при изменении значения не оставался старый хвост.
Скорость, длина проводов и здравый смысл
Стандартный режим шины — 100 кГц, быстрый — 400 кГц. Uno по умолчанию живёт на 100 кГц, и для экранов с датчиками этого хватает с запасом: LCD1602 всё равно не перерисовывается быстрее десяти раз в секунду. Разгон до 400 кГц имеет смысл на OLED с большими объёмами данных и только на коротких проводах — но это отдельная история с правкой регистров таймера Wire, к ней вернёмся в продвинутом разделе.
Про длину проводов у меня правило, проверенное тремя проектами: до полуметра обычные dupont-провода при 100 кГц работают без вопросов; от полуметра до метра — зависит от подтяжки и числа модулей; дальше метра начинаются сбои, которые лечатся подтяжкой пожёстче, 2,2 кОм, или снижением скорости. Если датчик надо унести на пять метров — I2C не тот инструмент, берите RS-485 или радиоканал.
И последнее, моё личное: если вы только начинаете, берите модули со штатной подтяжкой на борту и не паяйте дополнительные «для верности». Дублирующие резисторы включаются параллельно штатным, общее сопротивление падает, и при трёх-четырёх таких модулях линии начинают проседать. Я видел проект, где именно каскад лишних подтяжек заставлял экран показывать мусор каждые десять секунд — виноватых искали в коде, а он был ни при чём.
- I2C — шина на два сигнальных провода: SDA (данные, пин A4) и SCL (такт, пин A5), плюс общие VCC и GND
- Мастер (Arduino) задаёт такт и адресует слейвы; слейв молчит, пока к нему не обратились
- Классический диапазон адресов устройств — 0x03–0x77; передачу закрывает стоп-условие через endTransmission()
- Подтяжка 4,7 кОм к VCC обязательна, но на готовых модулях уже стоит на борту
- LiquidCrystal_I2C: init() → backlight() → setCursor(столбец, строка) → print()
- По умолчанию шина живёт на 100 кГц; провода до полуметра — без вопросов, дальше — осторожно
- 1. На каких пинах Uno сидит шина I2C?
- 2. Сколько сигнальных линий у шины I2C, не считая питания и земли?
- 3. Что делает Wire.endTransmission()?
- 4. Какой диапазон адресов обычно перебирают I2C-сканеры?
- 5. Экран LCD1602 с переходником PCF8574 чаще всего отвечает на адресе:
- 6. Зачем на SDA и SCL нужны резисторы 4,7 кОм?
Теперь у вас есть две линии и адресная книга. В следующем уроке напишем сканер I2C-адресов — двадцать строк, которые спасли мне проект и кучу нервов: экран молчал, потому что его адрес был 0x3F, а не 0x27, и без сканера я бы гадал до сих пор. А пока попробуйте вывести на симуляторный экран таймер обратного отсчёта: живой дисплей дисциплинирует лучше любой теории.
Частые вопросы по теме урока
- На каких пинах Uno сидит шина I2C?
- На Uno линии I2C выведены на A4 (SDA) и A5 (SCL); на плате R3 они продублированы отдельными гнёздами SDA и SCL. SDA — A4, SCL — A5
- Сколько сигнальных линий у шины I2C, не считая питания и земли?
- Только две — данные (SDA) и такт (SCL). Линия CS — это из интерфейса SPI. Две: SDA и SCL
- Что делает Wire.endTransmission()?
- Wire.write() только копит байты в буфере; endTransmission() отдаёт их на шину одним пакетом и ставит стоп-условие. Отправляет накопленные байты и закрывает передачу стоп-условием
- Какой диапазон адресов обычно перебирают I2C-сканеры?
- Классика — 0x03–0x77; крайние адреса зарезервированы стандартом, а строго чистые адреса устройств начинаются с 0x08. 0x03–0x77
- Экран LCD1602 с переходником PCF8574 чаще всего отвечает на адресе:
- 0x27 — типовой адрес PCF8574; вторая распространённая партия живёт на 0x3F. А 0x3C — это OLED, 0x68 — часы. 0x27
- Зачем на SDA и SCL нужны резисторы 4,7 кОм?
- Шина — «открытый сток»: устройства только прижимают линии к земле, вверх их поднимают подтяжки. На готовых модулях они уже распаяны. Они подтягивают линии к 5 В, когда никто не прижимает их к земле