Как узнать I2C адрес устройства?
I2C — это такая шина данных, широко используемая в микроэлектронике. С помощью I2C можно подключить к Ардуино много разных полезных модулей, включая датчики, дисплеи, АЦП и даже другие платы Ардуино.
Шина является адресной, так что каждое подключаемое устройство имеет свой адрес в диапазоне от 8 до 127. На одной шине не может быть два устройства с одинаковыми адресами.
В этой короткой статье мы победим одну из частых проблем, которые испытывают самодельщики про покупке неведомого модуля с этим самым I2C интерфейсом. Проблема состоит в том, что производитель может изменить адрес устройства, и стандартные библиотеки перестают работать. Часто с подобной неприятностью можно столкнуться, например, при подключении ЖК дисплея с интерфейсом I2C.
Программа для сканирования I2C шины
Чтобы понять, какой всё-таки адрес у модуля, подключаемого к плате Ардуино, нужно просто «постучаться» по каждому из 119 возможных адресов. Если кто-то ответит, значит адрес рабочий!
Загружаем программу на Ардуино Уно, подключаем тестируемое устройство к I2C шине и открываем монитор последовательного порта. Если все подключено правильно, то появится примерно такой отчет:

Это значит, что мой дисплей имеет адрес 0x27 в шестнадцатеричной системе счисления. Теперь можно смело подключить библиотеку для работы с такими дисплеями и указать в ней данный адрес.
Как узнать I2C адрес устройства? : 18 комментариев
Очень интересно, но думаю не помешала бы принципиальная схемка подключения I2C устройства к Ардуино. Ну или ссылка на такую процедуру.
SDA к SDA, SCL к SCL, Питание и земля…
и резисторы 10кОм с «+» на SDA(А4) и SCL(А5),
резисторы нужны обязательно, если подключено более 2х устройств, если одно, то необязательно
на китайце с али работает! адрес-0x3F
на двух lcd экранах 1602 — один адрес 0x27
на двух lcd экранах 2004 — один адрес 0x3F
Как узнать адрес pcf8574

Этот сдвиговый регистр наиболее известен по китайским драйверам дисплея HD44780, которые можно приобрести на али или ибэе. Сам регистр довольно подробно был разобран здесь: «Сообщество EasyElectronics.ru: I2C расширитель портов PCF8574». Я в свою очередь, попытаюсь сосредоточиться на программировании микроконтроллера ATmega8 для работы с этим регистром. Впрочем, начну я все же с Arduino и имеющегося у меня зоопарка: ATmega328/MSP430G2553/STM32F103C8.
Сдвиговый регистр PCF8574 может выпускаться разными фирмами, мне попались чипы с суффиксом «T», что обозначает производителя как «NXP Semiconductor». Руководство на pcf8574t можно скачать с официального сайта NXP: «PCF8574; PCF8574A Remote 8-bit I/O expander for I2C-bus with interrupt».
На мой взгляд, штука идеальная для подключения дисплея HD44780. Если сравнивать с драйвером на 595-м регистре, то вариант с pcf8574 будет немного дороже, но разница чисто условная: 25р за готовую плату на pcf8574 и
19р за самодельный вариант на 595-м(3р за чип + 11р за плату + 5р за подстроечный резистор). Сам дисплей HD44780 не слишком скоростной, необходимости в скоростях SPI интерфейса нет. С другой стороны, драйвер на 595-м собирается из рассыпухи «на коленках» за полчаса-час, а посылка из Китая идёт от пары недель в лучшем случае.
Но внешне, готовый вариант все же будет выглядеть более культурно:

дисплей HD44780 c драйвером pcf8574

дисплей HD44780 c самодельным драйвером на 74hc595
Немного справочной информации
Распиновка чипов PCF8574:

Таблица I2C адресов:

Принципиальная схема драйвера дисплея HD44780 (взято с сайта SUNROM):

1) Подключение LCD HD44780 к Arduino через модуль драйвера на PCF8574
Для Arduino существует «стандарт де-факто» библиотека для подключения дисплея HD44780 через модуль драйвера на PCF8574: Arduino-LiquidCrystal-I2C-library.
Перед подключением модуля к дисплею состоит проверить его I2C сканером. И хотя I2C адрес устройства точно задаётся маркировкой микросхемы, и пинами A2, A1, A0, все же могут быть нюансы.
Небольшой HelloWorld для проверки библиотеки Arduino-LiquidCrystal-I2C-library:
По сравнению со штатной LiquidCrystal библиотекой, эта обладает дополнительным функционалом: через нее можно включать и выключать подсветку дисплея. Если нужно отрегулировать яркость подсветки, то можно напаять резистор вместо джампика J3 сбоку.

2) Подключение LCD HD44780 к STM32duino через модуль драйвера на PCF8574
Подключение LCD HD44780 к 3.3 вольтовой логике несколько сложнее. Сам контроллер дисплея может работать от 3.3V уровней, но для выставления контраста дисплея нужна разность потенциалов между VDD и VEE около 4.5 Вольт.

Значит, подключение к модулю будет таким:

Прошивка после компиляции занимает более 17 килобайт:

В работе все это выглядит так:

3) Подключение LCD HD44780 к MSP430 Launchpad через модуль драйвера на PCF8574
В MSP430G2553 нет пинов толерантных к напряжению +5V, поэтому ничего не остаётся как прибегнуть к преобразователю логических уровней. Для последовательных интерфейсов китайцы продают специальный модуль на мосфетах:

Про него не писал только ленивый, его я и буду использовать.
Схематично, подключение будет таким:

После компиляции прошивка весит чуть более трёх килобайт:

Работает это как-то так:

4) Arduino библиотека PCF8574
Попробуем разобраться со сдвиговым регистром PCF8574 более подробно. В этом деле поможет одноимённая библиотека для Arduino. Она описана на сайте arduino.cc здесь: A class for PCF8574, скачать ее можно с гитхаба на странице автора: https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574
На всякий случай я помещаю код библиотеки под спойлеры, чтобы чтобы иметь его на виду.
Файл с исходным кодом:
Для начала попробуем помигать светодиодом через сдвиговый регистр pcf8574. Для этого загрузим из примеров библиотеки скетч PCF8574_test:

Этот скетч позволяет командой через UART установить на 4-м выводе регистра логическое состояние: высокое(команда H), низкое(команда L) или противоположное(команда T).
Высокий уровень на выводе регистра формируется подтяжкой к pullup резистору и в таком состоянии, через вывод может проходить только лишь 0.1 мА, что будет недостаточно даже для работы светодиода. Поэтому включать светодиод нужно будет при низком логическом уровне, или ставить транзисторный ключ:

Я лично использовал RGB-светодиод с общим анодом, он как раз включается выставлением земли на ножке соответствующего цвета.
Ещё забавный пример в стиле ёлочной гирлянды можно составить на основе демо-примера PCF8574_test2:
Здесь по умолчанию прописан I2C адрес 0x3F для чипа PCF8574A. К выводам сдвигового регистра нужно подключить светодиоды с токоограничивающими резисторами.
Из примеров библиотеки можно загрузить скетч ReadButton. Каждый раз при замыкании вывода сдвигового регистра P0 c землёй, будет переключаться светодиод на плате Arduino. Кроме того, через UART выводится состояние сдвигового регистра. Лог работы выглядит как-то так:

5) Работа со сдвиговым регистром PCF8574 в ATmega8
Для работы с I2C я буду использовать аппаратный I2C интерфейс ATmega8. Готовые функции для работы с ним взял из поста двухлетней давности: ATmega8 + аппаратный TWI модуль: «делаем распечатку памяти RTC DS1307». Я исправил ошибку в функции send_i2c() и немного «причесал» код, но все равно, на мой взгляд он еще очень сырой.
a) Сканер I2C
I2C расширитель портов PCF8574

Но есть у него и определенные недостатки.
Во-первых, как и все SPI-устройства, сдвиговый регистр требует для себя отдельной линии «chip select» (CS), и это при том, что шина как таковая и так занимает три свободных порта ввода/вывода (MOSI, MISO, SCK).
Во-вторых, сдвиговый регистр может увеличивать либо входы, либо выходы, но не то и другое стразу. А если нужны и входы, и выходы — то нужно ставить два регистра и выделять два пина CS. Обидно.
Ну и в-третьих, при разработке тянуть четыре дорожки через всю плату несколько достает. И их еще и перекручивать всегда приходится каким-нибудь странным образом.
А тут мне на глаза попался расширитель портов PCF8574 (даташит TI, даташит NXP) на базе шины I2C.
Для работы этого расширителя требуются всего два пина (причем вне зависимости от количества устройств на шине!). Устройство, с которым осуществляется обмен данными, цивилизованно определяется адресом, а не прижатием к нулю физической линии. Порты могут работать как порты ввода, так и порты вывода (правда весьма своеобразно, о чем ниже).
Ну и стоимость одной микросхемки при покупке десяти штук на ebay составляет порядка 15-ти рублей, что сопоставимо со стоимостью сдвигового регистра SN74HC595D в «Чип и Дип»-е (17 руб).
Адрес устройства формируется из неизменного для всех чипов префикса и 3-битной переменной части, которую можно задать подтягивая три специально выделенные ноги микросхемы (A0, A1, A2) к земле («0» в соответствующей позиции адреса) или к питанию («1»).
Подтягивать адресные ноги и к земле, и к питанию можно без какого бы то ни было дополнительного обвеса.
Что забавно, существует две модификации этой микросхемы — собственно PCF8574 и PCF8574A, которые отличаются друг от друга только значением адресного префикса.
У PCF8574 он равен 0100, а у PCF8574A — 0111. Сделано это для того, чтобы к одной шине можно было подключить до 16-ти расширителей с разными адресами — максимум 8 штук PCF8574 и 8 штук PCF8574A.
Так как у каждой такой микросхемы по 8 портов, получаем аж 128 портов ввода-вывода.
В даташитах несколько невнятно описано использование младшего бита адреса (бита R/W). Возможно, для человека работающего с I2C постоянно это является очевидным моментом, но начинающего может сильно сбить с толку.
Вот соответствующая картинка из даташита NXP, только там еще и опечатка в скобке, показывающей адрес для PCF8574A — в адрес включен R/W бит и адрес получился 8-ми битным, чего быть вообще не может.
Теперь о грустном.
Порты у PCF8574 назваются «квази-двунаправленными» (Quasi-bidirectional I/Os). И это «квази» — оно неспроста.
Смотрим на схему порта:
Фактически, при операции записи одного байта в PCF8574 происходит выставление подтяжек портов ввода/вывода исходя из значения соответствующего порту бита данных.
Причем, если в бит установлен в ноль, происходит «честная» подтяжка порта к земле (2).
А вот если бит установлен в единицу, порт будет подтянут к питанию — но как! — с ограничением тока в жалкие 100 uA (1)! То есть логический уровень есть, но светодиод с такой подтяжкой не зажжешь.
Еще на схеме порта виден транзистор (3), который как раз может подтянуть порт к питанию напрямую. Но увы, он включается только на короткое время, чтобы обеспечить быстрое переключение порта в логическую единицу. И управлять поведением этого транзистора мы не можем.
Чтение из PCF8574 — операция более простая для понимания. Какие уровни установлены на портах с учетом текущей подтяжки и того, что подключено к портам извне — то и будет отправлено микроконтроллеру.
Не то, чтобы такое построение порта сильно ограничивало возможности, но оказаться неприятным сюрпризом оно вполне может.
Так, светодиоды к PCF8574 надо подключать так, чтобы к порту подключался катод (минус) светодиода. Светодиод, подключенный анодом (плюсом) убогая подтяжка порта просто не потянет.
Вот, для примера я подключил два светодиода к соседним портам PCF8574. Левый подключен к порту катодом, правый — анодом.
Разница, что называется, видна невооруженным глазом.
Определенные ухищрения придется предпринимать и при подключении семисегментных индикаторов. Индикаторы с общим катодом лучше вообще не использовать (у него 8 анодов — и чего с ними делать?), а вот с общим анодом можно и прикрутить. Катоды сегментов можно напрямую подключить к PCF8574, а аноды знаков запитать, скажем, через полевые транзисторы P-типа, затворы которых будут управляться 100 uA подтяжкой PCF8574.
Использование каких-нибудь транзисторов на питании общих анодов вполне оправдано, так как с каждого из них кормятся восемь сегментов.
Очевидно, что для управления 2х и более значным семисегментным индикатором понадобится не менее двух PCF8574 — одна для 8ми катодов сегментов, а вторая — для управления транзисторами питания знаков.
Особенности подтяжки надо учитывать и при работе портов на ввод.
Смотрите, если мы подключаем к порту PCF8574 тактовую кнопку, которая при нажатии подсоединяет этот порт к земле, то все будет работать — операцией записи в PCF8574 мы заранее подтянем этот порт к питанию и, как только кнопка будет нажата и порт окажется соединен с землей, слабую подтяжку сорвет и при очередном опросе в бите, соответствующем порту кнопки мы увидим «0» вместо «1».
А что будет, если кнопка при нажатии будет соединять порт с питанием? А ничего хорошего.
Если подтянуть порт к питанию — его состояние не будет меняться при нажатии кнопки.
А если подтянуть его к земле, то при нажатии кнопки питание через кнопку и порт окажется напрямую подключенным к земле. Будет короткое замыкание.
Кстати, даташит в явном виде требует перед использованием порта в качестве порта ввода предварительно записать в него единицу. Вот именно поэтому.
Ну и чтобы не забыть, из вкусностей PCF8574 поддерживает генерацию сигнала прерывания, прижимая к земле ногу INT при изменении уровня на одном из портов. INT возвращается к высокому уровню при следующей же операции чтения из PCF8574.
Использование этой возможности занимает дополнительный порт микроконтроллера, но иногда она просто бесценна — например, если контроллер нужно будить по нажатию кнопки.
Вот простенькая макетная платка, с которой я и экспериментировал (кликабельно, по клику — архив с платой в формате SprintLayout).
С платой я слегка накосячил — сделал подтяжку кнопок к питанию. Ага, а как вы думаете, почему я теперь такой умный… По счастью, я сразу сделал все «рюшечки» вроде светодиодов и кнопок отключаемыми при помощи джамперов, чтобы можно было использовать макетку для каких-нибудь более сложных проектов «в чистом виде», и поэтому кнопки оказалось возможно подтянуть к земле проводком, надетым на пин джампера.
Кстати, резистор подтяжки для кнопок тоже не нужен, т.к. подтяжка к питанию реализована внутри PCF8574, а если случайно записать нолик в ногу, которая соединена с кнопкой, то получится подключение земли к земле, то есть тоже ничего страшного.
(В том файле, который в архиве — два варианта платы, с ошибкой и с исправленной подтяжкой кнопок).
А вот то, ради чего это все затевалось — подключение ЖКИ дисплея с контроллером HD44780 по I2C шине. Это пока макетирование, а будет полноценный шильдик для Arduino. Доделаю — опишу.
PCF8574P: подключение кнопок к Arduino по шине I2C или Люк Скайуокер наносит удар
Решил я сделать текстовую панель оператора(HMI) и подключить ее по «квадратной» шине I2C к Arduino. Для этого разработал на основе микросхемы PCF8574P плату клавиатуры из 5 кнопок.
PCF8574P это расширитель портов, корпус DIP, работает по шине I2C. Приобрел я партию из двух таких микросхем за 0.94$ с бесплатной доставкой из Китая, таким образом одна штука стоит 0.47$. Покупка выгодная, так как в местных магазинах эти же микросхемы стоят больше 2 долларов за штуку.
Дисплеем HMI будет стандартный экранчик 1602, так же через платку FC-113 работающий по квадратной шине.
PCF8574P выслали, дали трек-номер и через 2 недели я их уже получил на почте. 
Извлекаем из пластиковой трубки, вроде бы все нормально. 
Однако, снизу на корпусе одной из микросхем есть следы загадочных термомеханических воздействий. 
Природа этих повреждений мне не ясна, но очевидно, что во время пересылки они появиться не могли.
Долго думал над этой загадкой, пока меня не осенило.
Просто на склад продавца пробрался Люк Скайуокер, вдруг уменьшившийся до микроскопических размеров. Там он приметил один из расширителей портов, спутал с имперским шагоходом и принялся рубить его световым мечем. Тут зашла комплектовальщица, увидела эту картину и такая говорит: «Прекрати, Люк Скайуокер! Это не имперский шагоход, это микросхема PCF8574P, за которую уже уплочено из Запорожья».
Хорошо хоть, обе микросхемы при проверке оказались рабочими.
Приступаем к созданию самой клавиатуры по такой схеме. 
В Layout 6.0 нарисовал одностороннюю плату. 
Скачать файл с платой можно тут.
Плату травил перекисью водорода и лимонной кислотой.
В сети много рецептов травления платы перекисью.
Я делал такой раствор: 100 мл перекиси водорода 3%, 50 г лимонной кислоты, 3 чайные ложки соли. Баночку с перекисью подогрел в кастрюле с водой.
Погружаем плату в раствор рисунком вниз, как рекомендуют при травлении перекисью.
Пшшшшшш! Сначала процесс идет бурно. 
Пс… Потом заметно стихает. Переворачиваем, смотрим на рисунок. 
Красота. 
Готовая плата выглядит так. 

Адресные ножки микросхемы подключены на GND, поэтому адрес платы на шине будет 0x20.
Пишем программу для Ардуино.
#define led 13
#define ADDR_KBRD 0x20
#define ADDR_LCD 0x27
String str;
byte dio_in;
bool b;
bool key[5];
LiquidCrystal_I2C lcd(ADDR_LCD,16,2); // Устанавливаем дисплей
Как узнать адрес pcf8574
Расширители портов Arduino PCF8574 и PCF8575 приходят на выручку, когда для проекта не хватает буквально одного-двух свободных портов. А иногда портов хватает, но не хочется тянуть к другой части конструкции пучок проводов. Допустим, на передней панели устройства надо разместить несколько кнопок и светодиодов. Надежнее и проще соединить их с основной платой всего двумя проводами шины данных, а не шлейфом или жгутом, не так ли?
Для таких ситуаций предназначены различные расширители (экспандеры) портов Arduino.
Обычно выводы микроконтроллера реализуют несколько различных функций, поэтому расширители бывают разные:
Отдельно стоит упомянуть цифро-аналоговые преобразователи (ЦАП) и расширители адресного пространства шины I2C. Эти устройства не дублируют функции портов напрямую, но расширяют возможности микроконтроллеров.
В первой статье цикла мы поговорим о самых простых и полезных экспандерах, которые работают в качестве цифровых портов ввода-вывода. Это микросхемы PCF8574 и PCF8575. Они устроены и работают абсолютно идентично, и различаются только количеством портов.
Выбираем модуль расширителя для Arduino
Самый популярный и недорогой модуль изготовлен на микросхеме PCF8574 (рис. 1)
Рис. 1. Популярный модуль расширителя портов PCF8574
Достоинства:
Недостатки:
Если вы настроены на более серьезные проекты, закажите на Aliexpress 16-разрядный модуль на PCF8575. Настоятельно рекомендую именно модуль, изображенный на рис. 2.
Рис. 2. Модуль расширителя портов PCF8575
Достоинства:
Недостатки:
Принцип работы расширителя портов GPIO PCF8574/PCF8575
Обмен данными происходит по шине I2C. Для подключения к плате Arduino требуется лишь четыре провода, включая питание. Адрес расширителя задается тремя перемычками на входах A0…A2, поэтому к шине можно одновременно подключить восемь одинаковых микросхем и получить максимум 8*8=64 дополнительных порта с PCF8574 или 8*16=128 с микросхемой PCF8575.
Чтобы вывести данные в порт, записывают байт данных по адресу модуля на шине I2C. Чтобы прочитать данные с порта, читают байт по этому же адресу. Байт всегда пишется и читается целиком, работа с отдельными разрядами происходит программно.
Выходы микросхемы одновременно являются входами, и никакого служебного регистра, определяющего назначение вывода, нет. Есть только регистр-защелка, в который записывают выходной байт. Как такое возможно?
Порты работают по схеме, аналогичной открытому коллектору и оснащены внутренними подтягивающими резисторами. Если в выход записан логический ноль, то открывается выходной транзистор, который принудительно тянет вывод «на землю». Чтение из такого порта всегда будет возвращать ноль.
Будьте осторожны – при подаче прямого напряжения питания на вывод с низким уровнем или при превышении допустимого тока 50 мА вы испортите микросхему!
Чтобы использовать порт как вход, запишите в него единицу. В этом случае внутренний транзистор будет закрыт, а результат чтения будет определяться внешним логическим уровнем, приложенным к выводу. Свободный вывод подтянут к питанию встроенным резистором.
Чтобы одновременно использовать часть портов как входы, а часть как выходы, перед каждой записью байта данных в экспандер необходимо при помощи операции «логическое ИЛИ» накладывать маску из единиц на те разряды, которые соответствуют входам. Вот и все)))
Генерация прерывания
Расширители портов PCF857* генерируют импульс прерывания низкого уровня на выходе INT при любом изменении входного сигнала на любом входе микросхемы. Это удобно, если расширитель обслуживает кнопочную панель. Но вы должны сами определить в обработчике прерывания, какая кнопка была нажата или отпущена. Генератор прерывания оснащен фильтром подавления дребезга контактов.
Пример 1. Использование модуля PCF8574
Соберем простую схему из четырех светодиодов, модуля PCF8574 и платы Arduino (рис. 3 и 4). При такой схеме включения нам даже не требуются гасящие резисторы для светодиодов. Ток протекает через светодиод и встроенный резистор, подключенный к шине питания.
Рис. 3. Схема подключения модуля PCF8574
Рис. 4. Макет схемы с модулем PCF8574
Скопируйте и запишите в плату Arduino скетч 1:
Во все порты микросхемы изначально записывается высокий уровень, поэтому порты P0…P3 могут работать, как входы.
Уровни на выводах порта считываются каждые 500 мс и результат считывания выводится в монитор. Если вы соединяете один из входов P0…P3 с общим проводом, в его разряде появляется ноль. Затем считанное значение сдвигается влево на четыре бита, результат выводится в порт и гаснет один из светодиодов. Например, если прочитан ноль на выводе P0, то погаснет светодиод, подключенный к выводу P4.
Обратите внимание, что мы должны перед каждой записью в расширитель наложить битовую маску из единиц на все разряды, которые должны быть входами: dataSend |= B00001111;
Подпрограммы работы с шиной I2C предельно упрощены, никакие ошибки не обрабатываются.
Совет: для поиска и проверки адреса модуля на шине I2C можно использовать простой скетч. Он выводит в терминал адреса всех устройств, которые отвечают на запрос шины.
Пример 2. Использование модуля PCF8575
Особенность модуля PCF8575 состоит в том, что у него 16 портов, поэтому в него всегда записывают по два байта и читают по два байта. Это правило надо соблюдать, даже если второй байт не нужен.
Немного изменим схему. Светодиоды подключим к портам P10…P13, а соединять перемычкой с общим проводом будем порты P00…P03 (рис. 5 и 6).
Рис. 5. Схема подключения модуля PCF8575
Рис. 6. Макет схемы с модулем PCF8575
В скетче 2 сначала записываются единицы во все порты, затем каждые 500 мс читается их состояние. Процедура чтения возвращает 16-разрядное слово, которое разделяется на байты. Содержимое младшего байта (выводы P00…P07) копируется в старший байт и выгружается обратно в модуль. Если соединить с общим проводом один из выводов P00…P03, то погаснет один из светодиодов, подключенных к P10…P13.
Библиотека Arduino для PCF8574/PCF8575
Библиотеку можно скачать на GitHub. Но, как вы могли видеть, работа с расширителями портов очень проста и можно легко обойтись без специальной библиотеки.
Об авторе
Переводчик, редактор, писатель. Инженер по специальностям «Радиотехника» и «Микропроцессорные вычислительные системы». Автор учебных пособий по спутниковой навигации и программированию.
3 комментариев
Спасибо за наводку, а то я смотрел в сторону cd4051 и cd74hc4067 немного скептически, а по протоколу i2c, прямо как и хотел. И отдельное спасибо за код. Интересно, а 400кГц поддерживают данные микросхемы?
Будьте осторожны:
PCF8574 НЕ поддерживает 400 кГц.
PCF8575 более новый чип с поддержкой 400 кГц. Он в целом более надежный и живучий. Поэтому в любом случае лучше применять PCF8575.
Спасибо большое!
Как раз на этом модуле и остановился, уже полистал спецификации.













