Raspberry Pi має контакти GPIO, до яких можна підключити різноманітні пристрої, що особливо важливо при використанні RPi для Інтернету речей. Є підтримка шин UART, SPI, I2C і One-wire, а для зручності можна скористатися Pi Wedge:
Короткі пояснення наведених на малюнку вище позначень:
• GPIO - стандартні виводи, які можуть бути використані для керування такими пристроями (вмикання і вимикання), наприклад, як світлодіоди.
• I2C (Inter-Integrated Circuit) – контакти, які дозволяють підключати і спілкуватися з апаратними модулями, що підтримують даний протокол (I2C-протокол), який використовує, зазвичай, лише 2 виводи.
• SPI (Serial Peripheral Interface Bus) – виводи, які можуть бути використані для підключення і спілкування з пристроями SPI. Майже те ж, що і I2C, але використовується інший протокол.
• UART (універсальний асинхронний приймач/передавач) - контакти послідовного порта, що використовуються для зв'язку з іншими пристроями.
Для того, щоб скористатися підтримкою різних протоколів в RPi, необхідно їх дозволити через raspi-config:
Використання sysfs, як частини операційної системи raspbian
Ми можемо «експорувати» виводи GPIO для керування ними, використовуючи можливості самої операційної системи.
Експорт та скасування експорту контактів в ОС Raspbian Wheezy повинно бути зроблене від кореневого користувача (root). Щоб змінити користувача на кореневого, введіть:
sudo -i
Для повернення назад необхідно ввести слово exit.
Експорт створює нову папку для експортованого контакту, а також створює файли для кожної з його функцій керування (тобто active_low, direction, edge, power, subsystem, uevent і value). Після створення файл керування може бути прочитаний всіма користувачами (не лише root), але може бути записаний тільки користувачем root, власником файлу. Тим не менш, коли створили, то його можна дозволити іншим, не root-користувачам, а також написати файли керування входами, змінивши власника або права для цих файлів. Зміни власника або дозволів файлу повинні бути зроблені спочатку від root, тому що їх власник і група встановлені після створення для root. Зазвичай, ви можете змінити власника, щоб керувати GPIO (не від адміністратора), або можете додати дозвіл на запис і змінити власника групи, члени якої керують GPIO. Це важливо, коли GPIO будуть керуватися через Інтернет з віддаленого місця за допомогою браузера.
В Raspbian Jessie таких проблем не повинно бути, бо в ній керування GPIO дозволене звичайному користувачу.
Встановлення бібліотеки для роботи з GPIO
Заходимо в консоль RPi і завантажуємо архів:
wget www.airspayce.com/mikem/bcm2835/bcm2835-1.57.tar.gz
Примітка: Останню версію бібліотеки можна завантажити на цьому сайті.
Розархівуємо:
tar zxvf bcm2835-1.57.tar.gz
Переходимо в директорію, куди розвернулась бібліотека:
cd bcm2835-1.57
І встановлюємо її:
./configure make
sudo make check
sudo make install
Після цього бібліотека для роботи з GPIO буде встановлена, а модуль snd-bcm2835 доданий в файл /etc/modules, але не завантажений в пам’ять. Для завантаження в пам’ять скористаємося командою:
sudo modprobe snd-bcm2835
або просто перезавантажимося для застосування налаштування через команду
sudo reboot
На цьому етапі з виводами GPIO вже можна виконувати якісь прості дії, наприклад, читати стан порту або вмикати/вимикати підключене навантаження.
Приклад використання:
#!/bin/sh
# Номера GPIO повинні вибиратися з цього списку:
# 0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25
# Зверніть увагу, що номери GPIO, які ви тут вказуєте, відносяться до контактів
# BCM2835, а не до номерів виводів роз’єма.
# Тому, якщо хочете активувати контакт 7 на роз’ємі, то повинні
# використати GPIO4 в цьому сценарію. Аналогічно, для активувації контакту 11
# на роз’ємі повинні використати GPIO17.
# Налаштувати GPIO 4 і встановити його як вихідний
echo "4" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio4/direction
# Налаштувати GPIO 17 і встановити його як вхідний
echo "17" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio17/direction
# Записати на вихід
echo "1" > /sys/class/gpio/gpio4/value
# Прочитати із вхідного вивода
cat /sys/class/gpio/gpio17/value
# Очистити
echo "4" > /sys/class/gpio/unexport
echo "17" > /sys/class/gpio/unexport
Таблиця нижче показує номери контактів роз'єму RPi, імена element14 (Name), номери wiringPi, номери Python, і пов'язані з ними позначення на Pi Wedge (wedge silk).
Організація автозагрузки модулів для роботи з різними шинами
Автозагрузка модулів для роботи з 1-wire:
sudo echo "w1-gpio" >>/etc/modules
або
sudo echo "w1-gpio pullup=1" >>/etc/modules
якщо будемо підключати датчики типу DS18B20 через «паразитне живлення».
sudo echo "w1_therm" >>/etc/modules
Автозагрузка модулів для роботи з I2C:
sudo echo "i2c-bcm2708" >>/etc/modules
sudo echo "i2c-dev" >>/etc/modules
Для роботи від звичайного користувача з i2c можна виконати команду:
chmod 666 /dev/i2c-1
і прописати її в файл /etc/init.d/rc.local після рядка do_start() - тоді при завантаженні системи права на запис на пристрій i2c будуть призначатися для всіх автоматично.
Автозагрузка модулів для роботи з SPI:
sudo echo "spi-bcm2708" >>/etc/modules
Для миттєвого завантаження модуля ядра без перезавантаження системи скористайтеся командою:
sudo modprobe <назва модуля>
Використання Raspberry Pi в стилі Arduino
Однією з популярних бібліотек для роботи з GPIO на RPi сьогодні є wiringPi.
Встановлення wiringPi
1. Якщо у вас немає утиліти git для роботи з github-репозиторіями, то встановлюємо:
sudo apt-get install git-core
2. Завантажуємо первинний код бібліотеки з репозиторію:
git clone git://github.com/WiringPi/WiringPi
3. Встановлюємо:
cd WiringPi
./build
Приклади використання
Після того, як встановили бібліотеку wiringPi, можемо використовувати її в своїх проектах.
Тестова програма blink.c
/*
* blink.c:
* Проста тестова програма для моргання світлодіоду на виводі 7
*/
#include <wiringPi.h>
#include <stdio.h>
int main (void)
{
int pin = 7;
printf("Raspberry Pi wiringPi blink test\n");
if (wiringPiSetup() == -1)
exit (1);
pinMode(pin, OUTPUT);
for (;;){
printf("LED On\n");
digitalWrite(pin, 1);
delay(250);
printf("LED Off\n");
digitalWrite(pin, 0);
delay(250);
}
return 0;
}
Залишилось зібрати і запустити:
cc -o blink -lwiringPi -L/usr/local/lib blink.c
sudo ./blink
Ми повинні отримати світлодіод, який моргає. Тепер можна зробити щось більш цікаве:
/*
* buttonLED.c:
* Проста тестова програма для зміни частоти моргання світлодіоду, коли натиснута кнопка
*/
#include
#include
int main (void)
{
int pin_LED = 7; // GPIO7 / вивод 7 роз’єма
int pin_switch = 8; // SDA0 / вивод 3 роз’єма
int del = 250;
printf ("Raspberry Pi wiringPi button LED test\n") ;
if (wiringPiSetup() == -1)
exit (1);
pinMode(pin_LED, OUTPUT);
pinMode(pin_switch, INPUT);
for (;;){
if (digitalRead (8) == 0){ // кнопка натиснута
del = 100;
} else {
del = 250;
}
digitalWrite(pin_LED, 1);
delay(del);
digitalWrite(pin_LED, 0);
delay(del);
}
return 0 ;
}
Основні бібліотечні функції
Бібліотека повинна бути обов’язково ініціалізована викликом функції wiringPiSetup () ;
Після цього можна використовувати бібліотечні функції. Якщо бібліотека була ініціалізована функцією wiringPiSetup (), то в функції треба передавати «віртуальний» номер виводу. Вище була таблиця відповідності «віртуальних» виводів реальним, але її завжди можна отримати за допомогою команди:
gpio readall
(утиліта gpio встановлюється автоматично разом з бібліотекою WiringPi)
void pinMode (int pin, int mode)
Встановлює режим роботи виводу. Доступні значення параметра mode: INPUT, OUTPUT, PWM_OUTPUT, GPIO_CLOCK.
Примітка: Режим роботи PWM_OUTPUT підтримується лише виводом BCM_GPIO 18, режим GPIO_CLOCK підтримується лише виводом BCM_GPIO 4
void pullUpDnControl (int pin, int pud)
Включає внутрішні підтягуючі опори для виводу, який працює в режимі INPUT.
Можливі значення PUD_OFF (підтягуючі опори відключені), PUD_DOWN (подтягування до землі), PUD_UP (подтягування до 3.3В).
Підтягуючі опори на RPi мають величину опору 50KОм
void digitalWrite (int pin, int value)
Встановлює високий (value=1)/низький рівень (value=0) на виводі, який працює в режимі OUTPUT
void pwmWrite (int pin, int value)
Параметр value задає коефіцієнт заповнення імпульсу. value приймає значення від 0 (0% заповнення імпульсу) до 1024 (100% заповнення імпульсу).
Апаратна ШІМ підтримується лише виводом BCM_GPIO 18.
int digitalRead (int pin)
Зчитується стан виводу. В залежності від логічного рівня функція повертає 0 або 1.
analogRead (int pin)
Функція читає значення АЦП. Оскільки на RPi немає вбудованого АЦП, то перед викликом функції в програмі необхідно ініціалізувати зовнішній АЦП.
analogWrite (int pin, int value)
Функція записує значення в АЦП.
Часові функції
unsigned int millis (void)
Повертає час (в мілісекундах), який пройшов з моменту виклику функції ініціалізації (wiringPiSetup) бібліотеки WiringPi.
Значення обнулюється через 49 днів.
unsigned int micros (void)
Повертає час (в мікросекундах), який пройшов з моменту виклику функції ініціалізації (wiringPiSetup) бібліотеки WiringPi.
Значення обнулюється приблизно через 71 хвилину.
void delay (unsigned int howLong)
Призупиняє виконання програми на період часу, заданий в параметрі howLong (задається в мілісекундах).
void delayMicroseconds (unsigned int howLong)
Призупиняє виконання програми на період часу, заданий в параметрі howLong (задається в мікросекундах)
Переривання
int wiringPiISR (int pin, int edgeType, void (*function)(void))
Регіструє функцію, яка буде виконана, коли наступить умова переривання. Умова переривання (параметр edgeType) може приймати наступні значення:
INT_EDGE_FALLING (переривання при зміні рівня на виводі з високого на низький)
INT_EDGE_RISING (переривання при зміні рівня на виводі з низького на високий)
INT_EDGE_BOTH (переривання при будь-якій зміні рівня на виводі)
INT_EDGE_SETUP
При умові INT_EDGE_SETUP не буде відбуватися ініціалізація виводу — вважається, що він вже був налаштований в іншому додатку.
У випадку, якщо наступне переривання наступає до закінчення оброблення попереднього, то воно також буде оброблене. Але, якщо 2 переривання будуть знаходитися в обробленні одночасно, то наступні переривання будуть ігноруватися.
Функція-обробник переривання виконується з високим пріоритетом (якщо програма запущена від користувача root) і виконується одночасно з основною програмою. Також вона має повний доступ до глобальних змінних і т. д.
Способи керування GPIO з використанням мов Python та Wolfram розглянемо пізніше на інших заняттях.
Завдання та питання для перевірки
1. Встановіть на RPi актуальну версію бібліотеки для роботи з GPIO.
2. Повторіть наведений в уроці приклад керування GPIO за допомогою команд echo.
3. Встановіть бібліотеку wiringPi, зберіть схему керування світлодіодом, наведену в уроці, запрограмуйте вмикання/вимикання світло діода із змінною затримкою: спочатку частота миготіння збільшується, потім – зменшується і т.д.