сайт для палких паяльників

В предыдущей статье я затронул тему GPIO. Сегодня я расскажу как управлять выводами GPIO.

Еще раз напомню, что выводы GPIO Raspberry Pi предназначены для работы с напряжением уровня 3.3 В. Raspberry Pi не имеет защиты от перенапряжения, поэтому следует всегда использовать сигналы, не превышающие уровень 3.3 В.

Итак, для тестов приготовим светодиод, и кнопку. Подключим их как показано на схеме.

RaspberryPi2_button_LED

Распиновка Raspberry Pi была приведена в предыдущей статье. Обратите внимание, что для кнопки выполнена “подтяжка” к +3.3 через резистор R1. Т.е. когда на входе 1 – кнопка не была нажата. Когда на входе 0 – это означает, что кнопка нажата. Подтяжку можно делать и программно. Далее это будет описано. При включении подтяжки программно, используются внутренние резисторы. Если вход не имеет подтяжки (“висит в воздухе”), его потенциал может колебаться от 0B до напряжения питания (3.3В). Эта ситуация касается контактных сенсоров, кнопок, герконов и т.п. Если на вход подается сигнал с известным потенциалом, например: сигнал с компаратора или другой микросхемы или датчика, – подтяжку делать не обязательно. Но я рекомендую делать “подтяжку” всегда. Это может предотвратить возможные проблемы в случае физического обрыва связи с источником сигнала.

Существует два различных метода для записи и считывания с периферийных устройств на системах, использующих Linux-подобные системы. Первый из них: создавая доступ через типы файлов к периферии в файловой системе, а второй – запись/чтение базовых адресов памяти, выделенной в GPIO или модуля SoC. Описание участков этой памяти можно найти в данных в BCM2835.

Первый метод управления GPIO (файловая система)

Попробуем поморгать светодиодом. Следующие операции желательно выполнять с полномочиями пользователя root.

Создаем файл доступа GPIO:

echo 11 > /sys/class/gpio/export

Настраиваем как выход (out):

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

Записываем значение (0 или 1):

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

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

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

Светодиод должен погаснуть.

Следующая команда удаляет создан доступ к GPIO:

echo 11 > /sys/class/gpio/unexport

Вы можете управлять GPIO, используя любой язык программирования (С, Bash, Python).

Скачайте и запустите пример, написанный на Python:

wget https://sites.google.com/site/semilleroadt/raspberry-pi-tutorials/gpio/ADT_blink.py
python ADT_blink.py

Скрипт спросит, к которому вывода GPIO подключен диод и сколько раз он мигнуть. Чтобы убедиться в том, что ничего сложного в управлении GPIO нет, откройте скрипт ADT_blink.py редактором nano:

nano ADT_blink.py

Теперь то же самое сделаем для входа. Кнопка подключена к GPIO17.

Создаем файл доступа GPIO:

echo 17 > /sys/class/gpio/export

Настраиваем как вход (in):

echo in > /sys/class/gpio/gpio17/direction

Считываем значение:

cat /sys/class/gpio/gpio17/value

Как мы видим команда вернула 1 (помним про подтяжку к +3.3В). Нажмем кнопку и повторим команду:

cat /sys/class/gpio/gpio17/value

Команда должна вернуть 0.

Теперь напишем небольшой скрипт на Python (файл test_button.py):

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN)

while True:
  if (GPIO.input(17)==0):
    print("Button Pressed")
    time.sleep(1);

Запустим скрипт:

python test_button.py

Cкрипт должен писать “Button Pressed” когда кнопка нажата.

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

GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)

Небольшая памятка как работать GPIO на Python

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

2) Устанавливаем способ нумерации выводов GPIO
GPIO.setmode(GPIO.BCM)
# GPIO.BCM – будет использоваться нумерация GPIO
# GPIO.BOARD – будет использоваться нумерация P1-26

3) Конфигурируем выводы
Например, GPIO 11,  конфигурируем как выход, а GPIO 17 – как вход:
GPIO.setup(11, GPIO.OUT) # конфигурируем GPIO 11 как выход
GPIO.setup(17, GPIO.IN) # конфигурируем GPIO 17 как вход

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

4) Задание выходного сигнала и считывания входного
Записываем “1” і “0” в GPIO 11 и считываем сигнал с GPIO 17:
GPIO.output(11, True) # записываем в GPIO 11 “1” (3.3 V)
GPIO.output(11, False) # записываем в GPIO 11 “0” (0 V)
signal = GPIO.input(17) # считываем сигнал GPIO 17 в переменную signal

5) Завершаем работу
GPIO.cleanup() # выполнение этой команды переводит GPIO в исходное состояние.

Второй метод (прямой доступ через участки памяти)

Устанавливаем библиотеку bcm2835:

wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.36.tar.gz
tar zxvf bcm2835-1.36.tar.gz
./bcm2835-1.36
make
make check
make install
cd ..

Подробнее о библиотеке можно почитать здесь: http://www.open.com.au/mikem/bcm2835/

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

wget https://sites.google.com/site/semilleroadt/raspberry-pi-tutorials/gpio/main.c
gcc -o main -l rt main.c -l bcm2835

Запустим скомпилированную программу:

./main

Теперь светодиод, подсоединенный к GPIO 11 должен моргать.

Откройте main.c.  Строка:

#define PIN RPI_GPIO_P1_23

задает номер “ноги” на разъеме. Таблица соответствия двух способов нумерации:

GPIO02 — P1-03
GPIO03 — P1-05
GPIO04 — P1-07
GPIO07 — P1-26
GPIO08 — P1-24
GPIO09 — P1-21
GPIO10 — P1-19
GPIO11 — P1-23
GPIO14 — P1-08
GPIO15 — P1-10
GPIO17 — P1-11
GPIO18 — P1-12
GPIO22 — P1-15
GPIO23 — P1-16
GPIO24 — P1-18
GPIO25 — P1-22
GPIO27 — P1-13
GPIO28 — P5-03
GPIO29 — P5-04
GPIO30 — P5-05
GPIO31 — P5-06

Теперь напишем небольшую программу для считывания. Файл input.c:

</pre>
<pre>#include <stdio.h>
#include <bcm2835.h>

#define PIN RPI_GPIO_P1_11

int main(int argc, char **argv)
{
  if (!bcm2835_init())
    return 1;
  // Set the pin to be an input
  bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
  // with a pullup
  bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP);

  // Reading
  while (1)
  {
    uint8_t value = bcm2835_gpio_lev(PIN);
    printf("Pin 17 = %d\n", value);

    // wait
    bcm2835_delay(500);
  }
  bcm2835_close();
  return 0;
}</pre>
<pre>

Компілюємо:

gcc -o input -l rt input.c -l bcm2835

Запускаем:

./input

Программа показывает состояние входа GPIO17 (P1-11).

О скорости работы с GPIO различными способами подробно описано здесь:
http://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/

Успехов!

Смотри также:
Translate
Архіви

© 2011-2017 Андрій Корягін, Кременчук - Київ, Україна