Raspberry Pi: utilizando los GPIOs desde PHP y Symfony

Hoy traigo un howto para instalar PHP 7.2 en la Raspberry Pi.. luego un proyecto Symfony 4, con Symfony Flex.. y finalmente un code-kata para lanzar algunos comandos para encender unos LEDs conectados a unos pines del chip GPIO de la Raspberry Pi. Simplemente es un post de arranque para controlar desde PHP, con acceso casi directo a hardware, el chip de los GPIOs. Así de paso con Symfony, que aunque no es necesario, ayuda mucho en cualquier proyecto por los todos los extras que aporta.

Por si no lo conoces, Raspberry Pi es un pequeño ordenador de propósito general de apenas 30 €, que la última versión a fecha de hoy trae HDMI, USBs, Wifi, Gigabit Ethernet, GPIOs, etcétera. Siempre ha hecho furor entre los programadores, y en la comunidad maker de dispositivos electrónicos. Una de las tareas para las que puede servir, es como servidor de páginas web, y en paralelo, puede controlar cualquier dispositivo que se ocurra conectar a los GPIOs. La última versión que es la Raspberry Pi 3B+ tiene 1 GB de RAM, con un procesador de 4 núcleos, más que suficiente para darle la potencia lógica a casi cualquier dispositivo que quieras probar de construir.

Por otro lado tenemos que haciendo scripting en PHP se vuelve todavía más sencillo ya que PHP es muy permisivo para los nuevos que entran a la programación. Y para los nuevos como yo en el IoT, el empezar a juguetear con estas cosas, se vuelve muy divertido. Además así con Symfony como he dicho, de paso nos llevamos una tonelada de utilidades para hacer interfaces web, manejar bases de datos, almacenar y procesar, lanzar tareas automáticas, etc.. todo desde la Raspberry Pi. ¿A que pinta bien y se te ocurren muchas ideas? 😉

Instalando PHP

Entonces, nos hacemos administradores, y ejecutamos como administrador lo siguiente:

sudo su
apt-get install apt-transport-https lsb-release ca-certificates
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
echo "deb https://packages.sury.org/php/ stretch main" > /etc/apt/sources.list.d/php.list
apt update
apt install php7.2 php7.2-xml

A partir de aquí ya tenemos el hardware, sysfs (luego vamos con esto), y PHP. Mira que he añadido algunos módulos de PHP como el de XML porque se necesitan para Symfony.

No instalando Apache, Mariadb/Mysql

Para instalar estos servicios basta con seguir unas instrucciones estándar de cualquier otra instalación de servidor. Esto es material para otro post, así que me voy a centrar en lo peculiar de trabajar Symfony y la Raspberry Pi.

Para este post tendremos los siguientes elementos de software trabajando juntos:

  • Sysfs, el sistema de ficheros.
  • PHP.
  • PiPHP/GPIO.
  • Symfony con algunos vendors.

Es curioso que los GPIOs de la Raspberry Pi son accesibles directamente haciendo llamadas al sistema de ficheros. Es decir, podemos hablar casi directamente con la capa de hardware, desde PHP, a través del sistema de ficheros. Cómo se hace ésto en concreto, lo podemos encontrar dentro del proyecto PiPHP/GPIO que referencio al final del post, alojado en Github.. ¡una joya del software!

Accediendo a los GPIOs con PHP

Los GPIO de la Raspberry son los famosos pines que tiene este pequeño PC para conectar casi cualquier cosa: sensores, motores, luces, etc.. GPIO es la abreviatura de General Purpose Input Output. En la última versión de la Raspi tenemos 40.

Dentro del proyecto que acabamos de crear, instalamo https://github.com/PiPHP/GPIO, una librería para PHP de acceso a bajo nivel de los GPIO de la Raspberry Pi.

composer require piphp/gpio

Para acceder desde cualquier fichero PHP del proyecto, a las funcionalidades de PiPHP/GPIO, basta con añadir esto en la cabecera:

use PiPHP\GPIO\GPIO;
use PiPHP\GPIO\Pin\PinInterface;

Y en el cuerpo del programa algo tal que así:

$gpio = new GPIO();
        
$pinsOut[17] = $gpio->getOutputPin(17);
$pinsOut[27] = $gpio->getOutputPin(27);
$pinsOut[22] = $gpio->getOutputPin(22);

$interval = 0.1;

for($i = 0; $i < 100; $i++) {
    $pinsOut[17]->setValue(PinInterface::VALUE_HIGH);
    usleep($interval * 1000000);
    $pinsOut[17]->setValue(PinInterface::VALUE_LOW);
    $pinsOut[27]->setValue(PinInterface::VALUE_HIGH);
    usleep($interval * 1000000);
    $pinsOut[27]->setValue(PinInterface::VALUE_LOW);
    $pinsOut[22]->setValue(PinInterface::VALUE_HIGH);
    usleep($interval * 1000000);
    $pinsOut[22]->setValue(PinInterface::VALUE_LOW);
    usleep($interval * 1000000);
} 

Éste código simplemente pone en modo salida los pines 17, 27 y 22. Encendiendo y apagando unos LEDs que tengo conectados..

Creando un proyecto Symfony

Lo siguiente para encapsular la aplicación completa es ponerle la cáscara de proyecto Symfony. Así tendremos la tonelada de utilidades de Symfony para hacernos el día a día más fácil:

cd /home/pi
mkdir projects-src-pi
cd projects-src-pi/
composer create-project symfony/skeleton symfony-testing
cd symfony-testing

Accediendo a los GPIOs con Symfony

Vamos ahora a hacer un comando y así probamos los GPIO desde Symfony. Para esto añadimos el maker de Symfony y generamos el comando:

composer require --dev maker
php bin/console make:command

..le he llamado app:gpio-check, así de esta manera una forma de dar valores de salida a los pines 17, 22 y 27 podría ser como el script siguiente. Simplemene se encienden y se apagan uno detrás de otro:

<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use PiPHP\GPIO\GPIO;
use PiPHP\GPIO\Pin\PinInterface;

class GpioCheckCommand extends Command
{
    protected static $defaultName = 'app:gpio-check';

    protected function configure()
    {
        $this
            ->setDescription('Just testing the library!')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        
        // Create a GPIO object
        $gpio = new GPIO();
        
        $pinsOut[17] = $gpio->getOutputPin(17);
        $pinsOut[27] = $gpio->getOutputPin(27);
        $pinsOut[22] = $gpio->getOutputPin(22);

        $interval = 0.1;

        for($i = 0; $i < 100; $i++) {
            $pinsOut[17]->setValue(PinInterface::VALUE_HIGH);
            usleep($interval * 1000000);
            $pinsOut[17]->setValue(PinInterface::VALUE_LOW);
            $pinsOut[27]->setValue(PinInterface::VALUE_HIGH);
            usleep($interval * 1000000);
            $pinsOut[27]->setValue(PinInterface::VALUE_LOW);
            $pinsOut[22]->setValue(PinInterface::VALUE_HIGH);
            usleep($interval * 1000000);
            $pinsOut[22]->setValue(PinInterface::VALUE_LOW);
            usleep($interval * 1000000);
        } 

        $io->success('The command have just finished! All done!');
    }
}

Este código podemos lanzarlo con Symfony desde línea de comandos poniendo:

php bin/console app:gpio-check

Bibliografía, terminando

Ya sólo me queda decir que funciona xDDD estos 3 LEDs de la foto son los que se encienden y se apagan:

Unas referencias para el que quiera seguir curioseando:

https://github.com/PiPHP/GPIO
https://www.raspberrypi.org/
https://symfony.com/

Compartir..

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *