В этой статье описаны эксперименты с GPIO (General Purpose Input/Output, Входы/Выходы общего назначения) контактами Raspberry Pi. Я попробовал работать с ними тремя способами: Python, Bash и C. В этой статье будет описаны все три способа. Но для начала немного информации о настройке и подготовке.
Подключение к GPIO контактам RPi: Я использовал старый IDE шлейф от флоппи дисковода. Он имеет 34 контакта, а RPi имеет только 26 контактов, поэтому часть разъема не используется. На другом конце шлейфа припаяны BLS штырьки, которые вставлены в макетную плату и до сих пор очень хорошо работают.
Подключение выводов: По ссылкам есть таблица с значением выводов и схема их расположения. Выводы считаются слева на право, сверху вниз начиная с вывода 3.3В. Вот как использованы контакты у меня:
Вывод 2: 5В
Вывод 3: "GPIO0". К нему подключен один из выводов выключателя, другой его вывод подключен к GND. Этот вывод GPIO имеет внутренний подтягивающий pull-up резистор. Это означает, что когда переключатель не замкнут, на выходе высокий уровень, а когда замкнут – низкий.
Вывод 6: GND (этот вывод подключен к GND макетной платы)
Вывод 7: "GPIO4". К нему подключается анод светодиода через резистор 220 Ом.
Во всех следующих примерах будет использовано такое подключение. Различные библиотеки используют различные выводы, создавая путаницу, поэтому я постараюсь избавиться от неё. Также отметим, что всё это делается в режиме SSH, поэтому монитор не подключен.
Важное примечание: В RPi Wiki написано, что GPIO выводы небуферизованны и незащищены, поэтому короткое замыкание представляет опасность для всего RPi, поэтому будьте осторожны! Разрабатывается новая версия платы с защитой.
Важное примечание: Все программы, которые обращаются к GPIO контактам должны быть запущены с правами администратора, иначе вы получите сообщение об ошибке.
Python
Это один из моих любимых языков, поэтому я решил попробовать его. Во-первых, установите pip (Python package installer, пакет установки Python):
sudo curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
Затем установите RPi.GPIO модуль для Python:
sudo pip install rpi.gpio
Теперь вы можете войти в интерпретатор Python (sudo python), и делать такие вещи:
import RPi.GPIO as GPIO
GPIO.setup(7, GPIO.OUT)
GPIO.output(7, True)
GPIO.output(7,False)
Bash
Я всегда любил Unix за то, что основной его идеей является то, что все является файлом. GPIO контакты Raspberry Pi также являются файлами! С применением нашей макетной платы мы можем зажигать и гасить светодиод.
sudo su -
echo "4" > /sys/class/gpio/export
echo "4" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio4/direction
echo "1" > /sys/class/gpio/gpio4/value
echo "0" > /sys/class/gpio/gpio4/value
Для чтения входов используйте команду "cat" и путь файла.
echo "0" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio0/direction
cat /sys/class/gpio/gpio0/value
C
Старый добрый C. Базовый пример для C действительно сложный, но, к счастью Гордон написал Arduino подобную библиотеку, но для Raspberry Pi! Итак, вот что нужно сделать:
Загрузите и установите библиотеку:
cd /tmp
wget http://project-downloads.drogon.net/files/wiringPi-1.tgz
tar xfz wiringPi-1.tgz
cd wiringPi/wiringPi
make
sudo make install
В системе вашего Raspberry Pi теперь установлена библиотека wiringPi, поэтому мы можем написать небольшую программу с использованием её.
cd ~
nano blink.c
Скопируйте код данной программы:
/* * blink.c: * Simple test program to blink an LED on pin 7 */ #include #include 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; }
Компилируем код:
gcc -o blink blink.c -L/usr/local/lib -lwiringPi
И запускаем:
sudo ./blink
У вас должен получиться мигающий светодиод. Теперь можно сделать что-то более интересное:
/* * buttonLED.c: * Simple test program to change the blinking rate of an LED when a button is pressed */ #include #include int main (void) { int pin_LED = 7; // GPIO7 / header pin 7 int pin_switch = 8; // SDA0 / header pin 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){ // button pressed del = 100; } else { del = 250; } digitalWrite(pin_LED, 1); delay(del); digitalWrite(pin_LED, 0); delay(del); } return 0 ; }
А как же функция analogRead? К сожалению, в отличие от Arduino, RPi не имеет встроенного АЦП (аналого-цифрового преобразователя). Но некоторые из разрабатываемых плат будут включать в себя АЦП, например Gertboard
Комментарии (18) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация
compilation terminated.
Почему так происходит?
time.sleep(1)
GPIO.setup(7, GPIO.OUT)
GPIO.output(7, True)
GPIO.output(7,False)
GPIO.setup(7, GPIO.OUT) # определяет с каким портом будем работать
GPIO.output(7, True) # включает порт, светодиод горит
GPIO.output(7,False) # выключает, светодиод гаснет
Написан на питоне. Могу ошибаться
echo "4" > /sys/class/gpio/export
echo "4" > /sys/class/gpio/export
И почему 4, если во всех примерах используется 7й пин. Просто это сбивает с толку.
Да, кстати и что вернет cat /sys/class/gpio/gpio0/value
0/1 или true/false?
И статью можно было бы подправить с учетом комментариев и ответов на них.
wiringPi.c: In function ‘wiringPiSetup’:
wiringPi.c:305:28: error: ‘caddr_t’ undeclared (first use in this function)
gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
^
wiringPi.c:305:28: note: each undeclared identifier is reported only once for each function it appears in
wiringPi.c:305:36: error: expected ‘)’ before ‘gpioMem’
gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
^
wiringPi.c:305:22: error: too few arguments to function ‘mmap’
gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
^
In file included from wiringPi.c:50:0:
/usr/include/arm-linux-gnueabihf/sys/mman.h:57:14: note: declared here
extern void *mmap (void *__addr, size_t __len, int __prot,
^
Makefile:50: recipe for target 'wiringPi.o' failed
make: *** [wiringPi.o] Error 1
Что это такое?