Знакомство с шиной I2C в Raspberry Pi, работаем с ADC-DAC PCF8591 на Python

Содержание

Знакомство с шиной I2C в Raspberry Pi, базовая настройки и консольные инструменты. Основы применения и программирования для цифро-аналогового преобразователя PCF8591, напишем простые программы на Python, научимся считывать значения напряжений с аналоговых входов, а также устанавливать значение на аналоговом выходе. Соберем простой делитель для измерения напряжения батареи 12В (0-14,8В).

Постараюсь подробно рассказать как работать с шиной I²C в Linux (Raspbian), как узнать номер шины, адреса устройств и т.п. Приведу примеры практического применения модуля-конвертера PCF8591, распишу что в нем есть и как этим управлять.

Двухпроводная шина обмена данными I2C

I²C (I2C) — двунаправленная шина передачи данных, разработанная еще в 1980х годах компанией Philips для осуществления связи между разными схемами и устройствами.

Передача данных осуществляется по двум проводам — SDA (Serial Data) и SCL (Serial Clock). На одной такой двухпроводной линии связи можно держать до 127 различных устройств и модулей которые умеют работать с шиной I²C.

Подключение устройств к шине I2C

Рис. 1. Подключение устройств к шине I2C.

Режимы работы шины:

  • Скоростной — 400 кбит/с;
  • Обычный — 100 кбит/с;
  • С пониженной скоростью — 10 кбит/с.

В самом начале своего становления спецификация шины I 2 C была сфокусирована на логике, которая питается от напряжения +5V. В следующей своей спецификации 2.0 (1998 год) уровень опорного напряжения был уменьшен до 2V.

Линии SCL и SDA шины I 2 C являются двунаправленными, что делает невозможным подключение устройств с разными напряжениями питания. Для выхода из такой ситуации нужно использовать конвертеры уровней напряжения!

Существует достаточно много различных модулей и микросхем, которые управляются через шину I²C, приведу несколько примеров:

  • Микросхема TDA7448 — 6-ти канальный регулятор громкости для аудио-аппаратуры;
  • Микросхема TDA7313 — цифровой стерео аудио-процессор (регулировка громкости по каналам, эффект пространственного звучания, предусилитель, регулировка высоких и низких частот, приглушение, тонкомпенсация);
  • Микросхема TEA6420 — электронный переключатель аудио-сигналов (5 стерео-входов и 4 стереовыхода);
  • Микросхема TEA5767 — FM радиоприемник на диапазон частот 76. 108 МГц;
  • Микросхема DS1307 — часы реального времени;
  • Микросхема PCF8591 — аналогово-цифровой преобразователь (4 аналоговых входа, 1 аналоговый выход);
  • и другие.

Подобные микросхемы и модули применяются в автомагнитолах, музыкальных центрах, компьютерной электронике и автоматике, в электронных игрушках (квадрокоптеры, радиоуправляемые автомобили и другие), в системах контроля и охраны, а также во многих других промышленных и бытовых устройствах.

Работа с шиной I²C поддерживается в таких операционных системах как GNU Linux, FreeBSD, OpenBSD. Данная шина отлично подходит для связывания модулей в различных встраиваемых устройствах, как самодельных, так и промышленных.

Особенности подключения к шине I2C

Как уже было сказано выше, к шине I²C можно подключить до 127 устройств. Устройство которое будет управлять этим набором периферии является ведущим (master), а модули подключенные к нему — ведомыми (slaves).

Генерация сигнала осуществляется "прижиманием" линии к нулю (низкий уровень), высокий уровень присутствует по умолчанию за счет подключенных подтягивающих резисторов к каждой из линий (SCL, SDA) и шине питания (VCC). От сопротивления этих резисторов зависит скорость восстановления на линиях высокого уровня, а заодно и скорость работы шины I²C.

Оптимальное сопротивление подтягивающих резисторов — 10 кОм, минимальное — примерно 1,5 кОм. Как правило, на многих готовых модулях уже установлены подтягивающие резисторы сопротивлением 3,3 — 4,7 кОм.

Напряжения высокого (HIGH) и низкого (LOW) уровней на линиях I²C не фиксированы! Они напрямую зависят от напряжения питания подключаемого модуля.

В документе UM10204 от NXP Semiconductors указаны следующие уровни на линиях рассматриваемой нами шины:

  • LOW = 0.3 * Vdd (30% от напряжения питания);
  • HIGH = 0.7 * Vdd (70% от напряжения питания).

В случае подключения нескольких модулей к одной шине I²C подтягивающие сопротивления окажутся включенными параллельно и результирующее сопротивление такого себе, комплексного подтягивающего резистора, окажется достаточно низким (менее 1,5 кОм), что в свою очередь может негативно сказаться на работе модулей и шины в целом.

Поэтому, при подключении нескольких готовых модулей к одной шине I²C нужно осмотреть модули и оставить подтягивающие резисторы только на одном из модулей, а остальные — отпаять!

Схема подключения нескольких устройств к одной шине I2C, подтягивающие резисторы

Рис. 2. Схема подключения нескольких устройств к одной шине I2C, подтягивающие резисторы.

В свое время, не зная о данной особенности и не вникая в подробности подключил 4 разных модуля к одной шине I²C и заметил что одно из устройств (датчик температуры и влажности) при сканировании шины то появляется, то пропадает — думал уже выбросить его и заказать новый модуль.

Более детально изучил информацию по работе с шиной, осмотрел всем модули и их принципиальные схемы, выпаял лишние подтягивающие резисторы — все заработало стабильно!

Если нет схемы модуля — не страшно, ставим тестер в режим "прозвонки" и ищем на плате резисторы, выводы которых подключены вот так:

  • Первая нога — к выводу SCL или SDA;
  • Вторая — к линии питания VCC (или внутреннему стабилизатору напряжения 3,3В).

Подключение двух модулуй, каждый с подтягивающими резисторами на борту, еще вполне допустимо. К примеру, если на платах стоят 2 резистора по 3.3к и два по 4,7к, считаем их результирующее сопротивление, используя для этого формулы для расчета сопротивления параллельно-соединенных резисторов:

1 / Rсум = (1/R1) + (1/R2) . (1/Rn).

Для двух соединенных в параллель резисторов: Rсум2 = (R1*R2) / (R1+R2).

В нашем случае: Rсум = (3,3*4,7) / (3,3+4,7) = 1,93875 (кОм). Почти по два килоОма, что вполне еще допустимо.

Подключение по I2C нескольких устройств с разным напряжением питания

Если посмотреть на схему (рисунок 2) то там по шине i 2 C соединены 4 ведомых устройства и одно ведущее, предполагается что все они вместе с подтягивающими резисторами R1, R2 питаются от одного и того же источника напряжения (VCC).

В случае когда одно из устройств рассчитано на работу от +5V, а остальные — от +3,3V, потребуется двунаправленный конвертер уровней напряжения. Подключать напрямую к одной шине i 2 C устройства с разным напряжением питания не безопасно!

На рисунке ниже показан принцип подключения нескольких устройств с разным напряжением питания к одной общей шине i 2 C.

Подключение трех устройств с разным напряжением питания к общей шине I2C

Рис. 3. Подключение трех устройств с разным напряжением питания к общей шине I2C.

Как видим, здесь линии SCL и SDA для каждой стороны со своим напряжениями питания подтянуты двумя парами резисторов для обеспечения надежного высокого уровня на шине I2C.

Двунаправленный конвертер уровней напряжения можно собрать на основе транзисторов MOSFET (Metal-Oxide Semiconductor Field-Effect Transistor). Схема такого решения приведена в документе "AN10441 — Level shifting techniques in I 2 C-bus design" (NXP Semiconductors, Philips).

Вот как будет выглядеть схема соединений для двух устройств, одно из которых "ведущее" и питается от +3,3V, а второе — "ведомое" и с питанием от +5V:

Принципиальная схема двунаправленного конвертера уровней напряжения для шины I2C, собранного на MOSFET

Рис. 4. Принципиальная схема двунаправленного конвертера уровней напряжения для шины I2C, собранного на MOSFET.

Вот как работает эта простая схема (на основе описания из документа AN10441), три варианта состояний для линии SDA:

  1. Ни одно из устройств не установило на линии SDA логический 0. Линия SDA в левой части схемы (‘master’, с питанием от +3,3V) подтянута к высокому уровню с помощью резисторов R1, R2. На шлюзах (G, Gate) и истоках (S, Source) транзистора Q1 у нас также +3,3V. Значение напряжения между S-G не достаточно для открытия транзистора. Это позволяет линии SDA с правой стороны схемы (‘slave’) быть подтянутой к +5V резисторами R3, R4. Таким образом, линия SDA с каждой из сторон подтянута к высокому уровню, при разном значении питающих напряжений.
  2. Устройство ‘master’ с питанием +3,3V установило на линии SDA низкий уровень. Вывод S транзистора теперь подключен к земле (минусу питания через электронный ключ внутри устройства ‘master’), в то же время на выводе G у нас +3,3V. Напряжение между S-G достигло нужного значения и открыло транзистор Q1. Вывод SDA для устройства ‘slave’ с питанием +5V также подтянут к земле, через транзистор, на нем виставлен низкий уровень. Таким образом, мы имеем одинаковые низкие уровни напряжения на каждой из сторон.
  3. Устройство ‘slave’ с питанием +5V установило на линии SDA низкий уровень. Низкий уровень напряжения на линии SDA для устройства ‘master’ будет установлен через диод внутри транзистора Q1, но до тех пор пока напряжение S-G не станет достаточным для открытия этого транзистора. Когда это произойдет, транзистор откроется и через его выводы D-S низкий уровень будет установлен на линиях SDA для каждого из устройств. Таким образом, мы имеем одинаковые низкие уровни напряжения на каждой из сторон.

Аналогичным образом все происходит и с линией SCL. Состояние (1) здесь отвечает за нормализацию уровней напряжения для каждого из устройств.

Сопротивления резисторов в сравнении со схемой на рисунке 2 увеличены не спроста — когда любое из устройств ‘master’ или ‘slave’ выставит низкий уровень на любой из линий данных, то ему придется держать ток в нагрузке через два резистора: для SDA — R2 и R3, а для SCL — R1, R4.

Полевые транзисторы в этой хитрой схеме нужно использовать низковольтные быстродействующие N-канальные, с диодом внутри, например:

  1. BSS138 в корпусе SOT-23;
  2. TN2501 в корпусе SOT-89;
  3. 2N7002A в корпусе SOT-23 (TO-236AB);
  4. и другие.

Джим Хегирмен (Jim Hagerman, www.hagtech.com) предложил также вариант конвертера уровней напряжения для шины I2C на основе биполярных транзисторов структуры N-P-N.

Пример схемы такого конвертера показан ниже:

Принципиальная схема двунаправленного конвертера уровней напряжения для шины I2C, собранного на биполярных N-P-N транзисторах

Рис. 5. Принципиальная схема двунаправленного конвертера уровней напряжения для шины I2C, собранного на биполярных N-P-N транзисторах.

Такое решение вполне может подойти для несложных самодельных устройств, блоки которых взаимодействуют через шину I2C.

Из готовых решений также можно рассмотреть микросхему PCA9306 (2-bit bidirectional I2C bus and SMBus voltage-level shifter).

Пример сопряжения двух устройств по шине I2C с питающими напряжениями +3,3В и +5В используя микросхему PCA9306

Рис. 6. Пример сопряжения двух устройств по шине I2C с питающими напряжениями +3,3В и +5В используя микросхему PCA9306.

Два устройства с разными напряжениями питания можно попробовать соединить по шине I2C, подтянув резисторами высокий уровень до наименьшего из напряжений, но это не всегда сработает. Как уже было сказано выше, высокий уровень на линии шины будет получен при напряжении равному 70% от питающего, поэтому напряжения подтяжки к +3V(и даже +3,3V) может быть не достаточно: 5V * 70% = 3,5V.

Если одно устройство питается от +3,3V, а второе — от +5V, то подтянув резисторами выводы SCL и SDA к линии питания +3,3V мы обеспечим надежную работу первого устройства, но не второго, для которого высокий уровень (HIGH) на линиях шины I2C может быть и не достигнут.

Поэтому, ответ на вопрос "можно ли соединить два устройства с питанием +3,3В и +5В по шине I2C без схемы согласования уровней?" — можно, если подтягивающие резисторы подключить к питанию +3,3В, это будет безопасно для двух устройств, но стабильность работы такой связки будет низкой, зависящей от внутреннего строения устройства с питанием +5В, от того сможет ли оно толерантно воспринимать уровень напряжения +3,3В как высокий (HIGH).

Поэтому корректные пути решения проблемы здесь следующие, и их не много:

  1. Использовать преобразователь уровней напряжения;
  2. Рассмотреть возможность питания все устройств с шиной I2C одним напряжением (изучить даташиты, попробовать найти простое решение).

Одним из примеров подключения модулей с разным питанием к малинке может служить схема моего самодельного роутера на Raspberry Pi. Там к шине I 2 C подключены два модуля: дисплей SSD1306 (+3,3В) и часы реального времени DS1307 (+5В).

Настройка и инструменты для работы с I2C в Raspberry Pi

Предполагается что у вас уже установлена и настроена Raspbian (GNU Debian Linux for Raspberry Pi), о том как настроить Raspbian в Raspberry Pi я писал в одной из публикаций.

Первым делом нужно включить поддержку I2C в ядре операционной системы (ОС). Для этого запустим конфигуратор Raspbian при помощи следующей команды в консоли:

Идем по пунктам “Advanced Options” — “I2C” — "Yes" — жмем "Finish". Перезагружаем операционную систему:

Теперь модуль ядра для шины I²C должен быть активирован, можно приступать к работе. Полезно знать что проделанная операция в настройках конфигуратора равносильна добавлению или раскомментированию строчки "dtparam=i2c_arm=on" в файле "/boot/config.txt".

При помощи нехитрой связки из команд посмотрим загружены ли модули ядра для поддержки I2C:

В выводе должны присутствовать примерно такие строчки:

Если они есть — значит все в норме и можем продолжать дальше.

Установим модуль для работы с шиной I2C в Python, а также пакет с полезными консольными инструментами для I2C:

После установки нам будут доступны несколько полезных утилит: i2cdetect, i2cdump, i2cget, i2cset. Отобразим список доступных в системе шин I²C, этой командой можно проверить есть (+включена) ли поддержка шины в устройстве или нет:

У меня вывод команды имеет следующий вид:

В начале строчки "i2c-1" можно увидеть что номер шины к которой подключен адаптер I²C = 1, эта информация нам позже пригодится.

Для просмотра адресов подключенных устройств можно вызвать команду i2cdetect с указанным номером шины, также по умолчанию она запустится в интерактивном режиме, который мы отключим при помощи параметра "-y", это нужно чтобы просто вывести состояние шины на консоль в текстовом виде.

Какой номер шины указывать для Rasperry Pi:

  • 1 — для Model A, B Rev 2 or B+
  • 0 — для более старых моделей с Rev 1.

В моем случае используется Raspberry Pi2 model B, также раньше при помощи команды i2cdetect я узнал что номер шины адаптера — 1. Давайте посмотрим что у нас подключено к шине под номером 1:

К малинке подключен модуль PCF8591 и вывод команды выглядит следующим образом:

Контроллер PCF8591 на шине I2C найден, его адрес — 0x48. Зная адрес устройства и принимая во внимание тот факт, что оно обнаружилось, можно переходить к изучению документации и выполнению первых экспериментов.

Обзор АЦП-ЦАП (ADC-DAC) PCF8591

PCF8591 — это микросхема, которая содержит в себе 4 входа для Аналогово-Цифрового Преобразователя (АЦП, ADC) и 1 выход для Цифро-Аналоговый Преобразователя (ЦАП, DAC).

Как известно, в Raspberry Pi нет встроенного АЦП и ЦАП, данная микросхема позволит исправить эту проблему не только для Raspberry Pi, но и на других платформах.

На входы ADC микросхемы могут быть подключены четыре различных аналоговых сигнала для наблюдения и анализа их величины (термодатчик, фотодатчик, делитель напряжения я другие). Также в микросхеме есть возможность сконфигурировать четыре входа для для сравнения напряжений из различных источников.

К выходу ADC может быть подключено устройство, которым нужно управлять изменяя уровень напряжения (например светодиод — меняем его яркость свечения).

Работает микросхема в диапазоне питающих напряжений 2,5 — 6В, поэтому ее смело можно питать от линий с напряжением 3,3В или 5В.

Разрешающая способность данных для входов и выходов микросхемы — 8 Бит. Это значит что минимальный уровень у нас будет соответствовать 0, а максимальный — 255 (2^8-1). Такой разрешающей способности вполне достаточно для измерения напряжений источников питания и батарей, сигналов с разных датчиков и модулей где не нужна высокая точность измерений.

Для расчета значения на входе АЦП можно применить следующую формулу:

  • V — значение (value), полученное с ADC программным путем;
  • Uin, В — напряжение, полученное на выходе датчика что подключен к ADC;
  • Uadc, В — напряжение питания микросхемы (ADC).

Пример расчета: питаем PCF8591 от линии 3,3В и к нему на один из входов подключен аккумулятор с напряжением 1,2В.

Важно заметить, что напряжение питания микросхемы должно быть хорошо стабилизировано — его можно взять из GPIO линий питания 3,3В или 5В в малинке, а также от внешнего стабилизатора напряжения с хорошей помехозащищенностью.

Подключаем PCF8591 к Raspberry Pi

Для экспериментов был приобретен готовый модуль с микросхемой PCF8591 на котором также установлены: переменный резистор, фото-резистор, термо-резистор и два светодиода (1 для питания, 2й для индикации выхода DAC).

Все резисторы на плате можно отключить от входов при помощи джамперов, тем самым освободив входы для подключения каких-то датчиков и других источников сигнала.

Модуль PCF8591 с компонентами для экспериментов

Рис. 7. Модуль PCF8591 с компонентами для экспериментов.

Принципиальная схема модуля PCF8591

Рис. 8. Принципиальная схема модуля PCF8591.

Как видим из схемы, на плате модуля уже установлены подтягивающие резисторы — R7 и R8. Также есть переменный резистор (потенциометр), терморезистор, фоторезистор и два светодиода.

Сенсоры, подключенные к входам на плате и назначение джамперов приведено в табличке ниже:

Вход Описание
AIN0 Джампер P5 подключает фото-резистор
AIN1 Джампер P4 подключает термо-резистор
AIN2 Ничего не подключено
AIN3 Джампер P6 подключает переменный резистор

Для подключения модуля к плате с малинкой нужно выполнить соединение выводов:

Raspberry Pi Модуль PCF8591
SDA SDA
SCL SCL
3V3 VCC
GND GND

В данном случае модуль будет питаться от напряжения 3,3В и нам не потребуется дополнительный конвертер для нормализации уровней напряжений по линиям шины I2C для каждого из устройств (малинка и PCF8591).

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

В принципе светодиод можно и не подключать, поскольку на модуле уже установлен светодиод зеленого цвета свечения, он подключен к AOUT.

подключение модуля PCF8591 к Raspberry Pi схема

Рис. 9. Схема эксперимента — подключение модуля PCF8591 к Raspberry Pi.

Модуль PCF8591 подключен к Raspberry Pi

Рис. 10. Модуль PCF8591 подключен к Raspberry Pi.

Работа со входами и выходом PCF8591

Чтобы работать с I²C на языке Python в системе должен быть установлен модуль python-smbus, его мы уже установили на этапе конфигурации.

Для программного управления контроллером PCF8591 по шине I²C нужно отправить два байта:

  • Байт адресации (адрес устройства на шине I²C);
  • Байт управления (выбор входов, выхода и их режимов работы).

Структура командного байта:

A — состояние ЦАП:

BB — конфигурация входов АЦП:

  • 00 — четыре прямых входа;
  • 01 — три дифференциальных входа;
  • 10 — смешанный режим (два прямых и один дифференциальный вход);
  • 11 — два дифференциальных входа.

C — режим инкрементации:

  • 0 — не автоматический;
  • 1 — автоматический.

DD — выбор канала:

  • 00 — канал 0, AIN0;
  • 01 — канал 1, AIN1;
  • 10 — канал 2, AIN2;
  • 11 — канал 3, AIN3.

Чтобы лучше было понятно как работают режимы переключения входов приведу небольшой рисунок:

Режимы работы входов преобразователя PCF8591

Рис. 11. Режимы работы входов преобразователя PCF8591.

Простая программа на Python

Ниже приведена простая программа на Python, которая будет делать следующее:

  • Считывать значения на всех входах ADC (AIN0. AIN3) и отображать на экране в консоли;
  • Изменять значение на выходе DAC (AOUT) в соответствии со значением на входе AIN3 (переменный резистор).

Создадим файл для тестовой программы и откроем его в редакторе:

Поместим в него следующий код:

Для запуска программы нужно выполнить следующую команду:

После запуска программа начнет выводить на экран состояния всех четырех входов, вращая ползунок переменного резистора будет меняться значение на входе AIN3 и соответственно яркость свечения светодиода что подключен к выходу AOUT.

Вывод тестовой программы для PCF8591 в консоли

Рис. 12. Вывод тестовой программы для PCF8591 в консоли.

Для того чтобы яркость свечения светодиода изменялась при изменении освещения фото-резистора нужно изменить в программе проверку канала AIN3 на AIN0 — заменить "if channel == ‘AIN3’:" на "if channel == ‘AIN0’:".

Кратко о структуре программы. Сперва мы подключаем нужные библиотеки (os, time, smbus), затем переменной DEV_ADDR присваиваем адресс нашего контроллера в шестнадцатеричном виде (HEX).

Дальше мы создаем словарь adc_channels в котором перечисляем значения байта управления для установки нужного входа ADC. Для наглядности и понимания, все значения записаны в двоичной системе исчисления (Binary). В переменной dac_channel будет храниться значение байта управления для доступа к DAC.

Переменная bus содержит экземпляр объекта для работы с шиной I²C которая доступна в системе под номером 1. Также инициализируем временную переменную tmp, она нам понадобится для хранения значений из выбранного входа ADC и установки значения на выходе DAC.

Дальше идет вечный цикл в котором:

  • Очищаем экран консоли;
  • Выводим сообщение о том что прекратить выполнение можно нажав CTRL+C;
  • Перебираем из словаря adc_channels адреса всех каналов и считываем их значения на входах, значения входа AIN3 записываем во временную переменную, выводим на экран значение для каждого канала;
  • Устанавливаем значение на выходе AOUT равным значению временной переменной tmp;
  • Выполняем задержку в 100 миллисекунд (0,1с).

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

Краткое видео работы данного эксперимента:

Простой резистивный делитель напряжения

Применяя преобразователь PCF8591 мы упираемся в максимально возможный измеряемый уровень напряжения равный питающему напряжению ADC. Если же на вход ADC подать большее напряжение то канал (а то и вся микросхема) может выйти из строя.

Для того чтобы иметь возможность измерять напряжения более 5В (к примеру 12В) можно собрать несложный резистивный делитель напряжения.

Принципиальная схема резистивного делителя напряжения 14,8В - 3В

Рис. 13. Принципиальная схема резистивного делителя напряжения 14,8В — 3В.

Расчет параметров подобного делителя напряжения можно выполнить применяя закон Ома, я же здесь приведу готовые формулы. Для начала нужно было определиться с сопротивлением R1, оно будет в разы больше чем сопротивление R2, к тому же сумма сопротивлений должна получиться такой чтобы через них протекал небольшой ток (зачем нам лишние траты энергии) и его было достаточно для измерения при помощи ADC.

Было выбрано значение 62 КОм. Теперь зная входное напряжение, выходное напряжение и сопротивление резистора R1 можем перейти к расчету сопротивления R2.

Сопротивление резистора R2 равняется примерно 16 КОм.

Такой делитель можно собрать за несколько минут и при помощи тестера убедиться в том что на выходе будет примерно 3В при входном напряжении 14,8В.

Проверка резистивного делителя напряжения

Рис. 14. Проверка резистивного делителя напряжения.

Ток через делитель без нагрузки на выходе: I = U/R = 14,8V / (62000 + 16000) = 0,00019A = 0,19мА. При таком токе можно использовать резисторы на любую мощность.

Программа для измерения напряжения батареи 12В

Первым делом приведу дополненную схему эксперимента с делителем напряжения:

Принципиальная схема подключения делителя напряжения к PCF8591

Рис. 15. Принципиальная схема подключения делителя напряжения к PCF8591.

Теперь напишем программу, которая будет управлять яркостью свечения светодиода, который подключен к VOUT, в зависимости от входного напряжения на входе AIN2, к которому подключен резистивный делитель напряжения.

Создадим новый файл для программы и откроем его в редакторе:

Поместим в файл следующий код:

Запускаем программу командой:

После запуска программы в консоли будет обновляться и отображаться значение на входе AIN2.

Вывод выполняющейся программы в окне консоли

Рис. 16. Вывод выполняющейся программы в окне консоли.

Теперь изменяя напряжение на входе делителя можно наблюдать как будет меняться значение в консольном выводе программы, а также как это будет влиять на яркость свечения светодиода.

При разных напряжениях на входе AIN2 я получил следующие значения:

Напряжение, В Значение AIN2
1,1 20
2 35
4 67
5 83
6 100
8 131
9 147
10 164
10,3 168
11 180
12 198
13 214
14 228
14,5 238

Немного изменив программу можно заставить светодиод засвечиваться при достижении некоторого порога напряжения, например чтобы сигнализировать о разряде батареи до 10,5В.

Также для этого события можно запрограммировать и другие действия, например корректно завершить работу Raspberry Pi, которая питается от аккумулятора 12В через преобразователь DC-DC 5В и другие.

Краткая видео-демонстрация работы данного эксперимента:

Заключение

Работать с микросхемой (модулем) PCF8591P не составляет больших трудностей, ее можно применять в самых разных областях где нужен анализ и вывод значений аналогового сигнала со средней точностью.

При подключении нескольких PCF8591 на одну шину, как определить их адрес автоматически? Например нужно произвести замену или добавить новый датчик.

Например, готовый модуль PCF8591 содержит датчики температуры, влажности, освещения, таких моделей 10 расположение по разным комнатам.
И еще, расстояние кабеля от модуля до малины, как понимаю будет зависеть от подтягивающий сопротивления

К одной шине I2C можно подключить до восьми микросхем PCF8591. Данное число ограничено количеством возможных вариантов адресов, которые настраиваются подачей высокого или низкого уровня напряжения на пины 5, 6, 7 (A0, A1, A2).

Возможные комбинации подключения пинов 5, 6 и 7 (1-высокий уровень, 0-низкий уровень): 001, 011, 111, 110, 100, 000, 101, 010 (всего 8 комбинаций). Более подробная информация есть в даташие на микросхему PCF8591 (страницы 12-14).

В готовых модулях на основе микросхемы PCF8591, адрес устройства выставлен в одном и том же значении — выводы 5-7 подключены к минусу питания (смотрите схему на рисунке 4). Если отпаять вывод 5 (A0) и подключить его к плюсу питания, то модуль будет запрограммирован уже на другой адрес. Аналогично на смену адреса будут влиять подключения остальных двух выводов 6 (A1) и 7 (A2).

Адрес каждого сконфигурированного модуля лучше всего проверить экспериментально, с помощью утилиты i2cdetect, а потом уже прописать его в программном обеспечении и привязать к какому-то функционалу.

Шина I 2 C была спроектирована для внутрисхемной коммуникации между устройствами, зачастую длина линий передачи данных может варьироваться от нескольких сантиметров до метра или более. Данная шина не является помехоустойчивым интерфейсом для осуществления связи между устройствами на больших расстояниях.

Скорость и стабильность передачи данных по шине I 2 C будет изменяться в зависимости от длины проводников (SDL, SDA, GND) и их емкости, а также от влияния на них близко расположенных источников помех. Дополнительно нужно будет поэкспериментировать с сопротивлением подтягивающих резисторов.

Если скорость передачи данных по этой шине в вашей конструкции не критична (например нужно периодично "дергать" датчики температуры), то можно поэкспериментировать подключение на расстояния 50м и более.

Есть люди, которые пишут что соединяли по шине I 2 C устройства на расстоянии более 100 метров, используя для подключения кабель (витую пару) STP — это нужно проверять экспериментально и с учетом места где будет проложен кабель (учитывая влияние возможных источников помех в виде силовых кабелей и т.п.).

Также не помешает добавить дополнительные проверки правильности полученных данных в коде программы — например получать значение температуры 5-10 раз подряд с задержкой 100мс и потом высчитывать результирующее среднее значение.

Еще нашел одну интересную микросхему — P82B715, представляющую из себя такой себе буфер для возможности удлинения линий передачи данных SDA и SCL, соединяющих два устройства (нужно две такие микросхемы).


Источник: ph0en1x.net