Навчальний посібник з керування світлодіодами з допомогою Robotics Development Kit

У цьому навчальному посібнику демонструється управління контактами GPIO на простому прикладі, аналогічному написання найпростішої програми «Hello World»: шляхом налаштування плати UP так, щоб можна було блимати зовнішнім світлодіодом.




Плата UP у складі Robotics Development Kit
Комплект Intel RealSense Robotics Development Kit (RDK) складається з камери глибини Intel RealSense R200 і плати Aaeon* UP. Плата UP в цій системі є обчислювальним ядром. Для підключення зовнішніх пристроїв ця плата обладнана 40-контактної клемою вводу-виводу, показаної на малюнку вище. На платі UP розміщено в цілому 28 незалежних контактів GPIO, виведених на клему вводу-виводу. Для плати UP розроблені драйвери платформи ядра Ubuntu 14.04, що забезпечують нумерацію контактів GPIO в Linux в діапазоні від 0 до 27 з емуляцією можливостей плати Raspberry Pi.

Доступ до апаратних GPIO у цьому навчальному посібнику буде здійснюватися на низькому рівні з допомогою Linux sysfs. За допомогою Sysfs користувачі Linux (або код в користувацькому просторі) можуть взаємодіяти з пристроями на рівні системи (ядра).

Для цього навчального посібника не потрібні ніякі особливі бібліотеки, оскільки використовується інтерфейс sysfs.

Важливо! Зверніть увагу, що номери Linux GPIO на рис. 1 відрізняються і від номерів фізичних контактів, і від розводки на платі UP. Номери Linux GPIO призначаються у відповідності зі схемою нумерації GPIO Raspberry Pi BCM.

Для порівняння з розводкою на платі Raspberry Pi відвідайте сайт.

Як запалити світлодіод з допомогою плати UP
Досить налаштувати плату UP у складі RDK згідно керівництву по швидкому запуску From Zero to Hero: Getting up and running with the Intel RealSense Robotic Development Kit, і все готове для роботи над першим справжнім проектом. Ми будемо управляти включенням світлодіода з допомогою мови програмування C і контактів GPIO на платі UP.

Що ви дізнаєтеся
Ви зберете найпростішу електричну схему і підключіть її до контактів GPIO плати UP.

Що знадобиться
  • 1 невеликий світлодіод будь-якого кольору.
  • 1 резистор на 50 Ом.
  • Одножильний провід невеликого перерізу.
  • Макетні затискачі або затискачі типу «крокодил» (або і ті, і інші) для фіксації контактів.
Хай буде світло!
Перед написанням коду слід ознайомитися з нумерацією контактів на платі UP і зібрати просту електричну ланцюг. Для початку ми просто включимо світлодіод, використовуючи контакт 3,3 В і контакт заземлення на платі UP. Схема нашої електричної ланцюга така:


Перед початком роботи відключіть плату UP. Якщо працювати з нею у включеному стані, існує ризик короткого замикання, а цього слід уникати, особливо якщо врахувати, що це наш перший проект.

  • Виходячи з наявних деталей, зберіть електричне коло або на монтажній платі, або за допомогою затискачів-«крокодилів».
  • Контакт 1 (+3,3 В) повинен бути підключений до довгій ніжці світлодіода (анод). Цей контакт подає напругу 3,3 Ст. На відміну від контактів GPIO на платі UP цей контакт не є програмованим: неможливо керувати ним за допомогою програмного забезпечення.
  • Підключіть коротку ніжку світлодіода до резистору. Потім підключіть другий контакт резистора до контакту 6 (заземлення) на платі UP.
Ще раз перевірте, як все підключено. Коли все буде готово, електричний ланцюг має виглядати так:


Увімкніть плату UP. Світлодіод повинен відразу ж загорітися.

Управління світлодіодом за допомогою програмного коду
Отже, найпростіша електрична ланцюг перевірена, тепер пора переключити позитивний дріт з постійно включеного контакту 3,3 на один з програмованих контактів GPIO. Ось як буде виглядати схема:


  • Знову вимкніть плату UP перед тим, як змінювати що-небудь у з'єднанні.
  • Перенесіть позитивний дріт з контакту 1 на контакт 7.
Коли все буде готово, електричний ланцюг має виглядати так:


Вихідний код для управління миготінням
Наведений нижче приклад вихідного коду змусить блимати світлодіод.

Вихідний код
#include < sys/stat.h>
#include < sys/types.h>
#include <fcntl.h>
#include < stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define IN 0
#define OUT 1

#define LOW 0
#define HIGH 1

#define PIN 24 /* physical pin 18 */
#define POUT 4 /* physical pin 7 */

static int GPIOExport(int pin);
static int GPIOUnexport(int pin);
static int GPIODirection(int pin, int dir);
static int GPIORead(int pin);
static int GPIOWrite(int pin, int value);

int main(int argc, char *argv[])
{
int repeat = 9;

/*
* Enable GPIO pins
*/
if (-1 == GPIOExport(POUT) || -1 == GPIOExport(PIN))
return(1);

/*
* Set GPIO directions
*/
if (-1 == GPIODirection(POUT, OUT) || -1 == GPIODirection(PIN, IN))
return(2);

do {
/*
* Write GPIO value
*/
if (-1 == GPIOWrite(POUT, repeat % 2))
return(3);

/*
* Read GPIO value
*/
printf("i'm reading %d in GPIO %d\n", GPIORead(PIN), PIN);

usleep(500 * 1000);
}
while (repeat--);

/*
* Disable GPIO pins
*/
if (-1 == GPIOUnexport(POUT) || -1 == GPIOUnexport(PIN))
return(4);

return(0);
}

Int GPIOExport(int pin)
{
#define BUFFER_MAX 3
char buffer[BUFFER_MAX];
ssize_t bytes_written;
int fd;

fd = open("/sys/class/gpio/export", O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open export for writing!\n");
return(-1);
}

bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
write(fd, buffer, bytes_written);
close(fd);
return(0);
}

Int GPIOUnexport(int pin)
{
char buffer[BUFFER_MAX];
ssize_t bytes_written;
int fd;

fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open unexport for writing!\n");
return(-1);
}

bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
write(fd, buffer, bytes_written);
close(fd);
return(0);
}

Int GPIODirection(int pin, int dir)
{
static const char s_directions_str[] = "in\0out";

#define DIRECTION_MAX 35
char path[DIRECTION_MAX];
int fd;

snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);
fd = open(path, O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open gpio direction for writing!\n");
return(-1);
}

if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) {
fprintf(stderr, "Failed to set direction!\n");
return(-1);
}

close(fd);
return(0);
}

Int GPIORead(int pin)
{
#define VALUE_MAX 30
char path[VALUE_MAX];
char value_str[3];
int fd;

snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open gpio value for reading!\n");
return(-1);
}

if (-1 == read(fd, value_str, 3)) {
fprintf(stderr, "Failed to read value!\n");
return(-1);
}

close(fd);

return(atoi(value_str));
}

Int GPIOWrite(int pin, int value)
{
static const char s_values_str[] = "01";

char path[VALUE_MAX];
int fd;

snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open gpio value for writing!\n");
return(-1);
}

if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) {
fprintf(stderr, "Failed to write value!\n");
return(-1);
}

close(fd);
return(0);
}


Якщо файл із вихідним кодом називається blink.c, можна скомпілювати код за допомогою наступної команди:

gcc –Wall –o blink blink.c

Висновок
У цьому навчальному посібнику по роботі з платою UP створюється найпростіша електрична схема; плата UP і програма на мові C, що використовує механізм Linux sysfs, керують роботою світлодіода, який повинен мигнути 10 разів.

У наступному навчальному посібнику у цій серії ми будемо регулювати яскравість світлодіода з допомогою даних глибини, що надходять від камери R200 і межплатформенного API Intel RealSense, для чого нам доведеться дещо переробити і електричну зніманню, і програму на C.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.