Mostrando entradas con la etiqueta jdk. Mostrar todas las entradas
Mostrando entradas con la etiqueta jdk. Mostrar todas las entradas

15 de marzo de 2015

Java Thread


Thread: Crear aplicaciones cocurrentes.

La implementacion de hilos en Java se puede hacer de dos formas:
  • Heredando de la clase Thread
  • Implementando la interface Runnable
 La forma recomendad para hacerlo es implementando la interface Runnable. Pero esto genera dos dudas:
  • Como iniciarlo.
  • Como detenerlo.
 El inicio es sencillo:

        Thread myThread = new Thread(new MyThread());
        myThread.start();
       

 Como detenerlo es lo complicado, pero no lo es, la clase Thread proporciona un metodo stop(), pero este ya no se debe usar, es inseguro y puede que no detenga el hilo de forma apropiada.

Una forma recomendada es usar el metodo interrupt(), pero hay que implementarlo bien, para que el hilo se pueda detener. Se deben tener en cuenta lo siguiente:
  • Tener una variable (flag) para saber cuando se debe detener el hilo.
  • Controlar las excepciones tipo InterruptedException
  • Estar preguntando si el hilo donde se esta ejecutando fue interunpido.

Ejemplo:

 public class MyThread implements Runnable {

    private volatile boolean stop = true;

    @Override
    public void run() {
        stop = false;
        while (!stop) {
          
            try{
                Thread.sleep(1000);
            }catch(InterruptedException interruptedException){
                stop = true;
            }

            if (Thread.currentThread().isInterrupted()) {
                stop = true;
            }
        }//End While

    }//End run

}//End class

Tenemos la varible "stop" de tipo boolean y "volatil", con la cual vamos a detener el while y parar el hilo.

Si tenemos un Thread.sleep, se debe controlar la excepcion arrojada, porque si el hilo fue interrumpido la excepcion es arroja, y esto quiere decir que el hilo lo estan intentado detener.

Se esta preguntando con el llamado "Thread.currentThread().isInterrupted()", para saber si fue interrumpido, si este fue interrumpido, se debe controlar la terminacion del hilo. Tener en cuenta que es posible usar "Thread.interrupted()" para saber si fue interrumpido,  pero cambia el valor de la bandera (flag) interna del la clase Thread y puede afectar posteriores llamados, Thread.currentThread().isInterrupted() solo obtiene el valor mas no lo cambia.

Y para terminar el hilo solo se debe llamar:

myThread.interrupt();

Hilo Terminado.


Referencias:

10 de octubre de 2014

Streaming Video con Java en Raspberry Pi

Streaming de Video con Java en Raspberry Pi


Hay dos modos de crear streming, uno es capturando las fotos (jpeg) que se toman con raspistill, el otro modo es capturando el vídeo (h264) generado con raspivid, como se observa en el tutorial de:   Streaming Video desde el Raspberry Pi, ahora se va generar este streaming con Java.

Como funciona?

Proyectos necesarios vía GitHub:


git clone https://github.com/andrexweb/raspberry-pi.git
Proyecto Maven: StreamingPi
git clone https://github.com/andrexweb/java.git
Proyecto Maven: H264J


El server, es un servidor de paquetes UDP (Datagrama) que esta en el proyecto StreamingPi, el cual solo recibe el flujo de datos, dependiendo de la opción que se incluya jpeg o h264 se activa el reproductor correspondiente, para el caso de h264, es un codec escrito en java que es un "port" de la libreria ffmpeg-libavcodec (pero solo la parte de h264). El proyecto original esta en Google Code h264j, pero copie el proyecto y agregue unas mínimas modificaciones para que reciba el streaming de forma directa, proyecto H264J.

Proyecto disponible en:
GitHub: https://github.com/andrexweb/java
Original: https://code.google.com/p/h264j/


En el momento el reproductor de fotos/vídeo (jpeg/h264) es básico, solo muestra imágenes, próximamente mas opciones.

Para el lado del cliente, es UDP, solo envía lo que genera los aplicativos raspistill y raspisvid, no se usa el modo normal de "pipe" (|), el api de Java cuenta con con una clase que permite la ejecución de comandos y obtener el "stdout" vía inputStreaming.

Ejemplo:


//command: lista de parametros, primero parametro es el comando a ejecutar.
ProcessBuilder  processBuilder = new ProcessBuilder(command);
//Se incia el proceso y se obtiene el inpuStream de la ejecucion, esto es lo que se envía por UDP.
Process process = processBuilder.start();
InputStream  inputStream = process.getInputStream();

Ver Clase para ver implementación completa: 
org.avpsoft.streaming.net.DatagramCommandClient.java

Uso



Opción con raspistill


Primero ejecutamos el servidor (en windows), quien recibe el streaming:

D:\GitHub\raspberry-pi\StreaminPi>java -cp ./target/StreamingPi-1.0-SNAPSHOT.jar org.avpsoft.streaming.main.Streaming 4445 jpeg

Esto nos abre una ventana, donde se mostrara las imágenes.

Ahora ejecutamos el servidor (Raspberry Pi):

pi@raspberrypi ~ $ java -cp ./StreamingPi-1.0-SNAPSHOT.jar org.avpsoft.streaming.main.Streaming 192.168.1.2 4445 raspistill -n -t 0 -tl 150 -th 0:0:0 -w 640 -h 480 -q 5 -o -

Las primeras dos opciones es la ip del servidor y el puerto son fijas, no puede cambiar el orden.




Ejemplo del "lag" (retraso generado) al usar este metodo, 4 segundos, el mejor tiempo que pude registrar estuvo en 3 segundos.


Opción con raspivid

Se requiere este jar adicional H264J-1.0-SNAPSHOT.jar, para el codec h264.
Primero ejecutamos el servidor (en windows), quien recibe el streaming:

D:\GitHub\raspberry-pi\StreaminPi>java -cp ./*.jar org.avpsoft.streaming.main.Streaming 4445 h264

Esto nos abre una ventana, donde se mostrara las imágenes.

Ahora ejecutamos el servidor (Raspberry Pi):

pi@raspberrypi ~ $ java -cp ./StreamingPi-1.0-SNAPSHOT.jar org.avpsoft.streaming.main.Streaming 192.168.1.2 4445  raspivid -n -t 0 -w 640 -h 480 -fps 10 -o -

Las primeras dos opciones es la ip del servidor y el puerto son fijas, no puede cambiar el orden.






Ejemplo del "lag" (retraso generado) al usar este método, es de menos de 1 segundo, mas o menos 300 milisegundos.

Problemas:

* Debido a que se usa UDP y no TCP, es posible que las imágenes se distorsionen, pero es causado por la fiabilidad de la red, si tiene mala señal WIFI eso pasara.
* Cuando se ejecuta el server con h264, es posible que salga errores, pero el streaming sigue funcionando.
* Para terminan la ejecución use Ctrl+C



28 de septiembre de 2014

LCD+Keypad Kit for Raspberry Pi with Java

Kit LCD + teclado para Raspberry Pi con Java


Este Kit es vendido por Adafruit el cual trae los siguientes componentes:
  • Resistencias:
    • 2 de 220 ohm al 5%
    • 1 de 330 ohm al 5%
  • Un potenciometro ajustable de 10K
  • 5 pulsadores de 5x6mm
  • Expansor de puerto i2c: MCP23017
  • Una tira de 36 pines de conector macho
  • PCB kit
  • Bumper (Adhesibo grueso).
  • Character LCD 16x2 RGB (Positivo o Negativo). 
  • Header de 2x16

Imagen de Adafruit



Componentes adicionales que no vienen en el kit:
  • Raspberry Pi
  • Cinta aislante negra
  • Una base para chip integrado de 28 pines. (opcional).

 Armado


 Según el manual de Adafruit (assembly), se debe hacer en este orden:
  • Soldar la resistencia de 330 ohm en la etiqueta que dice GRN.
  • Soldar las otras dos resistencias.
  • Soldar los cinco pulsadores.
  • Soldar el potenciometro
  • Soldar el MCP23017, pero aquí un pequeño cambio, soldar la base de 28 pines, se recomienda esto para cuando no se sabe soldar muy bien y el exceso de calor no dañe el chip i2c, y también sirve cuando se requiere reutilizar MCP23017.
  • Soldar el "Header 2x16"
  • Soldar la tira de 18 pines al Display-LCD
  • Soldar (unir) el Diaply con el PCD-Kit.
  • Poner doble capa de cinta aislante negra en la pare de las resistencias, debido que al ponerlo sobre el Raspberry Pi  Model B+, los nuevos puertos USB hacen contantacto con las terminaciones de la resistencias.

El resultado es:





 Al conectar el LCD al Raspberry Pi tenga en cuenta la proteccion con la cinta adesiva.

Imagen de Adafruit

Para conectarlo se puede emsamblar directamente sobre el Raspberry Pi, o solo realizar las siguientes conexiones:
  • Conectar GND a GND del Kit Plate
  • Conectar 5V a 5V del Kit Plate
  • Conectar SDA a SDA del Kit Plate
  • Conectar SCL a SCL del Kit Plate
El Kit Plate tiene los mismos pin header de 26 pines del Raspberry PI Model A o B.



Controlador (Java)


El software esta disponible para descarga en:

git clone https://github.com/andrexweb/raspberry-pi.git

 Para saber como instalar el ambiente de desarrollo y otros usos ver:
Se necesita tener habilitado I2C:
Para usar el ejemplo en Python ver Adafruit: Usage - Character LCD+Keypad for Raspberry Pi

Uso

Cuando se ha descargado el código, se procede a abrir el proyecto con Netbeans, procedemos a abrir la clase rpi.main.Main, en esta clase observaremos los ejemplos que podemos correr, por defecto esta habilitado un ejemplo base, que para este caso NO Sirve, asi que cuando usemos el LCD+Keypad kit solo podemos usar el ejemplo que esta en la clase char_lcd_plate.java


//exampleCharLCD = new char_lcd();
//exampleCharLCD = new char_lcd_rgb();
//exampleCharLCD = new char_lcd_rgb_pwm();
//exampleCharLCD = new char_lcd_rgb_mcp();
exampleCharLCD = new char_lcd_plate();

Y se pueden usar todos lo metodos disponibles para "Character LCD con Raspberri Pi" menos las opciones del PWM, ya que el control del RGB se haciendo por el chip I2C MCP23017 y este no tiene PWM. La clase char_lcd_plate.java que tiene implementado los eventos de los pulsadores es basica: La configuracion, recibe el codigo del boton (pin del MCP23017), el nombre y la configuracion de color, el color usado en el ejemplo para cambiar el color cuando presionan un boton.

//Configuracion de los botones
buttons = new Button[]{
          new Button(SELECT, "Select", new int[]{1,1,1}),
          new Button(LEFT, "Left", new int[]{1,0,0}),
          new Button(UP, "Up", new int[]{0,0,1}),
          new Button(DOWN, "Down", new int[]{0,1,0}),
          new Button(RIGHT, "Right", new int[]{1,0,1})
        };

Ciclo para detectar que boton fue presionado.
//# Loop through each button and check if it is pressed.
        while(lcdPlate){
            for(Button button : this.buttons){
                if(lcd.is_pressed(button.getCode())){
                    try {
                        //# Button is pressed, change the message and backlight.
                        lcd.clear();
                        lcd.message(button.getName());
                        lcd.set_color(button.getRgb()[0],button.getRgb()[1],button.getRgb()[2]);
                    } catch (IOException ex) {
                        Logger.getLogger(char_lcd_plate.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            try {
                Thread.sleep(250);
            } catch (InterruptedException ex) {
                Logger.getLogger(char_lcd_plate.class.getName()).log(Level.SEVERE, null, ex);
            }
        }


Cuando  este ejecutando el ejemplo no olvide ajustar el potenciometro (contraste) para visualizar los caracteres.


Nota: Esta es una implementación en Java ME Embedded del código que esta disponible por parte de Adfruit, el código original esta escrito en Python. Para ver el tutorial y código en Python dirigirse a la pagina de Adafruit.



25 de septiembre de 2014

Java Device I/O


Java Device I/O o DIO es la librería que trae Java ME Embedded, que por el momento el JDK no lo trae, solo esta en el código del openJDK pero podemos descargar el código, compilarlo y usarlo.

Instalación

Instalamos la ultima versión jdk 8:

pi@raspberrypi ~ $ sudo apt-get install oracle-java8-jdk
pi@raspberrypi ~ $ java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode)

pi@raspberrypi ~ $


 Descargamos DIO de OpenJDK: Device I/O Project

Primero instalar mercurial (repositorio)

pi@raspberrypi ~ $ sudo apt-get install mercurial
Prodemos a monstar el ambiente para generar DIO:
pi@raspberrypi ~ $ mkdir java-dio
pi@raspberrypi ~ $ cd java-dio/
pi@raspberrypi
~/java-dio $

pi@raspberrypi ~/java-dio $ cd dev/
pi@raspberrypi ~/java-dio/dev $ hg clone http://hg.openjdk.java.net/dio/dev 

pi@raspberrypi ~/java-dio/dev $ export PI_TOOLS=/usr
pi@raspberrypi ~/java-dio/dev $ export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt
pi@raspberrypi ~/java-dio/dev $ make

Después de compilar, nos genera una carepta build/ donde están las librerias y ejemplos que trae
  • build/so -> libdio.so  Librería nativa para Raspberry Pi
  • build/jar -> dio-samples.jar  dio.jar  Archivos Java compilados, ejemplos y librería dio.
En la carpeta  samples/gpio/ se encuentra un archivo llamo gpio.policy este archivo se necesita para cargar los permisos al momento de ejecutar los ejemplos. Para ejecutar un ejemplo que trae, se debe tener dio-samples.jar, dio.jar,  libdio.so y gpio.policy en una misma carpeta.

Si estamos parados en la carpeta que se creo java-dio hacemos los siguiente:

pi@raspberrypi ~/java-dio $
pi@raspberrypi ~/java-dio $ cp dev/build/jar/*.jar . 
pi@raspberrypi ~/java-dio $ cp dev/build/so/libdio.so .
pi@raspberrypi ~/java-dio $ cp dev/samples/gpio/gpio.policy .
pi@raspberrypi ~/java-dio $ ls
dev  dio-samples.jar  dio.jar  gpio.policy  libdio.so
pi@raspberrypi ~/java-dio $


Pruebas y Ejemplos

El ejemplo que nos proporciona la pagina de DIO: Getting Started

Prerequisites:
1 LED
1 resistor (540 ohm)
1 breadboard
1 Raspberry Pi
jumper wires

The dio.jar, dio.samples.jar and libdio.so should be in your current directory, and java should be in your path.

1. Connect the cathode of the LED to GND on the Raspberry Pi.
2. Connect the anode of the LED to a resistor (540 ohm pictured above).
3. Connect the other end of the resistor to GPIO18 on the Raspberry Pi


Y se ejecuta de esta forma:


sudo java -Djava.security.policy=./gpio.policy -classpath .:./dio.jar:dio-samples.jar -Djava.library.path=. -Djdk.dio.registry=./dio.properties dio.gpio.GPIOLEDSample


Ahora vamos a ejecutar los ejemplos (ver al final los enlaces) que se han realizado para Java ME Embeddded y los ejecutamos de manera normal (jdk).

Se ha agregado una clase al proyecto rpi.main.DIOMain.java que tiene main para ser ejecutado, en esta clase hacemos lo mismo que en los anteriores ejemplos, comentar o descomentar el ejemplo que se requiera ejecutar:

public class DIOMain {

    public static void main(String args[]) throws IOException, InterruptedException {
      
        ExampleCharLCD exampleCharLCD = null;
      
        exampleCharLCD = new char_lcd();

        //exampleCharLCD = new char_lcd_rgb();

        //exampleCharLCD = new char_lcd_rgb_pwm();

        //exampleCharLCD = new char_lcd_mcp();
      
      
      
        exampleCharLCD.init();
        exampleCharLCD.stop();
    }

}


Para ejecutar el demo en el Raspberry Pi procedemos a copiar el jar que se encuentra en la carpeta del proyecto dist/  el nombre del jar es JavaMECharLCD.jar  lo copiamos en /home/pi/java-dio/ , antes de ejecutar configuramos un archivo java.policy con los permisos para la prueba.


grant {
        permission jdk.dio.gpio.GPIOPinPermission "*:*", "open,setdirection";
        permission jdk.dio.DeviceMgmtPermission "*:*", "open";
        permission jdk.dio.i2cbus.I2CPermission "*:*", "open";
};

Y procedemos a ejecutar:

sudo java -Djava.security.policy=./java.policy -classpath .:./dio.jar:JavaMECharLCD.jar -Djava.library.path=. -Djdk.dio.registry=./dio.properties rpi.main.DIOMain

pi@raspberrypi ~/java-dio $ sudo java -Djava.security.policy=./java.policy -classpath .:./dio.jar:JavaMECharLCD.jar -Djava.library.path=. -Djdk.dio.registry=./dio.properties rpi.main.DIOMain

De esta forma no estamos limitados a las API de JMEE, sino que tenemos todo el JDK, pero se recuerda que el consumo de memoria y procesamiento aumenta.

Ejemplos anteriores:

Nota: El proyecto no requiere cambios, se puede usar el mismo proyecto que es para Java ME Embedded, solo requiere una clase con un main para ser ejecutado.

13 de septiembre de 2014

Instalacion Java ME Embedded


 

 Java Micro Edition  Embedded


La instalación de Java ME Embedded se hace en dos partes, la primera es la plataforma de desarrollo, la segunda es el ambiente de ejecución, que para este caso es en el Raspberry PI.

Nota: El ambiente de Desarrollo SDK para JME solo esta disponible para Windows.


Instalación del Ambiente de Desarrollo


Ambiente Base , JDK y Netbeans
  • Java SE 8 (JDK) Seguir el Wizard del instalador.
  • Netbeans 8 Descargar versión completa, si instalan el servidor web hacerlo en el directorio raíz (C:/). En las ultimas versiones de netbeans, este no incluye los plugins para JME.

Ambiente para Java ME Emebedded (pagina principal: Java ME Embedded)

Cuando se ingresa a la pagina principal hay que seleccionar la descarga de SDK.



De la pagina de descarga del SDK, se encuentra el instalador para JME y el plugin que se requiere para Netbeans.



Paso 1: El jmesdk, se debe instalar en la unidad raíz(C:/).
Paso 2: Descomprimir el plugin de netbeans, luego en netbenas,  en el menú Tools -> Plugins, en la ventana nueva, seleccionar la pestaña "Downloaded" y dar click en el botón "Add Plugin", en la ventana de abrir archivos, buscar la carpeta donde descomprimio el plugin, seleccionar todos los archivos y dar click en el botón "Install".


Hasta este punto se ha instalado el ambiente de desarrollo.

El SDK de JME permite emular un dispositivo y todos sus accesos (GPIO, SPI, I2C, PWM), sin la necesidad de tener un dispositivo físico.

 Instalación Ambiente de Ejecución en Raspberry PI


Ambiente de ejecución de JMEE:
En la pagina también se encuentra el instalador para otros dispositivos.

El instalador es solo un archivo comprimido con los ejecutables.

Se descarga el archivo "oracle-jmee-8-0-rr-raspberrypi-linux-bin.zip", se procede a enviarlo al raspberry pi, usando  FileZilla (para transferencias ftp, sftp). Nos conectamos al raspberry pi mediant SSH con putty.


Después de tener el archivo en el dispositivos hacemos lo siguiente:

Paso 1: Crear un directorio:
pi@raspberrypi ~ $ mkdir jmee8.0
Paso 2: descomprimir el archivo en el directorio:
pi@raspberrypi ~ $ unzip oracle-jmee-8-0-rr-raspberrypi-linux-bin.zip -d jmee8.0/
Paso 3: movemos la carpeta jmee8.0 a /opt/
pi@raspberrypi ~ $ sudo mv jmee8.0 /opt/
Paso 4: ingresamos al directorio:
pi@raspberrypi ~ $ cd /opt/jmee8.0/
Paso 5: se dan permisos a dos directorios:
pi@raspberrypi /opt/jmee8.0 $ sudo chmod -R 755 appdb bin

Instalación completada; A este punto ya se tiene instalado el ambiente necesario para crear y ejecutar aplicaciones Java ME Embedded.

Ejemplo:


Para probar la instalación haremos el clásico Hola Mundo!!

Abrimos Netbeans y creamos el proyecto, se selecciona Java ME Embedded.


El proyecto se va ha llamar JavaMEHolaMundo.


Escribimos el código en la clase que nos creo por defecto.


Ejecutamos, y para ver la consola damos click en el botón "Output", el mensaje "Hasta pronto..." solo se muestra cuando damos click en el botón "stop".



Ahora ejecutaremos el código en el Raspberry PI, pero pimero haremos unos pasos adicionales.

Ingresamos a la consola y ejecutamos los siguiente comandos:
pi@raspberrypi ~ $ cd /opt/jmee8.0/bin/
pi@raspberrypi /opt/jmee8.0/bin $ sudo ./usertest.sh
Java is starting. Press Ctrl-C to exit

Este comando es el modo de desarrollo, que permite ejecutar el app sin tener que estar deplegando en el dispositivo de forma manual.

Se procede a conectar el SDK con el dispositivo.

En los iconos, vemos que esta el "demonio" del sdk de jmee, damos click y nos aparece una ventana, en esta agregamos la conexion al dispositivo.

Después de estar conectado, desde el netbeans, vamos a observar a que estamos conectados:

Ahora configuramos el proyecto para que se ejecute de forma remota en el rasbperry pi.,  en propiedades del proyectos cambiemos el "Device".
Y procedemos a ejecutarlo y detenerlo, el resultado es que en la pantalla de putty se observa lo siguiente:


FIN ;-)


Nota: En este mini-manual, se necesita haber instalado el SO en el Raspberry PI, tener acceso por SSH y haber manejado putty, filezilla, netbeans y conocer de programacion en java.

Cualquier dudad sera atendida en los comentarios de esta entrada.

Raspberry Pi is a trademark of the Raspberry Pi Foundation, http://www.raspberrypi.org
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. http://www.oracle.com

12 de agosto de 2014

J2ME

Java Micro Edition (Java ME), o anteriormente Java 2 Micro Edition (J2ME)



Java ME, es un subconjunto de Java para el desarrollo de aplicaciones Mobiles, PDA (del inglés: personal digital assistant (asistente digital personal)), aunque con los nuevos teléfonos inteligentes (Android) esta plataforma no es necesaria, y Oracle termino el  soporte para móvil como lo dice su "Release Notes"

Oracle Java ME SDK 8 release:

Terminated support for Mobile (CLDC) and CDC platforms.

Ver: Release Notes

Ya que Java ME no tiene soporte para móvil, Oracle se enfoco en el IoT (Internet of Things)  Internet de las Cosas, así que Java ME viene recargado para pequeños dispositivos (Ej: Raspberry PI).

Ultima versión con soporte móvil: Java ME SDK 3.4 (No existen versiones intermedias entre 3.4 y 8.0).

Y se viene un nuevo producto llamado Java Embedded (Java Embebido) que se clasifica en:
  • Java ME Embedded
  • Java SE Embedded
  • Java Card
 Hablemos de los dos primeros.

Java ME Embedded: Enfocado para pequeños dispositivos, heredando y actualizando el api existente del antiguo j2me, pero sin la parte mobil, es decir este pequeño java no tiene capacidad visual. (NO tiene interfaz gráfica de usuario), pero tiene una nueva api Device I/O, para usar los GPIO, I2C, SPI.... entre otros.

Java SE Embedded: Es el mismo JDK, es un subconjunto del JDK que solo incluye JRE (ejdk),  solo para procesadores ARM, (También funciona en Raspberry PI), enfocado y optimizado para sistemas embebidos, pero con la api completa de la versión normal. Para ser usado en produccion requiere licensia, solo es "free" para evaluacion y desarrollo, aplica para ejdk y jdk 8, para uso comercial se la version jdk 7 para ARM.

Saber mas: Java Embedded