Raspberry Pi: utilizando los GPIOs desde PHP y Symfony

2019-06-12 - Categorías: GNU/Linux / PHP / 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/

8 respuestas a “Raspberry Pi: utilizando los GPIOs desde PHP y Symfony”

  1. Guille dice:

    Amigo, que buen dato me tiraste, voy a hacer pruebas mas tarde, te consulto: hiciste alguna prueba leyendo un pin, en vez de escribir en el? Gracias

  2. Gonzalo dice:

    Muy bueno.. voy a instalar LAMP y hacerlo accesible desde afuera con port mapping. Linda data! gracias

  3. Gonzalo dice:

    Hola! muchas gracias por la info! estoy teniendo problemas de permisos, me podrías orientar?

    Asigné a toda la carpta /var/www al usuario www-data y les di permiso 777 sin embargo al correr tu script tengo un error de php «fopen(/sys/class/gpio/export): failed to open stream: Permission denied»

    • Jnj dice:

      Hola Gonzalo!
      De nada, gracias por dejar un comentario.
      En mi Raspberry los archivos de la carpeta /sys/class/gpio/export son del usuario root y grupo gpio. En teoría si añades al usuario www-data al grupo gpio debería de funcionar. Si estás corriendo el servidor web desde tu usuario, entonces correrá con el usuario pi, habría que añadir al usuario pi al grupo gpio en tal caso.

  4. Hola. El tutorial está muy claro y bien explicado. Me gustaría añadir que hay una manera de poder acceder directamente a los puertos GPIO para controlar los leds sin necesidad de instalar nada a parte del PHP, claro está. He realizado una clase en PHP para acceder a los puertos directamente. El uso se basa en la escritura/lectura de los GPIO tal cual se hace con un fichero. Esto permite un acceso directo y nativo de PHP. Por si a alguien le puede servir también, dejo el enlace. Siempre se puede aprender alguna cosa más y ayuda a generar nuevas ideas. Gracias de nuevo por el tutorial. https://rafamartin10.blogspot.com/2021/08/clase-en-php-para-encenderapagar-led-en.html

    • Jnj dice:

      Hola Rafael!
      Muchas gracias por el aporte! Te he dado una estrella en GitHub por el repositorio con la clase en PHP que has creado ???
      Igual te parece interesante este otro post relacionado:
      https://jnjsite.com/raspberry-pi-gnu-linux-encendiento-y-apagando-cosas/
      ..hay llamadas al sistema de ficheros para configurar los GPIO desde línea de comandos.
      En teoría se tienen que poder lanzar estos comandos del sistema desde cualquier lenguaje de programación instalado en la Raspberry Pi.
      Saludos!

Deja una respuesta

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

 

© 2024 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.