Raspberry Pi, interactuando con GPIO desde la línea de comandos

2013-01-12_23-14-50_804.jpg

En esta nueva entrada vamos a hablar un poco del GPIO y como podemos interactuar con el hardware de nuestro dispositivo a través del sistema.

Como ya hemos comentado anteriormente, el sistema elegido por los ingenieros que crearon Raspberry Pi fue Linux. Inicialmente la “distribución por defecto” era simple y llanamente Debian Wheezy. Digo por defecto porque era la recomendada por la fundación Raspberry Pi, no porque viniera con el dispositivo. De hecho el dispositivo, a menos que compres algún tipo de “pack”, viene pelado, es decir, no viene con ningún tipo de cable, carcasa o tarjeta de memoria.

Poco después de que empezaron a enviar los primeros dispositivos, la comunidad rápidamente creó Raspbian, una distribución basada en Debian Wheezy, pero optimizada para mejorar el rendimiento de nuestro RPi y es actualmente la distribución recomendada y la que yo tengo instalada actualmente, por lo que el resto de la entrada está basada sobre Raspbian, aunque debería ser aplicable a cualquier distribución Linux.

El kernel de mi RPi es:

[code] root@raspberrypi:~# uname -a Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux [/code]

La forma que vamos a usar interactuar con con GPIO es a través de lo que se conoce como Sysfs.

Sysfs no tiene nada que ver con Raspberry Pi, sino con Linux. Es un sistema de ficheros virtual que exporta información sobre el dispositivo y sus drivers desde el espacio del núcleo (kernel space) al de usuario (user space). Éste es parte del kernel de Linux.

Gracias a Sysfs y a que todo en Linux (*nix) es un fichero, veremos lo sencillo que es interactuar con el hardware.

En nuestro caso, Raspbian nos mapea la interface GPIO en /sys/class/gpio. Este directorio contiene tres tipos de ficheros:

  • Ficheros de Control de Interface. Inicialmente GPIO está sólo disponible en el espacio del núcleo y para poder usarlo, tenemos que pedir al núcleo que nos exporte al espacio de usuario el pin que queremos usar. Por lo tanto los ficheros de control nos sirven para pedir al núcleo el uso de cierto GPIO y también para liberar el mismo una vez hayamos terminado.
  • Los propios GPIOs. Estos aparecen en forma de directorios. Veremos más adelante que contienen.
  • Controlador GPIO. Este es también otro directorio con ciertos ficheros que proveen información sobre el chip GPIO de la placa.
Vamos a ver que tenemos en /sys/class/gpio:

[code] root@raspberrypi:~# ls -l /sys/class/gpio/ total 0 –w——- 1 root root 4096 Jan 12 20:06 export lrwxrwxrwx 1 root root 0 Jan 12 18:19 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0 –w——- 1 root root 4096 Jan 12 21:54 unexport [/code]

Como podemos ver, tenemos dos ficheros: export y unexport. Estos son los ficheros de control y un directorio, gpiochip0. Este contiene varios ficheros dentro a los que no prestaremos mucha cuenta. Por curiosidad vamos a ver que contiene el fichero label:

[code] root@raspberrypi:~# cat /sys/class/gpio/gpiochip0/label bcm2708_gpio [/code]

Como vemos nos da información sobre el chip integrado en la placa.

Como dijimos antes, los GPIOs aparecen en forma de directorios. Y como también comentamos al principio estos sólo están disponibles en el espacio del núcleo y para usarlos tenemos que exportarlos al espacio de usuario.

Para exportar un GPIO concreto, todo lo que tenemos es hacer una petición a export con el comando echo:

[code] root@raspberrypi:~# echo 0 > /sys/class/gpio/export root@raspberrypi:~# ls -l /sys/class/gpio/ total 0 –w——- 1 root root 4096 Jan 12 22:16 export lrwxrwxrwx 1 root root 0 Jan 12 22:17 gpio0 -> ../../devices/virtual/gpio/gpio0 lrwxrwxrwx 1 root root 0 Jan 12 18:19 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0 –w——- 1 root root 4096 Jan 12 21:54 unexport [/code]

El primer comando echo 0 > /sys/class/gpio/export, exporta el pin 0 al espacio de usuario. Si quisiéramos exportar el pin 1: echo 1 > /sys/class/gpio/export. El parámetro del echo es el número del pin que queremos exportar. El segundo comando lanzado es un simple ls que nos muestra el listado de /sys/class/gpio. Ahora vemos un directorio más (un enlace a un directorio) correspondiente a nuestro pin 0 (gpio0):

[code] gpio0 -> ../../devices/virtual/gpio/gpio0 [/code]

Si listamos el contenido de este directorio:

[code] root@raspberrypi:~# ls -l /sys/class/gpio/gpio0/ total 0 -rw-r–r– 1 root root 4096 Jan 12 22:21 active_low -rw-r–r– 1 root root 4096 Jan 12 22:21 direction -rw-r–r– 1 root root 4096 Jan 12 22:21 edge drwxr-xr-x 2 root root 0 Jan 12 22:21 power lrwxrwxrwx 1 root root 0 Jan 12 22:16 subsystem -> ../../../../class/gpio -rw-r–r– 1 root root 4096 Jan 12 22:16 uevent -rw-r–r– 1 root root 4096 Jan 12 22:21 value [/code]

Aquí vemos varios ficheros, de los cuales hablaremos y usaremos 2 de ellos:

  • direction: este fichero contiene “in” o “out” dependiendo si estamos leyendo (in) o escribiendo (out) información. Este fichero podría no aparecer si el núcleo no permite el cambio de dirección.
  • value: contiene 0 (low) ó 1 (high). Si la dirección de este pin es “out” lo que hacemos es sobre escribir el valor. Cualquier valor distinto de 0 (low) se convierte en 1 (high), es decir, si le mandamos un 2, -1 ó 5, el valor que se almacena es 1.
Los ficheros ueven y edge se usan para el control de interrupciones, pero por lo pronto no trataremos con estos.

En este punto ya tenemos suficiente información para una pequeña prueba. Lo que haremos es conectar a nuestro RPi un LED que encenderemos y apagaremos usando los comandos que hemos visto.

A partir de este punto se requiere la conexión física de un par de cables al dispositivo. RPi no proporciona ningún tipo de protección, como por ejemplo Arduino, por lo que nos equivocamos y metemos corriente por el sitio equivicado puedes dañar tu RPi. Por lo tanto ten mucho cuidado y no nos hacemos responsables de cualquie daño causado al dispositivo.

Otro apunte a tener en cuenta. Yo estoy usando un RPi modelo B revisión 1. La revisión 2 varía no sólo en el número de GPIOs, sino en la localización de los mismos. Por ejemplo en la revisión 1 el GPIO 0 es el pin número 3, mientras que este pin se corresponde con el GPIO 2 en la revisión 2.

Aquí puedes ver el esquema de los pines:

Raspberry-Pi-GPIO-Layout-Revision-1-e1347664808358.png Revisión 1

Raspberry-Pi-GPIO-Layout-Revision-2-e1347664831557.png Revisión 2

El esquema que voy a seguir es el visto en la siguiente imagen, con la salvedad que el cable amarillo irá al pin número 3, correspondiente a nuestro GPIO 0.

1led_gpio_bb1.jpg https://projects.drogon.net/wp-content/uploads/2012/06/1led_gpio_bb1.jpg

El material que necesitamos además del RPi:
  • Placa de pruebas
  • Dos cables. Idealmente con las macho/hembra. Yo los cables que tengo son machos (mu machos!) por ambos extremos y para no soldar nada al RPi, rebusqué por un cajón y me encontré con un cable IDE (disco duro) el cual me hizo el avío, como puedes ver en la imagen que encabeza la entrada.
  • 1 LED
  • Una resistencia idealmente entre 220 y 330 ohmios.
Ya que lo tenemos todo conectado y el sistema arrancado, vamos al lío. Lo primero que vamos a hacer es decir al kernel que queremos usar el GPIO 0 (recuerda, si as seguido el mismo esquema y tienes la revisión 2, tendrías que exportar el GPIO 2).

[code] root@raspberrypi:~# echo 0 > /sys/class/gpio/export [/code]

Listemos el contenido de nuestro gpio0 para asegurarnos que está allí:

[code] root@raspberrypi:~# ls -l /sys/class/gpio/gpio0/ total 0 -rw-r–r– 1 root root 4096 Jan 12 23:44 active_low -rw-r–r– 1 root root 4096 Jan 12 23:44 direction -rw-r–r– 1 root root 4096 Jan 12 23:44 edge drwxr-xr-x 2 root root 0 Jan 12 23:44 power lrwxrwxrwx 1 root root 0 Jan 12 23:43 subsystem -> ../../../../class/gpio -rw-r–r– 1 root root 4096 Jan 12 23:43 uevent -rw-r–r– 1 root root 4096 Jan 12 23:44 value [/code]

Ahora lo que haremos es establecer la dirección. Lo pondremos como salida (out)

[code] root@raspberrypi:~# echo out > /sys/class/gpio/gpio0/direction [/code]

Y si todo ha ido bien, encendamos el LED:

[code] root@raspberrypi:~# echo 1 > /sys/class/gpio/gpio0/value [/code]

Y ahora apaguémoslo:

[code] root@raspberrypi:~# echo 0 > /sys/class/gpio/gpio0/value [/code]

Para consultar el valor establecido en cualquiera de los ficheros, podemos usar el comando cat:

[code] root@raspberrypi:~# cat /sys/class/gpio/gpio0/direction out root@raspberrypi:~# cat /sys/class/gpio/gpio0/value 0 [/code]

Una vez que hayamos terminado de usar el GPIO, deberíamos liberarlo:

[code] root@raspberrypi:~# echo 0 > /sys/class/gpio/unexport [/code]

Hasta aquí hemos llegado. Ya veremos en futuras entradas más cositas de este gran dispositivo.