PHP on Raspberry Pi

Antes de que pueda comenzar a trabajar con PHP en Raspberry Pi, necesita instalar PHP en la máquina. En la mayoría de las situaciones, PHP se usa en tándem con un servidor web como Apache. Instalar tanto PHP como Apache en Raspberry Pi es una cuestión de ejecución:
sudo apt-get install apache2 php5
En lugar de Apache, puede instalar un servidor más liviano como lighttpd usando el
sudo apt-get install lighttpd php5
mando.

Construyendo puentes

Probablemente la forma más fácil de usar PHP con Raspberry Pi sea a través de la shell_exec()función. Esta función le permite ejecutar comandos de shell, por lo que puede actuar como una especie de puente entre PHP y Raspberry Pi. En el caso más simple, shell_exec()puede llamar a los scripts de Python que realizan ciertas tareas y controlan los pines GPIO.
Otro enfoque es implementar la biblioteca Wiring Pi [1] para trabajar con los pines GPIO y luego usar la biblioteca con PHP a través de la shell_exec()función. Para que esta solución funcione, primero debe instalar Wiring Pi en Raspberry Pi. La biblioteca no está disponible como un paquete binario, por lo que debe compilar e instalar desde el origen. Afortunadamente, este proceso es relativamente sencillo. Comience con la instalación del software Git usando:
sudo apt-get install git-core
Luego, clone el repositorio Wiring Pi Git ejecutando
git clone git://git.drogon.net/wiringPi
Cambie al wiringPidirectorio resultante y use el ./buildcomando para compilar e instalar Wiring Pi:
cd wiringPi
./build
Para asegurarse de que Wiring Pi está instalado y funciona correctamente, ejecute el gpio -vcomando; debería devolver la versión actual de Wiring Pi junto con la información básica de Raspberry Pi. A continuación, ejecute el gpio readallcomando para ver un diagrama de diseño de GPIO detallado.
Para poner Wiring Pi al uso práctico, construiré una aplicación PHP súper simple para controlar un LED. Conecte un LED con una resistencia al pin GPIO 17 y GND como se muestra en la Figura 1 . Abra el terminal en su Raspberry Pi (o conéctese a través de SSH) y cambie al /var/wwwdirectorio. Luego, use el sudo nano gpio.phpcomando para crear el gpio.phparchivo para editar. Coloque el código en el Listado 1(adaptado del sitio web de Raspberry Pi Tutorials [2] ) en el archivo.
Listado 1
Aplicación PHP simple para controlar un LED
01 <html>
02 <head>
03 <meta name=”viewport” content=”width=device-width” />
04 <title>LED Control</title>
05 </head>
06 <body>
07 LED Control:
08 <form method=”get” action=”gpio.php”>
09 <input type=”submit” value=”ON” name=”on”>
10 <input type=”submit” value=”OFF” name=”off”>
11 </form>
12 <?php
13 $setmode17 = shell_exec(“/usr/local/bin/gpio -g mode 17 out”);
14 if(isset($_GET[‘on’])){
15 $gpio_on = shell_exec(“/usr/local/bin/gpio -g write 17 1”);
16 echo “LED is on”;
17 }
18 else if(isset($_GET[‘off’])){
19 $gpio_off = shell_exec(“/usr/local/bin/gpio -g write 17 0”);
20 echo “LED is off”;
21 }
22 ?>
23 </body>
24 </html>
El elemento clave de la aplicación es un formulario HTML que contiene ONOFFbotones. Cuando presiona uno de los botones, su valor se pasa como una parte de la URL ( gpio.php?on=ONgpio.php?off=OFF). El pin 17 de GPIO está controlado por un código PHP que usa la shell_exec()función. La declaración en la línea 13 establece el modo del pin a out; el bloque de código en las líneas 14-21 lee el valor actual de la URL y usa la shell_exec()función para encender y apagar el pin.

Ahora, señale el navegador a http://127.0.0.1/gpio.php (reemplace 127.0.0.1 con la dirección IP real de la Raspberry Pi) y use los botones para encender y apagar el LED conectado a la Raspberry Pi (Figura 2).
                                      Fig.2

Si los botones no funcionan, lo más probable es que el servidor web no tenga los derechos adecuados para ejecutar comandos de shell. Para solucionar esto, ejecute el sudo visudocomando y agregue la siguiente línea al sudoersarchivo:
www-data ALL=NOPASSWD: ALL
Además, asegúrese de que el /var/wwwdirectorio pertenece al www-datausuario y grupo (use sudo chown -R www-data:www-data /var/wwwpara establecer el propietario correcto).
Incluso esta aplicación PHP muy simple se puede usar de varias maneras con un mínimo de ajustes. Por ejemplo, utilizo un interruptor de transistor simple conectado a Raspberry Pi para controlar mi cámara SLR de película [3] . La solución original usó un script simple de Python para controlar el cambio. Para ejecutar el script, tuve que hacer esto a través de una conexión SSH, que no era muy práctica en muchas situaciones. Entonces, modifiqué el script PHP de ejemplo para usarlo con el interruptor de transistor (Listado 2).
Listado 2
Aplicación de PHP para controlar un interruptor de transistor
01 <html>
02 <head>
03 <meta name=”viewport” content=”width=device-width” />
04 <title>Trigger</title>
05 </head>
06 <body>
07 Trigger switch:
08 <form method=”get” action=”switch.php”>
09 <input type=”submit” value=”Trigger” name=”switch”>
10 </form>
11 <?php
12 $setmode17 = shell_exec(“/usr/local/bin/gpio -g mode 17 out”);
13 if(isset($_GET[‘switch’])){
14 $gpio_off = shell_exec(“/usr/local/bin/gpio -g write 17 1”);
15 sleep (0.5);
16 $gpio_on = shell_exec(“/usr/local/bin/gpio -g write 17 0”);
17 echo “Done!”;
18 }
19 ?>
20 </body>
21 </html>
Todo lo que tuve que hacer fue quitar uno de los botones y modificar los comandos en la ifcondición para encender el interruptor, esperar 0,5 segundos (para que la cámara registre la señal), y luego apagar el interruptor. Ahora, puedo usar la aplicación PHP para activar mi cámara desde cualquier computadora y dispositivo móvil.

Tomando la ruta gpio-php

Aunque el uso de Wiring Pi a través de shell_exec()llamadas ofrece una manera fácil de controlar los pines GPIO en scripts PHP, no es la única opción a su disposición. El proyecto php-gpio [4] , por ejemplo, proporciona una biblioteca PHP dedicada para acceder al pin GPIO en Raspberry Pi. Para comenzar con php-gpio, use los siguientes comandos para instalar la biblioteca y los archivos que la acompañan en el /home/pidirectorio:
wget http://getcomposer.org/composer.phar
php composer.phar create-project –stability=’dev’ronanguilloux/php-gpio
php-gpio utiliza un puñado de llamadas API simples para establecer pines GPIO y cambiar sus estados de un script PHP. Para habilitar esta funcionalidad, sin embargo, la secuencia de comandos debe contener las siguientes declaraciones que cargan la biblioteca y configuran un pin GPIO:
require ‘vendor/autoload.php’;
use PhpGpio\Gpio;
$gpio = new GPIO();
$gpio->setup(17, “out”);
En este ejemplo, la última instrucción establece el pin 17 de GPIO para la salida. Controlar los pines requiere dos comandos más:
$gpio->output(17, 1)
$gpio->output(17, 0)
El primero establece el estado del pin 1(es decir, lo enciende) y el segundo cambia el estado a 0(es decir, desactiva el pin). Finalmente, el $gpio->unexportAll()comando restablece todos los pines.
Al usar estos comandos, puede acelerar rápidamente un simple script PHP que parpadea el LED conectado al pin 17 de GPIO ( Listado 3 ).

Listado 3
Script PHP simple para parpadear LED
01 <?php
02 require ‘vendor/autoload.php’;
03 use PhpGpio\Gpio;
04 $gpio = new GPIO();
05 $gpio->setup(17, “out”);
06 while (true){
07 $gpio->output(17, 1);
08 sleep(1);
09 $gpio->output(17, 0);
10 sleep(1);
11 }
Para ejecutar el script, ejecuta el sudo php blinking_led_script.phpcomando. Aunque la biblioteca php-gpio facilita el control de los pines GPIO desde scripts PHP, tenga en cuenta que los scripts mismos deben ejecutarse desde la línea de comandos. En otras palabras, no puede usar los comandos descritos directamente en las páginas PHP servidas por un servidor web.
La solución es simple: use la shell_exec()función para llamar al script desde una aplicación PHP. Por ejemplo, ejecuto una simple galería de fotos basada en PHP en mi Raspberry Pi, y he agregado la shell_exec('sudo php path/to/php-gpio/blink_led.php')declaración que llama al blink_led.phpscript. De esta forma, cuando alguien visita mi galería, el LED parpadea por un par de segundos.
El único problema es que toda la aplicación PHP se detiene mientras se ejecuta el script llamado. En el caso de la secuencia de comandos del LED parpadeante, eso podría no ser un problema, pero podría ser un problema grave si llama a una secuencia de comandos que tarda más en completarse. Afortunadamente, hay una solución fácil disponible. Puede ejecutar el script en segundo plano y descartar el resultado redireccionando el script:
shell_exec ('sudo php path /to/php-gpio/ \ 
  blink_led.php> /dev/null 2> /dev/null &');
Nuevamente, debido a que todos los scripts de PHP en Raspberry Pi deben ejecutarse con privilegios de administrador, debe agregar el www-datausuario al sudoersarchivo.
La biblioteca php-gpio también puede usarse para otros usos más avanzados. El repositorio phit-gpio-web GitHub, por ejemplo, contiene una aplicación web simple [5] que muestra cómo crear una interfaz web para controlar un LED, y el proyecto temperature-pi [6] muestra cómo leer y registrar datos de un sensor de temperatura
En este artículo, describí brevemente los posibles enfoques para usar PHP en Raspberry Pi. Y los scripts de ejemplo ofrecen algunos consejos para controlar GPIO a través de scripts PHP. Entonces, si quieres usar PHP con Raspberry Pi, ahora sabes por dónde empezar.

CONTROL GPIO EN SCRIPTS PHP

Una y otra vez surge la pregunta, cómo los GPIO pueden ser controlados o leídos de los scripts de PHP. Aquí hay algunas soluciones sugeridas.

exec y shell_exec

PHP no contiene funciones GPIO. Por lo tanto, para el control de GPIO debe recurrir a comandos externos, scripts bash o python y llamarlos desde el código PHP. Esto es posible, entre otras cosas, con las siguientes dos funciones de PHP:
  • execDocumentación ): exec("cmd")ejecuta el comando y devuelve la última línea del resultado (es decir, la salida estándar). En dos parámetros opcionales, puede pasar una referencia a la matriz output, así como una referencia a la variable returnvaroutputcontiene después de llamar a una matriz con todas las líneas de resultado del comando (salida estándar), returnvarel estado de retorno del comando.
  • shell_execDocumentación ): el shell_exec("cmd")comando especificado también se ejecuta. La función devuelve el resultado completo (es decir, la salida estándar) del comando, no solo la última línea. El estado de devolución se pierde. Si lo necesita, tiene que exectrabajar con eso.
execshell_exectrabaja sincrónicamente Por lo tanto, el script PHP no se continúa hasta que se complete la ejecución del comando. No olvide "cmd"especificar la ruta completa de sus propios scripts , por ej "/home/pi/mein-tolles-script.py".
Backticks (es decir, apóstrofes que apuntan hacia la derecha, documentación ) se pueden usar como acceso directo a la shell_execfunción:
echo "<pre>" . shell_exec("ls -l /etc") . "</pre>";
// gleichwertig
echo "<pre>" . `ls -l /etc`  . "</pre>";`

exec y el comando gpio de wiringPi

La forma más fácil de controlar GPIO es llamar con execshell_execel comando gpiode la biblioteca de WiringPi:
<?php

// Pin 26 als Ausgang verwenden und auf High stellen
exec("gpio -1 mode 26 out");
exec("gpio -1 write 26 1");

// so funktioniert es auch:
`gpio -1 mode 26 out`;
`gpio -1 write 26 0`;

// Zustand des GPIO-Pin 21
exec("gpio -1 mode 21 in");
$state = exec("gpio -1  read 21");
echo "<p>Pin 21 des J8-Headers hat den Zustand $state";
?>
El gpiocomando funciona en las versiones actuales de Raspbian sin sudoderechos, incluso desde scripts PHP.

Llamar a los scripts de Python

Con execsupuesto, también se puede llamar a un script en Python que a su vez el módulo RPi.GPIOse basa, por ejemplo, así:
exec("/home/pi/mein-script.py");
Sin embargo, el control de GPIO fallará debido a los derechos de acceso que se otorgarán. La forma de resolver este problema se describe a continuación ( agregue encabezado Apache al grupo gpio ).
A menudo, separado de esto, está la cuestión de cómo PHP transfiere los datos a un script de Python o los recupera. La forma más fácil de transferir información a la secuencia de comandos de Python es execpasar parámetros a. Dentro de la secuencia de comandos de Python, puede usar sys.argv[n]el parámetro nth, comenzando por n=1. Para n=0recuperar el nombre del script.
Supongamos que tiene el siguiente script, que espera dos números de coma flotante como parámetros, y los usa para calcular el área y el perímetro de un círculo:
#!/usr/bin/python3
# Datei /home/pi/rechteck.py
import sys;
l = float(sys.argv[1]);
b = float(sys.argv[2]);
print(l*b);
print((l+b)*2);
Una prueba en la terminal se ve así:
./rechteck.py 2.4 1.6
3.84
8.0
Desde un script PHP puedes llamar a este script de ejemplo así:
<?php

$l = 1.5;
$b = 0.8;
$result = array();
exec("/home/pi/rechteck.py $l $b", $result);
echo "<p>Flächeninhalt: ", $result[0];
echo "<p>Umfang: ", $result[1];

?>
Por supuesto, si se intercambian grandes cantidades de datos, también puede usar archivos temporales. Asegúrese de que los derechos de acceso sean correctos. Los scripts PHP son www-dataejecutados por Apache en la cuenta . Esta cuenta debe tener permisos de lectura y escritura para el archivo.

Agregue Apache al grupo gpio

El servidor web Apache se ejecuta bajo la cuenta de Raspbian www-data. Muchos comandos y bibliotecas de GPIO se comunican con el archivo del dispositivo /dev/gpiomem. En Raspbian, este archivo está configurado para tener acceso de lectura y escritura a este archivo, rootasí como a todos los miembros del grupo gpio. El usuario predeterminado pipertenece al gpiogrupo, pero la cuenta www-datano.
groups pi
  pi : pi adm dialout cdrom sudo audio video plugdev 
  games users input netdev spi i2c gpio lpadmin
groups www-data
  www-data : www-data
ls -l /dev/gpiomem 
  crw-rw---- 1 root gpio 244, 0 Feb 10 08:51 /dev/gpiomem
Los scripts PHP son www-dataejecutados por Apache con los derechos de la cuenta . Por lo tanto RPi.GPIO, se produce un error , por ejemplo, al ejecutar un script de Python que utiliza el módulo . Descubres este error cuando miras el final del archivo /var/log/apache2/error.log:
sudo tail /var/log/apache2/error.log
  RuntimeError: No access to /dev/mem.  Try running as root!
  Traceback (most recent call last):
    File "/home/pi/python/led-on-off.py", line 9, in <module>
      gpio.setup(26, gpio.OUT)
  RuntimeError: No access to /dev/mem.  Try running as root!
Si desea que los scripts PHP sean accesibles desde exec/ con los shell_execcomandos ejecutados /dev/gpiomem, agregue la cuenta www-dataal grupo gpio. Eso es fácil de hacer:
sudo adduser www-data gpio
sudo systemctl restart apache2
Si es necesario, deshaga este cambio:
sudo deluser www-data gpio
sudo systemctl restart apache2

derechos de sudo para scripts individuales

Dependiendo de las bibliotecas (Python) que use y lo que desee controlar, la solución simple anterior puede no ser suficiente. El control de hardware solo tiene éxito si el script respectivo se sudoejecuta con derechos de root, es decir, con .
Por razones de seguridad, no es deseable que Apache o el intérprete de Python generalmente se ejecuten con rootprivilegios. Por el contrario, solo el script python en cuestión debería ejecutarse con estos derechos, y eso sin una contraseña.
La configuración requerida se hace en el archivo /etc/sudoers. Este archivo solo se puede cambiar con derechos de administrador, es decir, puede iniciar el editor desde una terminal con sudo:
sudo leafpad /etc/sudoers
Ahora agregue la siguiente línea al final de este archivo:
# am Ende von /etc/sudoers
www-data ALL=(ALL) NOPASSWD: /home/pi/led-on.py
Esto significa que la cuenta www-data(y por lo tanto Apache) tiene permiso /home/pi/led-on-off.pypara sudoejecutar el script sin ninguna información de contraseña . Siga la sintaxis anterior exactamente y simplemente reemplácela /home/pi/led-on.pycon la ruta completa a su secuencia de comandos. Si hay varias secuencias de comandos que deben invocarse desde PHP, puede separar sus nombres con comas o /etc/sudoersespecificar una línea separada para cada secuencia de comandos .
En su script PHP, sudoahora también debe exec usar, por ejemplo:
<?php
exec("sudo /home/pi/led-on.py");
?>

Comentarios