Montar tu Propio Home Server: Cómo Almacenar una Gran Cantidad de Archivos Multimedia
October 1, 2017By odroidinc.comLinux, Mecaniqueo
¿Por qué necesitarías un servidor de almacenamiento conectado en red (NAS) en casa?
Copia de seguridad automática de los datos de tu Smartphone
Administrar y compartir datos en Internet
Transmitir y reproducir videos guardados
Descargar y administrar Torrents en un smartphone
Alojar un blog personal
Habilitar SSL por seguridad
Componentes necesarios:
Servicio de Internet
Un router WiFi
Un ordenador de escritorio o un ordenador portátil, como un MacBook Pro
Un ODROID-HC1 con su fuente de alimentación
Una Tarjeta MicroSD para el sistema operativo
Un Cable LAN para conectar el ODROID-HC1 al router WiFi
Una Unidad de disco duro (2,5 pulgadas) para almacenar los datos multimedia
También necesitas conocer un poco el sistema operativo, además de Open Media Vault (www.openmediavault.org), que nos permitirá instalar y administrar un almacenamiento conectado en red sin necesidad de tener conocimientos avanzados.
Preparación
En primer lugar, descarga Open Media Vault (OMV) para el ODROID-HC1 desde http://bit.ly/2xogExP a tu ordenador. Consulta el archivo readme.txt para conocer el nombre de usuario y la contraseña.
Nombre de usuario de la interfaz web = admin
Contraseña de la interfaz web = openmediavault
Nombre de usuario de la consola/ssh = root
Contraseña de la consola/ssh (3.0.75+) = openmediavault
A continuación, utiliza un adaptador USB con una tarjeta microSD de 8GB, abre Etcher (etcher.io) para grabar el sistema operativo, tal y como se muestra en la Figura 3. Asegúrate de descomprimir el archivo .7z antes de seleccionarlo en Etcher.
Configuración general
Inserta la SD con la imagen completada de Open Media Vault en el ODROID-HC1, luego desliza e inserta la unidad de disco duro en el conector SATA. Conecta el cable LAN desde el router WiFi al HC1 y utiliza la fuente de alimentación para encenderlo. Para el primer arranque necesitarás aproximadamente unos 10 minutos. Con otro cable LAN, conecta el ordenador al mismo router WiFi al que está conectado el HC1.
A continuación, descarga e instale Angry IP Scanner (http://bit.ly/2wCMeII) y escanea las direcciones IP de los dispositivos conectados. El nombre de equipo aparecerá como odroidxu4.local. Abre un navegador e introduce la dirección del ODROID-HC1.
Como ya he mencionado, el nombre de usuario y la contraseña por defecto se encuentran en readme.txt en http://bit.ly/2xogExP.
Nombre de usuario de la interfaz web = admin
Contraseña de la interfaz web = openmediavault
Dirígete a "System -> Date & Time" y cambia la zona horaria según tu ubicación actual, luego activa la opción “Use NTP server -> Save -> Apply”.
También puedes cambiar el tiempo de espera de la sesión a "0" para no cerrar sesión tras una cierta cantidad de tiempo de inactividad seleccionando "General Settings -> Session timeout -> 0 -> Save -> Apply -> Yes ".
A continuación, actualiza el sistema a la última versión seleccionando " Update Management -> Check Package information -> Upgrade ", vuelva a cargar la página una vez que haya finalizado la actualización, luego reinicie ODROID-HC1 utilizando la opción “Reboot” en la interfaz web de Open Media Vault
Definir los permisos
El disco duro debe estar en formato ext4 para que sea compatible con Open Media Vault. Si el sistema de archivos del disco duro no es ext4, necesitarás crear un nuevo sistema de archivos, tal y como se muestra en la Figura 18.
Una vez completado el formato, selecciona “Mount” tal y como se muestra en las Figuras 19 y 20.
El siguiente paso es registrar los usuarios que tendrán permisos para transferir datos hacia/desde el servidor.
Una vez creado el usuario, crea una carpeta compartida seleccionando " Shared Folders -> Add -> Name -> Select Device -> Set Permissions -> Save ". A cada usuario se le debe conceder los correspondiente sprivilegios. Concede al usuario “odroid” los privilegios de lectura/escritura para la carpeta compartida y guarda la configuración.
ACL es otro tipo de permiso que se deben conceder, tal y como se describe en http://bit.ly/2xn98sb. El usuario "odroid" necesita permisos de lectura/escritura/ejecución, y al resto de usuarios se les pueden conceder los permisos que sean necesarios.
Transferencia de datos usando Samba
El servidor se puede compartir con el grupo de trabajo utilizando Samba (SMB). Haz clic en "Apply" para ver la carpeta compartida.
Ten en cuenta que si tienes dos o más dispositivos o carpetas compartidas idénticas, tu ordenador puede cambiarle el nombre a uno de ellos. Por ejemplo, si tiene dos ODROID-HC1 conectados al router, reconocerá el primero como odroidxu4 y nombrará el segundo como odroidxu4-2, para diferenciarlos. Si no ves los dos automáticamente, intenta reiniciar el ordenador.
Abre Finder y marca “Shared” para ver el servidor compartido odroidxu4, que es el ODROID-HC1. Haz clic en "Connect As" e introduce el nombre y la contraseña que coinciden con el nombre de usuario y la contraseña que se crearon en el servidor. Una vez establecida la conexión, se pueden transferir los archivos y las carpetas desde y hacia el servidor ODROID-HC1.
Transferencia de datos mediante FTP
El Protocolo de Transferencia de Archivos (FTP) es un protocolo de red estándar utilizado para la transferencia de archivos entre un cliente y un servidor dentro de una red informática. En primer lugar, activa el FTP en Open Media Vault tal y como se muestra en la Figura 38.
Tras habilitar el FTP, los archivos se podrán transferir hacia/desde el servidor visitando ftp://192.168.0.111 en tu navegador, utiliza la dirección de tu servidor ODROID-HC1 en lugar de 192.168.0.111.
Después, instala un FTP en su teléfono movil, usando una aplicación como FTP Sprite para iPhone o ES File Explorer para Android.
Cierre del sistema
En la interfaz web de Open Media Vault, justamente debajo del banner, haz clic en los tres puntos verticales de la derecha y selecciona "Shutdown".
Cuando aparezca la pantalla que se muestra en la Figura 47, significara que tu sistema operativo ha dejado de funcionar y el LED azul deberías verlo apagado en el ODROID-HC1. Llegados a este punto, puedes desconectar la fuente de alimentación y extraer la tarjeta microSD. Sigue este procedimiento de apagado cada vez que necesites cambiar el disco duro, actualizar el sistema operativo en la tarjeta microSD o simplemente desenchufar la alimentación. Esto te ayudará a evitar daños en el ODROID-HC1.
Esta es una guía paso a paso sobre cómo activar KVM en un ODROID-XU4. Esta guía solo está disponible para las versiones de u-boot odroidxu4-v2017.05 y Linux kernel 4.9.x. El primer paso es recompilar el kernel. KVM necesita el arch timer en lugar de MCT (Multi-Core Timer), que es el temporizador por defecto del ODROID-XU4 (exynos5422-odroidxu4-kvm.dtb). Las configuraciones relacionadas con la virtualización están en el archivo odroidxu4_kvm_defconfig.
$ sudo apt update
$ sudo apt install git
$ git clone --depth 1 https://github.com/hardkernel/linux -b odroidxu4-4.9.y
$ cd linux
$ make odroidxu4_kvm_defconfig
$ make -j8
$ sudo make modules_install
$ sudo cp arch/arm/boot/zImage /media/boot/zImage_kvm
$ sudo cp arch/arm/boot/dts/exynos5422-odroidxu4-kvm.dtb /media/boot/
Modifica el archivo boot.ini cambiando "zImage" por "zImage_kvm" y "exynos5422-odrooidxu4.dtb" por "exynos5422-odrooidxu4-kvm.dtb"
/media/boot/boot.ini
(......)
# Load kernel, initrd and dtb in that sequence
fatload mmc 0:1 0x40008000 zImage_kvm
(......)
if test "${board_name}" = "xu4"; then fatload mmc 0:1 0x44000000 exynos5422-odrooidxu4-kvm.dtb; setenv fdtloaded "true"; fi
(......)
Reinicia el ODROID-XU4, después verifica si KVM está activado una vez que el proceso de arranque haya finalizado:
Ubuntu Mínimo 16.04.3 ejecutándose con QEMU y KVM/ARM
Para continuar con esta sección, asegúrate de que KVM ya esté activado, con 4 GB o más de espacio de almacenamiento disponible. En esta sección ejecutaremos la imagen Ubuntu Minimal 16.04.3 en la máquina virtual usando QEMU y KVM/ARM.
Para empezar, instala qemu-system-arm con el cual vamos a virtualizar la máquina arm y los paquetes requeridos:
A continuación, prepara las imágenes dtb y del kernel del Sistema Opertaivo invitado. Es necesario configurar la frecuencia del reloj para el temporizador en el archivo dts agregando la línea "clock-frequency = <100000000>;" en el nodo del temporizador.
$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.13.tar.xz
$ tar Jxvf linux-4.13.tar.xz
$ cd linux
$ nano arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
Compila y copia las imágenes dtb y zImage en el directorio de trabajo:
$ make vexpress_defconfig
$ make menuconfig
Enable the block layer --->
[*] Support for large (2TB+) block devices and files
$ make zImage dtbs -j8
$ cp arch/arm/boot/zImage ../
$ cp arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb ../
$ cd ..
Prepara la imagen del sistema de archivos root de Ubuntu Minimal descargando la imagen Ubuntu minimal 16.04.3 y genera la imagen del sistema de archivos root desde la imagen.
Mi ODROID-C2 Docker Swarm - Parte 2: Implementando una pila en un Swarm
October 1, 2017By Andy YuenDocker
En la Parte 1, puse en práctica servicios en mi clúster ODROID-C2 utilizando la línea de comando Docker. Funciona, pero debería haber una mejor forma de llevar a cabo la implementación, especialmente cuando una aplicación necesita varios componentes que trabajen conjuntamente. Docker 1.13.x ha introducido la nueva función de implementación de pila Docker que permite la utilización de una pila completa de aplicaciones en el Swarm. Una pila es un conjunto de servicios que componen una aplicación. Esta nueva función implementa automáticamente múltiples servicios que están vinculados entre sí, eliminando así la necesidad de definir cada uno por separado. En otras palabras, esto es docker-componer en modo swarm. Para hacer esto, tengo que actualizar mi Docker Engine V1.12.6 que instalé usando apt-get desde el repositorio de software de Ubuntu a la V1.13.x. Teniendo ya compilado la V1.13.1 en mi ODROID-C2 cuando experimentaba sin éxito con el modo swarm hace algunos meses, tal y como comenté en mi anterior artículo, sólo es cuestión de actualizar todos mis nodos ODROID-C2 a la V1.13.1 y estaré listo para trabajar.
La pila httpd-visualizer
Lo primero que hice fue utilizar las mismas aplicaciones (httpd y Visualizer) que en mi anterior artículo usando 'docker stack deploy’. Para hacer esto, necesitaba crear un archivo yaml. En realidad esta es la versión “3” del archivo yaml de docker-compose. Esto era relativamente fácil de hacer ya que no es necesaria la persistencia de datos. Aquí tienes el archivo yaml:
Ten en cuenta que el uso de "Networks" en el archivo yaml no es estrictamente necesario. Si lo omitimos, dDocker creará una red de superposición por defecto como verás en una sección más adelante. ¡Las 2 aplicaciones, en este caso, no necesitan hablar entre ellas de todos modos! Para implementarlo, simplemente cambia al directorio donde se encuentra el archivo yaml y ejecuta el comando:
Esto crea una pila llamada httpd-dsv. Puedes conocer el estado de la pila usando varios comandos de pila, tal y como se muestra en la Figura 1.
Puedes apuntar tu navegador al nodo gestor swarm o a cualquier otro nodo del swarm en el puerto 8080 para visualizar la implementación utilizando el Visualizer.
La figura 2 muestra un pantallazo de la pantalla de VuShell con la visualización tomada de una implementación de pila anterior:
Para desmontar la pila, introduce el siguiente comando:
$ docker stack rm httpd-dsv
Migrando mi blog de WordPress a swarm
Para hacer un ejemplo más realista de una implementación de pila, he decidido realizar una prueba migrando mi blog al swarm. Esto es muy útil para mí, ya que me permite iniciar mi blog fácilmente en otro entorno cuando ocurre un desastre. Para hacer esto, tenía que preparar unas cuantas cosas:
Crear una copia de la base de datos de WordPress usando mysqldump para crear: mysql.dmp.
Utilizar un editor de texto para reemplazar todas las referencias de mi dominio (mrdreambot.ddns.net) en el archivo .dmp por la dirección IP del gestor swarm que es 192.168.1.100.
Hacer una copia (comandos Tar) del directorio /var/www/html que contiene scripts y recursos cargados
Elegir las imágenes de docker a utilizar: mrdreambot/arm64-mysql y arm64v8/wordpress.
Con todo lo anterior, podía crear una implementación de pila docker para mi blog de WordPress.
Estado de persistencia utilizando volúmenes
bind-mount
El primer método por el que opte fue el de usar directorios del host como volúmenes de datos (también llamados volúmenes bind-mount) para la persistencia de datos. El contenido del archivo yaml se muestra a continuación:
Las figuras 3 y 4 muestran las capturas de pantalla para la implementación de la pila.
Posiblemente habrás notado que el sitio de WordPress ha perdido parte de su apariencia personalizada, ya que la imagen del docker arm64v8/wordpress no ofrece ninguna librería o personalización PHP.
Como he comentado anteriormente, si no defines las Redes en tu archivo yaml, docker crea automáticamente una red de superposición 'wordpress_default' para la puesta en funcionamiento automática. La red de superposición es necesaria para que WordPress pueda hacer referencia a la base de datos MySQL utilizando su nombre "db" tal y como se define en el archivo yaml:
WORDPRESS_DB_HOST: db: 3306
Los volúmenes de datos justifican ciertas explicaciones. Lo primero a tener en cuenta es que todos los directorios de host utilizados como volúmenes de datos están montados en NFS y accesibles a todos los nodos del swarm.
El directorio de host /nfs/common/services/wordpress/db_data es un directorio vacío. Es el equivalente al directorio del contenedor /u01/my3306/data donde se encuentra la base de datos MySQL. A continuación, se describe como se crea su contenido.
/nfs/common/services/wordpress/db_root:/root
He completado previamente el directorio del host /nfs/common/services/wordpress/db_root con 2 archivos:
run.sh: el script de inicio de MySQL que reemplaza al que se encuentra en el directorio /root del contenedor. Este script es el punto de entrada al contenedor MySQL. Cambié el script para buscar el archivo mysql.dmp ubicado también en /root. Si está, importa el archivo de copia en MySQL que completará el directorio /u01/my3306/data con los datos. Si no hay un archivo mysql.dmp, no se hace nada adicional al proceso habitual.
mysql.dmp: el archivo de volcado de la base de datos MySQL de mi blog
Los cambios en el archivo run.sh en comparación con el que viene con la imagen docker MySQL se muestran a continuación:
...
DMP_FILE=/root/mysql.dmp
...
if [ "$MYSQL_DATABASE" ]; then
mysql -uroot -e "CREATE DATABASE IF NOT EXISTS `$MYSQL_DATABASE`"
if [ -f "$DMP_FILE" ]; then
mysql -uroot $MYSQL_DATABASE < $DMP_FILE
fi
fi
...
Ten en cuenta que esto sólo es necesario cuando ejecutas el contenedor por primera vez. La implementación posterior no requerirá de esta distribución de volúmenes ya que la base de datos ha sido configurada durante la primera ejecución. Esto significa que puede comentar esta línea en el archivo yaml tras haber implementado correctamente una vez esta pila:
arm64v8/wordpress activa WordPress copiando los contenidos en su directorio /usr/src/wordpress al directorio /var/www/html en el arranque si /var/www/html no tiene contenido. Al rellenar previamente el directorio del host /nfs/common/services/wordpress/www_src /html con el contenido del archivo tar creado anteriormente, arm64v8/wordpress iniciará WordPress con el contenido de mi blog. Esto solo es necesario cuando ejecutes el contenedor por primera vez. Esto significa que puede comentar esta línea en el archivo yaml tras haber implementado correctamente esta pila una vez:
El directorio de host /nfs/common/services/wordpress/www_data es un directorio vacío cuyo contenido se activará mediante el script arm64v8/wordpress tal y como se ha descrito anteriormente.
¿Por qué no usar docker-componer?
Es posible que te pregunte por qué no utilice docker-compose para ejecutar el archivo yaml, por ejemplo, usando comandos de una sola vez como sugiere la documentación de docker. La razón es que el docker-compose que instalé usando apt-get es la versión 1.8.0, que no entiende la versión 3 del archivo yaml del docker-compose, que es necesario para "docker stack deploy". Intenté compilar la última versión de docker-compose desde la fuente pero no tuve éxito. Esta es la razón por la que no estoy usando docker-componer.
Persistencia del estado usando volúmenes de almacenamiento compartido
El uso de volúmenes bind-mount depende del host. El uso de volúmenes compartidos tiene la ventaja de ser independientes del host. Puede haber un volumen compartido disponible en cualquier host en el que se inicie un contenedor siempre que tenga acceso al back-end del almacenamiento compartido y tenga instalado el plugin (controlador) del volumen adecuado, el cual te permita usar diferentes back-end de almacenamiento, como, por ejemplo: Amazon EC2, GCE, Isilon, ScaleIO, Glusterfs, solo por nombrar unos cuantos. Existes muchos drivers o plugins de volumen disponibles como Flocker, Rex-Ray, etc. Desafortunadamente, no hay binarios para esos complementos disponibles para máquinas ARM64 como ODROID-C2. Afortunadamente, el driver 'local' integrado soporta NFS. Es el driver que yo estoy usando para la implementación de volumen compartido.
El archivo yaml para esto es el siguiente:
Una vez más, los volúmenes justifican alguna explicación:
/nfs/common/services/wordpress/db_root:/root
Sirve para el mismo propósito que en el caso del volumen bind-mount. Solo es necesario cuando ejecutas la pila por primera vez para iniciar la base de datos MySQL.
Sirve para el mismo propósito que en el caso del volumen bind-mount. Solo es necesario cuando ejecutas la pila por primera vez para iniciar el contenido de WordPress.
db_data:/u01/my3306/data
db_data es un volumen compartido creado fuera de la implementación de la pila, lo que significa que es creado antes de que llegue a usarse el archivo yaml. Se utiliza para almacenar el contenido de la base de datos MySQL y no se activa en la creación.
www_html:/var/www/html
www_html es un volumen compartido creado fuera de la implementación de la pila, lo que significa que es creado antes de que llegue a utilizarse el archivo yaml. Se utiliza para almacenar el contenido de WordPress y no se activa en la creación.
Creando los volúmenes compartidos
Probablemente hayas observado una sección en el archivo yaml que dice:
Los directorios /media/sata/nfsshare/db_data y /media/sata/nfsshare/www_htm deben existir antes de crear los volúmenes. Mi archivo /etc/exports tiene una entrada:
Para probar que los volúmenes compartidos funcionan, inicialmente implementé solo 1 réplica de mySQL y 1 de WordPress en el gestor de Docker y les permití iniciar los volúmenes compartidos.
Luego comenté las 2 líneas de la ubicación del WordPress:
Después, quise implementar 3 réplicas de WordPress en varios nodos. Como estamos usando el driver "local", debemos crear los volúmenes en cada nodo. Tal y como se muestra en la Figura 5, usé "parallel ssh" para crearlos en todos los nodos usando solo 2 comandos. La figura 5 muestra el volumen y la implementación de la pila:
Verifiqué que todas las réplicas estuvieran usando los volúmenes compartidos utilizando "docker exec -it" para acceder a los contenedores de WordPress en los nodos en los que se estaban ejecutando y examiné el contenido del directorio /var/www/html para verificar que todo funcionaba correctamente.
En el fondo, ambos planteamientos usan NFS para compartir entre los nodos. Sin embargo, los volúmenes compartidos proporcionan una abstracción independiente del host de mayor nivel que los volúmenes bind-mount. Potencialmente, puedes volver a crear los volúmenes compartidos utilizando backends de almacenamiento distintos de NFS, como AWS EC2 y Glusterfs. Bind-mount, por otro lado, está vinculado a tu sistema de archivos del host, que puede ser difícil de migrar a otro entorno.
Conclusion
Aprendí algo nuevo explorando el uso de la denominada "implementación de pila docker". Espero que encuentres útil e informativo este artículo. Todavía hay muchas características, como las actualizaciones sucesivas, la Implementación continua/Integración continua (CI / CD), las implementaciones A/B y azul/verde, solo por nombrar unas cuantas, que aún no he explorado con mi clúster ODROID-C2 Swarm. Además, existen otros entornos de trabajo de planificación de servicios como Kubernetes y Openshift que son más frecuentes en el entorno empresarial que en el modo Docker Swarm. Exploraré otros usos del modo Swarm de Docker y alternativas al modo Swarm e informaré de mis hallazgos en el futuro cuando surja la oportunidad.
Juegos Linux: Sistema de Entretenimiento Móvil
October 1, 2017By Tobias SchaafJuegos, Linux
Hardkernel ha hecho un gran trabajo con el lanzamiento de un nuevo hardware recientemente. Vi la oportunidad de crear mi propio sistema de entretenimiento móvil usando algunos componentes disponibles en Hardkernel. Este proyecto es bastante sencillo y muy apropiado para principiantes, incluso para niños.
Qué es lo que necesitarás
Este proyecto está basado en el VuShell y los componentes que puedan acoplar dentro de la carcasa. De hecho, hay un poco de espacio en la carcasa, lo cual permite hacer diferentes diseños. Por ahora, me centraré en el diseño que estoy usando, aunque si quieres probar este proyecto, puedes cambiar o agregar componentes como mejor te parezca.
ODROID-VuShell (http://bit.ly/2b8lk6a)
Como es la carcasa de nuestro proyecto, ¡ésta es absolutamente imprescindible!
ODROID-VU7 Plus (http://bit.ly/2cmKyuN)
También podrías usar el ODROID-VU7 en su lugar (http://bit.ly/1NWxgDx), si quieres ahorrarte unos dólares o usar una pantalla con un consumo de energía ligeramente menor.
ODROID-C1+ (http://bit.ly/1Upx5yI)
También puede usar un ODROID-C2 o XU4. Desafortunadamente, el C1 y el XU3 no funcionarán, ya que no cuentan con los conectores I2S necesarios.
El C1 + es probablemente tu mejor opción, ya que usa muy poca energía y te permite usar un pack de pilas. La placa alimenta el VU7 a través del conector USB 2.0 OTG, por lo que solo se necesita un conector de alimentación.
Stereo Boom Bonnet (http://bit.ly/2wbKkyE)
Como queremos que nuestro proyecto tenga sonido, para ser realmente móviles, esto es imprescindible
5V/2A PSU
Si usas un ODROID XU4, necesitarás una fuente de alimentación adicional de 5V/4A.
Tarjeta SD con 8 GB de almacenamiento o más
También puede usar un módulo eMMC, pero una vez montado todo, ya no podrá acceder al módulo eMMC, haciendo que las modificaicones y/o correcciones sean imposibles sin tener que desmontarlo todo. La tarjeta SD, por otro lado, seguirá siendo accesible con unas pinzas.
Separadores
Utilice los separadores de otros productos ODROID que tenía disponibles, pero también se pueden comprar por poco dinero en Amazon (http://amzn.to/2yj4OG8).
Teclado, Ratón
Tras la configuración inicial, es posible que ya no sean necesarios.
Teniendo en cuenta la lista anterior, el coste debería estar en torno a los 160$ (sin incluir el teclado y el ratón, ni los gastos de envío).
Hay algunos otros componentes que puede que quieras conseguir, pero éstos dependen de ti completamente:
Gamepad (para una mejor experiencia de juego)
Te sugiero un mando inalámbrico XBox 360 con un adaptador de PC inalámbrico, ya que un sólo adaptador admite hasta cuatro mandos, lo que significa que no tendrías que lidiar con ningún cable.
Almacenamiento externo (para almacenar grandes cantidades de datos)
Por ejemplo, es posible quieras usar una memoria USB o un disco duro externo para almacenar películas o juegos. Si usas una tarjeta SD de gran tamaño (32 GB o más) no necesariamente lo necesitas, pero probablemente será más fácil cambiarlo que una tarjeta SD si te encuentras con la necesidad de contar con más espacio de almacenamiento.
Módulo WLAN
Si deseas conectarse a una red inalámbrica, necesitarás uno de estos.
UPS3 o cualquier otro sistema de pilas o baterias También funcionará con la batería externa de tu teléfono móvil o tablet. De esta forma, puedes hacer que el sistema sea completamente móvil sin que necesites tener un enchufe cerca. Una batería externa decente debería permitir que el todo sistema funcionase entre 3 y 5 horas.
Micro USB-DC Power Bridge Board (http://bit.ly/2wbWQ1e)
Si usas un ODROID-XU4, esto asegurará que la potencia para la pantalla sea constante.
IR Remote Controller (http://bit.ly/1M6UGiR) o cualquier otro sistema de control remoto por inflarrojos
Los C1 + y C2 vienen con un receptor IR. Si quieres usarlo con Kodi, es algo que también puedes hacer.
Juego de soldadura
Esto es recomendados para usuarios avanzados que quieran tener un sonido estéreo más "realista"
Software
Antes de empezar a montar los componentes, debes configurar tu ODROID, instalar el sistema operativo (yo utilice mi propia imagen ODROID GameStation Turbo para la serie ODROID-C1), preparar el boot.ini y, si quieres, instar juegos , películas y lo que quieras en tu placa. Es mejor hacerlo al principio, ya que puede ser difícil hacerlo con posterioridad si no tienes una conexión de red.
Asegúrate de configurar los paramentos para VU7 o VU7 Plus (dependiendo de la pantalla LCD que elijas) en el boot.ini:
También puedes configurar el sistema para cargar los módulos necesarios para el Stereo Boom Bonnet.
Abre un terminal y escribe los siguientes comandos:
$ su -
$ echo "snd-soc-pcm5102 snd-soc-odroid-dac" >> /etc/modules
Después de esto, puedes copiar los juegos o las películas que quieras, y configurar Emulation Station, Kodi y cualquier otra cosa que desees, o puede hacer esto más tarde una vez que el todo el sistema esté montado.
Sin duda alguna necesitarás como mínimo configurar boot.ini o de lo contrario no verás nada en la pantalla.
Montaje
El montaje es bastante fácil, simplemente sigue los pasos de Hardkernel sobre cómo ensamblar el VuShell (http://bit.ly/2b8lk6a) con algunas pequeñas modificaciones.
Una vez que coloques la pantalla en el frontal y añadas el primer lateral sobre la placa (Paso 7), es hora de realizar algunas modificaciones. Primero, conecta el Stereo Boom Bonnet a la placa. Para hacerlo, dobla suavemente las partes que sostienen los altavoces hasta que se separen y tengas la placa y el altavoz por separado. Desenchufa el cable de los altavoces. Lo mejor es conectar el cable del Stereo Boom Bonnet antes de montarlo. Consulta la guía de Hardkernel para asegurarte de colocar el cable correctamente (http://bit.ly/2xuWVjA).
Retira el tornillo que se añadió en el paso 3 del montaje del VuShell en el lateral del VU7 Plus y reemplázalo con un par de separadores. Coloca el Stereo Boom Bonnet boca abajo sobre los espaciadores. Utiliza el tornillo que retiraste originalmente para fijar el Stereo Boom Bonnet. Usa (4) separadores M3 de 20 mm para elevar el Stereo Boom Bonnet, de modo que el control del volumen se alinee con uno de los agujeros del VuShell, lo cual te permitirá regular el volumen.
Tras acoplar el primer lateral, puede hacer lo mismo con el otro. Ten en cuenta que el orificio superior del C1+ normalmente no está unido a la carcasa, como se puede ver en el paso 5 del montaje del VuShell. Si colocas un separador aquí, no te preocupes si no está atornillado en el zócalo. Funcionará igual de bien sin él. Una vez montada la segunda línea de separadores en el C1 + y Stereo Boom Bonnet, puedes conectar el primer altavoz que viene con el Stereo Boom Bonnet.
Alinea el altavoz con uno de los agujeros de la carcasa VuShell. Yo utilicé cinta adhesiva transparente para sujetar el altavoz a la carcasa en mi primera prueba. Más tarde, usé super-glue para fijarlo mejor a la carcasa. Técnicamente, con un altavoz es suficiente para disponer de un sonido bastante bueno, pero si quieres, puedes fijar el segundo altavoz a otro de los agujeros del mismo lateral.
Si quieres tener un sonido estéreo más realista, necesitarás alargar el cable del segundo altavoz para poder ubicarlo en otro lateral del VuShell. Ten en cuenta que esto requiere algo de soldadura, de modo que, aunque es bastante fácil, se debe hacer con cuidado, y en el caso de niños, éstos deben estar supervisados por un adulto.
Incluso con solo un altavoz conectado, el sonido debería ser lo suficientemente bueno para ver películas o jugar. Hice un video donde probé la reproducción del video con ffmpeg http://bit.ly/2xox1wb. En este video, subo y bajo el volumen usando el control de volumen, el cual es fácil de alcanzar gracias a los separadores. Después de esto, también probé algunos sonidos antiguos de 8 bits iniciando Cave Story desde EmulationStation (http://bit.ly/2xlDxGo). También funcionó perfectamente. Disponer de un único altavoz conectado realmente no representaba un gran problema.
Montaje Avanzado
Como habrás notado, el cable del segundo altavoz es demasiado corto para llegar al otro extremo del VuShell. Por lo tanto, necesitaba alargar el cable para poder alcanzar el otro lateral de la carcasa. Este proceso es bastante sencillo y probablemente incluso lo puedan hacer los niños, pero siempre con la supervisión de un adulto
Necesitarás equipamiento básico de soldadura. Principalmente, un cable adicional, estaño para soldar y un poco de envoltura de cable termo retráctil (http://amzn.to/2wH9edI) si la tienes. Lamentablemente, yo no las tenía. Puede funcionar sin ella, pero es mejor tener la envoltura termo retráctil para proteger los cables una vez se hayan soldado. También necesitarás algo para cortar el cable. Un cortador de cable/alambre funcionará muy bien, como los cables son bastante delgados, posiblemente bastará con unas tijeras o incluso un cuchillo.
Cuando dispongas de todos los elementos, puedes empezar desenrollando los cables cerca del altavoz hasta una longitud de aproximadamente 5 cm (2 pulgadas). Luego corta el cable con el cortador de alambres y deja al descubierto los alambres blancos.
Corta dos alambres más largos de unos 20-25 cm (8-10 pulgadas). Recomiendo encarecidamente usar diferentes colores para los cables para saber así que cable es el que hay que conectar con el otro. Asegúrate de que los dos cables que cortas tengan la misma longitud. También sugiero usar cables finos similares a los de los altavoces. Los míos eran ligeramente más gruesos y se ajustaban perfectamente.
Después de cortar los cables, deja al descubierto los extremos retirando lentamente la funda del cable. Ten cuidado de no cortar el cable durante el proceso. Una vez hecho esto, retuerce los alambres descubiertos para que se mantengan unidos. Luego, puedes aplicar estaño a los extremos, cubriendo los alambres descubiertos de una capa delgada de estaño. Este también sería un buen momento para colocar la envoltura retráctil en los cables ampliados (dos para cada cable). Después, puedes soldar los extremos del cable. Asegúrate de conectar los cables correctos.
Después de soldar un extremo del cable, puedes conectar el otro extremo al altavoz.
Al final, retorcí el cable como lo estaba el cable original, así era más fácil de manejar. Esto realmente me llevo un poco de tiempo, pero el resultado fue bueno y me facilito bastante el montaje en el VuShell. Sin embargo, asegúrate de no tensar demasiado los puntos de soldadura cuando retuerzas el cable, o se pueden separar.
Ahora también sería un buen momento para colocar las fundas termorretráctiles en los extremos descubiertos del cable y calentarlas para que sellen los alambres. Intenté hacer lo mismo con cinta aislante, pero los cables eran demasiado finos para envolverlo correctamente. Una vez que termines de retorcer el cable, debería verse como una versión más larga del cable original, con algunos puntos de soldadura.
Ahora es el momento de juntar toda la unidad y colocar el nuevo altavoz dentro del VuShell. Cuando montes los altavoces, el conector del altavoz en la parte superior es para el canal izquierdo y el conector del altavoz en la parte inferior es para el canal derecho. También puedes usar algunos videos de YouTube para probar si los altavoces izquierdo y derecho están conectados en el orden adecuado. Puede fijar el altavoz izquierdo con pegamento super glue o cinta adhesiva.
Después de esto, encendí el dispositivo y lo probé para ver si ambos altavoces funcionaban correctamente desde el principio (http://bit.ly/2xuF4ct). Debido a que hay mucho espacio dentro de la carcasa, puedes añadir componentes adicionales con bastante facilidad. Tal y como muestras las instrucciones de montaje de Hardkernel, hay agujeros para colocar un disco duro o una batería externa en el interior, lo que haría que el dispositivo fuese totalmente móvil.
También podrías colocar fácilmente un adaptador de PC inalámbrico XBox 360 junto con la batería externa. De esta forma, podrías usar hasta 4 mandos XBox 360 al mismo tiempo sin tener que añadir un nuevo cable. Esto es fabuloso para controlar Kodi o EmulationStation sin la necesidad de un teclado.
Conclusión
Este es un proyecto divertido y fácil. Algunas personas ya están disfrutando de esta pequeña consola, afirmando que están sorprendidos por la idea y la movilidad que tiene gracias a la posibilidad de acoplarle una batería externa. Dado que el VuShell tiene mucho espacio, este proyecto puede tener muchas variantes dependiendo de los accesorios adicionales que quieras usar. Es posible que incluso desee eliminar los altavoces por completo y, en su lugar, simplemente uses el conector para auriculares de Stereo Boom Bonnet, el cual te permitiría jugar a tus juegos en un viaje en tren o en un avión durante varias horas.
Aunque no es la pantalla más grande, es lo suficientemente buena como para tener un par de amigos sentados a tu lado viendo algunas películas en una excursión, o jugar algunos juegos divertidos o competitivos en uno de los muchos emuladores. Algunos preferirán la potencia extra de un XU4 para jugar seriamente a algunos juegos de PSP, Dreamcast o N64, mientras que otros se conformarán con algunos de Nintendo, Super Nintendo, SEGA Genesis u otros clásicos en un C1. Colocarlo en la cocina con Android y un C2 te permitirá escuchar tu música favorita mientras cocinas. Gracias a la pantalla táctil, todo lo que necesitas está al alcance de tus dedos.
En definitiva, las opciones son casi ilimitadas y es muy fácil de hacer. Incluso los niños pueden montar su propia consola. Te invito a intentarlo y a que comentes lo que puedes llegar a hacer con este sistema todo en uno.
Cómo instalar ArchLinux con Full Disk Encryption en un ODROID-C2
October 1, 2017By @YesDayLinux, ODROID-C2, Tutoriales
La Full Disk Encryption (FDE) protege nuestros datos del acceso no autorizado en el caso de que alguien logre acceder físicamente a los medios de almacenamiento. En este artículo, voy a describir cómo instalar ArchLinux con Full Disk Encryption en el OROID-C2. El método de encriptación es LUKS con el tamaño de clave XTS 512 bit (AES-256).
En pocas palabras, Full Disk Encryption requiere lo siguiente:
Encriptar una partición y copiar el sistema de archivos root en ella.
El kernel para incluir el módulo dm_crypt. En nuestro caso, éate ya está incluido por defecto. De modo que, no necesitaremos volver a re-compilar el kernel.
Los initramfs para incluir el módulo del dm_crypt y el binario cryptsetup. Usamos una herramienta llamada dracut para generar los initramfs necesarios. Dracut soporta la funcionalidad requerida a través de los módulos adicionales crypt y lvm.
Pasar las opciones dracut para LUKS a los initramfs a través de la propiedad bootargs dentro de boot.ini. Por ejemplo, digamos que, en nuestro caso, queremos que los initramfs desbloqueen un volumen LUKS con UUID ae51db2d-0890-4b1b-abc5-8c10f01da353 y carguen el sistema de archivos root del dispositivo mapper/dev/mapper/vg-root. Para pasar estas opciones dracut configuramos lo siguiente:
sudo nano /boot/boot.ini
setenv bootargs "rd.luks.uuid=ae51db2d-0890-4b1b-abc5-8c10f01da353 root=/dev/mapper/vg-root rootwait < leave the rest as is >"
Note
Muchos de los pasos de este documento implican editar archivos de configuración. Para mantener las palabras al mínimo, usamos la notación anterior como una forma concisa de describir los pasos en los que hay que editar archivos. La notación anterior significa:
Debes editar el archivo /boot/boot.ini con privilegios root (sudo nano /boot/boot.ini). Nano es el editor de línea de comandos; sin embargo, puedes usar cualquier otro editor.
Busca la línea que comienza con setenv bootargs y añade o edite las opciones de configuración rd.luks.uuid=ae51db2d-0890-4b1b-abc5-8c10f01da353 root=/dev/mapper/vg-root rootwait. Es posible que algunos archivos mencionados en este documento tengan la correspondiente línea comentada o no presente en absoluto. Si ese es el caso, tendrá que descomentar o añadir la línea en el archivo, respectivamente.
Deja el resto de la línea después de rootwait como está.
Además, para una configuración sin monitor ni teclado, necesitarás habilitar el desbloqueo remoto mediante SSH como se describe en el artículo "Remotely unlock the LUKS rootfs during boot using Dropbear sshd" en http://bit.ly/2g6qjDv. Por último, pero no menos importante, si prefieres utilizar de inmediato esta funcionalidad, simplemente descárgate la imagen de sistema operativo en http://bit.ly/2xR8LDe. De cualquier modo, el documento actual te proporcionará más detalles técnicos sobre los componentes básicos y cómo trabajan conjuntamente en un entorno Full Disk Encryption.
Requisitos de hardware
ODROID-C2
Una maquina Linux desde donde garbar la imagen del SO e interactuar con el ODROID-C2
Disco USB con al menos 4GB de capacidad
Una tarjeta microSD o módulo eMMC con al menos 4GB de capacidad
(Opcional) Un kit módulo USB-UART para conectarse con la consola serie del ODROID-C2. Consulta la publicación de http://bit.ly/2fM29BB para obtener instrucciones sobre cómo conectarte y por qué la consola serie es muy recomendable en este caso.
Grabar la imagen del SO y arrancar ODROID-C2
Graba la imagen del SO en el disco USB siguiendo las instrucciones de http://bit.ly/2fGKEik Reemplaza /dev/mmcblk0 en las siguientes instrucciones por el nombre del dispositivo de la tarjeta microSD tal como aparece en tu ordenador. Si están montadas, desmonta las particiones de la tarjeta microSD
Ten en cuenta que, si hay UUID duplicados entre las particiones del disco USB y la tarjeta microSD, debes eliminar los duplicados para evitar futuros conflictos:
$ sudo tune2fs /dev/sda2 -U $(uuidgen)
Configura boot.ini para arrancar desde el disco USB. Para hacerlo, usa el UUID del paso anterior y configura el boot.ini de la tarjeta microSD:
Desmonta, ejecuta sync varias veces y retira la tarjeta microSD y el disco USB de la maquina Linux. Conecta la tarjeta microSD y el disco USB al ODROID-C2, luego inicia el ODROID-C2 y conéctate a su consola serie. Si necesitas instrucciones sobre cómo conectarte a la consola serie, consulte el artículo de http://bit.ly/2fM29BB.
Si todo va bien, deberías arrancar con el disco USB. Ten en cuenta que si root=UUID= 2b53696c-2e8e-4e61-a164-1a7463fd3785 no funciona, intenta root=/dev/sda1, root=/dev/ sdb1 o el nombre del dispositivo que veas en la consola antes de que falle el arranque (p. ej., [14.812393] sd 1:0:0:0: [sda] Attached SCSI removable disk). Si todavía tienes problemas, intenta reiniciar unas cuantas veces y/o reposiciona el disco USB en un puerto USB diferente en el ODROID-C2. No te preocupes sí parece que te está causando problemas, ya que no tendrá que arrancar de nuevo con el disco USB tras el primer arranque exitoso.
A continuación, verifica que el sistema de archivos root esté montado desde el disco USB:
$ df -h
Cambiar contraseñas
Cambia las contraseñas para el usuario root y alarm. Las credenciales predeterminadas son alarm/alarm y root/root.
Verifica la instalación de dracut listando los módulos
$ dracut --list-modules
Si el comando "pacaur -S dracut" informa de un error en el que la arquitectura aarch64 no es compatible con el paquete, sigue estos pasos para configurar el soporte para aarch64:
$ cd ~/.cache/pacaur/dracut/
$ nano PKGBUILD # replace `arch=("i686" "x86_64")` with `arch=("aarch64")`
$ makepkg -si --noconfirm --needed
Si makepkg informa de un error así como dracut-046.tar ... FAILED (unknown public key 340F12141EA0994D), introduce estos comandos e inténtalo de nuevo:
Consulta la documentación de Makepkg para obtener más información en http://bit.ly/2wuuBe6.
Si el comando "gpg -full-gen-key" informa del error, Key generation failed: No pinentry, sigue los siguientes pasos para configurar gpg tal y como se describe en http://bit.ly/2yDAJBye e inténtalo de nuevo. El gpg-agent necesita saber cómo solicitar el usuario para la contraseña:
-v = información detallada
-y = verifica la contraseña, pregunta dos veces y reporta un error si no coinciden
-c = especifica el cifrado utilizado
-s = especifica el tamaño de la clave utilizada
-h = especifica el hash utilizado
-i = número de milisegundos para gastar en el procesamiento de contraseña (si usa algo más que sha1, debe ser mayor que 1000)
–use-random = generador de números aleatorios para usar
luksFormat = para activar la partición y fijar una contraseña
/dev/mmcblk0p2 = la partición a encriptar
Desbloquea el dispositivo LUKS y móntalo en /dev/mapper/lvm:
$ sudo cryptsetup luksOpen /dev/mmcblk0p2 lvm
Crea el volumen primario, el grupo de volumen y volumen lógico:
Monta el nuevo volumen root encriptado (volumen lógico):
$ sudo mount /dev/mapper/vg-root /mnt
Copia el volumen root existente al nuevo volumen root encriptado. Una instalación de 1.5 GB se completa en aproximadamente 6 minutos con una microSD de gama media:
Si las claves SSH del host están vacías, elimínalas para que se regeneren la próxima vez que se inicie sshd. Esto evitará el problema de la pérdida de memoria tal y como se describe en http://bit.ly/2xQxGqe.
$ sudo rm /mnt/etc/ssh/ssh_host*key*
Crea algunos directorios y monta la partición de arranque:
$ sudo nano /mnt/etc/fstab
$ /dev/mapper/vg-root / ext4 errors=remount-ro,noatime,discard 0 1
$ /dev/mmcblk0p1 /boot ext4 noatime,discard 0 2
Next, generate a new initramfs using dracut. The following commands will add the dracut modules crypt and lvm to the initramfs. These modules will prompt for LUKS password during boot and unlock the LUKS volume. Note that the order of the modules is important:
$ sudo dracut --force --hostonly -a "crypt lvm" /mnt/boot/initramfs-linux.img
Ten en cuenta que en el paso anterior, NO se elimina el resto de bootargs, básicamente reemplaza root = UUID = 2b53696c-2e8e-4e61-a164-1a7463fd3785 por rd.luks.uuid=470cc9eb-f36b-40a2-98d8-7fce3285bb89 root=/dev/mapper/vg-root y no toques el resto de bootargs. Luego, desmonta y reinicia los rootfs de LUKS:
A continuación, desbloquea de forma remota los rootfs de LUKS durante el arranque usando Dropbear sshd. Reemplace 10.0.0.100 en las siguientes instrucciones por la dirección IP asignada al ODROID-C2 por tu servidor DHCP local. Usa la herramienta fing para encontrar la dirección IP asignada (por ejemplo, sudo fing 10.0.0.1/24). Luego, asegúrate de que el demonio SSH se está ejecutando:
Genera un nuevo initramfs usando dracut. Los siguientes comandos añadirán la red de módulos dracut y crypt-ssh a initramfs. Ten en cuenta que el orden de los módulos es importante:
Si prefieres DHCP en lugar de una ip estática, simplemente reemplaza con ip=dhcp. Consulta la documentación de red de dracut en http://bit.ly/2g6XCXky y las opciones dracut en http://bit.ly/2yUBFT6 para obtener más opciones (man dracut.cmdline). Reinicia para que se inicie Dropbear, permitiendo el desbloqueo remoto:
$ sudo reboot
Desde tu maquina Linux, conéctate al servidor remoto Dropbear SSH que se ejecuta en el ODROID-C2:
$ ssh -p 222 root@10.0.0.100
Desbloquea el volumen (te pedirá la contraseña y enviarla a la consola):
$ console_auth
Passphrase:
Si el desbloqueo del dispositivo tuvo éxito, initramfs se limpiará por sí mismo y Dropbear finalizará por si sólo y tu conexión.
También puede escribir "console_peek" que muestra lo que hay en la consola. También existe el comando unlock, pero encontramos un problema cuando realizamos las pruebas, tal y como se describe en http://bit.ly/2fHB2nw.
En algunos casos se requiere alimentar la entrada de datos automáticamente con el comando interactivo console_auth. Desde tu maquina Linux, desbloquea el volumen:
$ gpg2 --decrypt password-file.gpg | ssh -p 222 root@10.0.0.100 console_auth
For additional security, you might want to only allow the execution of the command console_auth and nothing else. To achieve this, you need to configure the SSH key with restricting options in the authorized_keys file. From your Linux box, copy the public SSH key, with restricting options, to the appconf/dracut-crypt-ssh/authorized_keys file on the remote ODROID-C2 server:
$ (printf 'command="console_auth",no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding ' && cat ~/.ssh/*.pub) | ssh alarm@10.0.0.100 'umask 077; mkdir -p appconf/dracut-crypt-ssh; touch appconf/dracut-crypt-ssh/authorized_keys; cat >appconf/dracut-crypt-ssh/authorized_keys'
Consulta la documentación de Dropbear para obtener una lista completa de las opciones restringentes. Antes de continuar, podría ser una buena idea crear una copia de initramfs:
En este caso, puede desbloquear el volumen de forma interactiva simplemente escribiendo el siguiente comando:
$ ssh -p 222 root@10.0.0.100
Ten en cuenta que, al escribir el comando anterior, el comando console_auth es activado automáticamente en el servidor remoto e inmediatamente solicita la contraseña, como si simplemente se escribiera ssh -p 222 root@10.0.0.100 console_auth. Mientras escribes la contraseña, se mostrará en la pantalla en texto plano. Por lo tanto, debe evitar desbloquear interactivamente cuando el acceso está restringido al comando console_auth. Cuando presiones enter, se desconectará sin importar si la contraseña era correcta o no. Mientras que con el inicio de sesión no restringido (ver http://bit.ly/2hHAGl0), solo se desconectaría si la contraseña es correcta, lo que significa que te aparecerán comentarios sobre si el desbloqueo ha tenido exito o no. Por otro lado, para desbloquear el volumen usando un archivo de contraseña, desde tu maquina Linux escriba el siguiente comando:
Módulo LCD I2C: Utilizando la LCD serie 1602 16x2 TWI
October 1, 2017By Miltiadis MelissasODROID-C2, Mecaniqueo
Después de haber hecho tantos proyectos de IoT con mi ODROID-C2 como el detector sismógrafo (http://bit.ly/2uWqas0), el sistema de conservación y notificación para bodegas (http://bit.ly/2wch3Vb), el notificador mecánico de Gmail (http://bit.ly/2wch3Vb) y muchos otros, estaba pensando en añadir una pantalla LCD de bajo consumo y coste para mostrar cualquier información valiosa de todas estas creaciones electrónicas teniendo en cuenta la portabilidad y la legibilidad. La pantalla del módulo LCD serie I2C TWI 1602 16×2 para Arduino JD es la solución ideal para visualizar datos técnicos y mucha más información
Esta pantalla módulo LCD se comunica con un ODROID-C2 utilizando el protocolo I2C con solo 4 cables. El protocolo I2C es un bus informático serie, multi-maestro, multi-esclavo, mono-terminal con intercambio de paquetes, inventado por Philips Semiconductor (ahora NXP Semiconductors). Normalmente se utiliza para conectar ICs periféricos de baja velocidad a procesadores y microcontroladores en comunicaciones a corta distancia, dentro de la placa (http://bit.ly/2qGiYP4). En las siguientes líneas, vamos a describir cómo poder materializar físicamente y en forma de programa esta conexión. El lenguaje utilizado es Python 2.7, y el programa se puede implementar fácilmente en otros proyectos como un módulo con pequeñas modificaciones.
Hardware
Necesitarás todos los accesorios habituales del ODROID-C2:
ODROID-C2
Tarjeta MicroSD con el último Ubuntu 16.04 proporcionado por HardKernel (http://bit.ly/2rDOCfn)
La librería WiringPi para controlar los GPIO de un ODROID-C2 que ejecuta Ubuntu 16.04 (las instrucciones de Hardkernel sobre cómo instalar la librería las puedes encontrar en http://bit.ly/1NsrlU9)
Teclado
Pantalla
Cable HDMI
El teclado, la pantalla y el cable HDMI son opcionales ya que puedes acceder a tu ODROID-C2 desde tu ordenador de escritorio a través de SSH
Alimentación por Micro USB o, mejor aún, la fuente de alimentación proporcionada por Hardkernel (http://bit.ly/1X0bgdt)
Opcional: Batería externa con UBEC (3A max, 5V), si deseas que el dispositivo funcione de forma autónoma (consulta la Figura 1). Hardkernel ofrece una solución mejor con el UPS3 diseñado específicamente para ODROID-C2. Puede comprar el UPS3 desde su tienda en este enlace: http://bit.ly/2l1rE25. El UPS3 es una muy buena opción, ya que ofrece al detector la posibilidad de trabajar de forma autónoma con mayor estabilidad y duración
Cable Ethernet o Dongle USB Wifi
El kit Tinkering C para Ubuntu, que se puede comprar en Hardkernel (http://bit.ly/1NsrlU9)
Pantalla modulo LCD Serie I2C TWI 1602 16×2 para Arduino JD, que se puede encontrar en varios sitios, como eBay
Para el cableado, sigue el esquema de la figura 1. Hay dos cables que son muy importantes para la comunicación: el SDA que proporciona los datos en serie de I2C y el SCL que proporciona el registro del tiempo en serie del I2C. El SDA está en el Pin 3 en la pantalla LCD I2C y está conectado al Pin 3 GPIO del ODROID-C2. El SCL está en el Pin 4 y está conectado al Pin 5 GPIO del ODROID-C2. A modo de referencia, echa un vistazo al esquema de la Figura 1 y al excelente diseño de 40 pines de Hardkernel para el ODROID-C2 (http://bit.ly/2aXAlmt). Esto te ayudará a colocar el cableado correctamente. Ahora que tenemos nuestro hardware listo, veamos cómo podemos establecer una comunicación entre el ODROID-C2 y la pantalla LCD serie I2C utilizando el protocolo I2C. El Pin 2 GPIO proporciona la potencia VCC, +5V, para la pantalla LCD y el Pin 39 GPIO es, por supuesto, la toma a tierra, GND.
Iomunicción I2C
Vamos a establecer una conexión entre ODROID-C2 y la pantalla LCD en serie utilizando el protocolo I2C. Los pasos que vamos a seguir son casi idénticos a los detallados en nuestro anterior artículo bajo el título "Detector sismógrafo de terremotos: Midiendo la aceleración sísmica utilizando el ODROID-C2", publicado en la edición de julio de ODROID Magazine (http://bit.ly/2uWqas0). En ese artículo, describimos todos los pasos necesarios para establecer la comunicación entre el ODROID-C2 y el acelerómetro MMA7455, que también usa I2C. Repetiremos el mismo procedimiento con el fin de garantizar la coherencia y la integridad del artículo.
Todos los comandos se introducen en una ventana de terminal o a través de SSH. Primero, deberás actualizar ODROID-C2 para asegurarte de que tienes instalados los últimos paquetes:
Tendrás que instalar SMBus y I2C-Tools, ya que la pantalla del módulo LCD utiliza este protocolo para comunicarse con el ODROID-C2. El Bus de administración del sistema, o SMBus, es un simple bus mono-terminal de dos hilos para comunicaciones livianas. Suele encontrarse con frecuencia en la placas base de los ordenadores para comunicarse con la fuente de alimentación (http://bit.ly/2rAWhuU).
Una vez que hayas iniciado sesión en tu ODROID-C2 desde la línea de comandos, ejecuta el siguiente comando para instalar Python-SMBus y I2C-Tools:
$ sudo apt-get install pythonsmbus
Configura ODROID-C2 para cargar el driver I2C:
$ modprobe ami-i2c
Configurar el ODROID-C2 para iniciar I2C automáticamente en el arranque editando /etc/modules:
$ sudo nano /etc/modules
Usa las teclas de cursor para moverte a la última línea y añade una nueva línea con el siguiente texto:
$ i2c-dev
Presiona intro, luego añade:
$ aml_i2c
Guarda tus cambios y salte del editor nano. Para evitar tener que ejecutar las herramientas I2C como root, agrega el usuario "ODROID" al grupo I2C:
$ sudo adduser Odroid 12c
Después reinicia el ODROID-C2:
$ sudo reboot
Una vez que hayas reiniciado tu ODROID-C2, tendrás soporte para I2C. Puedes verificar si hay dispositivos I2C conectados con el siguiente comando:
$ sudo i2cdetect -y -r 1
Si aparece '27' en la línea 20 de la columna 7, significa que la pantalla LCD se está comunicando con el ODROID-C2 y funciona correctamente. Puedes encontrar más detalles en http://bit.ly/2qCQM1s.
Software Pyton
Vamos a presentar el código por fragmentos, como lo hacemos siempre, para que nuestros lectores lo entiendan mejor. El código de aquí esta modificado ligeramente con respecto al código fuente (http://bit.ly/2w2a957) que ha sido adaptado a las necesidades de este proyecto. El código está en Python y lo que principalmente hace es establecer una conexión entre el ODROID-C2 y la pantalla LCD abriendo una conexión I2C que permite visualizar 16 caracteres en dos líneas. Puede descargar el código desde aquí (http://bit.ly/2vzSMqd) y ejecutarlo para obtener resultados inmediatos, o si simplemente no deseas volver a escribir todo el código. Primero, importa los módulos necesarios:
import smbus
import time
# Define device parameters
I2C_ADDR = 0x27 # I2C device address, if any error,
# change this address to 0x3f
LCD_WIDTH = 16 # Maximum characters per line
# Define device constants
LCD_CHR = 1 # Mode - Sending dataLCD_CMD = 0 # Mode - Sending command
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
LCD_BACKLIGHT = 0x08 # On
ENABLE = 0b00000100 # Enable bit
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
#Open I2C interface
bus = smbus.SMBus(1) # Open I2C interface for ODROID-C2
# Initialise display
def lcd_init():
lcd_byte(0x33,LCD_CMD) # 110011 Initialise
lcd_byte(0x32,LCD_CMD) # 110010 Initialise
lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01,LCD_CMD) # 000001 Clear display
time.sleep(E_DELAY)
# Send byte to data pins
# (#bits = the data, #mode = 1 for data or 0 for command)
def lcd_byte(bits, mode):
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT
bus.write_byte(I2C_ADDR, bits_high) # High bits
lcd_toggle_enable(bits_high)
bus.write_byte(I2C_ADDR, bits_low) # Low bits
lcd_toggle_enable(bits_low)
# Toggle enable
def lcd_toggle_enable(bits):
time.sleep(E_DELAY)
bus.write_byte(I2C_ADDR, (bits | ENABLE))
time.sleep(E_PULSE)
bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
time.sleep(E_DELAY)
# Send string to display
def lcd_string(message,line):
message = message.ljust(LCD_WIDTH," ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
# Main program block, # Initialize display
def main():
lcd_init()
# Send text to I2C TWI 1602 16x2 Serial LCD Module Display
while True:
lcd_string("***ODROID-C2***",LCD_LINE_1)
lcd_string("ODROID-magazine ",LCD_LINE_2)
time.sleep(3)
lcd_string("***HardKernel***",LCD_LINE_1)
lcd_string("*hardkernel.com*",LCD_LINE_2)
time.sleep(3)
# Handling keyboard interrupts and exception utility
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
finally:
lcd_byte(0x01, LCD_CMD)
Ejecutando el código
El código anterior se puede escribir en cualquier editor de texto. Sin embargo, es más fácil hacerlo con un IDE de Python, como Python IDLE. El Python IDLE es accesible desde el escritorio Mate (Aplicación -> Programación -> IDLE). Tan pronto como escribamos el programa, podemos guardarlo con cualquier nombre y finalmente, ejecutarlo como se muestra en la Figura 3:
$ sudo python lcd16x2i2c.py
Los mensajes se presentan en el módulo LCD de forma secuencial, 2 líneas de cada vez.
Conclusión
La aplicación "Drive I2C LCD screen with ODROID-C2" puede implementarse en cualquier otro proyecto con pequeñas modificaciones en un módulo Python. La única parte del código que debes modificar para cambiar las líneas de caracteres que se muestran en la pantalla LCD es la siguiente:
# Send text to I2C TWI 1602 16x2 Serial LCD Module Display
while True:
lcd_string("***ODROID-C2***",LCD_LINE_1)
lcd_string("ODROID-magazine ",LCD_LINE_2)
time.sleep(3)
lcd_string("***HardKernel***",LCD_LINE_1)
lcd_string("**hardkernel.com",LCD_LINE_2)
time.sleep(3)
No dude en hacer cambios en el código y en añadir funciones adicionales a cualquier otro proyecto que puedas crear.
GamODROID-C0: Una Consola de Juegos Retro portátil Basada en ODROID
October 1, 2017By Julien TiphaineJuegos, ODROID-C0, Mecaniqueo
Este artículo va de otra consola de juegos portátil casera a modo de continuación de la primera que desarrollé (http://bit.ly/2yFj4th). En mi primer desarrollo, utilicé un ODROID-W (clon de pi) y una carcasa GameBoy nueva. Para este nuevo proyecto, deseaba algo más potente para ejecutar juegos de N64, Dreamcast y PSX, y también algún que otro juego nativo de Linux. No hay muchas opciones de bajo consumo con suficiente CPU + GPU para esto, así que elegí un ODROID-C0. Además, en lugar de usar y transformar una carcasa existente, utilicé una impresión 3D diseñada por mí con un tamaño y unas dimensiones muy optimizadas. Quisiera dar las gracias a la comunidad ODROID (forum.ODROID.com) y en particular a @meveric por su distribución debian y los paquetes optimizados para ODROID.
Componentes
Aquí tienes una lista de todos los componentes que utilice en este desarrollo:
Componentes principales:
ODROID-C0
Módulo eMMC de 8GB
MicroSD XC de 128 Gb (SanDisk Ultra, XC I, clase 10)
Las fuentes principales de consumo de energía son el ODROID-C0, la pantalla y el sistema de audio (tarjeta de sonido y amplificador de audio). Antes de empezar, decidí medir el consumo de estos 3 componentes:
ODROID-C0: 200-400 mAh dependiendo del uso de la CPU y de la GPU
Sistema de audio: 310 mAh
Pantalla: 420 mAh
Hace un total de 1130 mAh a 5v, de modo que son 5650mA/hora. Las baterías que usé son de (al menos) 3.7v x 5000 mA con un total de 18500 mA. La consola debería durar más de 3h en todos los casos.
¿Por qué usar una pantalla con tan poca resolución?
Existen varios motivos para ello: baja potencia, 60 FPS, cableado sencillo y tiene poca definición aparentando un televisor antiguo, lo que hace que el suavizado de bordes por hardware sea muy bueno.
¿Por qué usar baterias en forma de cilindro?
Se trata de una cuestión de optimización del espacio en relación a la capacidad que quería. Usar una batería plana más clásica me habría obligado a ampliar la profundidad de la carcasa en más de 2 cm, aunque esa fue mi primera intención.
¿Por qué usar una placa prototipo para montar los componentes adicionales?
El objetivo era montar con facilidad todos los componentes como si fueran una única placa base, y realmente puedo decir que resulto muy útil.
¿Por qué es necesario un multiplexor analógico?
El ODROID-C0 solo proporciona 2 entradas analógicas, y una ya se usa para informar del nivel de batería. Por lo tanto, solo había 1 entrada analógica disponible para un total de 4 ejes analógicos (2 sticks con 2 direcciones cada uno). La única forma de leer los 4 ejes analógicos con una sola entrada analógica era con un multiplexor. Afortunadamente, el ODROID-C0 tiene suficientes pins digitales para usar 2 de ellos y así poder alternar los canales analógicos.
¿Por qué usar un módulo eMMC en lugar de una microSD?
El módulo eMMC es mucho más rápido que una microSD. Permite que la consola se inicie en unos pocos segundos incluso con Xorg, un gestor de ventanas, y Emulation Station con muchos juegos. Utilizo el eMMC para el sistema operativo y la microSD para los juegos y las vistas previas de los videos.
Carcasa impresa en 3D
La carcasa de la consola se ha modelado con Freecad. La diseñé específicamente para este proyecto, con un tamaño muy concreto para la placa base y todos los componentes. Fue mi primer modelo 3D y la primera impresión 3D, así que puede tener errores. No obstante, los archivos Freecad están disponibles en GitHub (http://bit.ly/2fGJWRU) y los archivos STL están distribuidos libremente en Thingverse en (http://bit.ly/2xW9FAh).
La carcasa es muy similar a una Nintendo DS. Puede que no sea tan evidente, pero usar las dimensiones de una consola tan conocida me permitió encontrar fundas de protección buenas y baratas. Como podrás ver en las fotos de más adelante, utilicé una funda NDS para proteger mi GamODROID-C0, que encontré por unos pocos euros.
Para conseguir un buen acabado, primero utilicé el papel de lija 600 y 1200 en todas las piezas. Luego, usé un producto llamado XTC-3D. Es asombroso y ofrece un aspecto brillante, pero todavía no tenía el acabado que perseguía. Utilicé de nuevo el papel de lija 1200 antes de usar una pintura satinada blanca. Finalmente, esto me dio el acabado que ves en las fotos.
Para las piezas más pequeñas como botones y el D-pad, utilicé un poco de esmalte de uñas. Es muy barato y realmente proporciona un acabado genial. Para finalizar barnicé los botones y el D-pad con un barniz de uñas transparente para proteger los colores, ya que éstos son muy utilizados en la consola.
Mi objetivo era desarrollar una placa base de una única pieza para hacerla más robusta y fácil de colocar dentro de la carcasa. También desarrollé pequeñas placas para los botones Inicio/selección y el D-pad.
Montar la pantalla
El sistema es aproximadamente el mismo que el que use para mi consola Retroboy (http://bit.ly/2yFj4th). Sin embargo, existen algunas diferencias en lo que respecta al conector: V-in y la salida compuesta han sido invertidas esta vez. La figura 5 muestra la pantalla original, tal como se encuentra en el sitio web de Adafruit.
Primero retiré el conector blanco, conecté el V-in directamente a la salida del regulador de voltaje y añadí dos cables para llevar la alimentación a través de uno de los pins ODROID 5V, como se muestra en la Figura 6.
Tarjeta de sonido
Elegí una tarjeta de sonido USB barata que tuviera un cable entre la placa y el conector USB. Esto era importante porque así resultaba más fácil retirar la soldadura.
Empecé a desmontar los cables, los conectores y volví a perforar los agujeros. Preparé la placa ODROID añadiendo los pins al primer conector USB, tal y como se muestra en las Figuras 8 y 9. Finalmente, soldé la tarjeta de sonido directamente a los pins, como se muestra en la Figura 10.
Placa de ampliación con puerto USB
Puse la placa de ampliación justo debajo de la tarjeta de sonido USB. Primero soldé un conector USB, luego lo conecté al segundo conector USB del ODROID a través de la placa de ampliación. Ten en cuenta que también soldé la placa de ampliación a la placa base ODROID para hacer que todo fuese más robusto.
Completando el sistema de audio en la placa de ampliación
Tener una tarjeta de sonido con salida analógica puede dar un buen resultado, pero es mejor una toma de audio 3.5 y un buen amplificador para montar los altavoces. Ese fue precisamente el siguiente paso: cablear y soldar los componentes en la placa de ampliación.
Cableado del multiplexor analógico
La soldadura de esta pequeña pieza supuso añadir muchos cables y terminó cubriendo casi toda la placa de ampliación. Tuve que usar lo siguiente: Vdd (Vin), Vss (tierra), x (salida analógica), x0, x1, x2, x3 (entradas analógicas), A, B (interruptores digitales). C no era necesario ya que 2 interruptores eran suficientes para alternar entre las primeras 4 salidas. Vee y INH fueron conectados a tierra. Ten presente que hice una separación de voltaje entre x (salida) y la entrada analógica del ODROID. Esto se debe a que los sticks analógicos PSP y MC14051B funcionan en 5V, mientras que la entrada analógica del ODROID-C0 acepta un máximo de 1.8v.
Botones del volumen
Es posible que hayas visto en la foto anterior que hay 2 botones pulsadores en uno de los bordes de la placa de ampliación. Los conecté a los pins GPIO para controlar el volumen del audio, tal y como se muestra en la Figura 20..
Botones de inicio/selección
Utilicé botones pulsadores para los botones de inicio y selección. Los monté en una pequeña placa adicional junto con un led azul para monitorizar la batería.
Baterías
Como he indicado anteriormente, he utilizado un par de baterías LiPo cilíndricas con protección. Las conecté en paralelo para conseguir 5000 mA. Tuve que soldar unos cables directamente a las baterías y añadir un conector Molex para poder conectar las dos baterías al conector LiPo del ODROID-C0.
Montaje de los componentes
Llegado a este punto, ya tenía todo lo relacionado con el hardware. Comencé a montar en la parte frontal de la carcasa la pantalla, los sticks analógicos, el D-pad, las placas a-b-x-y y los botones L1 + R1. La pantalla no está pegada, sino que se mantiene con dos barrotes transversales. Como puedes ver en la Figura 23, estas varillas me permitieron colocar y reconducir todos los cables.
El siguiente paso a realizar en la parte frontal de la carcasa es añadir los altavoces, los botones de inicio/selección y cablear todo con una puesta a tierra común. Los pasos finales antes del cierre son añadir un disipador de calor, colocar los botones L2 + R2 y la placa base en la parte posterior de la carcasa, luego soldar todo a GPIO. Ten en cuenta también el cable amarillo que es la salida compuesta del ODROID que va a la entrada 1 de la pantalla.
Software
Desarrollé un script que configura el 80% del sistema, incluida una copia de los archivos de configuración específicos. El otro 20% es para la ROMs y los ajustes personales. Si alguien quiere hacer lo mismo, el script es bastante fácil de adaptar y volver a ejecutar.
Antes de empezar a comentar el script de instalación, aquí te dejo los pasos de instalación que lleve a cabo:
Implementación de la imagen mínima Debian Jessie de @meveric en el módulo eMMC (http://bit.ly/2yF2PML)
Se crearon dos particiones en la microSD de 128GB: 4 Gb para guardar los estados y el resto para las ROMs, las cuales estarán montadas en /mnt/states y /mnt/ressources). Hice 2 particiones porque tenía la intención de crear un sistema de solo lectura a excepción de los estados, pero finalmente mantuve un sistema completo de lectura/escritura.
Se creó una carpeta GameODROID en /root y se copia el script de instalación y sus dependencias.
Script de Instalacíon
El script de instalación y todas las dependencias las puedes encontrar en GitHub en http://bit.ly/2fGJWRU. Está organizado con funciones dedicadas para cada paso.
La primera función crea puntos de montaje personalizados, copia el fstab personalizado y activa tmpfs:
function fstab
{
echo "fstab and filesystem"
mkdir -p /mnt/states
mkdir -p /mnt/ressources
cp /root/GameODROID/fstab /etc/fstab
sed -i "s/#RAMLOCK=yes/RAMLOCK=yes/" /etc/default/tmpfs
sed -i "s/#RAMSHM=yes/RAMSHM=yes/" /etc/default/tmpfs
}
El archivo fstab personalizado permite cambiar las opciones de montaje para optimizar la velocidad (noatime, discard) y usar una pequeña partición tmpfs para /var/log:
tmpfs /var/log tmpfs nodev,nosuid,noatime,size=20M 0 0
Tras esta primera función, el sistema se reinicia, luego se actualiza y se vuelve a reinicia:
function uptodate
El paso final de esta fase es instalar todos los paquetes base necesarios (paquetes de funciones). No tiene nada de especial excepto dos cosas:
evilwm : Tuve que usar un gestor de ventanas porque algunos juegos nativos no pueden detectar la resolución de pantalla nativa sin él. Descubrí que evilwm era muy buen candidato para la consola, ya que es muy ligero y casi invisible con las configuraciones por defecto.
Antimicro-ODROID : es un software muy bueno que no conocía. Me permite asignar cualquier evento de teclado y ratón al joypad.
Paquete de Python evdev: utilizado para configurar la entrada reicast
Utilicé un archivo de configuración xorg específico para ODROID C1/C0 proporcionado por (http://bit.ly/2xaSonP)
Juegos
Esta parte corresponde a las funciones "emulators", "emulators_glupen64_meveric" y “nativegames”. Excepto para los juegos de Dreamcast para los que utilicé Reicase, el resto de emuladores son parte de Retroarch:
pcsx-rearmed (PSX)
fbalpha (CPS2)
gambatte (Gameboy color)
gpsp (Gameboy advance)
mednafen-pce-fast (Pc-Engine + Cdrom)
nestopia (Nes)
picodrive (Sega 32X, SegaCD)
pocketnes (Snes)
genesis-plus-gx (GameGear, Genesis, MasterSystem)
mednafen-ngp (Neogeo pocket color)
Para los juegos nativos, seleccioné aquellos que fueran divertidos para jugar con un gamepad y funcionaran correctamente en el ODROID-C0 con una pantalla pequeña:
hurrican
hcraft
frogatto
SuperMario War
astromenace
neverball
shmupacabra
aquaria
Revolt
Open JK3
openjazz
supertuxkart
mars
puzzlemoppet
opentyrian
pushover
Lanzador de juegos
Esto corresponde a la función "userinterface". Inicialmente, quería usar el modo Attract. Lamentablemente, la implementación de GLES en ODROID-C0/C1 no parece incluir las funciones glBlendEquationSeparateOES () y glBlendFuncSeparateOES (), que son obligatorias para compilar libFSML, que a su vez es obligatorio para compilar el modo Attract. De modo que, utilicé la última versión de Emulation Station con soporte de vista previa de video. Como quería cambiar la pantalla de inicio por defecto por una personalizada, tuve que reemplazar el archivo "splash_svg.cpp" en "EmulationStation/data/converted". Este archivo es una simple matriz C que contiene los bytes de un archivo SVG. Al margen de la configuración clásica de los sistemas, creé una específica que incluye dos scripts para cambiar la pantalla: pantalla interna o HDMI (consulta los scripts composite.sh y hdmi.sh).
Herramientas específicas
Esto corresponde a la función "localtools". Ésta se utilza principalmente para manejar el gamepad GPIO personalizado. Tuve que escribir un pequeño programa en C que crea un gamepad mediante el sondeo GPIO y la entrada de Linux para generar eventos. Utilicé el sondeo en lugar del IRQ porque el SoC no tiene suficiente IRQ para manejar todos los botones. Llamé a esta herramienta gpio_joypad y el código fuente está en GitHub en http://bit.ly/2xaTdgp. También maneja el multiplexor analógico para recuperar los valores de izquierda y derecha del sticks analógico.
Archivo de configuración de arranque
Esto corresponde a la función "bootini". Esta función consiste en copiar un archivo boot.ini personalizado en la partición de arranque. Los cambios importantes que hice son:
Mantener súnicamente dos modos de video: cvbs480 (activado por defecto) y vga (comentado)
Cec y vpu desactivados
Argumentos del kernel modificados:
“cvbsmode=480cvbs” para lograr una resolución NTSC de 60Hz en lugar de 50Hz PAL
“max_freq=1824” para aumentar la frecuencia del reloj del SoC (necesario para los emuladores N64 y Dreamcast)
“quiet loglevel=3 rd.systemd.show_status=false udev.log-priority=3” para que el arranque sea lo más silencioso posible
Inicialmente, quería mostrar la pantalla de inicio durante el proceso de arranque. Está bien explicado cómo hacerlo en el wiki de ODROID, pero desafortunadamente sólo funciona para resoluciones 720p.
Lanzar todo en el inicio
Esto corresponde a la función "startup". El inicio automático de X y Emulationstation en el arranque consistia en un servicio tty1 personalizado en systemd que lanza agetty con autologin, un perfil BASH que inicia X cuando la variable tty = tty1 y finalmente un xinitrc que inicia el gestor de ventanas y Emulation Station.
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I $TERM
The bash /root/.profile :
# ~/.profile: executed by Bourne-compatible login shells.
if [ "$BASH" ]; then
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
fi
if [ "$(tty)" = "/dev/tty1" ] ; then
/usr/local/bin/battery.sh &
/usr/local/bin/gpio-joypad &
startx -- -nocursor 2>&1 &
fi
mesg n
/root/.xinitrc
# a WM is needed some software are correctly sized in full screen
# e.g : emulationstation, rvgl
evilwm & pid=$!
emulationstation.sh &
# this allows not to shutdown X when emulation is killed
# We want that because we have to kill it after gamelaunch
# else it does not reappear on screen (SDL_Createwindow() does never end)
wait $pid
Note that the bash profile start the joypad driver (gpio_joypad) and the battery monitoring script (battery.sh) before starting X.
The battery monitoring script is not very accurate, but I dit not found any way to make a better monitoring to switch on the led on low battery or when charging:
#!/bin/bash
PIN=75
GPIO=/sys/class/gpio
ACCESS=$GPIO/gpio$PIN
LOWBAT=780
CHARGING=1020
if [ ! -d $ACCESS ] ; then
echo $PIN > $GPIO/export
echo out > $ACCESS/direction
echo 0 > $ACCESS/value
fi
while true
do
ADCVAL=$(cat /sys/class/saradc/saradc_ch0)
# echo "value : $ADCVAL"
# charging
if [ $ADCVAL -gt $CHARGING ]; then
echo 1 > $ACCESS/value
else
# low bat
if [ $ADCVAL -lt $LOWBAT ]; then
echo 1 > $ACCESS/value
sleep 1
echo 0 > $ACCESS/value
else
echo 0 > $ACCESS/value
fi
fi
sleep 2
done
Finalizar y limpiar
Esto corresponde a la función "optimize_system". En esta función, el mensaje de inicio de sesión BASH está oculto (para que el proceso de arranque sea lo más silencioso posible) y se limpie la caché de los paquetes (apt-get clean). También se utilizan dos archivos de configuración. El journald.conf personalizado está aquí para escribir registros logs en la ram en lugar de en el disco para mejorar rendimiento:
[Journal]
Storage=volatile
I also created a specific alsa configuration file to add latency and buffers, so most sound stutering are avoided for n64 and dreamcast games:
pcm.!default {
type plug
slave.pcm "softvol"
ttable.0.1 0.8
ttable.1.0 0.8
}
pcm.dmixer {
type dmix
ipc_key 1024
slave {
pcm "hw:1,0"
period_time 0
period_size 2048
buffer_size 65536
rate 44100
}
bindings {
0 0
1 1
}
}
pcm.dsnooper {
type dsnoop
ipc_key 1024
slave {
pcm "hw:1,0"
channels 2
period_time 0
period_size 2048
buffer_size 65536
rate 44100
}
bindings {
0 0
1 1
}
}
pcm.softvol {
type softvol
slave { pcm "dmixer" }
control {
name "Master"
card 1
}
}
ctl.!default {
type hw
card 1
}
ctl.softvol {
type hw
card 1
}
ctl.dmixer {
type hw
card 1
}
Configuración general de Retroarch
Al margen de cambiar los botones y la ruta, tuve que adaptar algunos parámetros de videos de retroarch (root /.config/retroarch/retroarch.cfg) para optimizar el rendimiento y adaptar mejor al hardware:
También hice algunos ajustes en uno de los núcleos de emulador:
Permitiendo 6 botones para SegaCD y 32X:
picodrive_input1 = "6 button pad"
Changing glupen64 parameters to optimize rendering on the ODROID SoC:
glupen64-cpucore = "dynamic_recompiler"
glupen64-rspmode = "HLE"
glupen64-43screensize = "320x240"
glupen64-BilinearMode = "standard"
Allowing PSX analog joypad support:
pcsx_rearmed_pad1type = "analog"
Para el emulador Dreamcast, utilicé reicast-joyconfig (http://bit.ly/2fLE1yH) para generar la configuración del gamepad y copié el archivo resultante en /root/.config/reicast/joy.conf. También cambié la resolución de toda la pantalla para adaptarla a la pantalla CVBS:
[x11]
fullscreen = 1
height = 480
width = 720
Asignaciones de teclado y ratón para juegos nativos
Algunos juegos nativos funcionan muy bien, pero requieren de un ratón o un teclado para algunas teclas especiales como Esc, Enter, Space, Shift y las teclas de flechas. Para asignar estas teclas a la consola de gamepad, yo utilicé antimicro. Es un programa sencillo que te permite asignar cualquier tecla del ratón y del teclado a cualquier botón de gamepad.
Buscador de información de videos
Emulation Station tiene un buscador integrado para localizar la información de juegos e imágenes, pero no para videos. Además, si las vistas previas del video son compatibles dependiendo de los temas elegidos, se reproducen a través de VLC, que no permite aceleración en el Soc del ODROID-C0/C1. La consecuencia es que 320×240@30 FPS en h.264 es el tamaño más grande al que se puede jugar. Escribí y usé un script personalizado disponible en GitHub en http://bit.ly/2fGFSkU, que analiza la carpeta game de Emulation Station y rastrea videos desde www.gamesdatabase.org.
Lecciones aprendidas
No hay forma de controlar correctamente la batería en un ODROID-C0
Con solo una GPU Mali 450, incluso aumentando la frecuencia del reloj (overclock), aún sigue siendo lento para muchos juegos de N64 y Dreamcast
Hay algunos fallos que parecen estar relacionados con el driver gráfico, como que Emulation Station no se sale correctamente, y hurrican a veces no se inicia con la resolución correcta
No es posible utilizar un driver joypad apropiado basado en interrupciones, ya que no hay suficientes IRQ disponibles en el SoC.
Se hace necesario disponer de un gestor de ventanas, de lo contrario, la pantalla completa no está disponible para los juegos y Emulation Station
Reicast parece emular ruido de GDRom, realmente lo encuentro algo molesto
Desarrollo de Android: Proveedor de contenido de Android
October 1, 2017By Nanik TolaramAndroid, Tutoriales
Al igual que ocurre con cualquier otro sistema operativo, Android necesita internamente tener un almacenamiento de persistencia para almacenar información del sistema. Estos datos deben estar en un almacenamiento persistente, ya que siempre necesitará hacer referencia a éstos después de cada reinicio para poner el dispositivo en un estado específico. La información del usuario y del dispositivo, como el brillo de la pantalla, el volumen, las cuentas, el calendario, etc., necesitan almacenarse en algún lugar. Android usa lo que se conoce como Proveedor de Contenido. Básicamente, es un mecanismo persistente respaldado por SQLite, o más conocido simplemente como base de datos. La mayoría de los datos se almacenan internamente en varias bases de datos SQLite. En este artículo vamos a echar un vistazo a algunos de los proveedores de contenido que utiliza internamente el sistema operativo.
En este artículo analizaremos algunas de las bases de datos que el sistema operativo utiliza internamente. Un buen punto de partida para obtener información sobre los Proveedores de contenido es dirigirse al sitio web para desarrolladores Android de Google (http://bit.ly/2hkvljq).
Qué y donde
Los proveedores de contenido son simplemente aplicaciones corrientes de Android que tienen la función de servir y procesar solicitudes de base de datos desde un cliente. Los datos de los proveedores de contenido internos se almacenan en la carpeta /data/data tal y como se muestra en la Figura 1. Nos interesan las aplicaciones que tienen el siguiente formato de paquetes:
com.android.providers.< app_name >
La figura 1 muestra los proveedores de contenido internos de Android que hay disponibles.
Tenemos, por ejemplo, el servicio DownloadManager proporcionado por Android SDK. Este servicio permite que las apps descarguen archivos de forma asíncrona. Internamente, el entorno de trabajo utiliza este proveedor de contenido para mantener información persistente sobre el estado de un archivo que se va a descargar. El siguiente esquema SQL muestra la declaración que se utiliza internamente para mantener la información del archivo descargado.
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE downloads(_id INTEGER PRIMARY KEY AUTOINCREMENT,uri TEXT, method INTEGER, entity TEXT, no_integrity BOOLEAN, hint TEXT, otaupdate BOOLEAN, _data TEXT, mimetype TEXT, destination INTEGER, no_system BOOLEAN, visibility INTEGER, control INTEGER, status INTEGER, numfailed INTEGER, lastmod BIGINT, notificationpackage TEXT, notificationclass TEXT, notificationextras TEXT, cookiedata TEXT, useragent TEXT, referer TEXT, total_bytes INTEGER, current_bytes INTEGER, etag TEXT, uid INTEGER, otheruid INTEGER, title TEXT, description TEXT, scanned BOOLEAN, is_public_api INTEGER NOT NULL DEFAULT 0, allow_roaming INTEGER NOT NULL DEFAULT 0, allowed_network_types INTEGER NOT NULL DEFAULT 0, is_visible_in_downloads_ui INTEGER NOT NULL DEFAULT 1, bypass_recommended_size_limit INTEGER NOT NULL DEFAULT 0, mediaprovider_uri TEXT, deleted BOOLEAN NOT NULL DEFAULT 0, errorMsg TEXT, allow_metered INTEGER NOT NULL DEFAULT 1, allow_write BOOLEAN NOT NULL DEFAULT 0, flags INTEGER NOT NULL DEFAULT 0);
CREATE TABLE request_headers(id INTEGER PRIMARY KEY AUTOINCREMENT,download_id INTEGER NOT NULL,header TEXT NOT NULL,value TEXT NOT NULL);
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE downloads(_id INTEGER PRIMARY KEY AUTOINCREMENT,uri TEXT, method INTEGER, entity TEXT, no_integrity BOOLEAN, hint TEXT, otaupdate BOOLEAN, _data TEXT, mimetype TEXT, destination INTEGER, no_system BOOLEAN, visibility INTEGER, control INTEGER, status INTEGER, numfailed INTEGER, lastmod BIGINT, notificationpackage TEXT, notificationclass TEXT, notificationextras TEXT, cookiedata TEXT, useragent TEXT, referer TEXT, total_bytes INTEGER, current_bytes INTEGER, etag TEXT, uid INTEGER, otheruid INTEGER, title TEXT, description TEXT, scanned BOOLEAN, is_public_api INTEGER NOT NULL DEFAULT 0, allow_roaming INTEGER NOT NULL DEFAULT 0, allowed_network_types INTEGER NOT NULL DEFAULT 0, is_visible_in_downloads_ui INTEGER NOT NULL DEFAULT 1, bypass_recommended_size_limit INTEGER NOT NULL DEFAULT 0, mediaprovider_uri TEXT, deleted BOOLEAN NOT NULL DEFAULT 0, errorMsg TEXT, allow_metered INTEGER NOT NULL DEFAULT 1, allow_write BOOLEAN NOT NULL DEFAULT 0, flags INTEGER NOT NULL DEFAULT 0);
CREATE TABLE request_headers(id INTEGER PRIMARY KEY AUTOINCREMENT,download_id INTEGER NOT NULL,header TEXT NOT NULL,value TEXT NOT NULL);
El siguiente bloque de código muestra un ejemplo de información almacenada del archivo descargado:
Los proveedores de contenido proporcionados por el sistema operativo, que no todos están disponibles para una aplicación de usuario, generalmente tienen la siguiente declaración en su AndroidManifest.xml:
Listado 1: Proveedor de contenido de la configuración
El Listado 1 es el AndroidManifest.xml para la aplicación de Configuración que se almacena en el paquete com.android.providers.settings. Se puede ver otro ejemplo en el Listado 2 que muestra la declaración para el Proveedor de Contactos utilizado para la información de contactos almacenados:
Programación en Paralelo ODROID-MC1: Primeros Pasos
October 1, 2017By Andy YuenODROID-MC1
Esta guía no pretende enseñarte a escribir programas en paralelo sobre el ODROID-MC1. Está dirigida a proporcionarte un entorno acondicionado para experimentar con MPJ Express, una implementación de referencia de la API mpiJava 1.2. Se proporciona un programa paralelo en MPJ Express que genera imágenes Mandelbrot para que se ejecute en cualquier máquina o clúster que tenga instalado el SDK de Java: ARM o INTEL. En el caso de que exista mucho interés por conocer la programación MPJ Express, podemos escribir un tutorial para una futura edición de la revista.
¿Por qué la programación en paralelo?
La programación o la computación en paralelo es un modo de procesamiento en el cual muchos cálculos independientes se llevan a cabo de forma simultánea, operando bajo la premisa de que los grandes problemas a menudo se pueden dividir en pequeños, y que luego se resuelven al mismo tiempo. En resumen, lo que persigue es tipo de programación es:
Aumentar la velocidad general,
Procesar gran cantidad de datos,
Resolver problemas en tiempo real y
Solucionar problemas a su debido tiempo
¿Por qué ahora?
Mucha gente debate si la Ley de Moore todavía se mantiene. La ley de Moore viene a decir que el número de transistores en un denso circuito integrado se duplica aproximadamente cada dos años (algunos dicen que 18 meses). La ley de Moore debe su nombre a Gordon E. Moore, cofundador de INTEL y Fairchild Semiconductor. Es este continuo avance de la tecnología de circuitos integrados el que nos ha llevado a pasar del PC original de 4,77 megahertz a los actuales procesadores multi-gigahertz. La arquitectura de los procesadores también ha cambiado mucho con los múltiples hilos de ejecución, la ejecución fuera de orden, el almacenamiento en caché, etc.
Suponiendo que la ley de Moore se siga aplicando, nos enfrentamos a grandes problemas para mejorar el rendimiento de la CPU:
El Muro de la Potencia
Potencia = C * Vdd2 * Frecuencia
No podemos seguir escalando la cantidad de transistores y la frecuencia sin reducir el Vdd (voltaje de alimentación). El escalado del voltaje ya se ha estancado.
El Muro de la Complejidad
Depurar y verificar los grandes núcleos OOO (Out-Of-Order) es costoso (100 ingenieros durante 3-5 años). Las cachés son más fáciles de diseñar, pero solo pueden ayudar hasta cierto punto.
Como ejemplo del problema de la potencia (frecuencia), tenemos que:
E5640 Xeon (4 núcleos @ 2.66 GHz) tiene una sobre carga de potencia de 95 vatios.
L5630 Xeon (4 núcleos @ 2.13 GHz) tiene una sobre carga de potencia de 40 vatios.
Esto implica un aumento del 137% de potencia eléctrica para un aumento del 24% de la potencia de la CPU. A este ritmo, no se va a poder escalar.
Entra en escena el diseño de los multinúcleos. Un procesador multinúcleo ejecuta el multiprocesamiento en un único paquete físico. En lugar de aumentar la frecuencia para lograr un mayor rendimiento, se colocan más núcleos en un procesador para que los programas se puedan ejecutar en paralelo y así aumentar el rendimiento. En la actualidad, todos los procesadores INTEL son multinúcleo. Incluso los procesadores utilizados en los teléfonos móviles son todos procesadores con múltiples núcleos.
Limitaciones en las mejoras de rendimiento
¿Cuánta mejora puedo esperar de mi aplicación si logro que se ejecute en un procesador multinúcleo? La respuesta es que depende. Es posible que tu aplicación no tenga ninguna mejora de rendimiento si no se ha diseñado específicamente para aprovechar el potencial de múltiples núcleos. Incluso si lo hace, todavía depende de la propia naturaleza del programa y del algoritmo que utilice.
La ley de Amdahl establece que si P es la proporción de un programa que se puede hacer en paralelo, y (1-P) es la proporción de que no se puede poner en paralelo, entonces la aceleración máxima que se puede alcanzar utilizando N procesadores es:
1/[(1-P) + (P/N)]
La aceleración en relación al número de núcleos o procesadores con valores específicos de P se muestra en el siguiente gráfico.
Esto te puede dar una cierta idea de cuánto rendimiento puedes llegar a alcanzar a la hora de escribir tu programa pudiendo aprovechar la programación en paralelo en lugar de tener expectativas pocos realistas
W¿Por qué hacer programación paralela en Java?
Algunas de las ventajas de escribir programas java en paralelo son:
Se escribe una vez, se ejecuta en cualquier lugar,
Colectivo muy extenso de desarrolladores de software,
Programación orientada a objetos (OO),
Verificación del código en tiempo de ejecución y tiempo de compilación,
Recogida automática de basura (información no válida),
Soporte para múltiples hilos de ejecución (multi-threading) en el lenguaje y
Amplia colección de librerías
Java soporta múltiples hilos de ejecución desde sus inicios, entonces, ¿qué hay de nuevo? El multi-hilo Java utiliza el modelo de memoria compartida, lo que significa que no se puede escalar para usar varias máquinas.
Un modelo de memoria distribuida hace referencia a un sistema informático multiprocesador, como un ODROID-MC1, en el que cada procesador tiene su propia memoria privada. Las tareas informáticas solo pueden incidir en datos locales, y si se requieren datos remotos, las tareas informáticas debe comunicarse con uno o más procesadores remotos. En cambio, un multiprocesador de memoria compartida ofrece un único espacio de memoria que es usado por todos los procesadores. Los procesadores no tienen que estar pendientes de dónde residen los datos, excepto que pueden tener penalizaciones de rendimiento, y que deben evitar condiciones de competición (Procesador más rápido).
La Librería MPJ Express Paso de Mensajes
MPJ Express es una implementación de referencia de la API mpiJava 1.2, que es el equivalente de Java de la especificación MPI 1.1. Permite a los desarrolladores de aplicaciones escribir y ejecutar aplicaciones en paralelo para procesadores multinucleo y clústeres que utilicen una configuración multinúcleo (modelo de memoria compartida) o una configuración de clúster (modelo de memoria distribuida) respectivamente. Este último también es compatible con una técnica híbrida para ejecutar programas en paralelo en un clúster de máquinas multinúcleo, como el ODROID-MC1.
Todas las dependencias de software ya han sido instaladas en la imagen para tarjetas SD que proporciono Mi proyecto mpj-example en Github también ha sido clonado y compilado. Se ha copiado un archivo jar resultante y un archivo dependiente en el directorio ~/mpj_rundir donde puede probar en modo clúster o multicore. Toda la documentación sobre de MPJ Express la puedes encontrar en el directorio $MPJ_HOME/doc
Generación de Fractal usando MPJ Express
El proyecto mpj_example es un generador Mandelbrot. Las imágenes de conjunto Mandelbrot se obtienen muestreando números complejos y determinando para cada número si el resultado tiende hacia el infinito cuando se ejecuta la reiteración de una operación matemática particular. Las partes imaginarias y reales de cada número se convierten en coordenadas de imagen para un píxel de color según la rapidez con la que la secuencia diverge, o en nada en absoluto. Mi programa paralelo MPJ Express asigna cada núcleo disponible para que calcule un trozo vertical de la imagen del conjunto Mandelbrot a la vez. En consecuencia, cuantos más núcleos haya disponibles, más trabajo se puede realizar en paralelo. Las imágenes de Mandelbrot en coordenadas específicas se muestran en las siguientes imágenes.
Estas imágenes de Mandelbrot son generadas usando los siguientes comandos en una única máquina, el nodo maestro, utilizando una configuración multinúcleo. Desde el prompt del nodo maestro, introduce los siguientes comandos:
Puedes volver a ejecutar el comando anterior con valores -np entre 1 y 8 inclusive para ver la diferencia de rendimiento al variar la cantidad de núcleos utilizados para la generación de Mandelbrot. Recuerda que el XU4 tiene 4 núcleos pequeños A7 y 4 grandes núcleos A15.
Los parámetros que aparecen después de com.kardinia.mpj.ColourMandelbrot son:
parámetro 1: inicio de coordenada x
parámetro 2: inicio de coordenada y
parámetro 3: tamaño del paso
parámetro 4: mapa de color para asignar el número de iteraciones a un color en particular
parámetro 5: nombre de archivo para guardar el mandelbrot generado
Para ejecutar el generador de Mandelbrot en modo clúster, sigue las siguientes instrucciones:
Se necesita un archivo de texto llamado "máquines" que contenga los nombres de host de cada nodo de tu clúster ODROID-MC1 en líneas independientes. El archivo que se encuentra en ~/mpj_rundir contiene las siguientes líneas:
xu4-master
xu4-node1
xu4-node2
xu4-node3
Para iniciar el demonio MPJ en cada nodo, ejecuta el siguiente comando una vez desde el nodo maestro para iniciar un demonio MPJ en cada nodo:
$ mpjboot machines
Luego envía los siguientes comandos desde el nodo maestro:
Una vez más, puedes variar el número que aparece después de -np entre 4 y 32, ya que hay un total de 32 núcleos en tu clúster ODROID-MC1. La siguiente captura de pantalla muestra la ejecución de los comandos anteriores en el modo clúster.
Cuando hayas terminado de experimentar con el modo de clúster, introduce el siguiente comando en el sistema maestro para finalizar todos los demonios MPJ iniciados anteriormente:
$ cd ~/mpj_rundir
$ mpjhalt machines
Rendimiento en el ODROID-MC1
El rendimiento de la ejecución del generador de Mandelbrot en ODROID-MC1 tanto en modo multinúcleo como en modo clúster se resume en las siguientes gráficas. Para hacer una comparación, también lo ejecuté en una máquina virtual con 4 núcleos asignados a ésta en una vieja máquina INTEL I7 quad core. Aquí tienes una captura de pantalla del funcionamiento del generador en la máquina virtual.
El rendimiento de la ejecución en INTEL también se muestra en la misma gráfica. El eje vertical es el tiempo en segundos que se necesita para generar el Mandelbrot en la coordenada -0.5, 0.0. El eje horizontal es la cantidad de núcleos utilizados.
Representar gráficamente los datos de un modo diferente nos proporciona el coeficiente de incremento del rendimiento a medida que aumenta el número de núcleos.
Observé que cuando un nodo estaba usando los 4 núcleos grandes o los 8 núcleos, la corriente utilizada estaba entre 2.0 y 2.5 amperios. Mi barata fuente de alimentación no era capaz de suministrar suficiente corriente cuando los 4 XU4s en el ODROID-MC1 ejecutaban todos los núcleos al 100%. Esta es la razón por la que solo medí el rendimiento de la configuración del clúster hasta 12 núcleos. Otra cuestión interesante que observé fue que en el modo multinúcleo en un solo XU4, el mayor incremento de rendimiento se produjo cuando se utilizaron los 4 núcleos grandes. Añadir los pequeños núcleos apenas mejoró el rendimiento. Incluso en el modo clúster, el aumento de rendimiento se redujo a medida que la cantidad de núcleos aumentaba debido a la ley de Amdahl, ya que el sistema maestro tenía que dedicar la misma cantidad de tiempo combinando las imágenes parciales generadas en una imagen completa y disponía de un tiempo limitado para transferir las imágenes parciales a través de la red.
Conclusión
Espero que mis dos guías de inicio en ODROID Magazine te hayan dado algunas ideas sobre cómo utilizar tu ODROID-MC1 como un clúster swarm Docker y también como un clúster de computación para la programación en paralelo. Lo que puedes hacer con esto sólo está limitado por tu imaginación. Avísanos si está realmente estás interesado en información sobre cómo usar MPJ Express. Podemos crear tutoriales adicionales. Mientras tanto, disfruta y sigue explorando las posibilidades de tu ODROID-MC1.
Home Assistant: Scripts para Personalizar el Sistema
October 1, 2017By Adrian PopaTutoriales
En este artículo, profundizaremos en la personalización de Home Assistant, creando nuestros propios scripts para recopilar datos de sensores remotos y otros dispositivos de control. También veremos varias formas de comunicarnos con los sensores remotos.
Obtener datos de temperatura en remoto
Supongamos que tiene este problema: tienes varios sensores de temperatura, como el DS1820 en tu casa, conectados a varios ODROID y deseas enviar los datos a Home Assistant, que se ejecuta en un único dispositivo. Necesitas decidirte por un protocolo de transporte de datos y escribir un script para recopilar las lecturas de temperatura y pasarlas a Home Assistant.
Vamos a analizar algunas técnicas:
Sondeo por HTTP
Conexión a través de la API de Home Assistant
Conexión a través de MQTT
Sondeo por HTTP
Si estás acostumbrado a desarrollar web, probablemente habrás usado la denominada CGI (Interfaz Común de Comunicaciones), la forma más antigua de generar contenido dinámico utilizando un servidor web (http://bit.ly/2jNVkjT). Básicamente, carga un script en el servidor, independientemente del lenguaje, que es requerido por el servidor web y que a su vez sirve el resultado del script al cliente. Obviamente, primero necesitas instalar un servidor HTTP en tu host remoto y activar el soporte CGI. Usaremos Apache 2.4:
$ sudo apt-get install apache2
$ sudo a2enmod cgi
La configuración por defecto asigna /cgi-bin/URL a /usr/lib/cgi-bin en tu sistema de archivos. Cualquier script ejecutable que coloques en esta ubicación puede ser requerido por el servidor web. Vamos a suponer que puedes obtener los datos de temperatura del host remoto con estos comandos shell:
En el resultado anterior, la primera línea valida la lectura del valor (si coincide con el CRC) y la segunda línea devuelve el valor en mili-celsius. Vamos a crear dos scripts (no olvide marcarlos como ejecutables) para ilustrar el código en dos lenguajes diferentes: BASH y Python. Los archivos se almacenarán en /usr/lib/cgi-bin/temperature.sh y /usr/lib/cgi-bin/temperature.py.
#!/bin/bash
filename='/sys/devices/w1_bus_master1/28-05168661eaff/w1_slave'
valid=0
echo "Content-Type: text/plain"
echo
# read line by line, parse each line
while read -r line
do
if [[ $line =~ crc=.*YES ]]; then
# the CRC is valid. Continue processing
valid=1
continue
fi
if [[ "$valid" == "1" ]] && [[ $line =~ t=[0-9]+ ]]; then
# extract the temperature value
rawtemperature=`echo "$line" | cut -d "=" -f 2`
# convert to degrees celsius and keep 1 digit of accuracy
echo "scale=1;$rawtemperature/1000" | bc
fi
#read line by line from $filename
done < "$filename"
#!/usr/bin/python
import re
filename = '/sys/devices/w1_bus_master1/28-05168661eaff/w1_slave'
valid = False
print "Content-Type: text/plain"
print ""
# execute the command and parse each line of output
with open(filename) as f:
for line in f:
if re.search('crc=.*YES', line):
# the CRC is valid. Continue processing
valid = True
continue
if valid and re.search('t=[0-9]+', line):
# extract the temperature value
temperature = re.search('t=([0-9]+)', line)
# convert to degrees celsius and keep 1 digit of accuracy
output = "%.1f" % (float(temperature.group(1))/1000.0)
print output
Analicemos un poco los scripts. Ambos scripts empiezan con una línea shebang que le indica al llamador qué intérprete usar para ejecutar el script (línea 1). A continuación, definimos dos variables que apuntan al archivo que va a leer (línea 4) y una variable para recordar si la lectura es válida o no (línea 5). En las líneas 7 y 8, grabamos los encabezados HTTP. El script CGI tiene que devolver los encabezados HTTP en las primeras líneas, separados por una línea en blanco del resto del resultado. El servidor web necesita al menos el encabezado Content-Type para procesar la solicitud. Si omites esto, recibirás un error de HTTP 500. En la línea 11 empezamos a leer las líneas del archivo para analizarlas. Buscamos un CRC válido con una expresión regular en la línea 14 y si es correcto, fijamos valid = true. En la línea 19, si el CRC es true y la línea contiene una temperatura, extraemos la temperatura en bruto (línea 21) y la convertimos a Celsius, con un digito de precisión (línea 23), y la mostramos como resultado estándar. Para acceder a los datos, puede usar cualquier cliente HTTP, como wget, tal y como se muestra en la Figura 2.
Puede haber ligeras diferencias en el resultado que se devuelva debido a los diferentes métodos de redondeo utilizados, o por variaciones en el periodo de tiempo en el que se realiza la consulta, lo cual puede provocar que los datos del sensor fluctúen un poco.
Por razones de seguridad, puedes activar la autenticación básica HTTP en la configuración de tu servidor. Necesitarás SSL/HTTPS con certificados válidos para protegerte de cualquiera que quiera analizar tu tráfico, aunque esta cuestión está fuera del alcance de este artículo. Puedes leer más sobre este tema aquí y aquí.
Para añadir el sensor a Home Assistant podemos usar el sensor REST dentro de configuration.yaml :
sensor:
...
- platform: rest
resource: http://192.168.1.13/cgi-bin/temperature.sh
name: Temperature REST Bash
unit_of_measurement: C
- platform: rest
resource: http://192.168.1.13/cgi-bin/temperature.py
name: Temperature REST Python
unit_of_measurement: C
Es fácil de implementar si estás familiarizado con el desarrollo web.
En Home Assistant se reinician los nuevos datos que se sondean
Contras de este método:
El uso de un servidor web lo expone a posibles vulnerabilidades.
El servidor web puede usar muchos recursos en comparación con lo que realmente necesitas hacer.
Conexión a través de la API de HA
Una técnica diferente en la que no interviene un servidor web es mover los datos del sensor a Home Assistant desde el sistema remoto. Podemos usar una Plantilla Sensor para almacenar y presentar los datos. Para hacer esto, puedes hacer que el script de la Figura 3 sea requerido periódicamente por cron en el sistema remoto
#!/bin/bash
filename='/sys/devices/w1_bus_master1/28-05168661eaff/w1_slave'
homeassistantip='192.168.1.9'
haport=8123
api_password='odroid'
sensor_name='sensor.temperature_via_api'
valid=0
# read line by line, parse each line
while read -r line
do
if [[ $line =~ crc=.*YES ]]; then
# the CRC is valid. Continue processing
valid=1
continue
fi
if [[ "$valid" == "1" ]] && [[ $line =~ t=[0-9]+ ]]; then
# extract the temperature value
rawtemperature=`echo "$line" | cut -d "=" -f 2`
# convert to degrees celsius and keep 1 digit of accuracy
temperature=`echo "scale=1;$rawtemperature/1000" | bc`
# push the data to the Home Assistant entity via the API
curl -X POST -H "x-ha-access: $api_password" -H "Content-Type: application/json"
--data "{"state": "$temperature"}" http://$homeassistantip:$haport/api/states/$sensor_name
fi
#read line by line from $filename
done < "$filename"
Como puede ver, el código es similar al ejemplo anterior, excepto que en la línea 25 utiliza la API REST de Home Assistant para enviar la lectura de la temperatura. La API REST requiere que envíes la clave de la API de Home Assistant dentro de un encabezado HTTP, y los datos que quieras cambiar deben estar en una carga JSON en la solicitud POST. La URL que envías es tu instancia de Home Assistant /api/states/sensor.name. Para activar esto y enviar los datos cada 5 minutos, añade la siguiente entrada cron:
La configuración de Home Assistant debería parecerse a esto:
sensor:
…
- platform: template
sensors:
temperature_via_api:
value_template: '{{ states.sensor.temperature_via_api.state }}'
friendly_name: Temperature via API
unit_of_measurement: C
La plantilla sensor generalmente se utiliza para extraer los datos de otras entidades de Home Assistant y, en este caso, la utilizamos para extraer datos de sí mismo. Este truco te evita que se eliminen datos de estado tras una actualización externa. Antes de configurar la temperatura, el estado del sensor estará en blanco. Una vez que cron ejecute el script por primera vez, obtendrás datos de temperatura. Puedes descargar el código desde here
Pros de este método:
Permite controlar cuando se envían los datos
El uso de recursos es muy bajo.
Contras de este método:
Tu script necesita tener claramente tu contraseña secreta de Home Assistant
Cuando se reinicia Home Assistant, el sensor no tendrá ningún valor hasta la primera actualización
Conexión a través de MQTT
El protocolo MQTT es un protocolo de máquina a máquina diseñado para la eficiencia (y para entornos de baja potencia) y ya ha sido tratado en anteriores artículos de ODROID Magazine. El modo de funcionamiento parte de un servidor central llamado broker que transmite mensajes a clientes que se suscriben a un tema común. Piensa en un tema como si fuera algo así como un canal IRC donde los clientes se conectan y se envían mensajes específicos.
Home Assistant tiene un MQTT Broker, integrado, pero en mis pruebas lo encontré poco fiable, así que usé un broker dedicado llamado Mosquitto. Se puede instalar en el mismo sistema que Home Assistant o en un sistema diferente. Para instalarlo, sigue estos pasos:
La versión 3.11 de MQTT soporta autenticación, de modo que, debes configurar un nombre de usuario y una contraseña que serán compartidos por el bróker y los clientes y opcionalmente, Encriptación SSL. En mi configuración, utilicé la autenticación usuario-contraseña y añadí el usuario 'ODROID'
Puedes activar el soporte genérico para MQTT en Home Assistant añadiendo una plataforma MQTT en configuration.yaml (recuerda que el parámetro mqtt_password se define en secrets.yaml):
Para enviar datos de temperatura a Home Assistant, nuestro script necesitará la librería Python Paho-MQTT. Para analizar los datos de configuración necesitaremos también la librería python-yaml:
El script se ejecuta como un demonio, realizando lecturas periódicas de temperatura en segundo plano y enviando los cambios a través de MQTT. El código que lee la temperatura en sí (línea 40) es el mismo que aparecen en la Figura 1b y no se muestra en la Figura 4 para simplificar. El único cambio es que, en lugar de mostrar la temperatura, la devuelve como una cadena.
El código comienza importando algunos módulos auxiliares, definiendo las funciones para analizar la configuración YAML en un diccionario. La lectura de la temperatura y la ejecución empiezan en la línea 57. Se define y se activa un nuevo objeto cliente MQTT con los detalles necesarios para acceder al bróker MQTT. En la línea 61, hay un subproceso en segundo plano iniciado por la llamada loop_start () que asegura que el cliente permanezca conectado al bróker MQTT. Sin él, la conexión expiraría tras un tiempo y tendrías que volver a conectarte manualmente. Tienes más información sobre la API MQTT en Python disponible aquí. En la línea 65, aparece un bucle que lee los datos de temperatura, los compara con la última lectura de temperatura y, si hay un cambio, publica un mensaje MQTT al bróker con la nueva temperatura. Después, el código está inactivo durante un tiempo antes de la próxima lectura. Cuando se publican datos en el bróker (en la línea 71), debes especificar el tema MQTT, el valor que se envía y también si estos datos deben ser persistentes o no. Los datos persistentes son muy ventajosos, ya que puedes obtener la última lectura de temperatura desde MQTT cuando inicias Home Assistant y leer la temperatura desde el principio. Puedes conseguir el código completo aquí.
#!/usr/bin/python
import paho.mqtt.client as mqtt
import re
import time
import sys
import yaml
# Prerequisites:
# * pip: sudo apt-get install python-pip
# * paho-mqtt: pip install paho-mqtt
# * python-yaml: sudo apt-get install python-yaml
# Configuration file goes in /etc/temperature-mqtt-agent.yaml and should contain your mqtt broker details
# For startup copy temperature-mqtt-agent.service to /etc/systemd/system/
# Startup is done via systemd with
# sudo systemctl enable temperature-mqtt-agent
# sudo systemctl start temperature-mqtt-agent
filename = '/sys/devices/w1_bus_master1/28-05168661eaff/w1_slave'
valid = False
oldValue = 0
""" Parse and load the configuration file to get MQTT credentials """
conf = {}
def parseConfig():
global conf
with open("/etc/temperature-mqtt-agent.yaml", 'r') as stream:
try:
conf = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
print("Unable to parse configuration file /etc/temperature-mqtt-agent.yaml")
sys.exit(1)
""" Read temperature from sysfs and return it as a string """
def readTemperature():
with open(filename) as f:
for line in f:
if re.search('crc=.*YES', line):
# the CRC is valid. Continue processing
valid = True
continue
if valid and re.search('t=[0-9]+', line):
# extract the temperature value
temperature = re.search('t=([0-9]+)', line)
# convert to degrees celsius and keep 1 digit of accuracy
output = "%.1f" % (float(temperature.group(1)) / 1000.0)
# print("Temperature is "+str(output))
return output
""" Initialize the MQTT object and connect to the server """
parseConfig()
client = mqtt.Client()
if conf['mqttUser'] and conf['mqttPass']:
client.username_pw_set(username=conf['mqttUser'], password=conf['mqttPass'])
client.connect(conf['mqttServer'], conf['mqttPort'], 60)
client.loop_start()
""" Do an infinite loop reading temperatures and sending them via MQTT """
while (True):
newValue = readTemperature()
# publish the output value via MQTT if the value has changed
if oldValue != newValue:
print("Temperature changed from %f to %f" % (float(oldValue), float(newValue)))
sys.stdout.flush()
client.publish(conf['mqttTopic'], newValue, 0, conf['mqttPersistent'])
oldValue = newValue
# sleep for a while
# print("Sleeping...")
time.sleep(conf['sleep'])
El script también necesitará un archivo de configuración donde guardar las credenciales MQTT, ubicado en /etc/temperature-mqtt-agent.yaml:
En lo que respecta a Home Assistant, necesitamos definir un sendor MQTT con la siguiente configuración:
sensor:
...
- platform: mqtt
state_topic: 'ha/kids_room/temperature'
name: 'Temperature via MQTT'
unit_of_measurement: C
Pros de este método:
El uso de recursos es bajo
API estándar de bajo coste operativo diseñada para la comunicación máquina a máquina.
Contras de este método:
El sistema remoto necesita tener claramente la contraseña de MQTT
Cuando se reinicia Home Assistant, el sensor no tendrá ningún valor hasta la primera actualización a menos que se use la opción de persistencia de MQTT
Ahora que has visto varios ejemplos de cómo obtener datos en Home Assistant, deberá elegir cual es el mejor para tu configuración. De ahora en adelante yo usare MQTT porque, aunque parezca más difícil al principio, permite un mejor escalado con tareas más complejas.
Controlar una Smart TV con un componente personalizado
Aquí tenemos un nuevo problema que queremos resolver. Queremos obtener el número de canal actual, el nombre del programa y el estado de TV de un televisor Samsung con firmware SamyGO. El televisor revela esta información a través de una API REST que se puede instalar en el televisor desde aquí. La API devuelve información en formato JSON sobre el estado actual del televisor. Se puede inyectar códigos de control remoto y también se puede enviar de vuelta capturas de pantalla con lo que aparece actualmente en pantalla. La llamada y los resultados de la información actual se ven así:
En teoría, podríamos configurar los sensores REST para hacer la consulta anterior y utilizar la plantilla para conservar solo la información deseada, algo así como esto:
sensor:
...
- platform: rest
resource: http://tv-ip:1080/cgi-bin/samygo-web-api.cgi?challenge=oyd4uIz5WWAkWPo5MzfxBFraI05C3FDorSPE7xiMLCVAQ40a&action=CHANNELINFO
method: GET
value_template: '{{ value_json.channel_name }}'
name: TV Channel Name
Pero el problema es que, para obtener toda la información de diferentes sensores, debes hacer la misma consulta, descartar una gran cantidad de datos y mantener solo lo que necesitas para ese sensor en particular. Esto es ineficaz y en este caso, no funcionará porque, para obtener y presentar esta información, la API web que se ejecuta en el televisor inyecta varias librerías en los procesos que se ejecutan en el televisor para captar algunas llamadas de funciones y obtener los datos aquí. La fase de la inyección es muy crítica, y hacer varias inyecciones al mismo tiempo podría causar que se bloquee el proceso, lo cual bloquearía a su vez el TV. Esta es la razón por la cual la API web realiza las consultas de forma progresiva y no responde a una consulta antes de que se complete la anterior, aunque esto genere tiempos de espera.
Lo que se necesita en este caso es que el componente del sensor almacene todos los datos JSON y tenga una plantilla de sensores para extraer los datos necesarios y presentarlo. Para hacer esto, necesitamos un componente personalizado, que deriva del sensor REST y que actúa justamente como el sensor REST, pero cuando recibe datos JSON, los almacena como atributos de la entidad en lugar de descartarlos.
Los componentes personalizados se encuentran en el directorio ~ homeassistant/.homeassistant/custom_components y mantienen la estructura de los componentes habituales (lo que significa que nuestro sensor estará en el subdirectorio del sensor). Se cargarán en el Inicio de Home Assistant antes de que se analice la configuración. La Figura 5 muestra las diferencias entre el sensor REST y el nuevo sensor JsonRest personalizado.
Para entender los cambios realizados, deberías seguir la guía de componentes personalizada http://bit.ly/2fvc1PT. El código hace algunos cambios en el nombre de las clases del módulo para evitar enfrentamientos con el componente REST, y activa y gestiona una lista de atributos que se analizan desde la entrada JSON. Estos se mostrarán como atributos en la vista de estados. El nombre del nuevo componente es JsonRest, igual que el nombre del archivo.
Para instalar el componente JsonRest, puede seguir estos pasos:
TPara configurar el nuevo componente, una vez que se almacene en el directorio custom_components/sensor, podemos usar esta configuración para sondear el televisor cada 5 minutos:
sensor:
…
- platform: jsonrest
resource: http://tv-ip:1080/cgi-bin/samygo-web-api.cgi?challenge=oyd4uIz5WWAkWPo5MzfxBFraI05C3FDorSPE7xiMLCVAQ40a&action=CHANNELINFO
method: GET
name: TV Living ChannelInfo
scan_interval: '00:05'
- platform: template
sensors:
tv_living_powerstate:
value_template: '{{ states.sensor.tv_living_channelinfo.attributes.power_state }}'
friendly_name: TV Living Power
tv_living_channel_number:
value_template: '{{ states.sensor.tv_living_channelinfo.attributes.channel_number }}'
friendly_name: TV Living Channel Number
tv_living_channel_name:
value_template: '{{ states.sensor.tv_living_channelinfo.attributes.channel_name }}'
friendly_name: TV Living Channel Name
tv_living_program_name:
value_template: '{{ states.sensor.tv_living_channelinfo.attributes.program_name }}'
friendly_name: TV Living Program Name
Ahora solo el componente JsonRest será el que sondee el televisor para obtener la información, y la plantilla sensores extraerán los datos necesarios de los atributos, reduciendo la carga en el televisor.
Puesto que la API web del TV permite tomar capturas de pantalla, vamos añadir esta función también a Home Assistant (para no perder de vista lo que los niños ven el TV). La API devuelve una imagen JPEG cada vez que preguntes con el parámetro URL action=SNAPSHOT. Puedes usar un a Componente de Cámara IP genérica:
camera 2:
platform: generic
name: TV Living Image
still_image_url: http://tv-ip:1080/cgi-bin/samygo-web-api.cgi?challenge=oyd4uIz5WWAkWPo5MzfxBFraI05C3FDorSPE7xiMLCVAQ40a&action=SNAPSHOT
La API web TV también te permite enviar acciones de control remoto, que se pueden configurar a través del Componente de commandos Restful:
Tras agrupar un poco, el resultado final lo puedes ver aquí. Tienes un enlace a la configuración disponible aquí, y un ejemplo para el archivo secrets aquí. Puedes encontrar el código y la configuración en la pçagina de GitHub.
ODROID-MC1 Docker Swarm: Guía de Inicio
October 1, 2017By Andy YuenDocker, ODROID-MC1, Tutoriales
El personal de Hardkernel ha montado una gran instalación informática en forma de clúster para probar la estabilidad de Kernel 4.9. El cluster consistía en 200 ODROID-XU4 (es decir, un total neto de 1600 núcleos de CPU y 400 GB de RAM), tal y como se muestra en la Figura 1.
La experiencia resultante con este ejercicio les llevó a la idea de desarrollar un potente clúster personal a un precio razonable, de donde nació el ODROID-MC1. ODROID-MC1 significa My Cluster One. Consta de 4 unidades apilables, cada una con un ordenador de plaza reducida (SBC) específicamente diseñado y basado en el procesador Octa-core Samsung Exynos 5422. Es compatible con la serie SBC ODROID-XU4 y está montado en una carcasa de aluminio. Estas carcasas (que también incorporan un disipador de calor integrado) están apiladas con un ventilador fijado en la parte trasera que garantizase sufienciente refrigeración.
La placa de circuitos ODROID-MC1 es una versión recortada de la utilizada en el almacenamiento conectado en red (NAS) ODROID-HC1 (Home Cloud One), con el adaptador SATA suprimido. La placa de circuito ODROID-HC1, a su vez, es un ODROID-XU4 rediseñado con el conector HDMI, el conector eMMC, el hub USB 3.0, el botón de encendido y el interruptor deslizante eliminados.
Las principales características del ODROID-MC1 son:
CPUs Samsung Exynos 5422 Cortex-A15 2Ghz y Cortex-A7 Octa
2Gbyte LPDDR3 RAM PoP apilada
Puerto Ethernet Gigabit
Puerto USB 2.0 Host
Ranura para tarjeta microSD UHS-1 para el soporte de arranque
Imágenes SO de servidor Linux basadas en el moderno Kernel 4.9 LTS
El ODROID-MC1 viene montado y listo para usarse como un clúster personal para el aprendizaje, así como para hacer trabajos útiles. En la Parte 1 de esta serie del ODROID-MC1, describiré cómo usarlo como un clúster Docker Swarm. En la Parte 2, describiré cómo desarrollar programas en paralelo para que se ejecuten en el clúster ODROID-MC1
Para configurar el clúster MC1, necesitas lo siguiente, además del propio hardware MC1:
1 switch Gigabit con al menos 5 puertos
5 cables Ethernet
4 tarjetas SD (de al menos 8 GB de capacidad)
4 adaptadores de corriente para los ordenadores MC1
Configuración del sistema operativo en cada ordenador del clúster
La parte más tediosa de la configuración del clúster ODROID-MC1 es instalar el Sistema Operativo (SO) y los paquetes de software necesarios para ejecutar y administrar el Swarm Docker en cada nodo informático Para facilitar el proceso, puede descargar una imagen para tarjetaSD con casi todo listo en https://oph.mdrjr.net/MrDreamBot/. Digo "casi", porque todavía tienes que realizar unas cuantas cosas para que todo funcione correctamente". La tarjeta SD tiene los logins 'root' y 'odroid' ya configurados. La contraseña para ambos es "odroid”:
El swarm que estamos montando consta de 1 nodo maestro y 3 nodos de trabajo. A modo de ejemplo, supongamos que utilizan los siguientes nombres de host y direcciones IP. Por supuesto, puedes cambiarlos para que se adaptaen a tu entorno. Todos los nodos en el swam deben tener una dirección IP estática como la siguiente:
Para empezar el proceso de configuración, necesitas conectar tu PC y un nodo ODROID-MC1 a un switch Gigabit y que éste tenga conexión a tu router de casa (para acceder a Internet). La imagen está configurada para usar la dirección IP asignada dinámicamente usando DHCP de tu router. Debes concertarte usando SSH para configurar cada nodo y usar una dirección IP estática en su lugar. Hay otros parámetros de configuración que también necesitas cambiar.
Se supone que tiene algunos conocimientos de línea de comandos de Linux para realizar los siguientes pasos:
Escribe la imagen del sistema operativo en tu tarjeta SD: copia la imagen de la tarjeta SD en las 4 tarjetas SD clase 10 de 8GB. Si usas tarjetas SD de mayor capacidad, debe cambiar el tamaño del sistema de archivos en cada tarjeta SD para usar todo el espacio de la tarjeta SD. La forma más fácil de hacerlo es montar la tarjeta SD en una máquina Linux y usar gparted (www.gparted.com) para cambiar el tamaño. Este es el método que utilice para mis tarjetas SD. Inserta una tarjeta SD en uno de los ordenadores MC1.
Inicia una sesión SSH desde tu PC al nodo ODROID-MC1 como root. Su dirección IP la puedes encontrar en tu router. Omite el siguiente paso si estás configurando el nodo maestro.
Cambia el nombre de host editando el archivo /etc/hostname, modifica xu4-master por xu4-nodeX donde X es 1, 2 o 3 dependiendo del nodo de trabajo que estés configurando.
Configura una dirección IP estática editando /etc/network/interfaces, eliminando el "#" delante de la sección resaltada y reemplazando la dirección IP 192.168.1.80 con la dirección IP (en la subred de tu red doméstica) que deseas que se le asigne al nodo que estás configurando.
Actualiza el archivo /etc/hosts de modo que cada entrada de nodo ODROID-MC1 tenga el nombre y la dirección IP correctos.
Haz algunas pruebas con los cambios: reinicia el nodo para ver si puedes conectarte por SSH usando la nueva dirección IP que le asignaste. Si es así, has configurado con éxito ese nodo. De lo contrario, verifica los cambios que he descrito anteriormente y asegúrate de que no haya errores tipográficos.
Configure el siguiente nodo de trabajo: repite estos los pasos hasta que termines de configurar todos los nodos.
Para los usuarios experimentados de Linux, hay una forma alternativa de hacer todo anterior, montar cada tarjeta SD en tu sistema Linux y editar los correspondientes archivos directamente en la tarjeta SD.
Tras configurar tu clúster, conéctate por ssh al xu4-master como usuario "odroid", contraseña "odroid". Desde el maestro, entrar por SSH a todos los nodos de trabajo sin usar la contraseña, ya que los nodos del clúster se han configurado con una autenticación basada en claves. Haz lo mismo con "root" utilizando el comando "sudo -s" o utilizando SSH para establecer una conexión como usuario root en el nodo xu4-master, luego usa SSH para conectarse a todos los nodos de trabajo.
Configuración del modo Swarm de Docker
Un nodo es un host Docker que participa en un Swarm. Un nodo gestor (maestro) es aquel donde envías una definición de servicio y éste programa el servicio para que se ejecute como tareas en los nodos de trabajo. Los nodos de trabajo reciben y ejecutan tareas programadas por un nodo gestor. Un nodo gestor, por defecto, también es un nodo de trabajo a menos que esté expresamente configurado para no ejecutar tareas. Es posible configurar múltiples nodos maestros y de trabajo en un swarm para proporcionar Alta Disponibilidad (HA).
Para iniciar el modo swarm, introduce el siguiente comando en el nodo gestor:
$ docker swarm init --advertise-addr 192.168.1.80
que devolverá:
swarm initialized: current node
(8jw6y313hmt3vfa1fme1dinro) is now a manager
Ejecuta el siguiente comando para añadir un nodo trabajador a este swarm en cada nodo:
Para que los otros nodos se unan al clúster, envía el anterior comando "docker swarm join" en cada nodo. Esto se puede hacer usando parallel-ssh usando el comando una vez desde el gestor y ejecutandolo en cada nodo. La Figura 4 muestra una captura de pantalla del funcionamiento del comando "docker ps" usando parallel-ssh.
Ahora tenemos un Swarm Docker en funcionamiento.
Probando el Swarm
Para ayudar a visualizar lo que está sucediendo en el swarm, podemos usar la imagen Docker Swarm Visualizer image (visualizer-arm). Para implementarla como un servicio, envía el siguiente comando desde el prompt del gestor:
$ docker service create --name=dsv --publish=8080:8080/tcp --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock alexellis2/visualizer-arm
Ten en cuenta que ODROID-XU4 está basado en ARMv7, es decir, es un sistema de 32 bits, a diferencia del ODROID-C2 que está basado en ARMv8 de 64 bits. Por consiguiente, las imágenes Docker utilizadas en los siguientes comandos son diferentes de las utilizadas en mis ejemplos de Docker con el ODROID-C2.
Apunta tu navegador al gestor visitando http://192.168.1.80:8080, o puedes apuntar tu navegador a cualquiera de los nodos del swarm. Observa los cambios reportados por el visualizador al utilizar el servicio httpd usando mi imagen mdreambot httpd busybox de 32 bits en http://dockr.ly/2wWPCNP. Mi imagen se inicia con el comando:
En la Figura 5 aparece un Docker Swarm Visualizer que muestra los nodos en los que se ejecutan las réplicas del servicio, poniendo de manifiesto el modelo de servicio declarativo utilizado por el modo swarm.
Utiliza el siguiente comando curl para probar la función de balanceo de carga de swarm docker:
$ curl http://192.168.1.80/cgi-bin/lbtest
La Figura 6 es una captura de pantalla del resultado de los comandos curl, que confirma que cada solicitud ha sido redirigida a un nodo diferente.
Para hacer una prueba de auto-regeneración, detuve el contenedor httpd que se ejecutaba en el xu4-master, otro contenedor httpd fue ejecutado en otro nodo para reemplazar el que acababa de detener, como se puede ver en la siguiente captura de pantalla. Esto es debido a que cuando iniciamos el servicio, especificamos "replica = 3", de modo que swarm Docker mantendrá el número deseado de réplicas. Esto se conoce como reconciliación de estado deseado.
Conclusión
TEl modo swarm de Docker es ahora completamente funcional en tu clúster ODROID-MC1. Tomate la libertad de experimentar con él. Espero que esta guía logre su objetivo consiguiendo que ejecutes swarm de docker en el ODROID-MC1. Para obtener más información sobre el modo swarm de Docker, consulta mis otros artículos de ODROID Magazine sobre el tema.
Conociendo un ODROIDian: Brian Kim, Ingeniero de Hardkernel
October 1, 2017By Brian KimConociendo un ODROIDian
Por favor, háblanos un poco sobre ti.
Tengo 36 años y vivo en Seúl, Corea del Sur. Soy el ingeniero de investigaciones de Hardkernel Co., Ltd. Mi trabajo principal para Hardkernel es el de mantener el software de código abierto de u-boot, Kernel de Linux, WiringPi2-Python y Buildroot. Modifico el software de código abierto y realizo algunas tareas rutinas de soporte para ODROID. Hardkernel brinda soporte técnico en los foros de ODROID en http://forum.odroid.com, y mi jefe me asigna los problemas de software reportados en los foros. Aunque a veces es estresante especialmente cuando se trata de un problema complejo o no es un problema de software, es divertido tener discusiones técnicas con los usuarios de ODROID.
No solo tengo un grado en Información y Comunicación de la Universidad de Youngsan (Corea del Sur), sino también una licenciatura en Ingeniería de Comunicaciones Móviles de la Universidad Sungkyunkwan (Corea del Sur). No era un buen estudiante cuando estaba en el instituto, pero sí que estudié mucho en la universidad y logré obtener una nota media de 4.5/4.5 en un semestre. Aprendí conocimientos generales de Ciencias de la Computación en la universidad y la escuela de posgrado. Estudié CMT (Concurrence Multipath Transfer) usando SCTP en la licenciatura y escribí un artículo al respecto.
Comencé mi carrera profesional como desarrollador de software. Mi primer proyecto serio fue el software del sistema de información médica que usaba Delphi en 2005. Nuestro equipo diseñó una base de datos médica asociada a una base de datos de información personal, escribimos el código fuente Object Pascal para el software. Disfruté desarrollando software usando varios lenguajes de programación y librerías como Visual Basic, MFC, Win32, Qt, PHP, ASP, JSP, C, C ++ y Java.
Incluso después de graduarme en la universidad, seguía teniendo ganas de aprender. De modo que, me mudé a Seúl para recibir un curso profesional de sistemas embebidos en una academia privada. Aprendí el sistema embebido, la arquitectura ARM, el kernel de Linux, la programación de redes y los RTOS en este curso, desde 2005 hasta 2006. Aprendí mucho sobre la filosofía Unix durante este tiempo. Tras finalizar el curso, desarrollé un software POS (Point Of Sale) y decodificador IP como trabajo a tiempo parcial en 2007. Me uní a WIZnet en 2008, siendo éste mi primer trabajo a tiempo completo.
WIZnet es una fabulosa compañía que diseña chips de red embebidos con pila TCP/IP cableada. Mi primer trabajo en WIZnet fue desarrollar un controlador de red Linux para el conjunto de chips WIZnet. Trabajé mucho y terminé el proyecto en tres meses. Después de esto, desarrollé la placa embebida ARM que incluía el chip WIZnet llamada W5300E01-ARM, que fue mi primer producto comercial. El controlador de red modificado que desarrollé está incluido en el código fuente del kernel Linux estandar. Además de eso, desarrollé un módulo de puerta de enlace de serie a Ethernet y brindaba soporte técnico.
Participaba en un grupo de trabajo de análisis de software de código abierto todos los sábados en 2007 (Kernel Linux) y 2011 (Xen Hypervisor). Nuestro grupo de trabajo analizó el código fuente en detalle hasta conocerlo completamente, lo cual nos apasionaba. Tras finalizar el estudio en aproximadamente un año, escribimos artículos y libros sobre lo que aprendimos. El código fuente del software de código abierto es mi libro de texto, y los desarrolladores de software de código abierto son mis maestros incluso hoy en día.
¿Cómo empezaste con los ordenadores?
Cuando tenía 8 años, empecé con los ordenadores con un IBM XT. Aunque era el ordenador de mi primo, solía usarlo para jugar a juegos de DOS. Recuerdo los viejos dichos de la gente por aquel entonces: "con 640 KB es suficiente". Cuando tenía 10 años, mi padre me regaló por mi cumpleaños un PC 386, y empecé con las comunicaciones de PC con un simple módem de 2400 bps.
¿A quién admiras en el mundo de la tecnología?
Linus Torvalds, desde que creó el kernel Linux y Git. Linux y Git han cambiado el mundo del software.
¿Cómo decidiste trabajar en Hardkernel?
El factor más importante fue lo que iba a hacer para Hardkernel. Las responsabilidades del puesto de trabajo me parecieron interesantes.
¿Cómo usas tus ODROID en casa?
Disfruto haciendo cosas interesantes con los ODROIDs. Algunos de mis proyectos se pueden encontrar en ODROID Magazine, como Ambilight, cámara de vista posterior y ODROID Arcade Box. En la oficina de Corea del Sur, utilizamos los ODROIDs como servidores privados y comederos de peces automáticos. El sistema de minería de criptomonedas con 200 dispositivos ODROID-XU4 también fue un proyecto interesante. He creado un interruptor de luz por voz con el ODROID-C2 y Google Cloud Pech API para casa.
¿Cuál es tu ODROID favorito y por qué?
El ODROID-C2 es mi favorito, porque soy uno de los principales desarrolladores de ODROID-C2 y porque tiene una arquitectura ARM de 64 bits. Aunque trabajo con todos los ODROIDS que están actualmente en venta (ODROID-C1 +, ODROID-C2 y ODROID-XU4), me uní a la empresa después de que se desarrollasen el XU4 y C1+.
¿Qué innovaciones se verán en futuros productos de Hardkernel?
Pienso que mantener nuestra posición actual en el mercado de los SBC como dispositivos de alto rendimiento e intentar abrirnos camino en el mercado de servidores de gama baja es bueno para la supervivencia.
¿Qué aficiones e intereses tienes aparte de los ordenadores?
Disfruto viajando, con los juegos de ordenador, el snowboard, el wakeboard, buceando y haciendo triatlones (natación, ciclismo y maratón). Realicé un curso olímpico de Triatlón el año pasado. Este año he ido a Busan desde Seúl en bicicleta durante las vacaciones de verano. La distancia es de aproximadamente 325 millas (523 KM). Mi próximo reto es una maratón completa el próximo mes.
¿Qué consejo le daría a alguien que quiere aprender más sobre programación?
Leer un buen código fuente del software de código abierto. Escribir tantos códigos de alta calidad como puedas.