Raspberry pi gpio: GPIO для чайников (часть 1)

hexvolt-блог: Raspberry Pi. Работаем с GPIO на Python

Как-то я писал о том, что планирую использовать Raspberry Pi в качестве веб-сервера, управляющего моим устройством. Пришло время задуматься над интерфейсом подключения. У разработчика, желающего подключить свое железо к Raspberry есть два пути: использовать для этого USB или выводы общего назначения (GPIO). С возможностями USB все приблизительно понятно (в будущем постараюсь написать пост о работе с внешним железом через USB). О GPIO же информации не так много, да и опыта его использования нет. В общем я заинтересовался GPIO и его возможностями. В статье речь пойдет о выводах общего назначения Raspberry PiGPIO:

  • возможности GPIO
  • распиновка GPIO
  • как работать с GPIO на Python
  • характеристики GPIO (прежде всего показатели скорости)
  • пример использования GPIO Raspberry

Порт

GPIO — выводы общего назначения Raspberry Pi

Предварительно я наладил удаленную работу с Raspberry Pi через SSH, чтобы каждый раз не подключать  монитор и клавиатуру. Поэтому в исходном состоянии у меня к Raspberry подключено всего два «провода»: питание и сетевой кабель для соединения с роутером. Хотя принципиального значения это не имеет: все нижеописанное будет справедливо, как в случае работы с консолью Raspberry через SSH, так и при использовании подключенной клавиатуры.

Порт GPIO (сокращение от General Purpose Input Output) — это программно управляемые выводы общего назначения, которые могут работать как входы (для считывания сигнала) или как выходы (для передачи сигнала). На Raspberry Pi они выполнены в виде двух рядов штырьков с шагом в 2,54 мм (разъем PLD). Выражение «общего назначения» означает, что эти выводы пользователь может использовать в своих целях так, как ему захочется, поскольку они не выполняют каких-то определенных жестко заданных функций. При работе с

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

Итак, что представляет собой порт GPIO и каковы его возможности? GPIO объединяет в себе 26 выводов, среди которых присутствуют следующие:

  • 2 вывода с постоянным уровнем напряжения 5 В
  • 2 вывода с постоянным уровнем напряжения 3,3 В
  • 5 общих выводов (земля)
  • 17 цифровых программно управляемых выводов

Каждый из этих 17 выводов может работать как вход, либо как выход. Однако помимо этого, некоторые из этих выводов могут выполнять альтернативные

необязательные

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

Примечание: Это знакомые понятия для тех, кто сталкивался с программированием микроконтроллеров. Для тех, кто не сталкивался и на данном этапе пока желает просто программно выводить «1» и «0» на нужном выводе — знания этих интерфейсов не понадобится. Поэтому не буду здесь уделять этому внимание. Скажу только, что среди микроконтроллеров и других устройств (различные датчики, АЦП, ЦАП, микросхемы памяти) это очень распространенные интерфейсы, поэтому наличие выводов этих интерфейсов в

GPIO Raspberry при необходимости позволяет очень легко и с минимумом программного кода «научить» Raspberry «общаться» с вашим устройством.

Как понять где какой вывод находится? Для этого необходима распиновка (цоколевка) GPIO. В официальной документации приведена распиновка разных версий GPIO Raspberry Pi. Здесь я приведу самую последнюю на данный момент распиновку GPIO — для Raspberry Pi Model B Rev.2:

На схеме в скобках указана альтернативная функция каждого вывода:

  • SDA, SCL — выводы интерфейса I2C
  • TXD, RXD — выводы UART
  • MOSI, MISO, SCLK, CE0, CE1 — выводы интерфейса SPI
  • GPCLK0 — (
    General Purpose Clock
    ) вывод для формирования варьируемой тактовой частоты для внешних устройств
  • PCM_CLK, PCM_DOUT — выводы аудио-интерфейса I2S

Что ВАЖНО знать перед работой с

GPIO Raspberry Pi

Пожалуй, это самый важный раздел. Нужно помнить о некоторых особенностях GPIO и соблюдать определенные меры предосторожности, чтобы не залететь еще на 35-50$ не повредить Raspberry. Ниже приведены такие «критические особенности», а также несколько нюансов, которые просто могут быть полезны, и которые желательно помнить при разработке.

  • Максимальный суммарный ток обоих выводов 3.3 В равен 50 мА! Поэтому эти выводы могут использоваться для питания внешних устройств, только если их потребляемый ток меньше 50 мА.
  • Максимальный суммарный ток обоих выводов 5 В равен 300 мА!
     Эти выводы также могут использоваться для питания внешних устройств только в том случае, если их потребляемый ток меньше 300 мА.
  • Нельзя на GPIO подавать напряжение больше 3,3 В! Цифровые выводы GPIO имеют уровни напряжения 0 — 3,3 В и не совместимы с традиционными уровнями напряжения 0 — 5В! Поэтому нельзя напрямую соединять Raspberry Pi и цифровые устройства, работающие с TTL-уровнями 5 В. Если подать на GPIO вывод Raspberry логическую единицу, представляющую собой 5 В, а не 3,3 В — вывод может выйти из строя.
  • Выводы GPIO 14 и GPIO 15 по-умолчанию выполняют альтернативную функцию и являются выводами UARTRXD и TXD. Поэтому после включения на них присутствует высокий уровень 3,3 В. Программно их можно переконфигурировать в обычные выводы. Все остальные
    GPIO
    после включения Raspberry выполняют основную функцию и работают как обычные цифровые выводы.
  • Все настраиваемые пины GPIO по-умолчанию являются входами. И поэтому имеют высокое входное сопротивление. При этом подтяжка логического уровня у них не включена, выводы «висят в воздухе», поэтому после включения Raspberry напряжение на них может «плавать». Это нормально. Исключением является только 2 следующих вывода:
  • Выводы GPIO 0 (SDA) и GPIO 1 (SCL) по-умолчанию «подтянуты» к питанию. Поэтому после включения Raspberry на них присутствует напряжение логической единицы (3,3 В).
  • Сигнал на любом из цифровых выводов может служить источником внешнего прерывания. Кто раньше сталкивался с микроконтроллерами поймет, насколько это может быть полезно. Как использовать прерывания в Raspberry Pi
    — пока это идея для следующего поста.

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

    Как работать с

    GPIO на Python

    Примечание: Работать с GPIO, по сути, можно двумя способами:

    1) Используя bash и файловую систему Rasbian
    Raspbian является одним из дистрибутивов Linux, а концепция Linux предполагает, что любой объект является файлом.

    Именно это позволяет выводить и считывать сигналы с GPIO обычными командами оболочки bash прямо в терминале! Вывод логической единицы при этом выглядит как команда записи «1» в файл, соответствующий нужному выводу. Подробные примеры даны здесь. 

    2) Используя языки программирования (самые разные от C до Бэйсика)

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

    Предположим нам нужно вывести логическую «1» или «0» на GPIO7 и считать сигнал с GPIO 8.

    0) Для работы с GPIO на Python нужна специальная библиотека RPi.GPIO. Сейчас ее можно установить прямо с репозиториев, а не качать архив и устанавливать вручную, как было раньше.

    Воспользуемся этой возможностью:

         sudo apt-get install python-rpi.gpio (или python3-rpi.gpio для 3-й версии Питона)

    Оказывается, в новом дистрибутиве Raspbian она уже установлена, поэтому двигаемся дальше.

    0.5)  GPIO является системным элементом Raspbian, поэтому работать с ним нужно только под суперпользователем. Будем писать программу прямо в консоли, поэтому запускаем python

         sudo python

    1) Импортируем библиотеку для работы с GPIO:

         import RPi.GPIO as GPIO

    2) Устанавливаем способ нумерации выводов GPIO.
    Зачем? Дело в том, что во многих функциях этой библиотеки необходимо указывать номер вывода, над которым мы хотим произвести какую-либо манипуляцию.  Однако указываемый номер можно интерпретировать по-разному: либо это номер

    GPIO, либо это номер пина (P1-26) на плате Raspberry (см. распиновку). Чтобы не возникало путаницы, сразу после импорта желательно «указать библиотеке», какую нумерацию мы будем использовать в программе.
         GPIO.setmode(GPIO.BCM)   #GPIO.BCM — будет использоваться нумерация GPIO 

                                                         #GPIO.BOARD — будет использоваться нумерация пинов P1-26

    3) Конфигурируем выводы
    Поскольку мы будем выводить сигналы на GPIO 7, конфигурируем его как выход, а GPIO 8 — как вход:
         GPIO.setup(7, GPIO.OUT)    #конфигурируем GPIO 7 как выход
         GPIO.setup(8, GPIO.IN)        #конфигурируем GPIO 8 как вход

    Примечание: именно после выполнения этой команды на GPIO 7 установится ровно 0 В, поскольку этот вывод больше не является входом и на нем нет «плавающего» потенциала.

    С помощью необязательного параметра pull_up_down функции setup можно также настроить «подтяжку» вывода к питанию или к земле:
         GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_UP)           #подтяжка к питанию 3,3 В
         GPIO. setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)   #подтяжка к земле 0 В
         GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_OFF)        #режим по-умолчанию

    4) Формируем и считываем сигналы
    Формируем «1» и «0» на GPIO 7 и считываем сигнал с GPIO 8:

         GPIO.output(7, True)             #выводим на GPIO 7 логическую «1» (3.3 V)

         GPIO.output(7, False)            #выводим на GPIO 7 логический «0»
         signal = GPIO.input(8)           #считываем сигнал с GPIO 8 в переменную signal

    5) Завершаем работу
    После всех нужных операций корректно завершаем работу:
         GPIO.cleanup()

    Выполнение этой операции приведет к возвращению всех выводов GPIO в первозданное состояние.

    Примечание: если не выполнить эту операцию, то даже после закрытия программы и выхода из python, выводы GPIO останутся в том, состоянии, в котором они были на момент завершения. Это может быть чревато тем, что при попытке повторно поработать с этими выводами будет возникать сообщение, о том, что вывод уже используется: «RuntimeWarning: This channel is already in use, continuing anyway. «

    Весь пример целиком:
         import RPi.GPIO as GPIO       #подключаем библиотеку
         GPIO.setmode(GPIO.BCM)    #устанавливаем режим нумерации
         GPIO.setup(7, GPIO.OUT)     #конфигурируем GPIO 7 как выход
         GPIO.setup(8, GPIO.IN)         #конфигурируем GPIO 8 как вход
         GPIO.output(7, True)               #выводим на GPIO 7 логическую «1» (3.3 V)

         GPIO.output(7, False)              #выводим на GPIO 7 логический «0»
         signal = GPIO.input(8)             #считываем сигнал с GPIO 8 в переменную signal
         GPIO.cleanup()                        #завершаем работу с GPIO



    На мой взгляд, из всех характеристик наиболее интересны временные параметры GPIO, а именно — насколько быстро может меняться состояние цифрового вывода из «1» в «0» и обратно, если управлять портом программно. Для проверки этого использовался следующий код:

         import RPi.GPIO as GPIO
         GPIO. setmode(GPIO.BCM)
         GPIO.setup(7, GPIO.OUT)
         while (1):
              GPIO.output(7, True) 
              GPIO.output(7, False)

    Как можно применить все это на практике? Зачем выводить «1» или «0» на GPIO?

    Например, можно помигать светодиодами!

    Например, можно управлять силовой нагрузкой и включать / выключать любые бытовые приборы, работающие от сети 220 В. Для этого понадобится Raspberry Pi и всего 7 деталей. Схема такого программного «выключателя» приведена ниже:

    Примечание: микросхема-оптодрайвер MOC3041M имеет гальваническую развязку силовых цепей от слаботочных, поэтому она является «барьером безопасности» между Raspberry и сетью 220 В, выход ее из строя не повредит Raspberry. Конденсатор C8 должен быть высоковольтным и выдерживать напряжение ~400 В.

    Данная схема может коммутировать токи до 16А. Она полностью отлажена, проверена на практике и занимает очень мало места (к сожалению, у меня не сохранились фото устройства, где она используется). Подача «1» на GPIO 7 Raspberry Pi приведет к срабатыванию оптодрайвера и открытию симистора V2, который начнет пропускать через себя ток, идущий от сети 220 В к силовой нагрузке. Прибор включается. Как только на GPIO 7 возникает «0» — симистор V2 закрывается и цепь нагрузки размыкается. Прибор выключается. Все просто!

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

    На этом все. В следующем посте о Raspberry постараюсь описать работу с UART и SPI.

    GPIO-пины Raspberry Pi и их использование из Python

    В уже довольно не новом посте, посвященном Raspberry Pi, это устройство рассматривалось исключительно, как маленький и очень дешевый компьютер. Бесспорно, Raspberry Pi им и является. Но, помимо этого, у Raspberry Pi есть еще и 26 пинов GPIO (General Purpose Input Output), что очень кстати в свете моего недавнего увлечения электроникой. Почему? Давайте разберемся.

    Отмечу, что все написанное ниже справедливо для Raspberry Pi 2 Model B. Если у вас другая малина, то расположение пинов и другие детали могут отличаться. Поэтому обязательно сверьтесь с официальной документацией. В качестве операционной системы я использовал релиз Raspbian от 2016-09-28, который можно скачать здесь.

    Итак, расположение пинов описано на официальном сайте:

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

    Допустим, мы хотим программно управлять напряжением, подаваемым на 2-й пин. Проще всего это сделать через sysfs.

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

    echo 2 > /sys/class/gpio/export

    Делаем его out-пином, то есть, он будет либо подавать, либо не подавать напряжение в 3. 3 вольта:

    echo out > /sys/class/gpio/gpio2/direction

    Подаем напряжение:

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

    Перестаем подавать напряжение:

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

    Узнаем, подается ли сейчас напряжение:

    cat /sys/class/gpio/gpio2/value

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

    echo 2 > /sys/class/gpio/unexport

    Есть мнение, что 3.3 вольта — это как-то маловато. Кроме того, было бы неплохо не только включать и выключать напряжение, но и изменять его в некотором диапазоне. Увы, насколько мне известно, ничего этого Raspberry Pi не умеет. Поговаривают, что умеет Arduino, но опыта использования этого устройства на момент написания этих строк у меня нет.

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

    Важно! После загрузки Raspberry Pi некоторые пины по дэфолту могут подавать напряжение. Возможно, это не то, чего вы хотите для вашей цепи. У меня по дэфолту напряжение было на пинах 2, 3 и 14. Я бы советовал перепроверить эту информацию на вашей конкретной Raspberry Pi и конкретной версии Raspbian. Имейте также в виду, что написанная вами же программа может оставить пины в неизвестном состоянии (например, если вы прибьете ее kill’ом).

    До сих пор были рассмотрены out-пины. Они как бы «пишут» на макетную плату, но не позволяют узнать ее текущее состояние. Например, нажата ли в настоящих момент какая-то кнопка. Даже если цепь разомкнута, out-пины об этом не знают. Поэтому есть еще и in-пины.

    Экспортируем 5-ый пин и делаем его in-пином:

    echo 5 > /sys/class/gpio/export
    echo in > /sys/class/gpio/gpio5/direction

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

    «Прочитать» кнопку можно так:

    cat /sys/class/gpio/gpio5/value

    Считывается 1, если кнопка не нажата, то есть, цепь разомкнута, и 0, если кнопка нажата, то есть, цепь замкнута.

    В итоге получилась такая конструкция (иллюстрация про кнопку взята отсюда):

    А вот и скрипт на Python, который при нажатии на кнопку тушит текущий светодиод и зажигает следующий за ним:

    #!/usr/bin/env python

    import RPi.GPIO as GPIO
    import time

    # Use «logical» pin numbers
    GPIO.setmode(GPIO.BCM)

    # Disable «This channel is already in use» warnings
    GPIO.setwarnings(False)

    # Setup LED’s: 2 — green, 3 — yellow, 4 — red
    for i in range(2,5):
        GPIO.setup(i, GPIO.OUT)
        GPIO.output(i, False)

    current_led = 2
    GPIO.output(current_led, True)

    # Prepare to read button state
    BUTTON = 5
    PRESSED_CODE = 0
    GPIO.setup(BUTTON, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    while True:
    #    GPIO. wait_for_edge(BUTTON, GPIO.FALLING)
    #    print(«Button pressed»)
    #    GPIO.wait_for_edge(BUTTON, GPIO.RISING)
    #    print(«Button released»)
        time.sleep(0.05)
        if GPIO.input(BUTTON) == PRESSED_CODE:
            GPIO.output(current_led, False)
            current_led = max(2, (current_led + 1) % 5)
            GPIO.output(current_led, True)
            time.sleep(0.1)

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

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

    Дополнение: Еще один пример использования GPIO в одноплатном компьютере описывает заметка Реверс-инжиниринг роутера на примере GL. iNet GL-AR750. Также вас может заинтересовать статья Модули ядра Linux: таймеры и GPIO.

    Метки: Linux, Python, Электроника.

    Введение в Raspberry Pi GPIO и физические вычисления

    • Главная
    • Учебники
    • Введение в Raspberry Pi GPIO и физические вычисления

    ≡ Страниц

    Авторы: asassy

    Избранное Любимый 6

    Итак, мы подключили необходимое оборудование к Raspberry Pi, и вам не терпится начать использовать его в качестве универсального ПК для веб-серфинга, просмотра YouTube и просмотра кошачьих мемов. Но где Пи действительно блистает своим 40-контактным GPIO (ввод и вывод общего назначения). GPIO позволяет включать и выключать устройства (выход) или получать данные от датчиков и переключателей (вход). На самом деле это означает, что вы можете подключить Raspberry Pi ко всему, от умного зеркала до метеостанции и робота для отслеживания активов, который отображает свои координаты на веб-сервере. Давайте глубже погрузимся в то, что возможно с заголовком GPIO! Мы можем ссылаться на схему контактов GPIO, предоставленную Raspberry Pi Foundation ниже, в качестве визуального руководства для понимания контактов:

    Контакты питания

    Начнем с контактов питания, которые включают как 3,3 В, так и 5 В. Эти контакты передают мощность в качестве выхода для питания подключенных периферийных устройств.

    Заземление

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

    Стандартные контакты GPIO

    Удалите контакты питания и заземления, и у вас останутся контакты, предназначенные для отправки вывода и получения ввода. Все это можно использовать для простых задач ввода/вывода!

    Контакты Chatty Cathy

    Некоторые стандартные контакты GPIO используются для связи. Вот краткий обзор этих протоколов связи!

    • Контакты SPI — последовательный периферийный интерфейс (SPI) — это протокол связи, используемый для передачи данных между микрокомпьютерами, такими как Raspberry Pi, и периферийными устройствами. Вывод MISO получает данные, а вывод MOSI отправляет данные от Raspberry Pi. Кроме того, последовательный тактовый вывод посылает импульсы с постоянной частотой между Raspberry Pi и устройством SPI с той же скоростью, с которой устройства передают данные друг другу.
    • Контакты UART — UART означает универсальный асинхронный приемник-передатчик, представляющий собой физическую схему, предназначенную для отправки и получения данных.
    • Контакты ШИМ — ШИМ означает «широтно-импульсная модуляция», протокол связи, который лучше всего использовать с движущимися и светящимися объектами: двигателями, светодиодами и т. д.
    • Выводы I2C – I 2 C — сокращение от inter-integrated Circuit (два «меж» или I «квадрат» C). Он работает аналогично SPI, но не требует использования почти такого количества выводов.
    Идентификация контактов

    Существует два способа идентификации контактов GPIO… первый — по их физическому положению на плате или по названию BOARD. Он также имеет название канала Broadcom SOC (BCM). Открыв терминал и запустив pinout в качестве команды, он вернет карту контактов GPIO Raspberry Pi и их имена на основе микросхемы Broadcom на плате.

    Карта для Raspberry Pi 4 на основе команды распиновки.

    Если вы действительно хотите углубиться в распиновку Raspberry Pi GPIO, существует невероятно подробное руководство по распиновке Raspberry Pi GPIO, которое является интерактивным и содержит пошаговые инструкции по каждому типу контактов на плате. Этого общего обзора, изложенного выше, должно быть достаточно, чтобы мы начали наш проект!



    ОШИБКА — 404 — НЕ НАЙДЕНА

    • Дом
    • ЭТО ЛОВУШКА!

    Наши серверные гномы не смогли найти страницу, которую вы ищете.

    Похоже, вы неправильно набрали URL-адрес в адресной строке или перешли по старой закладке.

    Возможно, некоторые из них могут вас заинтересовать?

    Противостояние — металлический шестигранник (4-40; 3/8 дюйма; 10 шт. в упаковке)

    В наличии ПРТ-10463

    Избранное Любимый 7

    Список желаний

    SparkFun MicroView — OLED-модуль Arduino

    В наличии DEV-12923

    44,95 $

    47

    Избранное Любимый 113

    Список желаний

    Буквенно-цифровой стартовый комплект SparkFun Qwiic — красный и белый

    В наличии КОМПЛЕКТ-18624

    22,95 $

    Избранное Любимый 3

    Список желаний

    Лицензионная карта программного обеспечения Machinechat — JEDI One

    19 доступно COM-20674

    79,00 $

    Избранное Любимый 1

    Список желаний

    DA16200 приходит к делу+

    16 сентября 2022 г.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *