Симулятор PCF8574: расширитель I2C портов без пайки
PCF8574 выручает, когда пинов на плате не хватает: восемь дополнительных линий ввода-вывода по двум проводам SDA/SCL. На бумаге просто, на практике новички застревают на адресах: у PCF8574A адреса 0x38-0x3F, у PCF8574 — 0x20-0x27, и скетч из интернета под PCF8574A на плате с PCF8574 не находит модуль. В браузере можно прогнать логику «записать байт в порт, прочитать байт из порта» и заодно — I2C-сканер для проверки адреса.
Встроенного устройства «PCF8574» в каталоге симулятора нет — лендинг текстовый с разбором API Wire, рабочего скетча, теста ввода-вывода 8 битов и честной границы. Ниже — проба, кросс-ссылки на уроки по Wire-PCF8574 и на I2C-сканер.
С чего начать: восемь портов на двух проводах
PCF8574 — 8-битный расширитель портов на I2C: два провода SDA/SCL, восемь линий P0-P7 для ввода или вывода. На Uno SDA — A4, SCL — A5; адрес по трём выводам A0-A2 модуля (земля или +3V3): 8 адресов от 0x20 до 0x27 у PCF8574, от 0x38 до 0x3F у PCF8574A. Библиотека Wire прячет обмен в beginTransmission(addr), write(byte) и endTransmission(). Логику «записал — зажёг светодиод, прочитал — увидел кнопку» можно проверить без модуля.
- 8 портов P0-P7: любой бит байта — светодиод (OUTPUT) или кнопка (INPUT с подтяжкой).
- Адрес по A0-A2: три бита → 8 адресов; PCF8574: 0x20-0x27, PCF8574A: 0x38-0x3F — не путайте.
- Wire.beginTransmission(addr) + write(byte) + endTransmission(): записать байт в порт.
- Wire.requestFrom(addr, 1) + read(): прочитать байт из порта — состояние всех восьми линий.
- Подтяжка 10 кОм: у PCF8574 слабая внутренняя подтяжка, для кнопок ставят внешнюю.
Скетч-проба: 8 светодиодов по I2C
#include <Wire.h> const byte ADDR = 0x20; // PCF8574 с A0-A2 на земле void setup() { Wire.begin(); Serial.begin(9600); Serial.println("Start");} void loop() { for (byte i = 0; i < 8; i++) { byte mask = 1 << i; // один горящий бит Wire.beginTransmission(ADDR); Wire.write(mask); Wire.endTransmission(); Serial.print("P"); Serial.print(i); Serial.print(" = "); Serial.println(mask, BIN); delay(150); }}Скетч вставьте в основной симулятор: компилятор поймёт Wire.begin/endTransmission, и монитор порта печатает «P0 = 1, P1 = 10, P2 = 100...» — логика работает, светодиоды в браузере не зажгутся: в каталоге деталей PCF8574 нет. Полный разбор wiring, подтяжек и адресации — в уроке про PCF8574 на шине I2C.
I2C-сканер: найти адрес модуля
#include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("Skan I2C..."); for (byte addr = 0x20; addr < 0x40; addr++) { Wire.beginTransmission(addr); byte err = Wire.endTransmission(); if (err == 0) { Serial.print("Naiden: 0x"); Serial.println(addr, HEX); } } Serial.println("Gotovo");} void loop() {}Скетч перебирает адреса 0x20-0x3F и печатает «Naiden: 0x20» при ответе модуля. В браузере модуля нет, и сканер ничего не находит — это честная граница. На живой плате сканер находит ваш модуль, и вы подставляете его адрес в рабочий скетч. Полный сканер с таблицей адресов популярных модулей — I2C-сканер на лендинге и урок про сканер-диагност кодов.
Честная граница: модель против живого модуля
| Проверка | Симулятор | Только железо |
|---|---|---|
| Wire.begin/endTransmission/write | компилируется, без устройства | записывает байт в PCF8574 |
| Wire.requestFrom + read: чтение байта | компилируется, без устройства | читает 8 линий P0-P7 |
| I2C-сканер: поиск адреса | ничего не находит | находит PCF8574/8574A по ответу |
| Подтяжка 10 кОм и слабая внутренняя | не моделируется | да — для кнопок обязательна внешняя |
| Ток на линии и емкость шины | нет: модель без физики | да — при длине провода > 30 см нужны подтяжки сильнее |
| Адреса PCF8574 против PCF8574A | логически разные | то же — перепутать легко, лечится сканером |
Браузер исполняет логику Wire, а PCF8574 в каталоге нет: beginTransmission/endTransmission проходят без ответа, и сканер не находит адреса. После того как скетч компилируется в основном симуляторе, переходите на плату: подключите модуль, запустите I2C-сканер, и подставьте найденный адрес в константу ADDR. Полный разбор адресов и таблица клонов — в уроке про подключение PCF8574 и адреса.
Грабли PCF8574
- Адрес 0x20 против 0x38: PCF8574 живёт в 0x20-0x27, PCF8574A — в 0x38-0x3F. Перепутали — модуль не найдется. Сканер решает за минуту.
- Подтяжка SDA/SCL: у PCF8574 слабая внутренняя 100 мкА, для кнопок обязательна внешняя 10 кОм. На длинной шине — 4,7 кОм.
- Чтение кнопок без задержки: после записи OUTPUT-байта нужно 10-20 мкс до чтения INPUT; в быстром цикле кнопка «дребезжит».
- Конфликт адресов с LCD I2C: типичный 0x27 — это и LCD-модуль, и PCF8574 с A0-A2 на земле. Решение — TCA9548A мультиплексор или перемычка адреса.
- Ток на линии: PCF8574 отдаёт 1 мА на пин — светодиод тусклый, ставьте транзистор или ULN2003.