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

Raspberry Pi – GPIO
(на русском языке)

У попередній статті я торкнувся теми 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.

Перший метод (файлова система)

Спробуємо поморгати світлодіодом. Наступні операції бажано виконувати з повноваженнями користувача 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:

#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;
}

Компілюємо:

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-2018 Андрій Корягін, Кременчук - Київ, Україна