2 de octubre de 2014

Streaming Video from the Raspberry Pi

Streaming Video desde el Raspberry Pi



A continuacion se menciona las cuatro formas mas usadas para streaming en el Raspberry Pi.


Para habilitar la cámara se debe abrir desde la terminal raspi-config y habilitarla.



Ver:  Enabling the camera

Streaming con VLC

Instalar VLC:  

pi@raspberrypi ~ $ sudo apt-get install vlc

Para su computador descargar la versión que corresponde a su sistema operativo: http://www.videolan.org/

Creando el Streaming

pi@raspberrypi ~ $ raspivid -o - -t 0 -n -w 600 -h 400 -fps 12 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264

Para recibir el streaming, se usara VLC en Windows, al abrir VLC Archivo->"Abrir dispositivo de captura...", en la venta que nos abre, seleccionar la pestaña "Red" se ingresa la URL: rtsp://192.168.1.10:8554/ (cambiar por la ip que tenga su Raspberry Pi).



Resultado del Streaming.


El comando raspivid es el usado para capturar vídeo desde la cámara, opciones usadas:

  • "-o -" causa que la salida sea stdout
  • "-t 0" que grabe indefinidamente
  • "-n" que no muestre imagen por la conexión hdmi.
  • "-w xxx" xxx= ancho del video (64 a 1920)
  • "-h yyy" yyy= alto del video (64 a 1080)
  • "-fps nnn" nnn= Frame por segundos (2 a 90) 

Nota: La combinación de parámetros esta condicionada, video a 1080p30, 720p60 y 640x480p60/90.
Ver Opciones: Camera

Opciones usadas de VLC:

  • "-vvv" Verbose ouput (debug y otros).
  • "stream://"   Captura de vídeo.
  • "--sout "    Salida del stream.

Con esta opcion el retraso (lag) del video es mayor a 6 segundos.


Streaming con MJPG-Streamer


Instalación de MJPG-Streamer

pi@raspberrypi ~ $
pi@raspberrypi ~ $ sudo apt-get install libjpeg8-dev imagemagick libv4l-dev


pi@raspberrypi ~ $ mkdir  mjpg-streamer
pi@raspberrypi ~ $ cd mjpg-streamer
pi@raspberrypi ~/mjpg-streamer $ wget http://sourceforge.net/code-snapshots/svn/m/mj/mjpg-streamer/code/mjpg-streamer-code-182.zip

pi@raspberrypi ~/mjpg-streamer $ unzip mjpg-streamer-code-182.zip
pi@raspberrypi ~/mjpg-streamer $ cd mjpg-streamer-code-182/mjpg-streamer
pi@raspberrypi ~/mjpg-streamer/mjpg-streamer-code-182/mjpg-streamer $ sudo ln -s /usr/include/linux/videodev2.h /usr/include/linux/videodev.h
pi@raspberrypi ~/mjpg-streamer/mjpg-streamer-code-182/mjpg-streamer $ make

Uso:

Consola 2: (se abre otra consola)
pi@raspberrypi ~ $ mkdir /tmp/stream 
pi@raspberrypi ~ $ raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0

Consola 1: (donde se estaba trabjando)
pi@raspberrypi ~/mjpg-streamer/mjpg-streamer-code-182/mjpg-streamer $ ./mjpg_streamer -i "./input_file.so -f /tmp/stream -n pic.jpg" -o "./output_http.so -w ./www"


Abrir el Navegador con esta ruta: http://192.168.1.2:8080/  (La ip es la del Raspberry Pi).






Al lado derecho se tienen las diferentes opciones del Streaming.

Con esta opcion el retraso (lag) del video es mayor a 3 segundos.

Fuente: How to build and run MJPG-Streamer on the Raspberry Pi  y  Step 5: Get the webcam streamer for Raspberry Pi


Streaming con nc & mplayer


Instalación:

NC: NetCat es una herramienta sencilla que permite crear conexiones de red TCP/UDP, sea cliente o server para trasmitir mensajes, en la mayoria de los sistemas Linux trae este comando (hasta el momento no he visto un Linux que no lo traiga). Pero para windows el tema es otro, hay que descargarlo de una fuente fiable o descargar el fuente y compilarlo. He decido por la primera descargarlo de una fuente fiable, asi que me dirige a nmap y descargar nmap para windows, entre sus archivos tiene una version para windows de NetCat. La version usada es nmap-6.47-win32.zip, al descomprimir necesitamos solo tres archivos ncat.exe, libeay32.dll y ssleay32.dll.

mplayer: Es un reproductor multimedia libre, existe version para Windows. Se descarga de: mplayer para windows y el archivo mplayer-svn-37292-x86_64.7z 


Uso:

Primero en la consola cmd de windows no situamos donde se haya descomprimido el archivo de mplayer.
(a esta carpeta copiar los archivos de netcat).

En windows:

D:\mplayer-svn-37291-x86_64>ncat.exe -u -l 5001 | mplayer.exe -fps 60 -cache 1024 -

En el Raspberry Pi:

pi@raspberrypi ~ $ raspivid -n -t 0 -w 640 -h 480 -fps 10 -o - | nc -u 192.168.1.2 5001

La IP que se pone en el Raspberry Pi, es la IP de su computador, ya que el PC actua como server y el Rpi como server.

Al inicio tarda un poco mplayer en abrir la ventana del video, despues de abierta el straming es inmediato.






A diferencia de las otras opciones el retraso (lag) del video es menor a 300 milisegundos.


Fuente: What streaming solution for the Picam has the smallest lag?



Streaming con GSTREAMER


GStreamer: es un framework multimedia libre multiplataforma.

Instalacion:

En windows, se descarga directamente de Download GStreamer o ir directamente a windows y decargar la version que se necesita, para este caso gstreamer-1.0-x86_64-1.4.3.msi

En el Raspberry Pi,

pi@raspberrypi ~ $ sudo apt-get install gstreamer1.0

Algunos tutoriales dicen que hay que agregar un repositorio extra, en este caso no se hizo.

Uso:

En el Raspberry Pi:

pi@raspberrypi ~ $ raspivid -n -t 0 -h 720 -w 1080 -fps 25 -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse !  rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.0.200 port=5000

En Windows:

D:\gstreamer\1.0\x86_64\bin>gst-launch-1.0 -v tcpclientsrc host=192.168.0.200 port=5000  ! gdpdepay !  rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false

La ip que se ve en los comandos se cambia por la IP que tenga el Raspberry Pi.



Esta opcion como la anterior tienen un retraso (lag) del video menor de 300 milisegundos.


Fuente: Raspberry Pi camera board – Gstreamer


Artículos externos relacionados:




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.