PI4J es un proyecto que provee un puente entre librerías nativas y Java para ganar acceso a los pines de comunicación GPIO del Raspberry PI.
Los autores de las librerias nos recuerdan que es un proyecto joven, en constante cambio, y nos alentan a probar las versiones snapshot, cosa que haremos.
Que es GPIO
El conector GPIO del PI es un interfaz en forma de serie de pines al cual enchufar hardware externo:
Las funciones de estos pines son las siguientes:
- GPIO Real (General Purpose Input Output) pines para controlar leds, etc
- El interfaz I2C permite conectar módulos controlados con tan solo dos pines
- Interfaz SPI un estándar alternativo al I2C
- Pines Rx and Tx comunicación con dispositivos en serie
- PWM control de dispositivos como pueden motores y servos
Preparativos
Partimos de una instalación básica de Raspberry Pi
https://unpocodejava.wordpress.com/2013/07/05/java-en-un-raspberry-pi-desde-cero-2/
Incluyendo la instalación de la versión 1.8.0 de Java, que vendrá muy bien.
Aunque Java 1.7 dice no ser compatible sobre el sistema operativo Raspbian “wheezy” (se sugiere la alternativa “wheezy” soft-float), parece que a versión Java 1.8 no ha dado ningún tipo de problemas con el Wheezy. De modo que nos mantenemos en esta versión.
Pi4J implementa un envoltorio JNI de la librería WiringPI https://projects.drogon.net/raspberry-pi/wiringpi/
Y utiliza esta numeración de pines (que abstrae la numeración hardware, para mantenerla constante en caso de cambios)
Preparar Java
Para completar la instalación JDK del post anterior, le indicaremos al sistema donde está localizada la JVM.
>sudo update-alternatives –install «/usr/bin/java» «java» «/opt/jdk1.8.0/bin/java» 1
Indicamos al sistema cual es la JDK por defecto.
>sudo update-alternatives –set java /opt/jdk1.8.0/bin/java
Configuramos la variable de entorno JAVA_HOME en el entorno
>sudo nano /etc/environment
y añadimos
JAVA_HOME="/opt/jdk1.8.0"
Despues editar
>sudo nano ~/.bashrc
y añadir
export JAVA_HOME="/opt/jdk1.8.0"
export PATH=$PATH:$JAVA_HOME/bin
>sudo reboot
Configuración
En el PI descargamos una copia del último paquete de instalación
>wget http://pi4j.googlecode.com/files/pi4j-0.0.5.deb
Lo descomprimimos e instalamos
>sudo dpkg -i pi4j-0.0.5.deb
Los paquetes instalados irán a las rutas
/opt/pi4j/lib
/opt/pi4j/examples
Es necesario incluir el directorio lib en el classpath de java, como veremos más adelante. Los ejemplos se pueden compilar con
>cd /opt/pi4j/examples
>./build
Instalación
Aparte del PI necesitaremos:
- Faja de salida GPIO con conectores (si los pedís a adafruit preparad un soldador muy fino. Las piezas vienen sueltas)
https://www.modmypi.com/raspberry-pi-expansion-boards/adafruit-pi-t-cobbler-breakout-kit-for-raspberry-pi - Una placa de pruebas
- Resistencia 220ohm
- led
- cables
Y lo conectamos todo de este modo:
Ejemplo de Salida
Aquí hay un ejemplo para controlar el led mediante la salida GPIO_01
>sudo nano ControlGpioExample
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
/**
* Ejemplo encendido/apagado de un led
*/
public class ControlGpioExample {
public static void main(String[] args) throws InterruptedException {
System.out.println("<--Pi4J--> GPIO Control Example ... started.");
// crear controlador gpio
final GpioController gpio = GpioFactory.getInstance();
// provisionar pin #01 como output y encenderlo como estado inicial
final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "MyLED", PinState.HIGH);
System.out.println("--> GPIO state: ON");
Thread.sleep(5000);
// apagarlo gpio pin #01
pin.low();
System.out.println("--> GPIO stat: OFF");
Thread.sleep(5000);
// cambiar al estado contrario (should turn on)
pin.toggle();
System.out.println("--> GPIO state: ON");
Thread.sleep(5000);
// toggle (should turn off)
pin.toggle();
System.out.println("--> GPIO state: OFF");
Thread.sleep(5000);
// encender gpio pin #01 1 segundo y apagar
System.out.println("--> GPIO state: ON 1 second");
pin.pulse(1000, true); // set second argument to 'true' use a blocking call
// acabar con todos los hilos del controlador gpio
gpio.shutdown();
}
}
Salvamos y compilamos con la orden
>javac -classpath .:classes:/opt/pi4j/lib/'*' -d . ./ControlGpioExample.java
y ejecutamos
>sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlGpioExample
Si todo ha ido bien el led se encenderá y apagará 3 veces
Desarrollo en PC
Aunque podemos compilar en el raspberry pi
>javac -classpath .:classes:/opt/pi4j/lib/'*' ...
Es mejor optar por la ventaja multiplataforma de java y desarrollar y compilar en un PC de desarrollo con eclipse.
Para ello podemos importar las librerías
O montar un proyecto maven con el repositorio en el POM.XML
<repositories>
<repository>
<id>oss-snapshots-repo</id>
<name>Sonatype OSS Maven Repository</name>
<url>https://oss.sonatype.org/content/groups/public</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
Y las dependencias
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-gpio-extension</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-device</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-example</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Otros Ejemplos
Con Pi4J podemos realizar lectura asíncrona de señales
// provision gpio pin #02 as an input pin with its internal pull down resistor enabled
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN);
// create and register gpio pin listener
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
Crear triggers que realizan callbacks y redirección de señales entre pines
// provision gpio pin #02 as an input pin with its internal pull down resistor enabled
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN);
// create and register gpio pin listener
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
Lectura y escritura del puerto serie
// create an instance of the serial communications class
final Serial serial = SerialFactory.createInstance();
// create and register the serial data listener
serial.addListener(new SerialDataListener() {
@Override
public void dataReceived(SerialDataEvent event) {
// print out the data received to the console
System.out.print(event.getData());
}
});
// open the default serial port provided on the GPIO header
serial.open(Serial.DEFAULT_COM_PORT, 38400);
// write a formatted string to the serial transmit buffer
serial.write("CURRENT TIME: %s", new Date().toString());
En el javadoc y los ejemplos podemos encontrar más operaciones, como definición de estados en caso de shutdown, obtener información de la placa, creación de pulsos de amplitud modulada (PWM) , etc.
Referencias
http://pi4j.com
https://projects.drogon.net/raspberry-pi/wiringpi/
[…] https://unpocodejava.wordpress.com/2013/08/08/pi4j-control-del-gpio-de-raspberry-pi-con-java/ […]
[…] https://unpocodejava.wordpress.com/2013/08/08/pi4j-control-del-gpio-de-raspberry-pi-con-java/ […]
Amigo muy bueno el tutorial, pero tengo un problema. A la hora de escribir el comando para ejecutar el programa (sudo java -classpath .:classes:/opt/pi4j/lib/’*’ ControlGpioExample), me sale en la terminal «sudo: java: command no found». Quisiera saber si me podria ayudar. Gracias.
Parece que o no has instalado la maquina virtual de java correctamente (ver final del tutorial)
https://unpocodejava.wordpress.com/2013/07/05/java-en-un-raspberry-pi-desde-cero-2/
o lo mas seguro es que la orden no encuentra la ruta a «java». Pruebas a escribir la ruta completa al comando:
>sudo /opt/jdk1.8.0/bin/java -classpath .:classes:/opt/pi4j/lib/’*’ ControlGpioExample
——————-
Si quieres que se ejecute el comando desde cualquier directorio -sin poner la ruta completa- tienes que hacer lo siguiente.
Añade al fichero «/etc/environment» con un editor
>nano /etc/environment
la linea
JAVA_HOME=»/opt/jdk1.8.0″
Despues edita el fichero «/home/pi/.bashrc» con el editor nano
>nano /home/pi/.bashrc
ya añade estas dos lineas al final y salva:
export JAVA_HOME=»/opt/jdk1.8.0″
export PATH=$PATH:$JAVA_HOME/bin
Reinicia el sistema para que se apliquen los cambios
>sudo reboot
Tengo un proyecto para poder depurar tranquilamente en el PC el código PI4J. Por si interesa:
http://sourceforge.net/projects/testpi4j/
Puedes depurar usando eclipse o netbeans y ver los resultados en vivo y en directo. Lo que hago es reenviar las llamadas a la librería GPIO a través de la red.
hola tengo un problema al ejecutar
sudo update-alternatives –install “/usr/bin/java” “java” “/opt/jdk1.8.0/bin/java” 1
me manda un error de que install no es un argumento reconocido
[…] https://unpocodejava.wordpress.com/2013/08/08/pi4j-control-del-gpio-de-raspberry-pi-con-java/ […]