Программирование, радиоэлектроника,
саморазвитие и частичка из моей жизни здесь...

Изучаем GPIO в Raspberry Pi, эксперимент со светодиодом и кнопкой

Познакомимся с портами общего назначения GPIO (General-purpose input/output) в Raspberry Pi, разберем простой пример с подключением светодиода и кнопки (переключателя) к портам GPIO, а также напишем простую программу на Python, которая будет управлять свечением (миганием) светодиода при помощи кнопки. Простые эксперименты с Raspberry Pi GPIO для начинающих.

Содержание:

  1. Что такое GPIO
  2. GPIO в Raspberry Pi для моделей A и B
  3. GPIO в Raspberry Pi для моделей A+, B+ и B2
  4. Распиновка разъемов GPIO
  5. Использование пинов GPIO и меры безопасности
  6. Уровни на пинах GPIO по умолчанию
  7. Светодиод и кнопка - правильное и неправильное подключение
  8. Расчет гасящего резистора для светодиода
  9. Схема эксперимента со светодиодом и кнопкой
  10. Модуль RPi.GPIO
  11. Программа для эксперимента со светодиодом и кнопкой
  12. Мониторинг состояния всех выводов GPIO
  13. Как управлять пинами GPIO на любом языке программирования
  14. Управление светодиодами активности и питания на плате малинки
  15. Модуль RPIO
  16. Заключение

Что такое GPIO

Первым делом давайте разберемся что такое GPIO и для чего оно нужно.

GPIO (General-purpose Input/Output) - это интерфейс, который содержит Входы (Input) и Выходы (Output) "общего назначения" (General Purpose), к которым можно подключать разнообразные исполнительные устройства, датчики, дисплеи, контроллеры, разные модули и периферию.

Как выглядит интерфейс GPIO? - это разъем, который размещен непосредственно на платке Raspberry Pi и который содержит набор из пинов:

  • В старых моделях (A и B) - 26 шт (+8шт отдельным разъемом);
  • В новых моделях (A+, B+ и B2) - 40 шт.

Внешний вид разъемов GPIO для разных моделей малинки изображен ниже.

GPIO в Raspberry Pi для моделей A и B

Raspberry Pi model B GPIO разъем и нумерация пинов

Рис. 1. Raspberry Pi model B GPIO разъем и нумерация пинов.

В версиях A и B разъем содержит 26 пинов (P1 header), 8 из которых являются общими портами ввода-вывода GPIO, а также пины для подключения интерфейсов I²C, SPI, UART и линии питания +5В, +3,3В, GND.

В самых ранних версиях малинки также можно встретить небольшой разъемчик с 8-ю пинами (P2 header) - это интерфейс отладки VideoCore JTAG, в последующих версиях он был исключен.

Еще можно заметить несколько не распаянных разъемов - это:

  • P3 (LAN9512 JTAG)
  • P5 (8 выводов - 4 GPIO, 5V, 3,3V, 2 GND)
  • P6 (для сброса BCM2835, Reset).

GPIO в Raspberry Pi для моделей A+, B+ и B2

Интерфейс GPIO в Raspberry Pi 2 и нумерация пинов

Рис. 2. Интерфейс GPIO в Raspberry Pi 2 и нумерация пинов.

В новых версиях платформы разъем GPIO уже содержит 40 пинов (2 ряда по 20 штук). Первые 26 пинов (по 13 в ряду) - такие же как и в более ранних версиях Raspberry Pi, а остальные 14 штук являются дополнительными:

  • GPIO (9шт);
  • GND(3шт);
  • 2 вывода для EEPROM.

Больше пинов - больше возможностей по расширению и применению малинки!

Распиновка разъемов GPIO

Для использования разъема GPIO необходимо знать точное назначение каждого из его пинов (контактов). Ниже приведены распиновки разъемов GPIO для разных моделей и разных версий платформы Raspberry Pi.

Raspberry Pi model A B - расположение пинов на разъеме GPIO

Рис. 3. Raspberry Pi model A B - расположение пинов на разъеме GPIO.

Важно заметить что у ревизий печатной платы "1.0" (сентябрь 2012 или раньше) и "2.0" расположение пинов немножко отличается:

  • Пин 3 = GPIO0, SDA0, I2C (v1.0)  |  GPIO2 (v2.0);
  • Пин 5 = GPIO1, SCL0, I2C (v1.0)  |  GPIO3 (v2.0);
  • Пин 13 = GPIO21 (v1.0)  |  GPIO27 (v2.0).

Это нужно учесть при проектировании и переделке устройств на платформах с разной ревизией печатных плат.

Распиновка разъема GPIO в Raspberry Pi 2

Рис. 4. Распиновка разъема GPIO в Raspberry Pi A+, B+, 2.

Использование пинов GPIO и меры безопасности

Прежде чем что-то подключать к пинам интерфейса GPIO очень важно разобраться какие напряжения можно подавать на установленные как "вход" (Input) пины и какие токи допустимы через пины, настроенные как "выход" (Output).

Пин GPIO в режиме "вход":

  • максимально допустимое напряжение равно +3.3В;
  • уровень логической единицы (1) получаем начиная примерно с напряжения +1.8В;
  • максимальный ток: всего лишь 0.5мА!

Пин GPIO в режиме "выход":

  • Получаемые уровни напряжений: 0В и +3.3В (не +5В, от которых питается малинка!);
  • Максимальный ток: 2 - 16мА (по умолчанию 8мА);
  • Максимальный суммарный ток нагрузки для всех задействованных пинов GPIO - 50мА!

Также важно помнить что:

  1. Внутренние буферы и ключи, которые подключены к пинам GPIO, НЕ защищены от перегрузки по напряжению и току;
  2. Пины питания с выходным напряжением +3.3В можно нагружать током не более 50мА;
  3. Пины с выходным напряжением 5В стараемся грузить током не более чем на 500мА (для Model A) и не более чем на 300мА (для Model B) - почему так, расскажу ниже.

Рекомендации по использованию пинов GPIO

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

Для чего это нужно? - чтобы обезопасить малинку от возможного повреждения (выгорания) электронных коммутаторов (ключей) и буферов внутри чипа.

Давайте посмотрим что получится если мы подключим к трем портам GPIO и общему для них выводу 3.3В три светодиода, через каждый из которых будет протекать ток 20мА (сверхъяркие светодиоды):

20мА * 3 = 60мА.

Ток 60мА уже является превышением рекомендуемого разработчиками максимально допустимого значения на пине +3.3В, а также небольшой перегрузкой для каждого из пинов GPIO (по 20мА на пин вместо 18мА).

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

Если к каждому из нескольких пинов GPIO мы подключим по светодиоду, то можно их общую точку подключить к земле (к GND). В таком случае светодиод будет светиться если на пине будет присутствовать высокий уровень (+3.3В).

Для ограничения протекаемого через светодиод тока до 10-15мА необходимо будет его подключить через токоограничительный резистор.

Хочу заметить что для отлично видимого свечения сверхъяркого светодиода достаточно всего лишь несколько миллиампер тока.

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

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

Необходимо с осторожностью отнестись к использованию линии питания +5В, допустимый ток не должен превышать 1А (без учета потребления самой платы, примерно 700мА). Получается что для питания разных модулей и периферии доступна нагрузочная способность примерно в 300мА.

Если какой-то модуль потребляет много тока, то лучше запитать его от отдельного источника со стабилизированным напряжением +5В.

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

Также стоит обратить внимание на количество устройств, подключенных к USB портам. Например USB CDMA модем может потреблять в пике примерно 200мА, а веб-камера Logitech - до 300мА.

Значение общего потребляемого малинкой (с подключенными модулями и периферией) тока может варьироваться в пределах от 250мА до 1А. Для старших моделей Raspberry Pi - еще больше.

Опасность статического электричества

На некоторой чувствительной электронике можно иногда встретить надпись наподобие "CAUTION - Static sensetive devices" (ПРЕДОСТЕРЕЖЕНИЕ - устройства, чувствительные к статическому электричеству).

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

Статическое электричество - это общее название процессов возникновения и накопления свободных зарядов на поверхностях диэлектриков (материалах, которые плохо проводят электрический ток).

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

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

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

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

Перед тем как приступать к работе с чувствительной электроникой (микросхемы, микроконтроллеры, КМОП-компоненты и т.д.) нужно убрать такой паразитный и не несущий пользы заряд. Для этого достаточно коснуться руками какого-то массивного металлического предмета.

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

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

Перед использованием убедитесь что в браслете действительно присутствует такой резистор! Для этого достаточно измерить значение сопротивления между контактами пластины и заземления с помощью мультиметра или мегаом-метра.

Пайка контактов

Перед пайкой модулей и плат желательно отключить их от разъема GPIO, будет неплохо если есть возможность выполнять монтаж паяльником на напряжение 36В (или ниже) с использованием понижающего трансформатора 220В - 36В и т.п.

Подведу небольшой итог по мерам безопасности:

  • Перед работой стоит убрать с себя статический заряд, а еще лучше использовать антистатический браслет;
  • Пайку электроники желательно выполнять с отключенным разъемом GPIO (чтобы не было прямого контакта "жало паяльника - пин");
  • Не перегружать пины питания +5В (макс. ток 300-500мА) и +3.3В (50мА), не закорачивать их напрямую с другими пинами;
  • Исключить протекание тока величиной более 8-15мА через пины GPIO;
  • Исключить попадание напряжения выше +3.3В на пины GPIO;
  • Подключать напрямую не более 3х светодиодов (по 2-15мА каждый) к Raspberry Pi;
  • Перед подачей питания на схему и малинку внимательно проверить правильность всех подключений.

Уровни на пинах GPIO по умолчанию

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

После того как Raspberry Pi включена и операционная система Linux загружена, на выводах GPIO установлен низкий уровень (0В), и так будет до тех пор, пока какая-то программа или скрипт не изменит состояние портов GPIO.

Эта информация взята из документации, также она подтверждается "прощупыванием" состояний пинов при помощи тестера (вольтметра).

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

И все бы здесь хорошо если бы не небольшое но... Суть его заключается в том, что начиная с момента подачи питания на платформу и до момента инициализации драйверов в ОС (в процессе загрузки), на произвольных пинах могут кратковременно присутствовать высокие уровни (напряжение +3.3В).

При проектировании подключаемых к GPIO электронных схем и блоков, этот момент желательно предусматривать!

Для защиты портов GPIO, подключение пинов к схеме желательно выполнять через резисторы с сопротивлением 680 Ом - 2К и даже больше. Схема подключений должна быть построена так, чтобы с этими резисторами все работало уверенно и надежно.

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

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

Более детальную информации о том как работает GPIO на платформе Raspberry Pi можно узнать из документации к процессорам Broadcom (смотри ссылки в конце статьи).

Светодиод и кнопка - правильное и неправильное подключение

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

Иногда встречаются схемы включения, которые даже оказавшись работоспособными могут нести опасность для платформы Raspberry Pi. Дальше я покажу несколько примеров и кратко расскажу почему так.

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

Правильное и неправильное подключение светодиода к Raspberry Pi

Рис. 5. Правильное и неправильное подключение светодиода к Raspberry Pi.

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

При прямом подключении без резистора, на светодиод поступит напряжение +3.3В, что есть больше нормы для светодиодов (2-3В). Прямое напряжение такой величины станет причиной резкого возрастания тока в цепи и может с легкостью достигать 50-100мА и даже больше!

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

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

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

Правильное и неправильное (опасное) подключение кнопки или переключателя к Raspberry Pi

Рис. 6. Правильное и неправильное (опасное) подключение кнопки или переключателя к Raspberry Pi.

Дело в том, что после подачи питания на Raspberry Pi и ее процессор, в процессе загрузки ОС, кратковременные состояния напряжений на пинах GPIO могут быть хаотичными: высокий (+3.3V) или низкий уровень (0V). Об этом уже упоминалось выше в статье.

При прямом подключении кнопки к GPIO и GND (как на перечеркнутом рисунке) есть вероятность подпалить используемый выход порта (внутренние микроскопические транзисторы, которые управляют уровнем напряжения на пине).

После подачи питания на процессор (инициализация малинки) или при неверной программной установке режимов порта (сконфигурирован как OUTPUT) на используемый пин может пойти напряжение +3.3V.

В свою очередь, при замыкании кнопки или с замкнутыми контактами переключателя, это вызовет короткое замыкание пина порта на землю GND.

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

При использовании кнопки с фиксаций или переключателя опасность возрастает в разы, так как в процессе перезагрузок ОС малинки используемый в таком случае пин может оказать постоянно подключенным к GND.

В схеме с резисторами мы получаем следующую ситуацию:

  1. Пока кнопка SW1 не нажата то через резисторы R1 и R2 на входе порта установлен высокий уровень (+3.3В);
  2. При замыкании кнопки SW1 через резистор R1 и кнопку пойдет ток, равный I=U/R=3.3В/10000Ом=0.33мА, а через ограничивающий резистор R2 и кнопку на входе порта будет установлен низкий уровень - 0В;
  3. Если пин порта выставлен неверно (в режиме выхода с высоким уровнем +3.3В) - через цепочку R1-R2 не будет идти никакой ток (3.3В=3.3В), а при нажатии кнопки через R2 и SW1 потечет ток равный R=3.3В/750Ом=4.4мА, что является безопасным значением для порта в режиме выхода и никак не повредит схему и сам порт GPIO.

Резистор R1 можно установить на сопротивление 10 КОм - 20 КОм, а для резистора R2 на 600 Ом - 2 КОм, все должно уверенно работать.

Плюсы такого включения:

  1. БЕЗОПАСНОСТЬ - при любых экспериментах, в любой, пусть даже ошибочной конфигурации пина GPIO, порту ничего не грозит;
  2. НАДЕЖНОСТЬ - такая схема обеспечивает надежную установку каждого из состояний (высокий и низкий уровни) в любой момент работы малинки и ее программ (мы не используем управляемые программно, внутренние подтягивающие резисторы).

Минусы:

  1. НЕБОЛЬШАЯ ИЗБЫТОЧНОСТЬ - придется "разориться" на 2 маломощных резистора для каждой из кнопок/переключателей.

В зарубежных книгах и на зарубежных сайтах я не раз встречал примеры подключения кнопок к малинке как на перечеркнутом рисунке #6.

Например такое можно увидеть в книге "Simon Monk - Raspberry Pi Cookbook (O'Reilly)". В другой книге "Tim Cox - Raspberry Pi Cookbook for Python Programmers (Packt Publishing)" можно видеть аналогичную схему включения кнопки, только уже через резистор (ура)!

Мое мнение:

Подключение кнопки как на перечеркнутом рисунке #6 - несет опасность, лучше так не делать!

Не стоит жалеть резисторов!

Лучше уж установить последовательно к каждому пину по одному резистору, чем потом, в случае ошибки, поплатиться ценой всей платы Raspberry Pi.

В статье про RPi.GPIO я рассказал как использовать внутренние подтягивающие резисторы (Pull-Up, Pull-Down resistors). Там приведено описание и схема включения кнопки с одним резистором (рис. 2).

Кстати, такой метод подключения может понадобится если надумаете задействовать под кнопки порты GPIO2 и GPIO3. Схема, показанная на рисунке 6, в этом случае не сработает, поскольку на плате Raspberry Pi уже распаяны резисторы, подтягивающие выводы пинов GPIO2 и GPIO3 к линии +3.3V.

Указанные резисторы предусмотрены для режима, в котором оба порта используются для шины I2C как линии SDA (Data) и SCL (Clock).

Ниже привожу схему подключения кнопки к GPIO3 с учетом внутреннего резистора сопротивлением 1.8К на плате Raspberry Pi. В данной реализации программная активация подтягивающих резисторов уже не понадобится.

Схема подключения кнопки к пину GPIO3 в Raspberry Pi

Рис. 7. Схема подключения кнопки к пину GPIO3 в Raspberry Pi.

Расчет гасящего резистора для светодиода

Как правило, для экспериментов со светодиодами будет достаточно гасящего резистора на 270-600 Ом. При большем сопротивлении светодиод будет светиться немного тусклее (ток через него меньше), а при меньшем сопротивлении - ярче (ток возрастет).

Для более точного расчета сопротивления гасящего резистора (при питании от линии 3.3В) используем формулу:

R = (3.3В - Uд) / Iд

где:

  • R - сопротивление гасящего резистора;
  • - рабочее напряжение светодиода;
  • - рабочий ток светодиода.

Приведу здесь типовые значения напряжения для светодиодов разного цвета:

  • красные - 1,8...2В;
  • желтые и зеленые - 2...2.4В;
  • белые и синие (яркие) - 3...3.5В.

Рабочий ток светодиодов, в зависимости от их типа, может колебаться в пределах 10-25мА. Для более точных расчетов лучше не полениться и узнать параметры конкретного светодиода по справочнику.

В нашем случае, для экспериментов, ток величиной 8-15мА будет достаточен и безопасен.

К примеру возьмем отечественный светодиод АЛ307 красного цвета и рассчитаем для него гасящий резистор при токе 10мА:

R = (3,3В - 2В) / 0.01А = 130 Ом.

При сопротивлении гасящего резистора 130 Ом и питании напряжением 3.3В светодиод будет светить достаточно ярко. Можете поэкспериментировать с сопротивлением резистора, скорее всего даже при значении 300 Ом яркости свечения будет вполне достаточно для экспериментов с GPIO в Raspberry Pi и нам не придется волноваться о перегрузке порта.

Схема эксперимента со светодиодом и кнопкой

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

Схема безопасного подключения кнопки и светодиода к Raspberry Pi GPIO

Рис. 8. Схема безопасного подключения кнопки и светодиода к Raspberry Pi GPIO.

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

Схема подключения переключателя и светодиода на макетной панели к малинке

Рис. 9. Схема подключения переключателя и светодиода к малинке используя макетницу.

Примечание: обе приведенные выше схемки рисовались в замечательной свободной программе под именем "Fritzing" для операционных систем Linux, Windows, Mac OS X.

Скачать программу можно на сайте fritzing.org.

Тем, кто использует Debian GNU Linux, Ubuntu, Linux Mint для установки программы достаточно выполнить команду установки из консоли:

sudo apt-get install fritzing

Проект принципиальной схемы и ее разводки на панели для Fritzing:  ZIP архив (7,4 КБ).

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

Макет эксперимента со светодиодом, кнопкой и Raspberry Pi GPIO

Рис. 10. Макет эксперимента со светодиодом, кнопкой и Raspberry Pi GPIO.

Для удобного удаленного программирования и управления к малинке подключен беспроводный Wi-Fi адаптер. О том как подключить raspberry Pi и настроить беспроводную сеть было подробно рассказано в предыдущей статье.

Сама малинка у меня запитана через понижающий стабилизатор напряжения (на микросхеме LM2596S), а в качестве основного источника питания используется аккумулятор на 6В и емкостью 6А*Ч.

Можно все запитать и от сетевого блока питания на +5В с током до 2А, но у меня уже был собран тестовый стенд с питанием от такого аккумулятора, вот я его и применил.

Модуль RPi.GPIO

Для написания программы мы будем использовать модуль "RPi.GPIO", который содержит достаточно много разных возможностей по управлению GPIO в Raspberry Pi.

В операционной системе Raspberry Pi OS (Raspbian) этот модуль установлен по умолчанию. Думаю чтьо не помешает его обновить до последней доступной и актуальной версии, для этого выполним следующие команды в консоли малинки:

sudo apt-get update
sudo apt-get install python-rpi.gpio

Подробное описание модуля "RPi.GPIO" с примерами приведено в статье "RPi.GPIO - работа с входами, выходами и прерываниями в Raspberry Pi, простые примеры".

Программа для эксперимента со светодиодом и кнопкой

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

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

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

Из простейших задач, которые приходят на ум - заставить светодиод (LED) светиться после нажатия кнопки. Но согласитесь, это как-то не очень интересно.

Поэтому мы реализуем программку, которая при запуске заставит светодиод мерцать с частотой 2 раза в секунду (2 Гц), а при нажатии на кнопку - частота мерцания будет увеличена примерно в 5 раз (10Гц) - думаю что такой пример более интеерсный чем просто нажать кнопку и засветить LED.

Для выполнения программы файл с ее кодом (скрипт) должен размещаться на файловой системе в Raspberry Pi.

Если малинка подключена к монитору и клавиатуре, то вы скорее всего работаете в графической среде Raspberry Pi OS (Raspbian). Для создания и редакторивания файла-скрипта вам понадобится запустить программу "Терминал" (Terminal).

Также, если на малинке запущен SSH-сервер, к ней можно подключиться удаленно (по сети) используя любой из SSH-клиентов (Console, Konsole, Putty) на вашем рабочем ПК.

В нашей программе мы будем использовать модуль GPIO из пакета RPi (RPi.GPIO).

Для создания файла-программы под именем "led_key_test.py" в директории "/home/pi" и его последующего открытия для редактирования в редакторе (nano) нужно выполнить простую команду:

nano /home/pi/led_key_test.py

Откроется тектовый редактор, куда необходимо скопировать приведенный ниже листинг программы:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Подключаем необходимые библиотеки (для задержки по времени и GPIO)
import time
import RPi.GPIO as GPIO

# Установим номера пинов GPIO, с которыми будем работать
LED = 4
KEY = 17

# Делаем сброс состояний портов (все конфигурируются на вход - INPUT)
GPIO.cleanup()
# Режим нумерации пинов - по названию (не по порядковому номеру на разъеме)
GPIO.setmode(GPIO.BCM)
# Сконфигурируем пин LED на вывод (OUTPUT)
GPIO.setup(LED, GPIO.OUT)
# Установим низкий уровень (0) на пине LED
GPIO.output(LED, GPIO.LOW)
# Сконфигурируем пин KEY на ввод (INPUT)
GPIO.setup(KEY, GPIO.IN)
# Выведем на экран текст-приветствие
print 'Hello! Blink...blink...'

# Проверка на прерывание программы с клавиатуры (CTRL+C)
try:
    # Вечный цикл
    while True:
        # Если кнопка нажата (на пине KEY низкий уровень 0V)
        if GPIO.input(KEY) == False:
            # Устанавливаем задержку 0,1 сек. и выводим сообщение
            timeout = 0.1
            print 'Key pressed.'
        else:
            # в противном случае задержка - 0,5 сек.
            timeout = 0.5
        # Засветим светодиод, подключенный к пину LED
        GPIO.output(LED, GPIO.HIGH)
        # Подождем (выполним заданную выше задержку)
        time.sleep(timeout)
        # Погасим светодиод, подключенный к пину LED
        GPIO.output(LED, GPIO.LOW)
        time.sleep(timeout)
# Если комбинация клавиш CTRL+C была нажата - сброс пинов и завершение
except KeyboardInterrupt:
    GPIO.cleanup()

Важно: в программе на Python необходимо соблюдать все отступы - каждый по 4 пробела. 

Например, после "else" строчка начинается с 3х отступов по 4 пробела (12 пробелов), а перед "while True:" - один отступ (4 пробела). Это необходимо для правильного структурирования и работы программы!

Чтобы сохранить файл и выйти из редактора "nano" нажимаем комбинацию клавиш "CTRL+X", а на вопрос о сохранении файла жмем клавишу "y" и подтверждаем при помощи "ENTER".

Теперь сделаем наш скрипт исполняемым и можем запустить нашу программу, выполним команды:

chmod +x /home/pi/led_key_test.py
/home/pi/led_key_test.py

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

Raspberry Pi GPIO тестовая программа для светодиода и кнопки

Рис. 11. Raspberry Pi GPIO тестовая программа для светодиода и кнопки, результат работы.

Небольшое видео, демонстрирующее работу программы (18 секунд):

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

Чтобы прекратить работу программы достаточно нажать комбинацию клавиш "CTRL+C" (Break, прерывание).

Мониторинг состояния всех выводов GPIO

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

gpio readall

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

 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 0 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 1 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 1 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 1 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 1 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 1 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 1 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+

Чтобы каждый раз не запускать команду в ожидании наблюдаемых изменений, можно применить утилиту "watch", которая будет обновлять вывод команды "gpio readall" в консоли с интервалом в 1 секунду (параметр "-n 1"):

watch -n 1 "gpio readall"

Как управлять пинами GPIO на любом языке программирования

Интерфейс GPIO, как и другие устройства в Линукс, представлен в псевдо-файловой системы SysFS, состоящей из директорий и файлов-устройств.

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

SysFS (System File System) - это виртуальная файловая система, которая отображает состояние и настройки ядра Linux.

Давайте проведем краткий эксперимент: засветим и погасим светодиод, который подключен через гасящий резистор к пину под номером 15 (GPIO 22).

Для упрощения запуска следующих команд понадобятся права суперпользователя, поэтому перейдем в режим "root", выполнив команду:

sudo -i

Итак, укажем драйверу что мы будем работать с пином GPIO22 - зарезервируем порт на время работы (другие приложения не смогут им пользоваться, пока мы его не освободим).

Делается это при помощи команды:

echo 22 > /sys/class/gpio/export

При помощи следующей команды смотрим создался ли файл для нашего GPIO22:

ls /sys/class/gpio/

Увидим примерно вот такой список:

export  gpio22  gpiochip0  unexport

Наш пин готов к работе - появилась папка с названием gpio22. Также можем посмотреть какие файлы в папке создало ядро Linux для нашего виртуального пина (к ним можно будет обращаться - писать и считывать информацию для этого порта):

ls /sys/class/gpio/gpio22

На выходе команды получим:

active_low  device  direction  edge  subsystem  uevent  value

А теперь установим при помощи следующей команды направление (direction) пина GPIO22 на вывод (OUTPUT) и сразу же посмотрим второй командой все ли установилось как нужно:

echo out > /sys/class/gpio/gpio22/direction
cat /sys/class/gpio/gpio22/direction

В результате на экране должно появиться слово "out", что свидетельствует о том что все установлено верно. Теперь осталось лишь подать высокий уровень на наш пин чтобы засветить светодиод.

Сделаем это выводом числа 1 в файл /sys/class/gpio/gpio22/value, используем вот такую команду:

echo 1 > /sys/class/gpio/gpio22/value

Светодиод должен зажечься.

Прочитать состояние пина можно при помощи команды:

cat /sys/class/gpio/gpio22/value

А теперь погасим светодиод  - выполним команду:

echo 0 > /sys/class/gpio/gpio22/value

Ну и напоследок, после всей проделанной полезной работы выполним освобождение пина GPIO22, заставим драйвер разрегистрировать его:

echo 22 > /sys/class/gpio/unexport

Вот таким образом можно общаться с GPIO при помощи обычных запросов к виртуальным текстовым файлам, можно писать скрипты на любых языках (C, Java, Sh, Bash...) и под любые задачи.

Чтобы выйти из режима "root" и вернуться к строке обычного пользователя запустим команду:

exit

Важно помнить что после резервирования пина (export) и выполнения работ связанных с ним, его нужно разрезервировать (unexport), иначе он останется занят и другие программы и скрипты не смогут получить к нему доступ!

Управление светодиодами активности и питания на плате малинки

Небольшое продолжение темы о светодиодах и Raspberry Pi... :)

Индикаторами активности и питания (зеленый и красный светодиоды на плате), расположенными на плате Raspberry Pi, также можно управлять.

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

Делается это через изменение связанных со светодиодом (как системным устройством) файлов в дереве виртуальной файловой системы SysFS, о которой было сказано в предыдущем разделе.

Вот пути к директориям со специальными файлами и папками, которые "своим содержимым конфигурируют и управляют" этими светодиодами:

  • /sys/class/leds/led0/ - зеленый светодиод, индикатор активности;
  • /sys/class/leds/led1/ - красный светодиод, индикатор питания.

В каждой из этих папок есть по два специальных файла:

  1. brightness - управление состоянием свечения светодиода: 1 - светится, 0 - потушен
  2. trigger - строка специальных параметров, названий зарезервированных событий, которые будет индицировать светодиод (своим миганием).

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

  1. Отвязать все связанные с этим светодиодом события в файле "trigger";
  2. Записать в файл "brightness" число 0. А если понадорбится его снова зажечь - то число 255.

Давайте посмотрим на текущее содержимое файла "trigger" для каждого из устройств-индикаторов:

cat /sys/class/leds/led0/trigger
cat /sys/class/leds/led1/trigger

В консоль будет выведено примерно следующее:

# Для LED0
none rc-feedback kbd-scrolllock kbd-numlock kbd-capslock 
kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock
 kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer 
oneshot heartbeat backlight gpio cpu cpu0 cpu1 cpu2 cpu3 default-on
 input panic actpwr mmc1 [mmc0] rfkill-any rfkill-none rfkill0 rfkill1

# Для LED1
none rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock 
kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock 
kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer oneshot heartbeat 
backlight gpio cpu cpu0 cpu1 cpu2 cpu3 default-on [input] panic actpwr
 mmc1 mmc0 rfkill-any rfkill-none rfkill0 rfkill1

Это список событий и активностей, к которым можно привязать индикатор. В каждом из случаев, текущая привязка взята в квадратные скобки:

  • Для LED0 - [mmc0] индикация обмена данных с первой SD-картой;
  • Для LED1 - [input] индикация опасного понижения напряжения питания (under-voltage detection).

Вот описания еще нескольких интересных событий, к которым можно автоматически привязать данные светодиоды:

  • cpu0...cpuN - индикация состояния (активно/неактивно) ядра процессора с указанным номером. cpu0 это первое ядро, cpu1 - второе и т.д.;
  • timer - таймер, индикатор начнет мигать каждую секунду;
  • heartbeat - пульсация по типу сердцебиения;
  • kbd-numlock, kbd-scrolllock - индикация состояний режимов "Num Lock" и "Scroll Lock" на подключенной клавиатуре;
  • none - отвязка от каких-либо событий.

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

Давайте заставим светодиод питания (LED1) мигать каждую секунду, привяжем его к событию "timer":

sudo sh -c 'echo timer > /sys/class/leds/led1/trigger'

А теперь ассоциируем LED1 с событием "none", чтобы его свечением можно было уверенно управлять через файл "brightness":

sudo sh -c 'echo none > /sys/class/leds/led1/trigger'

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

sudo sh -c 'echo 255 > /sys/class/leds/led1/brightness'
sudo sh -c 'echo 0 > /sys/class/leds/led1/brightness'

Расскажу кратко что это за конструкции из команд и как они работают.

Команда "sudo sh -c 'command' " вызывает оболочку командного интерпретатора "sh" с правами суперпользователя (root), переданная далее в кавычках команда или связка из команд будут автоматически выполнены с правами root.

Теперь о связке инструкций в кавычках. Команда "echo 255" выводит на экран (стандартное устройство вывода) число 255. Символ ">" служит для записи полученного ранее из стандартного вывода потока в указанный далее файл, в данном случае это "/sys/class/leds/led1/brightness".

Для чего нужны такие сложности? - возможно спросите вы...

Попробуйте выполнить следующие команды под обычным пользователем:

echo none > /sys/class/leds/led1/trigger
sudo echo none > /sys/class/leds/led1/trigger

Вы получите сообщение о запрете доступа:

-bash: /sys/class/leds/led1/trigger: Permission denied

Казалось бы, с первой командой понятно, ведь там 'echo' запущен с правами обычного пользователя, а вот почему же вторая команда с 'sudo' не сработала? - дело в том, что операция записи в файл с помощью инструкции ">" также является командой, которой нужны разрешения на запись в указанный файл.

Вот поэтому хитрость с "sudo sh -c 'command' " нас и выручила.

Еще один вариант решения задачи - использовать конвеер перенаправления ввода-вывода "|" и команду "tee", которая умеет писать переданный ей поток в файлы:

echo 255 | sudo tee /sys/class/leds/led1/brightness
echo 0 | sudo tee /sys/class/leds/led1/brightness

Все эти команды можно выполнять прямо из-под 'root' и без 'sudo', как и в предыдущем разделе. Но я не рекомендую применять такую практику постоянно, поскольку из-за невнимательности или ошибки в коде можно повредить важные данные и системные файлы.

А вот как можно заставить светодиод питания быстро мигать, используя скрипт, написанный на Python.

Создадим файл скрипта:

nano power_led_blinking_test.py

Поместим в него код:

# Raspberry Pi power-led blinking program.
# https://ph0en1x.net/

from time import sleep

# Функция для записи данных в указанный файл.
def write_to_file(data='', path=''):
    with open(path, 'w') as f:
        f.write(data)

# Отвязка LED1 от событий в Raspberry Pi.
write_to_file('none', '/sys/class/leds/led1/trigger')

# Вечный цикл, зажигаем и гасим LED1.
while True:
    write_to_file('255', '/sys/class/leds/led1/brightness')
    sleep(0.1)
    write_to_file('0', '/sys/class/leds/led1/brightness')
    sleep(0.1)

Запускать нужно с правами суперпользователя, например вот так:

sudo python3 power_led_blinking_test.py

Чтобы прервать работу скрипта, нажмите комбинацию клавиш CTRL+C.

Запуская от имени суперпользователя (root) сценарии, написанные на языке Python будьте предельно внимательны и осторожны. Все запускаемые в скрипте операции получат в системе неограниченные права и полный доступ!

Модуль RPIO

В приведенной выше экспериментальной программе мы использовали модуль GPIO из пакета RPi. Существует еще один интересный модуль, заслуживающий внимания - это RPIO.

RPIO - это модуль с дополнительными возможностями для работы с GPIO Raspberry Pi. Он содержит весь функционал пакета GPIO(RPi) и некоторые дополнительные фишки.

Также, данный модуль содержит две полезные и удобные консольные утилиты:

  1. rpio-curses  - удобный консольный графический интерфейс для мониторинга и установки состояний пинов;
  2. rpio - консольная утилита для установки состояний пинов, мониторинга состояний пинов и их режимов, а также для получения другой полезной информации.

Заключение

Надеюсь было не скучно и информация, которую я привел в данной статье, будет полезна для ваших будущих проектов и экспериментов с платформой Raspberry Pi.

Что можно сделать после светодиода и кнопки? - можно подключить три светодиода и сделать небольшой "бегущий огонь" (зажигать светдиоды по очереди).

Также вместо светодиода можно подключить ключевой транзистор и малогабаритное электромагнитное реле - для включения и выключения различных устройств с питанием от +12В или даже ~220В.

Количество вариантов ограничивается только вашей фантазией и желанием.

Полезные источники:

5 39966 Железо
Комментарии к публикации (43):
crazyfrogpvl #1crazyfrogpvl
03 Август 2016 14:19

А можно ли на один GPIO подключить несколько кнопок задав для каждой кнопки через резисторы разный ток?

0
ph0en1x #2ph0en1x
04 Август 2016 15:45

У Raspberry Pi нет встроенного Аналогово Цифрового Преобразователя (АЦП, ADC), который подключен к GPIO. Поэтому ответ на ваш вопрос - НЕТ.

Зато у малинки есть много других цифровых интерфейсов (SPI, I2C, UART) к которым можно подключить множество различных кнопок и устройств, используя при этом парочку пинов GPIO и какую-то небольшую схему для связки с интерфейсом.

На выводах GPIO может быть только логический 0 (0В) или 1 (3,3В), чередуя эти сигналы и с некоторой задержкой по времени можно кодировать и принимать/передавать различную информацию.

К малинке можно подключить АЦП, к примеру на микросхеме PCF8591 - интерфейс i2C, микросхема имеет 4 аналоговых входа и 1 аналоговый выход. Здесь уже можно подключить десяток кнопок через резисторы, переменный резистор, фото-резистор, термо-резистор, индикатор уровня сигнала на выход, схему плавного управления мощностью нагревателя и другие источники аналогового сигнала и все это можно будет читать и управлять используя 2 пина шины I2C.

Специально для подключения множества кнопок/светодиодов/ключей есть микросхема-расширитель ввода-вывода с интерфейсом I2C - PCF8574(PCF8575). Используя ее можно подключить к Raspberry Pi цифровую клавиатуру, матрицу из светодиодов и т.п.

Всего суммарно к пинам шины I2C можно подключить до 127 устройств, которые умеют работать с данным интерфейсом!

+2
Алексей #3Алексей
02 Ноябрь 2017 20:13

Добрый день! Подскажите, как по Вашей схеме подключить вторую кнопку на другой GPIO разъём?

0
ph0en1x #4ph0en1x
02 Ноябрь 2017 23:34

Доброй ночи. Все дополнительные кнопки подключаются по такой же схеме - с двумя резисторами подключенными к линиям GND и 3.3V.
Вот схема подключения трех кнопок к трем GPIO-пинам в Raspberry Pi:
/uploads/Image/comments/raspberry-pi-3-switches-connection-gpio.png
Сопротивления резисторов здесь оптимальные: 1кОм и 20кОм.

+2
Виктор #5Виктор
11 Декабрь 2017 18:21

А можно ли с помощью консольных команд и записью в файл управлять не только отдельными выводами, но и, например, SPI?

0
ph0en1x #6ph0en1x
11 Декабрь 2017 20:35

Виктор, можно.
Первым делом нужно включить поддержку шины SPI (по умолчанию отключена), сделать это можно одним из способов:

  1. через конфигуратор, в который можно попасть запустив команду "raspi-config";
  2. отредактировав файл "/boot/config.txt", раскомментировав строку "dtparam=spi=on".

После перезагрузки малинки, шина SPI будет доступна через файл "/dev/spidev0.0".
Пример консольной команды, которая выполнит запись сочетания цифр "123" в шину SPI:

echo -ne "\x01\x02\x03" > /dev/spidev0.0

Эту и много другой полезной информации о данной шине в Raspberry Pi можно получить из следующих ресурсов:

  1. Официальная документации по SPI
  2. RPi SPI - eLinux.org
  3. Serial Peripheral Interface Bus (Wikipedia)
0
Игорь #7Игорь
22 Февраль 2018 13:48

Доброго времени суток!
Подскажите, если подключить мембранную клавиатуру между GPIO не подключая через +3,3 и GND, что тагда произойдет. В примере, как на ардуино пин 2, 3 кнопка 1; пин 4,3 кнопка 2; пин 5,3 кнопка 3 и т.д.

0
ph0en1x #8ph0en1x
22 Февраль 2018 15:22

Здравствуйте!

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

Например, между двумя GPIO (порт 1 и 2) подключена кнопка, порт 1 установлен на чтение, а 2 - на вывод, установив 3,3В на порте 2 считываем значение на порте 1 и проверяем нажата ли кнопка, все работает хорошо.

Каким образом можно подпалить порты:

  1. при включении RaspberryPi, на выводах GPIO может кратковременно появиться логический 0 (0В) или 1 (3,3В). Для приведенного выше примера: на порте 1 может появиться 0В, а на порте 2 - 3,3В, в этот момент кнопка нажата - порты могут быть повреждены;
  2. не верно выставлена конфигурация портов при разработке и экспериментах - порт 1 ошибочно настроили на вывод и там низкий уровень (0В), порт 2 настроен на вывод и там высокий уровень (3,3В), нажали на кнопку и получили замыкание.

Чтобы избежать подобного сценария подключайте все выводы мембранной клавиатуры к GPIO через резисторы на 620-1200 Ом.

+1
Игорь #9Игорь
22 Февраль 2018 17:58

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

0
ph0en1x #10ph0en1x
22 Февраль 2018 20:06

По каждой из линий добавляем по резистору на 620 Ом, при подключении клавиатуры 4x4 понадобится 8 пинов GPIO и соответственно 8 резисторов.

Для подключения к Raspberry Pi клавиатуры 4x4 более целесообразно использовать специальную микросхему PCF8574A. Подключение выполняется через шину I2C, для этого используются два пина GPIO (SDA, SCL) и GND.

Подключение клавиатуры к PCF8574A выполняется также через резисторы:
/uploads/Image/comments/i2c-pcf8574a-keyboard-connection.png

В прошлых статьях я рассказывал как работать с шиной I2C.

0
Игорь #11Игорь
22 Февраль 2018 20:27

Спасибо, Вам большое за помощь!
А у Вас есть статья как создать меню на дисплее lcd 1602 и нескольких кнопок на raspberry pi 3?

+2
ph0en1x #12ph0en1x
22 Февраль 2018 21:47

Дисплей 1602 пока что не использовал, для большинства задач использую OLED дисплеи, подключаемые по шине I2C.

0
Harly #13Harly
04 Апрель 2018 09:09

Доброго дня!
Я только знакомлюсь с распберри, моя ещё едет) но возник вопрос: можно прикрутить к "малинке" физ кнопку? Хочу использовать её без монитора (настроить один раз и все) и вкл - выкл: либо реле, либо кнопкой; не могу найти информацию как сделать это безболезненно для "малинки". В идеале: поставить фотореле(5v), и при изменении освещения реле командует включится-"малинке", а при отключении питания реле - "малинка" выключалась бы. Извините за возможно путанный текст. С ув. Дмитрий

0
ph0en1x #14ph0en1x
06 Апрель 2018 16:55

Здравствуйте!

Перед выключением питания малинки нужно выполнить корректное завершение работы операционной системы Raspbian, на основе которой работает Raspberry Pi. Нужно как-то подать системе сигнал о том, что пора "завершать работу" - это можно сделать с помощью кнопки, подключенной к одному из свободных каналов GPIO.

Я описал как это сделать вот в этой статье: Безопасное завершение работы Raspbian с помощью кнопки, подключенной к Raspberry Pi

0
Jivktov #15Jivktov
25 Апрель 2018 20:50

Здравствуйте!
Не посоветуете, как лучше организовать снятие показаний со счетчиков воды с помощью Raspberry?

0
ph0en1x #16ph0en1x
26 Апрель 2018 12:19

Здравствуйте!

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

Над счетчиком устанавливается веб камера, подключенная к Raspberry Pi через USB. Для освещения табла счетчика к одному или нескольким пинам GPIO подключаются светодиоды.

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

Распознавание картинки программным способом можно попробовать реализовать на Python и OpenCV. На подобную тему в интернете есть не мало статей, например - Recognizing digits with OpenCV and Python. Мощности последней версии Raspberry Pi должно хватить для данной цели.

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

0
Jivktov #17Jivktov
26 Апрель 2018 13:28

Спасибо! На самом деле, я имел в виду более простой вариант, связанный с темой данной статьи: подключение к портам GPIO счетчика воды с аналоговым интерфейсом вывода данных (геркон)

+1
ph0en1x #18ph0en1x
26 Апрель 2018 15:09

В случае с герконом (герметизированные контакты), контакты которого замыкаются если приблизить к нему магнит, его можно подключить к одному из пинов GPIO и программным путем считывать количество импульсов (замыканий-размыканий). Геркон с контактами внутри - это в принципе та же кнопка, здесь придется позаботиться о подавлении такого явления как "дребезг контактов".

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

Еще один из вариантов - использование внешней схемы со счетчиком, которая будет связываться с малинкой и передавать ей свои данные. Тут может подойти модуль PCF8583 RTC - это часы реального времени с батарейкой, которые можно перестроить для работы в режиме счетчика (нужно переключить один джампер). Для связи с Raspberry Pi здесь будет использоваться шина I2C. Также плюс этого варианта в том, что счетчик продолжит считать импульсы даже при отсутствии питания (например пропал свет), его работу будет поддерживать встроенная батарейка на +3В.

+1
Jivktov #19Jivktov
27 Апрель 2018 15:29

Спасибо!

+1
SpV #20SpV
13 Июнь 2018 12:31

Доброго дня, а для тумблера вместо кнопки данная схема подключения актуальна?

0
ph0en1x #21ph0en1x
13 Июнь 2018 16:02

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

0
Петруха #22Петруха
01 Ноябрь 2018 21:30

Статья интересная, и все объясняете доходчиво. За это отдельное благодарность!
В распиновке прописаны какие контакты использовать под звук, но не расписаны как именно их подключать к усилителю, и как ему прописать, чтоб он выдавал в них звук, и в каком виде он его будет выдавать. Если не сложно можете показать схемой.

0
ph0en1x #23ph0en1x
02 Ноябрь 2018 12:11

Здравствуйте, Петр.

Все выводы GPIO в Raspberry Pi - цифровые (на выходе можно воспринимать или генерировать логические 1 или 0), там нет АЦП/ЦАП. Можно конечно подключить вход усилителя низкой частоты или пьезо-пищалку (как в статье про самодельный роутер) к какому-то из пинов GPIO и программно генерировать звуковые сигналы (чередование разной длительности и тональности), но это будет восприниматься на слух как рингтоны из старых мобильных телефонов.

Для воспроизведения двухканального (стерео) аналогового сигнала у малинки есть свой модуль воспроизведения звука (ЦАП). Выход этого модуля подключен к HDMI и к разъему под mini-jack 3,5mm. К этому разъему можно подключать наушники, аудио-усилитель мощности и различные устройства для обработки звукового сигнала.

0
AlexHate #24AlexHate
06 Март 2019 10:55

- Raspberry Pi (питание по microusb)
- MCP3208 или MCP3201 (АЦП)
- Цепь: светодиод + выключатель + батарея 9 вольт

ЗАДАЧА: Cкриптом на Python проверять есть питание на светодиоде или нет.
ПРОБЛЕМА: Как подключить цепь (светодиод + выключатель + батарея 9 вольт) к АЦП MCP3208?

0
ph0en1x #25ph0en1x
11 Март 2019 13:12

Здравствуйте. Странная постановка задачи, для ее решения не нужен АЦП, достаточно просчитанного делителя напряжения на резисторах и одного из выводов GPIO.

Указанная вами цепь содержит ошибку - в ней нет гасящего резистора, без него светодиод при питании от 9В просто сгорит.

Максимально допустимые напряжения для MCP3208 (данные из datasheet):

  • питание Vdd - 7.0V;
  • на аналоговых входах от -0,6V до (напряжение питания + 0.6V).

Если на аналоговый вход MCP3208 подать 9В то микросхема скорее всего выйдет из строя.

Допустим что MCP3208 питается от +5V (напряжение на входах максимум 5+0,6В), светодиод на 2,5В и ток 15мА (0,015А). Расчет гасящего резистора для светодиода при питании от 9V, по закону Ома: (9V-2,5V)/0,015А=433 Ом. Собираем резистивный делитель напряжения чтобы получить из 9В примерно 2В, им проверяем напряжение на цепочке "светодиод+резистор", подключаем к АЦП.
Батарейка 9В + светодиод - проверяем светится ли светодиод с помощью АЦП

Очень похоже на случай: преподаватель дал задачку с подвохом - студент ищет помощь для решения )

+1
Fer #26Fer
16 Октябрь 2019 13:15

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

+1
ph0en1x #27ph0en1x
16 Октябрь 2019 22:04

Fer, пожалуйста! Smile

0
maks #28maks
11 Ноябрь 2019 12:59

Здравствуйте! Огромное спасибо за ваши материалы и подробное изложение, изучаю с интересом.
Может подскажете, мне нужно одной кнопкой подавать одновременно сигнал на несколько устройств Raspberry, у каждой свое отдельное питание. Как можно реализовать такую задачу? Сделать общую землю GND возможно.

0
ph0en1x #29ph0en1x
11 Ноябрь 2019 19:29

Здравствуйте!

Вот несколько возможных вариантов того, как одной кнопкой подать сигнал на отдельно запитанные платы Raspberry Pi:

  1. Использовать кнопку с двумя (для 2х малинок), тремя (для трех малинок)...группами контактов. При нажатии такой кнопки замыкаются сразу несколько групп контактов, которые подают сигналы на соответствующие GPIO плат Raspberry Pi;
  2. Применить реле с нужным количеством групп контактов, подключенных к малинкам. Напряжение на обмотку реле подается с помощью кнопки, а группы контактов реле будут управлять сигналами на каждой из плат мини-компьютеров;
  3. Установить несколько реле, которые срабатывают от замыкания кнопки и коммутируют сигналы для каждой из малинок;
  4. Для коммутации и развязки применить оптопары (светодиод-фотодиод, светодиод-фототранзистор). Похоже на вариант с применением реле, но он не создает шума и более экономичен по потребляемому току;
  5. Использовать питание +3,3В одной платы для установки высокого уровня на всех входах каждой из плат, кнопкой сбрасываем уровень напряжения на всех входах к нулю.

Схема реализации вариантов 4 и 5:

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

На первой схеме нет развязки, используемые на каждой из малинок пины GPIO связаны через резисторы, питание +3,3В для этой схемы берем из первой платы.

Вторая схема - с развязкой и общим минусовым проводом (GND), использованы оптопары. При замыкании кнопки на внутренние светодиоды каждого из элементов оптопар поступает напряжение. Свечение светодиодов открывает соответствующий фото-транзистор, через который напряжение +3,3В с каждой малинки через резистор 20К стекает в землю, тем самым устанавливая на GPIO низкий уровень сигнала.

Изменив немного схему, вместо оптопар можно применить мультиплексоры - микросхемы содержащие управляемые электронные ключи на полевых транзисторах. Например, микросхема CD4066A содержит 4 коммутационных элемента, ее советский аналог К561КТ3. Схема получится еще более экономичной, поскольку CD4066 с 4мя элементами потребляет менее 0,5мА!

+1
maks #30maks
12 Ноябрь 2019 02:04

Спасибо! Вариант с оптопарами или микросхемой с электронными ключами - супер!

+1
Jarek #31Jarek
15 Декабрь 2019 12:01

"Прямое напряжение такой величины станет причиной достаточно большого тока в цепи 50+мА"
По каким расчётам Вы это определили?

0
ph0en1x #32ph0en1x
15 Декабрь 2019 17:09

Смотрите, например, имеется в наличии светодиод с рабочими параметрами: напряжение - 2,5В и ток - 20мА. При подаче прямо на него 3.3В, остаток напряжения 3.3-2.5=0.8(В) должен куда-то деться, а поскольку гасящего резистора нет, то это напряжение повысит ток в цепи. Там будет уже не 20мА, как при номинальном питании светодиода от 2.5В, а в разы больше.

Вот несколько примеров реальных измерений, которые вы можете выполнить сами, используя блок питания и мультиметр:

Зеленый светодиод, подключенный напрямую к линии питания напряжением 3,3В, ток в цепи - 87,8мА

Зеленый светодиод, подключенный напрямую к линии питания напряжением 3.3В, ток в цепи - 87.8мА!

Платка что справа - это набор стабилизаторов напряжения на 5В и 3.3В для макетной панели. На нижней линии питания, куда подключен светодиод, сейчас выставлено как раз 3.3В.

Красный светодиод напрямую подключен к 3,3В, ток в цепи - 122,6мА!

Красный светодиод подключен напрямую к 3.3В, ток в цепи - 122.6мА!

Желтый светодиод подключен к питанию 3,3В без гасящего резистора, ток в цепи - 140,8мА!

Желтый светодиод подключен к питанию 3.3В без гасящего резистора, ток в цепи - 140.8мА!

Советский светодиод АЛ307 подключен к питанию 3,3В без гасящего резистора, ток в цепи - 136,5мА!

Советский светодиод АЛ307 подключен к питанию 3.3В без гасящего резистора, ток в цепи - 136.5мА!

Советский светодиод в металлическом корпусе подключен к питанию 3,3В без гасящего резистора, ток в цепи - 98,1мА!

Советский светодиод в металлическом корпусе подключен к питанию 3.3В без гасящего резистора, ток в цепи - 98.1мА!

Что случится если светодиод подключить к линии питания напряжением 3,3 Вольта? - скорее всего он "подгорит" и станет светить тусклее или же вовсе выйдет из строя!

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

P = U * I = 3.3В * 140.8мА = 464,64мВт = 0,46Вт !!!

При перенапряжении очень быстро из строя выходят советские АЛ307. В детстве я их много спалил, подключая к двум пальчиковым батарейкам (в заряженном состоянии 1.65В+1.65В), а доставались они мне не просто... Потом мне подсказали о токе, гасящем резисторе...начал интересоваться и пришло счастье вместе с пониманием.

Что случится если светодиод напрямую подключить к GPIO на выходе которого 3,3В? - в цепи "источник питания--транзисторный_ключ_GPIO--светодиод" начнет протекать большой ток, который в состоянии повредить ключевой транзистор, не рассчитанный на коммутацию такой большой нагрузки.

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

+1
SaX #33SaX
25 Январь 2021 21:12

Добрый день!
А почему нельзя подключить кнопку от 3.3V через резистор сразу на GPIO пин? Зачем занимать третий контакт?

0
ph0en1x #34ph0en1x
26 Январь 2021 01:07

Приветствую!
Подключение кнопки к GPIO с одним резистором - возможно. Такую цепочку можно подключать как к GND, так и к линии питания 3.3V, но придется сделать следующее:

  1. Подобрать сопротивление резистора, чтобы добиться безопасного тока через пин и надежного срабатывания;
  2. Программно активировать внутренний подтягивающий резистор (Pull-Up или Pull-Down).

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

Дополнил часть статьи о подключении кнопки, там есть подробности - перечитайте, пожалуйста.

0
SaX #35SaX
26 Январь 2021 18:35

Спасибо большое за ответ!
Я пока только учусь, поэтому, возможно, задаю несколько глупые вопросы.)

0
Alendas67 #36Alendas67
16 Февраль 2021 21:30

Спасибо! Отличная работа. Интересно как выключить светодиод питания на плате?

0
ph0en1x #37ph0en1x
16 Февраль 2021 22:57

Приветствую! Дополнил статью еще одним разделом, там описано то о чем вы спрашиваете.

0
Жека #38Жека
29 Март 2021 10:54

Здравствуйте. при подключении кнопки как на рис6 происходят ложные срабатывания. т.е. кнопка не замыкается, а программа выдает сигнал замыкания. даже при выключения света в комнате (лампы ЛДС) происходит ложное срабатывание. ставил и кондеры и диоды, не помогло

0
ph0en1x #39ph0en1x
29 Март 2021 13:00

Здравствуйте. Где-то в соединениях может быть ненадежный контакт, проблемы с питанием (мало мощности, помехи), ошибки в коде...
Подкину некоторые из идей по поиску и устранению проблемы:

  1. Попробуйте для подключения схемы с кнопкой использовать другой пин GPIO. Если будет та же самая история, значит с портами GPIO скорее всего все в порядке и нужно искать проблему в другом.
  2. Попробуйте временно использовать другую кнопку или переключатель. Посмотрите изменит ли это ситуацию хоть как-то.
  3. Убедитесь в том, что малинка подключена к надежному источнику питания (например 5В/2,5А+ для Raspbery Pi 3) и порты USB не перегружены другими устройствами. Ненадежное питание может быть причиной сбоев при работе малинки, проблем с портами, некорректного поведения периферийных устройств и т.д.
  4. Если подключенные к кнопке проводники размещены близко с каким-то силовым кабелем питания (~220, ~380В) или же около мощного бытового прибора (микроволновка, тен на 3кВт и т.п.), то это также может стать причиной помех в работе малинки и ее портов. Когда для подключения кнопки вами используются длинные проводники, то попробуйте временно подключить схему с кнопкой короткими проводниками. Если проблема исчезнет, то нужно искать причину в проводниках, использовать экранированный кабель с несколькими жилками внутри. Экран (оплетку) со стороны малинки подключить к общему (GND).
  5. Внимательно пересмотрите свой код, возможно для порта ошибочно активирован какой-то из внутренних подтягивающих резисторов (Pull-UP или Pull-Down), чего для схемы (рис.6) делать не нужно. Попробуйте для теста вашей конструкции с кнопкой использовать простейший код, например как в моей статье.
  6. В одной из статей я рассказывал что такое дребезг контактов и как с ним бороться, там есть примеры подключений кнопки, тестовый код. Ознакомьтесь с этой информацией и попробуйте поэкспериментировать.

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

+1
Саня #40Саня
09 Май 2021 13:00

Добрый день, подключаю по вышеуказанной схеме кнопку к GPIO3 нажатии никакой реакции, но если перекидываю например на GPIO17 то все отлично работает. При том если замкнуть контакты на GPIO3 без резисторов, то все работает. 3.3v подключил через резистор на 10кОм, GPIO через последовательно соединенные 4 на 220Ом т.е. получается 880) не подскажете в чем может быть дело? Видел ниже на схемах рекомендуется 20кОм и 1кОм, но под рукой к сожалению пока нету других резисторов и добраться до них смогу только через неделю в лучшем случае, решат ли они проблему? Хочется все-таки использовать GPIO3 планирую оптопарой включать/выключать малинку при определённых событиях, а этот функционал реализован на 3-м пине.

0
ph0en1x #41ph0en1x
09 Май 2021 19:46

Здравствуйте. Для схемы на рис. 6. точность в сопротивлениях резисторов не нужна. R1 - можно ставить даже в пределах от 5К до 47К, а R2 - от 500 Ом до 2К. Суть здесь в том, что при замыкании кнопки, ток с линии +3.3В через резисторы начнет течь только через R1 и на общий, а GPIO окажется подключен через R2 к общему.

Чем большее суммарное сопротивление R1+R2, тем меньший ток будет протекать через эти резисторы когда кнопка отжата, экономия энергии (может быть важно при множестве кнопок и питании от батарей).

Что касается вашей проблемы, то стоит проверить следующее:

  1. Отключена ли в Raspberry Pi OS поддержка шины I2C, поскольку в новых малинках пин GPIO3 используется для этой шины как линия SCL (clock). Включить или выключить поддержку этой шины можете через raspi-config.
  2. Пересмотреть весь код, убедиться что для GPIO3 в коде не активированы подтягивающие резисторы (Pull-Up или Pull-Down).
  3. Возможно какой-то ранее установленный скрипт или программа задействует этот порт и конфигурирует его по своему усмотрению. Нужно установить чистую Raspberry Pi OS на временную карточку, проверить работу GPIO3 без активации дополнительных возможностей и установки дополнительного ПО.
0
Саня #42Саня
10 Май 2021 02:12

Использую свою сборку ОС и она 100% чистая никаких скриптов и тд не было это первый + как уже упоминал выше без резисторов на GPIO3 все работает нормально. По работе резисторов примерно так все и понимал, но спасибо за то что еще раз разьяснили. По проблеме выяснить причину проблемы удалось когда загуглил схему малинки на GPIO2 и GPIO3 уже распаяны резисторы на 1.8k (R23 R24 на схеме) накинув еще свой я получал 2,68k что объясняет почему на других портах указанная схема работала, а на 3м c использованием резисторов нет. Подскажи пожалуйста, учитывая что я его замыкаю на землю есть ли необходимость кидать еще 3.3 + 20k резистор для данного порта?

Схема обвязки выводов GPIO на плате Raspberry Pi

0
ph0en1x #43ph0en1x
10 Май 2021 13:48

Вот и нашлись подтягивающие резисторы, как оказалось они запаяны для использования с шиной I2C, а точнее для ее линий SDA (Data) и SCL (Clock) прямо на плате малинки.

Схему подключения кнопки, показанную на рисунке 6 уже собрать не получится. Один из вариантов - выпаять эти резисторы, но можно обойтись и так. Кнопку к GPIO3 пробуйте подключать на общий (GND) через резистор на 300 Ом. Добавил схему в статью - рисунок 7.

При таком сопротивлении любой ток через GPIO3 будет ограничен значением:

I = U/R = 3.3V/300 = 0.011A = 11mA.

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

R1 = R23 / (3,3V/x - 1)
300 Ом = 1800 Ом / (3.3/x - 1)
3.3/x - 1 = 1800 Ом / 300 Ом = 6
3.3/x = 7
x = 3.3/7 = 0.47

При нажатой кнопке на выводе GPIO3 должно получиться напряжение 0.47В и такого уровня должно быть достаточно чтобы перевести вход этого порта на низкий логический уровень (0). При этом пин GPIO3 в полной безопасности.

0