Nothing Special   »   [go: up one dir, main page]

Android

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 57

Home Assistant: Diseñando un Elegante Cuadro de Mandos

 January 1, 2018

En este artículo vamos a analizar un compañero de Home Assistant – AppDaemon

Módulo eMMC Naranja: Llega el chipset Samsung 5.1


 January 1, 2018

El módulo eMMC Naranja de Hardkernel que usa el chipset Samsung eMMC 5.1, ha
estado enviándose desde Octubre de 2017

Recompilando imágenes Docker x86amd64 para Swarm ARM


 January 1, 2018

Recompilar imágenes Docker x86/amd64 para un Swarm ARM continua los recientes
artículos sobre cómo compilar swarm Docker en ARM, y como no había disponible
ninguna imagen ARM o no había disponible ninguna imagen ARM con una versión
reciente, sin lugar a duda era hora de cambiar esto.

Juegos Android: Monument Valley, Hopscotch, Aqueducts


 January 1, 2018

No siempre nos desviemos de los extraños juegos indie para Android, pero durante las
vacaciones play store nos ha dotado con grandes títulos, así que sin más preámbulos
permite presentarte:

Android TV ODROID-C2 con Amazon Prime Video y Net ix


 January 1, 2018

He estado usando un ODROID-C2 con LibreELEC durante bastante tiempo, pero me


sentía muy decepcionado por la falta de compatibilidad con Amazon Prime Video y
Net ix. También he estado usando un teclado/ratón inalámbrico para controlarlo, lo
cual me permitía censurar a su compañero, ya que deseaba tener único un mando  

Ambilight en ODROID-C2 Usando LibreElec: Adaptando Ambilight al


ODROID-C2
 January 1, 2018

Conseguí montar un sistema Ambilight funcional usando un ODROID-C2 y LibreElec.

Divirtiéndonos con GPIO en Android


 January 1, 2018

El ODROID-C1/C1+, ODROID-C2 y ODROID-XU4 tienen pines GPIO (Entrada/Salida de


Propósito General) que permiten controlar dispositivos externos a través de software.
Para acceder correctamente al puerto GPIO, debes instalar la imagen Android
Marshmallow versión 2.8 o superior en el ODROID-C2, la imagen Android KitKat versión 3.2 o superior en el  
UART Daisy Chain: Depuración Avanzada con el ODROID-C2
 January 1, 2018

Este artículo explica como usar múltiples puertos UART en ODROID-C2 ejecutando el
Sistema Operativo Android

Juegos Linux: Mech Warrior 2


 January 1, 2018

Mech Warrior es un juego de simulación de combate sobre los llamados “Mechs”, que
son robots gigantes pilotados por un humano.

Conociendo un ODROIDAN: Dongjin Kim


 January 1, 2018

Por favor, háblanos un poco sobre ti. Soy un ingeniero de software embebido, he
participado en muchos y diferentes proyectos comerciales desde 1994. Actualmente,
estoy desarrollando el software para un dispositivo móvil que se ejecuta sobre un
procesador ARM y trabaja principalmente con un driver de dispositivo o capa HAL/framework.  
Home Assistant: Diseñando un Elegante Cuadro de Mandos
 January 1, 2018  By Adrian Popa  Linux, Mecaniqueo

En este artículo vamos a analizar un compañero de $ sudo pip3 install appdaemon


Home Assistant – AppDaemon
(https://goo.gl/UD3hDA). Se trata de un entorno de En el futuro, podrás actualizar fácilmente appdaemon
trabajo que te permite desarrollar tus propias con:
aplicaciones Python y hacer que éstas reaccionen a
$ sudo pip3 install ­­upgrade appdaemon
los eventos e interactúen directamente con Home
Assistant. Te proporciona la exibilidad de poder También deberías crear este servicio systemd para
escribir complejas automatizaciones directamente en gestionar el inicio automático:
Python, y si cuentas con ciertos conocimientos de
$ cat /etc/systemd/system/appdaemon.service 
programación, te puedo decir que bastante más fácil
[Unit] 
que escribir largas automatizaciones en YAML. Tiene Description=AppDaemon 
la ventaja añadida de contar con un entorno de After=homeassistant.service 
trabajo que te permite desarrollar cuadros de [Service] 
mandos muy atractivos. Type=simple 
User=homeassistant 
AppDaemon se puede instalar en el mismo sistema ExecStart=/usr/local/bin/appdaemon ­c 
que Home Assistant, también conocido como HA, o /home/homeassistant/.homeassistant 
en un sistema diferente, ya que se comunica con HA a [Install] 
través de un socket de red. La instalación es sencilla, WantedBy=multi­user.target 

puede encontrar instrucciones para ello  

en https://goo.gl/Hci4zm.
$ sudo systemctl enable appdaemon 
$ cat 
$ sudo systemctl start appdaemon
/home/homeassistant/.homeassistant/apps.yaml 
 hello_world: 
Necesitarás crear una con guración por defecto
 module: hello 
preferiblemente dentro del directorio de
 class: HelloWorld
con guración de HA y añadir aplicación para probar
tu con guración. El archivo de con guración Una vez que reinicies AppDaemon, las aplicaciones se
appdaemon.yaml también almacena las credenciales cargarán automáticamente. En este caso, deberías ver
para acceder a tu Home Assistant, o puede leerlas el mensaje “Hello from AppDaemon” en tus registros
desde el archivo “secrets.yaml”. log, lo cual indica que la con guración inicial se ha
cargado, puedes veri carlo con:
$ sudo su ­ homeassistant 
$ cat  $ sudo journalctl ­f ­u appdaemon
/home/homeassistant/.homeassistant/appdaemon.y
aml  La mejor manera de empezar es leyendo la
 AppDaemon:  documentación. Hay un completo tutorial que te guía
 logfile: STDOUT  por todos los pasos: https://goo.gl/ha5iC8. Además,
 errorfile: STDERR 
existe una referencia API para la búsqueda rápida:
 logsize: 100000 
https://goo.gl/QeJSYu. El entorno de trabajo está
 log_generations: 3 
basado en eventos, de modo que necesitas con gurar
 threads: 10 
 HASS:  “oyentes” para los varios eventos que tienen lugar en
 ha_url: http://127.0.0.1:8123  Home Assistant, de esta manera tu código será
 ha_key: !secret api_password  llamado automáticamente. Además, puedes acceder
$ mkdir  a todos los estados y atributos de las entidades de
/home/homeassistant/.homeassistant/apps 
Home Assistant. Cuando estés familiarizado con el
$ cat 
entorno de trabajo, puedes echar un vistazo a las
/home/homeassistant/.homeassistant/apps/hello.
aplicaciones de ejemplo para tener una idea de cómo
py 
import appdaemon.appapi as appapi  se hacen las cosas.
  ¿Te acuerdas del proyecto del calentador con Home

Assistant, publicado en el último número de ODROID
# Hello World App 
Magazine? Pues bien, quizás porque me estoy

# Args:  haciendo viejo, siento la necesidad de encender la
#  calefacción durante ciertas horas del día y de la
  noche, así que quería crear una aplicación que lo
class HelloWorld(appapi.AppDaemon):  hiciera por mí. No obstante, hay un problema: quiero
  disponer de algún tipo de panel de control que sea
def initialize(self): 
fácil de usar dentro de Home Assistant y que me
 self.log("Hello from AppDaemon") 
permita seleccionar el momento en el que quisiera
 self.log("You are now ready to run Apps!")
que se encendiera la calefacción, como si fuera algún
El código hello.py anterior ha sido sacado de las tipo de sustituto a la típica tarea cron. Considere
instrucciones de instalación, aunque también puede apropiados los intervalos de 15 minutos por
encontrar algunas aplicaciones útiles en el interruptor, de modo que si quería encender el
repositorio https://goo.gl/6nkzhm. Para activar y calentador de 4:00 a 4:30, tendría que pulsar dos
con gurar una aplicación, deberás añadir lo siguiente interruptores en la interfaz de usuario (4:00 y 4:15).
dentro de ‘apps.yaml’: Haciendo un cálculo rápido podemos concluir que un
día tiene 96 intervalos de 15 minutos, y puesto que
soy algo ojo y no quiero escribir todo este código de … 

con guración, hice un script para que generase la  heater: 


 name: Gas heater 
con guración (https://goo.gl/DYY5Mj). Si ejecutas el
 view: yes 
script, se crearán 96 interruptores input_boolean
 icon: mdi:fire 
(https://goo.gl/BtJZ41)  que serán distribuidos en  entities: 
grupos de 4 horas. Puedes copiarlo/pegarlo en tu  ­ switch.heater 
archivo de con guración bajo las secciones  ­ climate.heater_thermostat 
correspondientes y reiniciar Home Assistant. No  ­ group.heater_timer_group

olvides añadir el ‘heater_timer_group’ en la vista


Cuando termines deberías ver una pantalla similar a
‘heater’:
la que se muestra en la Figura 1.
$ wget https://raw.githubusercontent.com/mad­
ady/home­assistant­
customizations/master/configuration_helper/mak
e_heater_switches.py 
$ python make_heater_switches.py

Con guration.yaml debería parecerse a esto:

input_boolean: 
 … 
 heater_timer_00_00: 
Figura 1 – Montones de interruptores de tiempo
 name: Heater timer 00:00 
 initial: off  Para que estos interruptores funcionen, hay que
 icon: mdi:fire 
hacer una aplicación que escuche sus cambios de
 heater_timer_00_15: 
estado y de este modo se llevarán a cabo las acciones
 name: Heater timer 00:15 
deseadas. Escribí un código para AppDaemon que
 initial: off 
 icon: mdi:fire  hace lo siguiente:
 … 
  Al arrancar, empieza a escuchar eventos de entidades

group:  input_boolean llamadas heater_timer_ *, que se

 heater_timer_group_0:  repiten a lo largo de todas las entidades y registra un

 name: Timer group 00:00 ­ 04:00  “oyente” para cada una.

 control: hidden  Cuando detecta que se ha activado un booleano,


 entities:  comprueba si el nombre del booleano es el mismo que
 ­ input_boolean.heater_timer_00_00  el momento actual y si es así, controla la calefacción
 ­ input_boolean.heater_timer_00_15  Cada minuto se comprueba el correspondiente
 ­ input_boolean.heater_timer_00_30  input_boolean para el intervalo del momento actual. Si
 …  está activado, entonces la calefacción se enciende.
 heater_timer_group: 
 name: Heater timer  El código fuente completo está disponible
 control: hidden 
en https://goo.gl/WGvoAL, y se puede instalar con los
 entities: 
siguientes comandos:
 ­ group.heater_timer_group_0 
 ­ group.heater_timer_group_1  $ cd ~homeassistant/.homeassistant/apps/ 
 ­ group.heater_timer_group_2  $ wget  
 ­ group.heater_timer_group_3   https://raw.githubusercontent.com/mad­
 ­ group.heater_timer_group_4  ady/home­assistant­
 ­ group.heater_timer_group_5  customizations/master/appdaemon_apps/manual_he
  ater.py
También necesitarás editar el archivo apps.yaml y haciendo persistentes los estados de nuestros
añadir lo siguiente: interruptores.

manual_heater:  Aunque utilizamos aplicaciones automatizadas, la


 module: manual_heater  razón principal por la que las personas usan
 class: ManualHeater  AppDaemon es porque proporciona una interfaz a
 climate: "climate.heater_thermostat"  modo de cuadro de mandos que permite presentar y
 heater: "switch.heater" 
controlar las entidades de Home Assistant en una
 interval_length: 15
pantalla táctil. Por lo general, las personas usan un
Ahora, cuando reinicies AppDaemon, la nueva televisor o una tablet para mostrar el cuadro de
aplicación se cargará y reaccionará al estado de tus mandos, pero yo he utilizado la LCD 3.5” de
input_booleans. Puede seguir su avance leyendo el HardKernel 
registro log de AppDaemon. (http://www.hardkernel.com/main/products/prdt_in
fo.php?g_code=G147435282441), con un ODROID-C2
Todo parece funcionar bien, sin embargo, existe un
como unidad de procesamiento.
problema. Si reinicias Home Assistant, o si hay un
corte de luz en medio de la noche, los 96
interruptores pasarán a la posición de apagado por
defecto. Tiene que haber alguna manera de guardar
su estado y hacer que éste se cargue al reiniciar.
Afortunadamente ya existe una aplicación para eso:
switch_reset.py, disponible en https://goo.gl/LVYdD2.
Así es como puedes con gurarlo:

$ cd ~homeassistant/.homeassistant/apps/ 
$ wget ­O switch_reset.py  
 https://raw.githubusercontent.com/home­
assistant/appdaemon/dev/conf/example_apps/swit
ch_reset.py 
$ wget ­O globals.py   Figura 2 – Ejemplo de cuadro de mandos

 https://raw.githubusercontent.com/home­ Para activar el cuadro de mandos


assistant/appdaemon/dev/conf/example_apps/glob
(https://goo.gl/Z8iMW8), deberás añadir la siguiente
als.py
sección a appdaemon.yaml:
Añade la siguiente con guración a apps.yaml:
HADashboard: 

switch_reset:   dash_url: http://0.0.0.0:5050 

 module: switch_reset   dash_password: !secret api_password 

 class: SwitchReset   dash_dir: 

 log: ""  /home/homeassistant/.homeassistant/dashboards

 file: 
La directiva dash_password es opcional. Para facilitar
"/home/homeassistant/.homeassistant/switch_sta
tes"  el uso, es mejor no utilizar una contraseña, para que
 delay: 10 los cuadros de mandos puedan cargarse al arrancar
sin la intervención del usuario. Necesitarás crear un
Tras reiniciar AppDaemon, los cambios en las cuadro de mando de muestra en
entidades input_boolean, input_number, input_select ~homeassistant/.homeassistant/dashboards. Primero
y device_tracker se almacenarán dentro de crea el directorio y luego ponle el nombre hello.dash:
/home/homeassistant/.homeassistant/switch_states,
$ mkdir  Los cuadros de mandos generan dinámicamente
~homeassistant/.homeassistant/dashboards  páginas web que pueden representar y controlar los
$ mkdir ­p   estados de las entidades de Home Assistant. La
 /home/homeassistant/.homeassistant/compiled/j mayoría de las entidades cuentas con los
avascript/css 
correspondientes fragmentos de con guración del
$ mkdir ­p 
cuadro de mandos, que permiten controlar las
/home/homeassistant/.homeassistant/compiled/cs
apariencias. La documentación de referencia la tienes

$ mkdir ­p   disponible en https://goo.gl/G6iYib.
 /home/homeassistant/.homeassistant/compiled/h Para empezar, debes especi car las dimensiones de
tml/default 
la pantalla y pensar en cómo quieres dividir la
$ cd ~homeassistant/.homeassistant/dashboards 
pantalla en widgets. Normalmente, la pantalla se
$ vi hello.dash
divide en celdas x*y, y cada celda tiene una anchura y
hello.dash una altura jas. Dispones de cierta exibilidad ya que
puede combinar celdas para crear una más grande y

también puede dejar celdas o las vacías. El tamaño
# Main arguments, all optional 
#  estándar de la celda es de 120×120 píxeles. Puesto
title: Hello Panel  que la pantalla de 3.5″ tiene una resolución pequeña
widget_dimensions: [120, 120]  (480 × 320), necesitaremos ser creativos e
widget_margins: [5, 5]  implementar algún tipo de menú para saltar de un
columns: 8  panel a otro. También utilizaremos celdas pequeñas,
 
38×38, con un margen de 1 píxel y las combinaremos
label: 
para crear widgets más grandes cuando sea
 widget_type: label 
 text: Hello World  necesario. Ten en cuenta que, si utilizas una pantalla
  lo su cientemente grande puede y deberías usar,
layout:  tamaños de widget más grandes para evitar así tener
 ­ label(2x2) problemas con el diseño.

Tras reiniciar AppDaemon, podrás acceder a esto en Con respecto a la navegación con menús,
http://[ip-odroid]:5050/hello, donde [ip-odroid] es la HADashboard tiene un widget de navegación que se
dirección IP del ODROID-C2. puede usar para cargar un cuadro de mando
diferente. La idea es crear un menú vertical de 8
elementos que aparecerá en todos los cuadros de
mandos permitiendo una rápida navegación, luego
rellenar los paneles de acuerdo a mis necesidades
con datos internos de Home Assistant, sensores,
interruptores, reproductores multimedia, cámaras y
datos externos tales como grá cos de Netdata o
datos meteorológicos online. Uno de los botones
puede servir como menú y cargar así un panel
diferente con más botones, así que dispones de
muchas opciones.

Aquí tienes un ejemplo de encabezado de cuadro de


mandos, el cual he duplicado en todos los paneles:

Figura 3 – Hola desde el otro lado # Main arguments, all optional 


#  se carga el panel “lcd35-hq”, si no hay otra acción.
title: 3.5in LCD panel ­ 480x320 divided into  Esto te permite simular un menú pop-up que
12x8 cells ­ Home 
desaparece por sí sólo.
widget_dimensions: [38, 38] 
widget_margins: [1, 1]  El diseño de los widgets sobre la página se lleva a
columns: 12  cabo creando una directiva de diseño con las las que
use_gass_icon: 1 se detallan a continuación. Para cada celda de una
la, debes escribir el nombre del widget tal y como
Para poner en marcha la navegación, he con gurado
está de nido en el cuadro de mandos o los archivos
una lista de “botones” en un archivo diferente
importados. Los nombres de los widgets pueden
llamado
tener su tamaño anexado al nombre. Con el n de
~homeassistant/.homeassistant/dashboards/navigati
reutilizar la con guración tanto como sea posible,
on-de nition.yaml, que se incluirá en todos los
también puedes importar de niciones externas desde
paneles y que tendrá un aspecto similar al siguiente,
otros paneles, como el fragmento de navegación
solo se muestran algunos elementos para que te
anterior. El siguiente fragmento es del cuadro de
hagas una idea:
mandos principal:
home: 
layout: 
 widget_type: navigate 
 ­ include: navigation­definition 
 dashboard: "lcd35­hq" 
 ­ include: sensors 
 icon_active: fa­home 
 ­ home, clock(4x4), weather(7x4) 
 icon_inactive: fa­home 
 ­ mpd 
mpd: 
 ­ webcams 
 widget_type: navigate 
 ­ tv 
 dashboard: "mpdkitchen" 
 ­ heating, sensorliving(2x4), 
 icon_active: fa­music 
sensorkids(2x4), heater(2x4), forecast(5x4) 
 icon_inactive: fa­music 
 ­ cooling 
tv: 
 ­ blinds 
 widget_type: navigate 
 ­ extendedmenu
 dashboard: "tv" 
 icon_active: mdi­television­classic 
Los elementos más a la izquierda de la lista son los
 icon_inactive: mdi­television­classic 
 icon_style: "font­size: 1.5em !important;" 
destinos de la navegación de nidos en el archivo
 …  navigation-de nition.yaml. Desafortunadamente,
  puesto que quería disponer de un menú vertical,
extendedmenu:  necesito añadirlo especí camente a cada cuadro de
 widget_type: navigate  mando. Si sólo tuviera una la horizontal, podría
 dashboard: "extendedmenu" 
haber hecho el diseño dentro del archivo navigation-
 args: 
de nition.yaml.
 timeout: 10 
 return: lcd35­hq  La la superior empieza con un pequeño widget
 icon_active: mdi­menu  “home” utilizado para empezar a navegar de nuevo
 icon_inactive: mdi­menu desde aquí, luego un widget de reloj 4×4 y un widget
de clima 7×4. La siguiente la solo muestra “mpd”,
Puedes conseguir una copia completa del archivo
que forma parte del menú. El resto de la la está
en https://goo.gl/vwYD33. Como puede ver, la
ocupada por los grandes widgets de reloj y clima, de
mayoría de las entradas son widgets de navegación
modo que no hay añadido ningún otro elemento más.
que incluyen el nombre de archivo del cuadro de
Usando esta lógica, puedes hacerte una imagen
mando como parámetro y puede tener un estilo o
mental de cómo se supone que debería verse. El
icono personalizados. El ítem “extendedmenu” hace
que este panel se cargue durante 10 segundos, luego
resto de los elementos están de nidos en el cuadro
de mando y en el sensors.yaml incluido:

clock: 
 widget_type: clock 
 time_format: 24hr 
 show_seconds: 0 
 time_style: "color: yellow; font­size: 40pt; 
font­weight: bold;" 
 date_style: "font­size: 16pt; font­weight: 
bold;" 
 
weather: 
 widget_type: weather  Figura 4 – Panel de control con la navegación inservible
 units: "°C" 
Sin embargo, parece haber un problema con el
 sub_style: "font­size: 110%; font­weight: 
diseño de los widgets de navegación. Si utilizaras las
bold;" 
 main_style: "font­size: 75%; font­weight:  herramientas de desarrollo de tu navegador y
bold;"  analizas el diseño, veras que, aunque los widgets
 unit_style: "font­size: 250%;"  están colocados correctamente, los iconos heredan
  un estilo CSS que usa un posicionamiento absoluto
forecast: 
que desplaza el icono de 43 píxeles hacia abajo. Esto
 widget_type: sensor 
es un problema porque el cuadro de mandos fue
 title: Prognoza 
diseñado para pantallas más grandes con widgets
 title_style: "font­size: 14pt;" 
 text_style: "font­size: 16pt; font­weight:  más grandes. Para evitar este problema, lo mejor es
bold;"  crear un skin que cargue un archivo JavaScript
 precision: 0  personalizado que restablezca el diseño absoluto de
 entity: sensor.dark_sky_forecast_ro los iconos y también ajuste el tamaño. Para hacer
esto, necesitarás algunos conocimientos de Javascript,
Como puede ver, la mayoría de los widgets requieren
HTML y CSS, aunque puedes conseguir el skin
una entidad que proporcione el lazo de unión con los
completo en https://goo.gl/Fwcbti.
elementos de Home Assistant, un “type” y el resto de
con guración gestiona las fuentes, los colores y los $ sudo su ­ homeassistant 
iconos. Los iconos de los widgets pueden proceder de $ cd .homeassistant/ 
Home Assistant, aunque pueden sustituirse por $ mkdir ­p custom_css/defaultsmall 
$ cd custom_css/defaultsmall 
iconos de Material
$ wget ­O dashboard.css  
Design, https://materialdesignicons.com, con el
 https://raw.githubusercontent.com/mad­
pre jo mdi, o de Font Awesome, ady/home­assistant­
http://fontawesome.io, con el pre jo fa. customizations/master/appdaemon_skins/defaults
mall/dashboard.css 
Si tuvieras que cargar este cuadro de mandos ahora
$ wget ­O dashboardsmall.js  
mismo en un navegador introduciendo http://ip-
 https://raw.githubusercontent.com/mad­
odroid:5050/lcd35-hq, se vería como en la Figura 4.
ady/home­assistant­
customizations/master/appdaemon_skins/defaults
mall/dashboardsmall.js 
$ wget ­O variables.yaml  
 https://github.com/mad­ady/home­assistant­
customizations/blob/master/appdaemon_skins/def
aultsmall/variables.yaml
Ahora, si vuelve a cargar el cuadro de mandos y
especi cas un skin especi co, conseguirás mejores
resultados (http://[ip-odroid]: 5050/Icd35-hq?
Skin=defaultsmall)

Figura 6 – Tres instancias MPD

También tengo una vista del cuadro de mandos para


controlar mi TV, que fue importada a Home Assistant
tal y como se describe
Figura 5 – Cuadro de mandos con navegación en  https://magazine.odroid.com/article/home-

Ahora puedes echar un vistazo a mis cuadros de assistantscripts-customization/. Estamos obteniendo

mandos. Toda la con guración está la imagen de un componente de cámara dentro de

en  https://goo.gl/VuB9sr. El panel MPD se compone Home Assistant y usando el Widget de cámara. Los

de 3 cuadros de mandos similares en los que puedo botones se utilizan para controlar el control remoto

desplazarme utilizando los widgets de navegación virtual y conectarse a los componentes del script en

superiores. Éstos cargan 3 instancias MPD diferentes Home Assistant, así como a la entidad del script en
en la casa. La diferencia entre los paneles únicamente HADashboard. A continuación, tienes un ejemplo de
es la instancia cargada (ver mpdkitchen más abajo). El diseño y de los widgets:
diseño del cuadro de mando es bastante simple: layout: 
 ­ include: navigation­definition 
layout: 
 ­ home, streamtv(10x8), tv_living_off 
 ­ include: navigation­definition 
 ­ mpd, tv_living_on 
 ­ include: mpd 
 ­ webcams, tv_living_source 
 ­ home, navigationmpdliving(4x1), 
 ­ tv, tv_living_mute 
navigationmpdkids(4x1), 
 ­ heating, tv_living_volume_up 
navigationmpdkitchen(3x1) 
 ­ cooling, tv_living_volume_down 
 ­ mpd, mpdkitchen(11x7) 
 ­ blinds, tv_living_ch_up 
 ­ webcams 
 ­ extendedmenu, tv_living_ch_down 
 ­ tv 
 
 ­ heating 
streamtv: 
 ­ cooling 
 widget_type: camera 
 ­ blinds 
 entity_picture: 
 ­ extendedmenu
http://192.168.1.4:8123/api/camera_proxy/camer
a.tv_living_image?
token=62f78994c790a89459e2f60cc6ed80bdfce3e9b5
ff5473633ba60e3d7089f0a6&api_password=odroid 
 refresh: 2 
 
tv_living_off: 
 widget_type: script 
 entity: script.tv_living_power_off 
 icon_on: mdi­power­plug­off   title: Thermostat 
 icon_off: mdi­power­plug­off   step: 0.5 
   precision: 1 
tv_living_on:   entity: climate.heater_thermostat 
 widget_type: script   unit_style: "color: yellow;" 
 entity: script.tv_living_power_on   level_style: "color: yellow; font­size: 
 icon_on: mdi­power  48pt;" 
 icon_off: mdi­power  unit2_style: "color: yellow;" 
 level2_style: "color: yellow; font­size: 
Lo que diferencia al widget de cámara es que necesita 40pt;" 
una URL a través de la API de Home Assistant. Esta  level_up_style: "font­size: 20pt;" 
URL debe incluir la clave API y también un token que  level_down_style: "font­size: 20pt;"

es visible en Home Assistant -> Entities para la


entidad en cuestión. Si también usas una contraseña
para acceder a Home Assistant, deberás añadirla a la
URL. La gura 7 muestra el resultado nal.

Figura 8 – Panel del calentador

Durante el verano, el panel del aíre acondicionado


tendrá un cierto uso. Aquí se colocan los sensores,
Figura 7 – Cuadro de mandos para monitorizar el TV
interruptores y temporizadores que controlan el
Otro cuadro de mandos permite controlar el sistema de AC, como se describe en
calentador, manualmente y el termostato. La https://magazine.odroid.com/article/home-
con guración para el widget del termostato es similar assistantscripts-customization/. El panel es similar al
a la que aparece a continuación, y el resultado nal lo se muestra en la Figura 9.
puedes ven en la Figura 8.

layout: 
 ­ include: navigation­definition 
 ­ include: sensors 
 ­ home, heater(4x4), thermostat(6x8) 
 ­ mpd 
 ­ webcams 
 ­ tv 
 ­ heating, sensorliving(2x4), sensorkids(2x4) 
 ­ cooling 
 ­ blinds 
 ­ extendedmenu 
 
thermostat:  Figure 9 – Control del Aire Acondicionado
 widget_type: climate 
El menú extendido no es más que un panel con más También prepararemos un script que ejecute
widgets de navegación. En él, tengo enlaces a un Chromium en modo Kiosco, sin almacenamiento de
cuadro de mandos de Netdata y un pronostico contraseñas, para que no te solicite contraseña cada
meteorológico cada hora e imágenes de mis cámaras vez que se desbloquee. Chromium también se
web, con espacio para más en el futuro. El panel de con gurará con un parche que hace que se olvide de
pronóstico del tiempo por hora utiliza el widget que se ha bloqueado, por lo que, en caso de un cierre
iframe para cargar una URL, mientras que el Panel de no limpio, no te preguntará si deseas restaurar la
Netdata carga una lista de URLs cada 5 segundos: sesión anterior. Además de esto, con guraremos el
monitor para que siempre esté encendido:
mynetdata: 
 widget_type: iframe  $ cat /usr/local/bin/kiosk­mode.sh 
 refresh: 5   #!/bin/bash 
 url_list:   /usr/bin/xset s off 
 ­ http://192.168.1.5:19999/server1.html   /usr/bin/xset ­dpms 
 ­ http://192.168.1.5:19999/server2.html   /usr/bin/xset s noblank 
 ­ http://192.168.1.5:19999/server3.html   /bin/sed ­i 's/"exited_cleanly": 
 ­ http://192.168.1.5:19999/server4.html  false/"exited_cleanly": true/' 
 ­ http://192.168.1.5:19999/server5.html ~/.config/chromium/Default/Preferences 
 dashboard=lcd35­hq 
 /usr/bin/chromium­browser ­­noerrdialogs ­­
incognito ­­password­store=basic ­­kiosk 
http://odroid­ip:5050/$dashboard?
skin=defaultsmall 
$ sudo chmod a+x /usr/local/bin/kiosk­mode.sh

También puedes añadir la extensión de Scrollbar


Anywhere Chrome (https://goo.gl/UD3hDA).
Con gúrala para que reaccione con el botón
izquierdo y active “Use Grab-and-drag style scrolling”
para que puedas desplazarte, si fuera necesario, con
el dedo sobre el cuadro de mandos.
Figura 10 – Menú extendido
Comprueba que el script funciona correctamente
Ahora que tienes el cuadro de mandos funcionando a
cuando se inicia desde el entorno grá co y, cuando
tu gusto, tendrás que invertir un poco de tiempo en el
esté listo, puedes añadirlo a la lista de aplicaciones
tema de la pantalla. Puedes empezar con el script de
que se inician automáticamente en Control Center ->
instalación de @FourDee para la pantalla de
Personal -> Startup Applicat. Simplemente haz clic en
https://forum.odroid.com/viewtopic.php?t=24248.
“add”, usa “Kiosk mode” en el nombre y
También necesitarás activar el acceso automático en
/usr/local/bin/kiosk-mode.sh como comando. Una vez
lightdm
que reinicies lightdm, deberías ver un panel a pantalla
(https://wiki.odroid.com/accessory/display/3.5inch_l
completa.
cd_shield/autox#auto_login). Una vez hecho esto, es
hora de realizar una limpieza. Lo mejor es eliminar Lo que muestra la Figura 11 es el resultado nal,
aquellos programas que muestran ventanas pop-up ejecutándose en una pantalla de 3.5″. La pantalla de
en pantalla, como son el gestor de actualizaciones y el 3.5 “de Hardkernel es perfecta para un pequeño
protector de pantalla: cuadro de mandos. Los tamaños y colores de fuente
utilizados están optimizados para una fácil lectura a
$ sudo apt­get remove update­manager gnome­
una distancia de 2-3 metros y el contraste ayuda a
screensaver
leer desde ángulos más amplios. La baja velocidad de
refresco de la pantalla de unos 10 fps no se aprecia Puedes conseguir los archivos de con guración del
con el cuadro de mandos. cuadro de mandos desde proyecto GitHub
en  https://github.com/mad-ady/home-assistant-
customizations, y ver un video de demostración
en youtu.be/fEoHs3-_3B0. Pen en cuenta que todo ha
sido probado con el appdaemon 2.1.12, puesto que la
versión 3 está actualmente en desarrollo,   para
cuando pongas en funcionamiento esto, quizás
algunas cosas hayan cambiado ligeramente. Está
atento al repositorio de GitHub y al hilo de soporte
en    https://forum.odroid.com/viewtopic.php?
Figura 11 – Pantalla de 3.5 “con el cuadro de mandos t=27321.
Módulo eMMC Naranja: Llega el chipset Samsung 5.1
 January 1, 2018  By Justin Lee  ODROID-C2

Hardkernel ha presentado ahora el módulo eMMC Compatibilidad del Módulo eMMC naranja con
naranja, que utiliza el chipset eMMC 5.1 de Samsung, imágenes de sistema operativo de la serie XU4
el cual se ha estado enviando desde octubre de 2017.
Imagen SO Información del Estado
Archivo de
Imagen

Ubuntu Mate ubuntu-16.04.3- OK


4.14-mate-
odroid-xu4-
20171212.img

Ubuntu Minimal ubuntu-16.04.3- OK


4.14-minimal-
odroid-xu4-
20171213.img

Android 7.1.1 Alpha- OK


1.1_14.11.17
Figure 1 – Hardkernel now o ers an orange eMMC
module) Android TV 7.1.1 Alpha- OK
1.0_20.11.17
Funciona con las series C1/C2/XU4 y el sistema
operativo adecuado. Las últimas imágenes o ciales Android 4.4.4 Android 4.4.4 OK

del sistema operativo funcionan correctamente. Los (v5.8)

esquemas están disponibles en  eMMC PCB Rev 0.4. Debian Jessie Debian-Jessie- OK
1.1.4-20171121-
XU3+XU4.img

ODROID Game ODROID- OK


Station Turbo GameStation-
(OGST) Turbo-3.9.5-
20171115-
XU3+XU4- Figura 2 – El eMMC versión 5.0 (izquierda) tiene el código
Jessie.img QR en el lado derecho, y eMMC versión 5.1 (derecha)
tiene el código QR en el lado izquierdo
Armbian All Armbian OK
variants starting El Kernel versión 3.10 debería tener los siguientes
with version 5.35 parches aplicados para que funcione correctamente
OMV OMV_3_0_92_Odr OK con la serie XU4: Github, Github, Github.
oidxu4_4.9.61

DietPi DietPi_OdroidXU4 OK
-armv7-(Jessie).7z
22-Nov-2017

Yocto project No Flashable le No Probado


reference

Kali-Linux No Flashable le No Probado


reference

Arch-Linux No Flashable le No Probado


reference

ROS No Flashable le No Probado


reference

Lakka Lakka- OK
OdroidXU3.arm-
2.1-rc6.img.gz

Batocera batocera-5.12- OK
xu4-
20171214.img.gz

RecalBox recalbox ¿OK?


(17.11.10.2)

RetroPie No Flashable le No Probado


reference

Los eMMC de Sandisk tiene una versión hasta la 5.1 Figura 3 – Tabla de módulos eMMC de productos
con velocidad de transferencia de datos ligeramente actuales en ejecución 2016

más rápida a partir del 20 de julio de 2017. Tal y como


se muestra en la Figura 2, el código QR está en el lado
izquierdo del chipset ver. 5.1 mientras que el eMMC
ver. 5.0 lo tiene en el lado derecho.
Pruebas de lectura/escritura del eMMC bajo el
modo HS400 ODROID-C2 (Unidad: MByte/seg)

Samsung Toshiba Sandisk

8G Escritura 45.4 21.9 N/A

8G Lectura 113 148 N/A

16G Escritura 80.1 N/A 25.6

16G Lectura 126 N/A 153

32G Escritura 124 N/A 98.7

32G Lectura 125 N/A 153

64G Escritura 124 83.7 107

64G Lectura 124 153 153

Comando de lectura/escritura para la pruebas de


rendimiento del eMMC:
 

$ dd if=/dev/zero of=test.tmp oflag=direct 
bs=1M count=1024 
$ dd if=test.tmp of=/dev/null iflag=direct 
bs=1M

ODROID-C2 + Prueba de rendimiento del Emmc


negro en condiciones de E/S de archivos

Ubuntu 16.04

Figura 4 – Módulos eMMC de antiguos productos Versión Kernel : Linux odroid64 3.14.79-115
Herramienta para pruebas : iozone revision 3.429
Referencias
Esquemas del módulo eMMC Revison 0.3 Esquemas Prueba de instalación y rendimiento de iozone:
del módulo eMMC amarillo revisión 0.4 Esquemas
$ sudo apt install iozone3 
de la placa lectora eMMC
$ iozone ­e ­I ­a ­s 100M ­r 4k ­r 16k ­r 512k 
­r 1024k ­r 16384k ­i 0 ­i 1 ­i 2< 
Dimensiones de la placa eMMC: 18.5mm x 13.5mm
/* 8G */ 
Hueco entre las PCBs: 1.1mm (Altura de los conectores
random random 
B2B ensamblados)
kB reclen write rewrite read reread read write 
102400 4 9290 13582 13570 13568 11900 8787 
El conector está hecho por LS-Mtron Korea. En el 102400 16 10934 15680 27511 27484 25976 7699 
módulo eMMC, se utilizó el GB042-34S-H10 (Socket- 102400 512 14943 23761 42163 42121 41361 15122 
34pin). En la placa host, se utilizó el GB042-34P-H10 102400 1024 15140 28564 41951 41915 41196 
(clavija-34pin). Las especi caciones del conector 16743 
102400 16384 16559 24001 42308 42267 42287 
están aquí Información sobre el eMMC Sandisk
28604 
(iDisk Extreme) Información sobre el eMMC
/* 16G */ 
Samsung Información sobre el eMMC Essencore (el
random random 
eMMC de 8GB se utiliza para XU4) Información kB reclen write rewrite read reread read write 
sobre eMMC Toshiba 102400 4 14602 14622 18102 17953 16768 14421 
102400 16 49363 49279 52902 52808 47450 48389 
102400 512 49779 49993 138268 138315 137171  La nueva PCB roja eMMC de 8GB para el modelo
48836  ODROID-XU4 está basada en la tecnología eMMC 5.0
102400 1024 50005 49870 137522 137709 136958 
de Essencore/AIO. Velocidad secuencial con prueba
49027 
“dd”:
102400 16384 49861 50058 139358 139154 139299 
50024 
Escritura dd: 15.1 MB/s
/* 32G */ 
random random  Lectura dd: 104 MB/s

kB reclen write rewrite read reread read write  Prueba de velocidad de acceso aleatorio (IOPS) con


102400 4 14608 14670 18333 18343 17935 14624  bloque 4k.
102400 16 58393 66157 56412 56766 55744 56371  Escritura aleatoria : io=993228KB, bw=9928.2KB/s,
102400 512 80356 81074 136828 137132 137503  iops=2482
79224  Lectura aleatoria : io=1479.1MB, bw=15149KB/s,
102400 1024 80464 81036 137368 137278 136896  iops=3787
79191 
102400 16384 80388 81070 139486 139612 139446 
Comparando el rendimiento del Módulo eMMC frente
80560 
a la Tarjeta SD en el C2 con Android utilizando una
/* 64G */ 
random random 
PCB negra eMMC de 16 GB y una tarjeta SDHC UHS-1
kB reclen write rewrite read reread read write  de 16 GB (modelo OEM Sandisk SDSDQAD-016G UHS-
102400 4 14240 14299 17619 17548 16012 14216  I 50), con una imagen Android 5.1 V2.8 limpia y con el
102400 16 49991 57484 53245 53405 50001 59302  paquete GApps Pico instalado:
102400 512 132316 135079 134154 134016 134208 
129755  Tiempo de arranque del eMMC desde el encendido: 18
102400 1024 132476 134966 133753 133840 133677  ~ 20 segundos
130054  Tiempo de arranque de la SDHC desde el encendido:
102400 16384 135772 139140 136133 136019  32 ~ 35 segundos
135821 135107 
/* 128G */ 
random random 
Puntos de control para los desarrolladores de
software de sistemas
kB reclen write rewrite read reread read write 
102400 4 14162 14152 18161 18184 17833 14200  No sobrescribas la partición de arranque oculta del
102400 16 56527 64906 55057 55684 54492 66525  eMMC. Si es así, visita cómo recuperar el cargador de
102400 512 131327 131444 137307 137040 137358  arranque del eMMC para solucionarlo. El eMMC
132500 
debería estar dividida de la siguiente forma:
102400 1024 131908 131896 137570 137495 136844 
132365 
Partición FAT16 con UUID 6E35-5356 (arranque)
102400 16384 136418 134070 139940 133304 
Partición EXT4 con e139ce78-9841-40fe-8823-
121160 134002
96a304a09859 (Linux)

El módulo eMMC negro está hecho con el chipset


eMMC de Samsung. El módulo eMMC rojo y azul Copia los contenidos de las particiones de la imagen

(normal) está hecho con chipset Sandisk o Toshiba o de Ubuntu a las particiones de arranque y Linux

AIO. Los dispositivos ODROID-C1/C0/C1+/C2 usando “cp -afpv source destination”, luego inserta el

funcionan con los módulos eMMC negro y rojo. Los módulo eMMC y arranca como normalmente lo

dispositivos ODROID-XU4/XU3/U3/X2/U2 NO haces. Para comentarios, preguntas y sugerencias,

funcionan con el módulo eMMC negro. visite la página wiki original


en https://wiki.odroid.com/accessory/emmc/referen
Testeo del nuevo módulo eMMC de 8 GB en ce_chart.
Ubuntu XU4
Recompilando imágenes Docker x86amd64 para Swarm ARM
 January 1, 2018  By Mike Partin  Docker, Linux, Tutoriales

Tras nalizar los recientes artículos sobre cómo Usaremos una imagen ya creada para esto
compilar swarm Docker en ARM de  http://dockr.ly/2kmNgod. El registro proporciona
(https://goo.gl/2FjP8f) y (https://goo.gl/ZTXcp), me un lugar para almacenar e implementar tus imágenes
encontré con que quería activar servicios, para los personalizadas. Se trata de un excelente escenario
cuales no había imagen ARM disponible, o no había antes de enviar tu producto nal
ninguna imagen ARM con una versión reciente. Las a https://hub.docker.com o a cualquier otro registro
alternativas son tres: 1) prescindir de lo que quería, 2) que elijas.
conformarme con una versión anterior, o 3) averiguar
El front end del registro es simplemente un pequeño
cómo compilar lo que quería. Soy un poco chapucero
servicio muy útil para poner en marcha un registro
y me gusta tener al menos un conocimiento básico de
(http://dockr.ly/2D5DRt3). No entraremos en
mis herramientas, así que me decanté por la tercera
funciones avanzadas como eliminar imágenes, lo cual
opción. En su mayor parte, se trata un proceso
requiere una con guración adicional en el registro,
bastante sencillo, aunque de vez en cuando, terminas pero podremos navegar por nuestras imágenes y
modi cando algunas cosas. No te deje intimidar por obtener información sobre ellas.
ello, porque realmente merece la pena, y no es tan
Utilizaré go-carbon para el caché
difícil. Para facilitar las cosas, con guremos una pila
(https://goo.gl/hgjGZo). La razón fue simple, go-
Graphite. Para esta pila, necesitaré varios elementos,
carbon usa más de un núcleo en una única instancia.
además de un poco de soporte en forma de registro
Es realmente fácil de con gurar, y si tienes alguna
de imágenes alojado internamente.

Un registro
de nición de esquema, puede funcionar muy bien y asumiendo que dispones de una con guración por
también es compatible con el formato pickle. defecto y que el archivo está completo:

Utilizaré graphite-api para el punto nal de la API de { 


renderizado  https://goo.gl/P43pHC. Hay otras     "insecure­registries": ["10.0.0.15:5000"] 
opciones como carbonserver y carbonzipper. Creo }
que go-carbon ahora tiene soporte para
carbonserver, pero aún no lo he probado. Creo que ir Interfaz de Usuario del Registro Docker
en modo stock no es tan malo en este caso. Solo se Ahora vamos a movernos para que la interfaz del
consulta de vez en cuando, así que no se necesita registro esté en su lugar, lo cual nos permitirá
tener un rendimiento tan alto como el caché. compilar nuestra primera imagen. Ten en cuenta que

Usaré grafana para la interfaz de usuario de la yo he usado el nombre de host swarm. Esto es lo

pantalla, ya que es bastante común correcto para mi con guración, ya que tengo un

(https://grafana.com). Podríamos usar el paquete registro CNAME en mi servidor DNS, aunque tu


con guración puede ser diferente:
graphite-web, aunque las posibilidades de
representación grá ca son las mismas, son bastante $ git clone 
menos accesibles que las de Grafana. También https://github.com/parabuzzle/craneoperator.gi
existen otras opciones, si bien deberías analizarlas t 
antes de tomar cualquier decisión sobre lo que más $ cd craneoperator 
$ docker build ­t docker­registry­ui . 
te conviene.
$ docker tag docker­registry­ui 
Implementar la infraestructura swarm:5000/docker­registry­ui­arm 
$ docker push swarm:5000/docker­registry­ui­
Dado que el swarm es realmente de alta
arm
disponibilidad con balanceo de carga de esos
servicios (tanto a nivel de hardware como de red), los Ahora podemos lanzar nuestro servicio. Éste, como
servicios que hemos enumerado anteriormente se muchos otros, utiliza variables de entorno que
lanzarán como servicios independientes. Ten en in uyen en su funcionamiento. Por supuesto, tendrás
cuenta que hay múltiples opciones para cada uno, de que editarlas para apreciar los cambios:
modo que cubrirlas todas es demasiado para este
$ docker service create ­­name=docker­
artículo. Una vez dicho esto, centrémonos en
registry­ui ­­publish=8081:80/tcp ­e 
nuestras necesidades de infraestructura e
REGISTRY_HOST=swarm ­e REGISTRY_PROTOCOL=http 
implementemos nuestro registro: ­e SSL_VERIFY=false swarm:5000/docker­
registry­ui­arm
$ docker service create ­­name=docker­registry 
­­publish=5000:5000/tcp cblomart/rpi­registry
Caché Carbon y API renderizado
Una vez que se complete el comando, dispondremos Go-carbon es una aplicación Go que requiere Go 1.8+.
de un registro. Sin embargo, tenemos el problema de Para evitar problemas innecesarios nos basaremos en
que ninguna de nuestras instancias Docker lo usará una versión reciente de Go que está disponible en mi
porque no es seguro. Tenemos dos opciones: la gestor de paquetes favorito, simplemente
primera es con gurar tus instancias docker para que colocaremos la última versión en una ubicación
usen un registro inseguro (concretamente una lista personalizada. En este momento, Go 1.9.2 es la última
blanca), y la segunda es obtener un certi cado versión, así que la usaremos. Además, doy por hecho
(auto rmado o públicamente veri cable). Este es un que estás ejecutando Linux en una máquina ARM,
registro interno. Para ir avanzando, he optado por la como un ODROID-XU4, que es una maravillosa
primera opción. Para hacerlo así en todos los nodos estación de trabajo. Manejo cada uno de mis 3
docker, añadí lo siguiente a /etc/docker/daemon.json, monitores con un XU4, y uso x2x para poder
compartir el teclado y el mouse, aunque esto da para schemas.conf:
un artículo que escribiremos en otro momento.
[default] 
$ cd ~  pattern = .* 
$ mkdir ­p ~/.golang/path  retentions = 10s:1h, 30s:3h, 60s:6h, 1h:1d, 
$ wget  6h:1w, 12h:1m, 24h:1y
https://redirector.gvt1.com/edgedl/go/go1.9.2.
linux­armv6l.tar.gz  Esto nos proporciona mucho espacio para que
$ tar ­zxf go1.9.2.linux­armv6l.tar.gz  nuestras estadísticas se almacenen y se mantengan
$ mv go .golang/root  en el tiempo. Llegados a este punto, estamos listos
$ export GOROOT=${HOME}/.golang/root  para empezar a compilar nuestra imagen Docker.
$ export GOPATH=${HOME}/.golang/path  Supongo que, a afectos de este artículo, te encuentras
$ export 
en la misma máquina en la que compilaste go-carbon
PATH=${GOROOT}/bin:${GOPATH}/bin:${PATH}
y en la que tienes instalado Docker.
Ahora estamos listos para empezar a trabajar en go-
$ docker build ­t go­carbon . &&  
carbon. Este es realmente bueno, puesto que dispone $ docker tag go­carbon swarm:5000/go­carbon­
de un archivo Docker le ya creado, y lo único que arm &&  
tenemos que hacer es compilar el binario y preparar $ docker push swarm:5000/go­carbon­arm
nuestros archivos de con guración. Obtener la fuente
Ahora podemos publicar nuestro servicio para
y compilar el binario se puede hacer de una sola vez:
nuestro swarm. Ya lo hemos hecho varias veces, así
$ go get ­v github.com/lomik/go­carbon que debería serte familiar:

Ahora que tenemos esto hecho, vamos a compilar $ docker service create ­­name=carbon­cache ­­


nuestra imagen Docker: publish=2003:2003/tcp ­­publish=2003:2003/udp 
swarm:5000/go­carbon­arm
$ cd ${GOPATH}/src/github.com/lomik/go­carbon 
$ cp ${GOPATH}/bin/go­carbon .  Sin embargo, ahora nos encontramos con otro
$ mkdir config­examples inconveniente. Necesitamos tener instalada la
graphite-api en la imagen, ya que necesitamos
Seguimos adelante y nos detendremos aquí, ya que
disponer de acceso a los archivos whisper. Podríamos
necesitamos modi car el archivo de con guración.
crear un sistema de archivos compartido y montarlo
Hay un gran número de opciones, pero es probable
tanto para la memoria caché como para las imágenes
que no necesites modi car ninguna. Dejaré que seas
API, pero en este caso, creo que es mejor que
tú el que se ocupe más adelante de las
simplemente modi quemos nuestra imagen go-
personalizaciones, simplemente daré por sentado
carbon para que soporte ambos. Lo primero a tener
que los valores por defecto son lo su cientemente
en cuenta es que la imagen docker se llame
buenos por ahora. La única modi cación que
“busybox”. Como necesito Python, decidí mover esto
haremos es apuntar al archivo de esquemas correcto
a ‘debian: stretch’. Lo primero es conseguir nuestro
y a nuestro directorio de datos. Podemos hacer esto
graphite-api.yaml, que se encuentra en ./conf-
con un simple comando sed:
examples/graphite-api.yaml:
$ ./go­carbon ­config­print­default | sed ­E 
search_index: /data/graphite/index 
's,(schemas­file =).*, "/data/graphite/go­
finders: 
carbon­schemas.conf",g' | sed ­E 's,(data­dir 
  ­ graphite_api.finders.whisper.WhisperFinder 
=).*, "/data/graphite/whisper",' > ./conf­
functions: 
examples/go­carbon.conf
  ­ graphite_api.functions.SeriesFunctions 

A continuación, podemos conseguir nuestro archivo   ­ graphite_api.functions.PieFunctions 


whisper: 
de esquemas en /conf-examples/go-carbon-
  directories:  publish=2003:2003/tcp ­­publish=2003:2003/udp 
    ­ /data/graphite/whisper ­­publish=8000:8000/tcp swarm:5000/go­carbon­
arm
Puesto que estamos iniciando más de un servicio,
debemos usar un script de punto de entrada Con guración de Graphite
personalizado. Seguimos avanzando y escribimos
Llegados a este punto, estamos listos para la última
esto.
parte del proyecto, que es otra imagen que
#!/bin/sh  necesitaremos recompilar. Sin embargo, gracias a los
gunicorn ­b 0.0.0.0:8000 ­w 2  “fat manifests” o listas de mani esto de Docker, al
graphite_api.app:app &  hacer referencia a “debian” obtendrás la imagen
sleep 2  adecuada para tu arquitectura. Casi todas las
/go­carbon ­config /data/graphite/go­
compilaciones o ciales se hacen de esta forma, así
carbon.conf
que ya no es necesario buscar hasta dar con una
Después de desplazarnos a debian:stretch e instalar imagen para la arquitectura ARM
nuestros paquetes y con guraciones, nuestro Con suerte, en mi próximo artículo, exploraremos la
Docker le en nuestro directorio go-carbon debería con guración de tus propios “fat manifests” en tu
verse ahora de la siguiente forma: registro privado. Esto es muy útil si tienes, como yo,
arquitecturas mixtas como amd64 en tu swarm y
FROM debian:stretch 
RUN mkdir ­p /data/graphite/whisper/  quieres que cualquiera de tus servicios pueda
RUN apt update && apt upgrade ­y && apt dist­ implementarse en cualquiera de tus nodos. Así que
upgrade ­y && apt autoremove ­y  empecemos por la imagen Grafanas. Elegí la imagen
RUN apt install ­y gunicorn graphite­api  en  https://goo.gl/pfpVef, ya que tiene todos los
ADD go­carbon /  plugins que quería ya cargados, y eso ahorra un
ADD entrypoint.sh / 
montón de trabajo para todo el mundo. Por supuesto,
ADD conf­examples/* /data/graphite/ 
puedes hacerte con la imagen o cial y seguir el
RUN chmod +x /entrypoint.sh 
RUN rm /etc/graphite­api.y* ; ln ­s  mismo proceso:
/data/graphite/graphite­api.yaml 
$ git clone 
/etc/graphite­api.yaml 
https://github.com/monitoringartist/grafana­
CMD ["/entrypoint.sh"] 
xxl.git 
EXPOSE 2003 2004 7002 7007 2003/udp 8000 
$ cd grafana­xxl 
VOLUME /data/graphite/
$ cp Dockerfile Dockerfile.arm

Avancemos y recompilemos, luego impulsemos


Necesitamos cambiar la línea 17 de:
nuestra nueva imagen:
$ curl https://s3­us­west­
$ docker build ­t go­carbon . &&   2.amazonaws.com/grafana­
$ docker tag go­carbon swarm:5000/carbon­ releases/release/grafana_${GRAFANA_VERSION}_am
cache­arm &&   d64.deb > /tmp/grafana.deb &&  
$ docker push swarm:5000/carbon­cache­arm Por los siguiente: 
$ curl https://github.com/fg2it/grafana­on­
Después eliminaremos nuestro antiguo servicio y lo
raspberry/releases/download/v${GRAFANA_VERSION
volveremos a crear. Soy consciente de los procesos }/grafana_${GRAFANA_VERSION}_armhf.deb > 
de actualización para ejecutar los servicios, aunque /tmp/grafana.deb && \
sentía que podía escribir un buen tocho sobre este
tema, así que lo dejaría como está. Despues, la línea 20 debe cambiar de:

$ docker service rm carbon­cach  $ curl ­L 

$ docker service create ­­name=carbon­cache ­­ https://github.com/tianon/gosu/releases/downlo
ad/1.10/gosu­amd64 > /usr/sbin/gosu && \ $ docker tag grafana­xxl­arm 
swarm:5000/grafana­xxl­arm 
A esto: $ docker push swarm:5000/grafana­xxl­arm 
$ docker service create ­­name=grafana ­­
$ curl ­L 
publish=3000:3000/tcp swarm:5000/grafana­xxl­
https://github.com/tianon/gosu/releases/downlo
arm
ad/1.10/gosu­armhf > /usr/sbin/gosu && \

El último paso es iniciar sesión en tu instancia grafana


Una vez hecho esto, estamos listos para recompilar,
en http://swarm:3000/ con el nombre de usuario y la
mover e implementar nuestro servicio. Usaremos
contraseña por defecto “admin” y “admin”. Una vez
nuevamente esos comandos cada vez más útiles y
que hayas iniciado sesión, simplemente agrega
familiares:
http://swarm:8000/ como fuente de datos grafana
$ docker build ­t grafana­xxl­arm ­f  predeterminada y estarás listo para usar Docker.
Dockerfile.arm . 
Juegos Android: Monument Valley, Hopscotch, Aqueducts
 January 1, 2018  By Bruno Doiche  Android, Juegos

No siempre nos desviemos de los extraños juegos


indie para Android, pero durante las vacaciones play
store nos ha dotado con grandes títulos, así que sin
más preámbulos permite presentarte:

Monument Valley
Podría hablar largo y tendido de este juego, pero la
mejor reseña nos llega de la propia descripción de
Play Store: “En Monument Valley, manipularás
estructuras imposibles y guiarás a una princesa
sigilosa a través de un mundo increíblemente
hermoso. Monument Valley es una exploración
surrealista a través de una arquitectura fantástica y
una geometría imposible. Guía a la princesa sigilosa a
través de misteriosos monumentos, descubriendo
caminos ocultos, desplegando ilusiones ópticas y
burlando a la enigmática Crow People”.
Figura 1: Monument Valley te atrapará desde el Figura 2 – Aunque lo he comentado en el artículo, usa
principio tus auriculares para disfrutar al máximo

Este es un juego que elevará tu experiencia de juego Monument Valley en Play Store
como pocos lo harán, úsalo con tus mejores
Hopscotch
auriculares, no te arrepentirás de tener este juego en
tu colección. Un juego que canaliza el espíritu de M.C. Después de tanta grandiosidad con Monument Valley,
Escher, que te sumerge en una aventura que solo ¿qué juego deberíamos perseguir en nuestra
llegará su n cuando termines este asombroso juego, búsqueda de juegos? Todo parece tan trivial e inútil.
y luego cogerás el ODROID con el que jugaste y lo Todo era mucho más fácil cuando estábamos en la
enmarcarlas con una placa en la que se podrá leer la escuela, donde todo era más simple y nos
siguiente frase: “Jugué al Monument Valley con este divertíamos mucho. ¿Podríamos capturar este
hardware “(Compré otro ODROID después, por sentimiento? ¡Da la casualidad de que sí!
supuesto). Simplemente conecta tu pantalla táctil a tu ODROID e
instale Hopscotch. No tengo mucho más que decir al
respecto: “Prepárate para que te quiten tu dispositivo,
pero esta vez no será el profesor, sino cualquiera que
quiera sentir el gustado de jugas a este gran juego”.
Hopscotch en Play Store

Aqueducts

Figura 4 – Aqueducts es muy divertido siendo un


concepto tan simple.

Y para nalizar esta edición de Juegos Android, otro


juego de puzles al estilo fontanería: Aqueducts. Este
juego te enfrenta al trabajo de telequinesia más
potente que existe mientras mueves gigantescas
piezas que parecen ser colocadas por algún tipo de
repartidor enfadado, o se trata de un proyecto de un
ingeniero con muy poca nanciación. Bromas aparte,
estás a punto de enfrentarte a un juego que está muy
bien diseñado y que convierte un juego muy común
en una experiencia extremadamente divertida.
Pruébalo, disfrutarás un buen rato.

Aqueducts en Play Store

Figura 3 – Después de jugar un montón a este juego,


¡Inténtalo a la inversa!
Android TV ODROID-C2 con Amazon Prime Video y Net ix
 January 1, 2018  By @goldpizza44  Android, ODROID-C2, Tutoriales

He estado usando un ODROID-C2 con LibreELEC desde Playstore, se puede descargar el APK e
durante bastante tiempo, pero me sentía muy instalarlo. La con guración del mando a distancia
decepcionado por la falta de compatibilidad con lleva algo más tiempo, ya que no logre encontrar un
Amazon Prime Video y Net ix. También he estado solo tutorial en línea que detallase todo el proceso.
usando un teclado/ratón inalámbrico para Esperemos que este artículo ayude a otros con este
controlarlo, lo cual me permitía censurar a su tema.
compañero, ya que deseaba tener único un mando a
El primer paso es instalar Android en una tarjeta
distancia de TV para controlar tanto el televisor
Flash. Android para C2 se puede descargar desde
(encendido/volumen) como el ODROID-C2.
https://goo.gl/cuLqSU. Cuando escribí este artículo, la
Aquí tienes el procedimiento que seguí. Doy por v3.5 era la última versión, y esa es lo que yo usé.
hecho que sabes moverte por Android, a la hora de Descarga la imagen, descomprímela e instálala en la
buscar aplicaciones y realizar con guraciones, tarjeta ash con Etcher, que está disponible para
necesitarás usar Linux a través de Android Terminal muchos sistemas operativos, o win32diskimager que
Emulator. se ejecuta en Microsoft Windows, o usa la utilidad dd

Este procedimiento no consiste en instalar sólo Kodi, de Linux. Puede encontrar más información
en https://goo.gl/RPyiwr.
sino también Youtube TV, Amazon Prime Video,
Net ix y algunas aplicaciones de Canales especí cas. Instala la tarjeta ash en el ODROID-C2 que tengas
También te ayudara a instalar aplicaciones desde conectado a un televisor a través de HDMI junto con
Google Playstore. Aunque Net ix no se instalaría un teclado/ratón USB y enciéndelo. Tarda unos
minutos, pero al nal acabarás teniendo un nuevo y Una vez completada la instalación, puedes abrir la
brillante sistema Android, y el ratón debería aplicación Google Play Store e instalar las siguientes
permitirle navegar por el sistema. aplicaciones:

El primer paso después de arrancar Android es


Amazon Prime Video
ajustar el overscan en la pantalla. Observé en mi
Kodi
televisor que faltaban todos los bordes. No podía ver
Chrome Browser
la barra de noti caciones en la parte superior y los
Pluto TV
botones de la parte inferior estaban cortados en su
Un cliente VPN (si quieres … yo uso OpenVPN)
gran mayoría. Esto se soluciona fácilmente usando la
aplicación “ODROID Utility”. A través de esta utilidad
Aunque hay numerosas aplicaciones de video, no
puede ajustar la resolución (el “autodetect” por
todas son aptas para TV. Instálalas una por una y
defecto también me funciono), utilicé las echas para
pruébalas para asegurarse de que funcionan como
ajustar el overscan y apagué el LED azul, que
esperas. Puedes desinstalar las aplicaciones que no
parpadea y distrae. Tras ajustar la con guración con
funcionan correctamente.
esta aplicación, debes hacer clic en “Apply and
Reboot”, lo cual reiniciará el sistema. Por defecto, la con guración de Android “Settings ->
Security -> Untrusted Sources” está jada en “Yes”.
El siguiente paso es instalar Google Apps para tener
Esto es necesario para instalar Net ix. Net ix era la
disponible la tienda Google Play. Utilizando el
única aplicación que no está disponible en Google
navegador por defecto, el APK de Google Apps se
Play Store. Sin embargo, Net ix tiene una página de
puede descargar desde  http://opengapps.org/. En
ayuda con un enlace a su versión v4.16 del APK en
esta página yo seleccioné lo siguiente:
https://goo.gl/22XXZi.

Platform: ARM Descargué esta APK y la instalé con FileManager.


Android: 6.0 Funciona bien con el mando a distancia. Hay
Variant: pico versiones más recientes de la APK de Net ix
disponibles en  https://goo.gl/tkDbkz. Sin embargo,
Pico es la compilación mínima. También puedes cuando las descargué, observé que no funcionaba
intentar instalar nano y micro. Aunque no instalé el muy bien con el mando a distancia. No tengo muy
Calendario y otras aplicaciones en mi sistema, creo claro por qué.
que funcionará.
La con guración de las aplicaciones es la misma en
Al pinchar en el botón de Descargar, se bajará un todas las plataformas. La instalación de mi Kodi se
archivo ZIP a la carpeta de descargas. Este archivo ZIP comunica con un back-end de MythTV en otro
debe tratarse como una actualización de Android y servidor que hace todas las grabaciones de LiveTV y
por lo tanto, se carga utilizando la misma aplicación administra mi colección de películas. Encontrar el
Odroid Utility que se usó para actualizar Overscan y el complemento MythTV PVR fue todo un desafío en
LED azul. Ejecuta la aplicación Odroid Utility y haga Krypton. Está en Addons-> My Addons, pero está
clic en la esquina superior derecha (tres puntos). El desactivado.
menú que aparece tendrá la opción “Package install
Mando a distancia
from storage” en el cual debes hacer clic. En la
siguiente página, selecciona “File Manager” y navega Utilizo un ODROID-C2 TV con algunos televisores
hasta la carpeta de descargas donde debe seleccionar antiguos que heredé, cuyos mandos a distancia
el archivo ZIP open_gapps. Se te pedirá que originales se perdieron hace mucho tiempo. Sin
continúes, tras lo cual el odroid se reiniciará y se embargo, dispongo de algunos mandos a distancia
instalará Google Apps. Dish Network 3.0 IR PVR. Estos se pueden conseguir
en Ebay por menos de10$. En mi opinión, estos son
mandos a distancia bastante resistentes, su tacto es de navegación y todos los botones numéricos del
muy bueno y cuentas con su cientes botones para mando a distancia. No permite enviar los códigos ‘*’,
poder hacer lo que necesitas. También son ‘#’, Volumen o Mute. Los códigos de Volumen y Mute
“programables”, ya que vienen con una lista de TVs y son relegados al código de TV y por lo tanto, solo
otros códigos de dispositivo permitiendo emular los puedo controlar el Volumen de TV con los botones, no
mandos a distancia del otro fabricante. con el Volumen de Android.

Fue bastante fácil encontrar el código para controlar Puesto que las “teclas numéricas” son en su gran
mi viejo televisor. Encender, subir volumen, bajar mayoría inútiles para un TV (a excepción de los
volumen y silenciar es todo lo que verdaderamente números de los canal), las reasigné en el remote.conf
necesitaba. Deseaba que “Input select” funcionase para realizar operaciones como son Home en
para poder cambiar los puertos HDMI, pero nada de Android, Subir volumen/Bajar volumen/Mute en
lo que probé hizo que ese botón funcionara. Android y Avance Rápido/Volver atrás.
Afortunadamente, el ODROID-C2 es el único Para entender cómo una señal de IR entrante llega a
dispositivo de entrada que tengo, así que no es
la aplicación correctamente, debes tener en cuenta
necesario cambiarlo. Si alguna vez coloco un segundo que hay 3 señales independientes involucradas:
dispositivo HDMI, posiblemente será necesario volver
a investigar hasta encontrar una solución viable. el código IR enviado por el mando a distancia

El primer origen de mi frustración fue encontrar un el KEYCODE de Linux, y

código de dispositivo que activase todos los botones el código ACTION de Android

con el protocolo correcto. El ODROID-C2 utiliza el chip


El truco está en asignar el código IR entrante al código
Amlogic S905 que contiene una interfaz para el
ACTION de Android correcto a través de un KEYCODE
receptor de infrarrojos. La instalación del sistema
de Linux, y esta conversión se realiza mediante dos
operativo Android de Hardkernel contiene el driver
archivos independientes en Android:
“amremote” integrado en el kernel (es decir, no se
carga como un módulo). Por lo que el driver /system/etc/remote.conf ­­ maps IR code to 
“amremote” solo reconoce el protocolo de infrarrojos Linux KEYCODE 
NEC. Los códigos IR en otros protocolos (R5 / R6 o /system/usr/keylayout/Vendor_0001_Product_0001
Sony) simplemente son ignorados por el driver .kl ­­ maps Linux KEYCODE to Android ACTION

“amremote”. Si desea saber más sobre Consumer IR,


En mi caso, ambos archivos requirieron tratamiento,
visita https://goo.gl/WLgtv9.
aunque procure limitar los cambios a la distribución
Dotado con una lista de unos cuantos cientos de de las teclas. Para modi car estos archivos, utilicé la
códigos, busqué un código de dispositivo de mando a aplicación Android Terminal Emulator, que me
distancia que enviara códigos NEC para todos los proporciona un intérprete de comandos “bash” y el
botones. Me llevé un chasco cuando descubrí que editor “vi”. Si no sabe usar el editor “vi”, puede copiar
muchos dispositivos compatibles con el mando a los archivos en /storage, usar la aplicación
distancia Dish Network solo enviaba códigos para un FileManager que está instalada y editarlos usando
conjunto limitado de botones. Me costó bastante esta App, y luego copiar de nuevo a la ubicación
encontrar uno que enviase códigos para los 5 /system. Más adelante me valgo de “vi” y de varios
botones de navegación (arriba, abajo, izquierda, comandos de Linux para hacer este trabajo.
derecha y centro). Muchos códigos sólo facilitarían 3
La primera tarea es cambiar el sistema de archivos de
opciones (arriba/abajo/centro o
/sistem de ReadOnly a ReadWrite para que podamos
izquierda/derecha/centro), o 4 o 5 de las opciones.
actualizar los archivos. Abre la aplicación Android
Finalmente encontré un reproductor de DVD
Terminal Emulator y escribe:
Memorex (código 709) que ofrecía las 5 direcciones
$ su ­  [98086.788285@0] remote: Wrong custom code is 
# mount ­o remount,rw /system 0x7c83ff00

El primer comando (su -) te otorga privilegios de Los últimos cuatro dígitos del número que aparece al
SuperUser. La primera vez que la uses aparecerá una nal del mensaje de registro log nos dicen qué tipo de
ventana emergente que te pregunta si esta aplicación mando a distancia es este (0x 00 en mi caso). El
(Android Terminal Emulator) siempre debe tener este remote.conf por defecto de Android Odroid busca el
privilegio. Yo respondí “Yes” y la hice permanente. Se código 0x4db2. No estoy seguro de cuál es la
supone que todos los comandos que se ejecuten se probabilidad de que cuentes con un mando a
cargarán con privilegios de SuperUser. Si abandonas distancia con ese código si no estás utilizando el
Android Terminal Emulator y regresas de nuevo, es mando a distancia disponible en HardKernel
posible que necesite ejecutar nuevamente el (https://goo.gl/yVLVLC). Si no tiene suerte, y el
comando “su -“. mando a distancia que estás utilizando transmite

El segundo comando cambiará el sistema de archivos 0x4db2, entonces verá algo más en dmesg. Si no ves
nada en dmesg, entonces es que no está usando un
de /system de ReadOnly a ReadWrite. A continuación,
debemos editar /system/etc/remote.conf para activar mando a distancia que transmite el protocolo NEC y
debe buscar otro mando a distancia (o código de
la depuración. La depuración nos permitirá
dispositivo).
determinar qué códigos estamos recibiendo. Cambia
“debug_enable” de “0” a “1” con vi y actívalo con En mi caso, aquí es donde empecé a buscar los
remotecfg: códigos del dispositivo Dish Network 3.0 IR
investigado el dispositivo adecuado. Con guré el
# vi /system/etc/remote.conf 
código del dispositivo en el mando a distancia y
# remotecfg /system/etc/remote.conf
presioné los botones para ver si obtenía las
Remotecfg lee el archivo remote.conf, el cual respuestas en dmesg. Probé muchos códigos hasta
analizará los contenidos y luego enviará la que estuve lo su cientemente cerca de mis
información al software amremote en el kernel Linux. necesidades con el código 709 de DVD Memorex, que
Esto normalmente se hace una vez en el arranque tal transmite el tipo de mando a distancia 0x 00.
y como se especi ca en /system/init.odroidc2.rc. Esto El extenso número HEX 0x7c83 00 es en realidad 2
supone una gran ventaja, ya que podemos hacer
trozos de información. Descomponiéndolos en bytes:
cambios y luego activarlos de inmediato. 7c 83 00, deberías observar que los primeros 2
Con debug_enable jado en “1”, cualquier mando a bytes son complementarios entre sí (es decir,
distancia que envíe un protocolo NEC será detectado, 01111100 -> 10000011 – ceros y unos invertidos). De
y el software amremote registrará los errores en el manera similar, los 3º / 4º bytes son complementarios
registro log del sistema. Usaremos “dmesg” para ver en muchos casos (pero no en todos). La “verdadera”
el registro log del sistema. Prueba el cambio usando información está en los bytes 2 y 3/4 (0x83 es el
estos comandos: botón, 0x 00 es el tipo de mando a distancia).

$ dmesg ­c > /dev/null # clear previous log  En remote.conf, ahora es el momento de con gurar el


contents  tipo de mando a distancia que estás utilizando en
$ while sleep 1; do dmesg; dmesg ­c >  remote.conf con gurando la entrada para
/dev/null; done “factory_code” y reemplazando el XXXX con el código
de 4 dígitos que aparece arriba (ajuste el mío en
Con el modo “while sleep” activado, al presionar un
0x 000001):
botón en el mando a distancia debería aparecer algo
como esto: $ vi remote.conf 
$ remotecfg /system/etc/remote.conf 
$ while sleep 1;do dmesg;dmesg ­c >  VOLUME_DOWN — key 114
/dev/null;done VOLUME_MUTE — key 113
MEDIA_REWIND — key 121
Tras introducir estos comandos, deberías presionar
MEDIA_FAST_FORWARD — key 120
nuevamente los botones y ocurrirá una de estas dos
APP_SWITCH — NO KEY available!
cosas: ver un error que indique que el botón del
mando a distancia no está asignado a nada, o ver
¡El último, “APP_SWITCH” no está en
información sobre la asignación del botón.
Vendor_0001_Product_0001.kl! Me llevó 2 horas
[101131.973324@0] remote: scancode is  solucionar el tema. Me apropié de una tecla (158, que
0x00c5,invalid key is 0x0000.  anteriormente era BACK) actualizando
or 
Vendor_0001_Product_0001.kl con vi y cambiando
[101214.803355@0] remote: press ircode = 0xc5 
“BACK” a “APP_SWITCH” en la línea correspondiente.
[101214.903456@0] remote: scancode = 
0x74,maptable = 0,code:0x3ac5ff00  Ahora pégalo todo junto actualizando remote.conf en
[101214.903492@0]  la sección key_begin/key_end y posiblemente en la
[101214.993555@0] remote: release ircode 0xc5  sección repeat_key_begin/repeat_key_end. No suelo
[101214.997312@0] remote: scancode = 
valerme de las repeticiones de teclas, de modo que
0x74,maptable = 0,code:0x00000000
mi sección repeat_key_begin/repeat_key_end está
La primera sucede porque el botón 0xc5 no está en vacía. Tampoco suelo apoyar en la sección
remote.cfg. La segunda ocurre cuando el botón se mouse_begin/mouse_end.
encuentra en remote.cfg. Si el mando a distancia que Mi archivo remote.conf resultante es así:
estás utilizando envía códigos similares a los del
work_mode = 0 
mando a distancia de Hardkernel, verás el segundo
repeat_enable = 1 
tipo de mensaje.
repeat_delay = 40 
Aquí es donde empieza la diversión. Debes presionar repeat_period = 39 
cada botón y ver qué código envía, y tenerlo en release_delay = 121 

cuenta. Luego debes averiguar qué quieres que haga debug_enable = 0 


factory_code = 0xff000001 
y encontrar la acción Android en el archivo
left_key_scancode = 0x88 
Vendor_0001_Product_0001.kl que corresponda a la
right_key_scancode = 0xc8 
acción que deseas que haga el botón. Finalmente, up_key_scancode = 0xc9 
debes conseguir el KEYCODE de Linux desde down_key_scancode = 0xd7 
Vendor_0001_Product_0001.kl que se usará para ok_key_scancode = 0x8b 
unirlo todo. mouse_begin 
mouse_end 
Estas son las acciones de ANDROID que he usado: key_begin 
0xc5 116 # Power 
POWER — key 116 0x8b 97 # Center 
HOME — key 102 0xc9 103 # Up 
BACK — key 15 0xd7 108 # down 

MENU — key 139 0x88 105 # Left 


0xc8 106 # Right 
DPAD_CENTER — key 97
0x93 15  # cancel 
DPAD_LEFT 1 — key 105
0x93 15  # Info 
DPAD_RIGHT — key 106 0x81 114   # 1 ­­ becomes VOLUME DOWN 
DPAD_UP — key 103 0x83 113   # 2 ­­ becomes MUTE 
DPAD_DOWN — key 108 0xc1 115   # 3 ­­ becomes VOLUME UP 
0x82 121   # 4 ­­ becomes REWIND 
VOLUME_UP — key 115
0x80 139   # 5 ­­ becomes MENU 
0xc0 120   # 6 ­­ becomes FF  seguro de tener todos los botones con gurados
0x8d 8     # 7  correctamente, pero el sistema es funcional y
0x8f 158   # 8 ­­ APP SWITCH 
amigable.
0xcd 10  # 9 
0x8c 102  # 0 ­­ becomes HOME  Realicé una copia de seguridad de
key_end  Vendor_0001_Product_0001.kl y remote.conf
repeat_key_begin  copiándolos en /storage/emulated/0/Download y me
repeat_key_end
aseguré de que estuvieran guardados en el sistema
de archivos /system. Si actualizas Android, es posible
Ten en cuenta que también apagué “debug_enable”
que necesites restaurar estos archivos o tu mando a
jándolo en cero. Después de actualizar remote.conf
distancia no funcionará. Espero que todo esto le sea
nuevamente, escribe el siguiente comando:
útil al menos a una persona. Probablemente
$ remotecfg /system/etc/remote.conf necesitare sacarlo a la luz en el futuro para recordar
lo que hice en su momento. Para comentarios,
Ahora es el momento de probar el mando a distancia.
preguntas y sugerencias, visita el post original del foro
Deberías probarlo con cada aplicación, ya que ésta
en https://goo.gl/6sc8GU.
puede reaccionar de forma diferente a un código en
particular o ignorarlo por completo. Todavía no estoy
Ambilight en ODROID-C2 Usando LibreElec: Adaptando
Ambilight al ODROID-C2
 January 1, 2018  By @rokapet  ODROID-C2, Mecaniqueo

En este artículo, me gustaría compartir cómo llegué a hechas para usarse con la Raspberry Pi, necesitaba
montar un sistema Ambilight funcional con un adaptarlas al ODROID-C2.
ODROID-C2 y LibreElec. Previamente localicé otras
Raspberry Pi 3 Mediacenter + Hyperion Ambilight +
guías que se centraban principalmente en la NO soldering: https://goo.gl/q8q6PK Amblight
Raspberry Pi, así que tuve que recopilar información
project/guide – Hyperion – WS2801/ WS2812B /
usando Google y recurrir al método ensayo y error. APA102: https://goo.gl/CEgT1U
El diseño de alto nivel utiliza Hyperion instalado como Resulta que mi con guración está afectada por un
complemento para Kodi, desde el repositorio de
error bastante molesto, el cual se describe aquí:
LibreElec instalar HyperCon no es posible debido a https://goo.gl/HUwa2k
que la CPU es desconocida, y un Arduino para
La reproducción de video empieza a ralentizarse
controlar los LED usando la librería FastLED. Arduino
transcurrido un periodo de tiempo arbitrario (entre
está conectado al ODROID-C2 a través de un cable
30-70 minutos en mi caso) mientras que el audio
USB (el Arduino tiene un conversor USB a serie). Mi TV
continúa reproduciéndose a una velocidad adecuada,
es FullHD, así que no necesite recurrir a la magia (es
lo que provoca que el audio y el video no estén
decir, hacer overclock de RAM y cosas así) para el 4K.
sincronizados. Después de 30-60 segundos se
Utilicé las siguientes guías como base para el montaje
produce una pequeña pausa y salto, el audio y el
y la con guración. Pero como estas guías están
video vuelven a sincronizarse, hasta que vuelva a
suceder a los 30-70 minutos.
En el foro de LibreElec aún no está resuelto este Herramienta HyperCon para Hyperion
tema, ya que el problema está resultando bastante (https://goo.gl/7F5fDc)

complicado de solucionar. Si alguien tiene un sistema IDE Arduino (https://goo.gl/wqP28G)

en funcionamiento (ODROID-C2 con LE8/Kodi 17 con Librería FastLED para Arduino (descargar ZIP – –

Hyperion) que no se vea afectado por este error, ¡Que https://github.com/FastLED/FastLED)

no dude en contribuir con el archivo de con guración Esquema de control (script) para Arduino
(https://pastebin.com/2L9ZBhYe)
de Hyperion! Tengo pensado retocar la con guración
de Hyperion para ver si se puede hacer algo, pero
  
esto me puede llevar bastante tiempo
#include "FastLED.h" 
Hardware  
// How many leds in your strip? 
ODROID-C2 mas carcasa y fuente de alimentación de #define NUM_LEDS 92 
Hardkernel, que me costó alrededor de 72€ cuando lo  
comprés en https://www.pollin.de el pasado año // For led chips like Neopixels, which have a 
Tarjeta MicroSD Kingston 16GB Clase 10, que cuesta data line, ground, and power, you just 
alrededor de 8€ en eBay // need to define DATA_PIN. For led chipsets 

Clon chino de la placa Arduino Uno R3 más carcasa y that are SPI based (four wires ­ data, clock, 

cable USB, que cuesta alrededor de 8,50€ en eBay // ground, and power), like the LPD8806 define 


both DATA_PIN and CLOCK_PIN 
Tira LED RGB WS2812B de 3 pin, 30 LEDs por metro,
#define DATA_PIN 12 
5m de rollo, que costó alrededor de 13.50€ en eBay
//#define CLOCK_PIN 13 
Fuente de alimentación 5V 10A. Tenía una por ahí, así
 
que no me supuso ningún coste, pero puedes
#define COLOR_ORDER GRB 
encontrar una por unos 10-20€ en eBay o Aliexpress
 
Clavija de alimentación DIN, que cuesta alrededor de // Adalight sends a "Magic Word" (defined in 
1,50€ en eBay /etc/boblight.conf) before sending the pixel 
Cables conector JST macho y hembra de 3 pines, que data 
cuestan aproximadamente 1,50€ en eBay 5 piezas uint8_t prefix[] = {'A', 'd', 'a'}, hi, lo, 
Conectores de 3 pines de 10 mm para el conjunto chk, i; 
WS2812, que cuestan aproximadamente 2€ en eBay 5  
piezas // Baudrate, higher rate allows faster refresh 
rate and more LEDs (defined in 
Cables jumper macho Dupont, que cuestan
/etc/boblight.conf) 
aproximadamente 1€ en eBay 40 piezas
#define serialRate 115200 
Tubos termo-contraíbles, que cuestan
 
aproximadamente 1€ en eBay 70 piezas
// Define the array of leds 
Resistencia de 500 ohmios o resistencias de 2x1K CRGB leds[NUM_LEDS]; 
ohmmios cableadas en paralelo  
Cable HDMI void setup() { 
Soldador eléctrico para soldar los conectores y los  // Uncomment/edit one of the following lines 
cables for your leds arrangement. 
 // FastLED.addLeds<TM1803, DATA_PIN, RGB>
(leds, NUM_LEDS); 
Software
 // FastLED.addLeds<TM1804, DATA_PIN, RGB>
(leds, NUM_LEDS); 
Imagen LibreElec 8.2.1 MR para ODROID-C2
 // FastLED.addLeds<TM1809, DATA_PIN, RGB>
descargada desde https://libreelec.tv
(leds, NUM_LEDS); 
Complemento Hyperion para Kodi del repositorio de
 // FastLED.addLeds<WS2811, DATA_PIN, RGB>
LibreElec
(leds, NUM_LEDS); 
 // FastLED.addLeds<WS2812, DATA_PIN, RGB>
(leds, NUM_LEDS);   
 FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds,  // Hi, Lo, Checksum 
NUM_LEDS);   
 // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds,  while (!Serial.available()) ;; 
NUM_LEDS);   hi=Serial.read(); 
 // FastLED.addLeds<UCS1903, DATA_PIN, RGB>  while (!Serial.available()) ;; 
(leds, NUM_LEDS);   lo=Serial.read(); 
 // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>  while (!Serial.available()) ;; 
(leds, NUM_LEDS);   chk=Serial.read(); 
 // FastLED.addLeds<GW6205, DATA_PIN, RGB>  
(leds, NUM_LEDS);  // if checksum does not match go back to wait 
 // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>  if (chk != (hi ^ lo ^ 0x55)) 
(leds, NUM_LEDS);   { 
    i=0; 
 // FastLED.addLeds<WS2801, RGB>(leds,    goto waitLoop; 
NUM_LEDS);   } 
 // FastLED.addLeds<SM16716, RGB>(leds,   
NUM_LEDS);  memset(leds, 0, NUM_LEDS * sizeof(struct 
 // FastLED.addLeds<LPD8806, RGB>(leds,  CRGB)); 
NUM_LEDS);  // read the transmission data and set LED 
  values 
 // FastLED.addLeds<WS2801, DATA_PIN,  for (uint8_t i = 0; i < NUM_LEDS; i++) { byte 
CLOCK_PIN, RGB>(leds, NUM_LEDS);  r, g, b; while(!Serial.available()); r = 
 // FastLED.addLeds<SM16716, DATA_PIN,  Serial.read(); while(!Serial.available()); g = 
CLOCK_PIN, RGB>(leds, NUM_LEDS);  Serial.read(); while(!Serial.available()); b = 
 // FastLED.addLeds<LPD8806, DATA_PIN,  Serial.read(); leds[i].r = r; leds[i].g = g; 
CLOCK_PIN, RGB>(leds, NUM_LEDS);  leds[i].b = b; } // shows new values 
  FastLED.show(); }
 // initial RGB flash 
 LEDS.showColor(CRGB(255, 0, 0));  Montaje de la tira LED
 delay(500); 
La tira LED que compré ya tenía un conector hembra
 LEDS.showColor(CRGB(0, 255, 0)); 
 delay(500); 
JST de 3 pines integrado en el extremo de inicio, más
 LEDS.showColor(CRGB(0, 0, 255));  dos cables adicionales (sin enchufe) para 5V y GND.
 delay(500);  Soldé los dos últimos cables a la toma de corriente
 LEDS.showColor(CRGB(0, 0, 0));  DIN para poder alimentar los LED desde la fuente de
  alimentación. ¡Asegúrate de usar una clavija que sea
 Serial.begin(serialRate); 
compatible con tu fuente de alimentación!
 Serial.print("Ada 
"); // Send "Magic Word" string to host  Cogí un cable conector macho JST y soldé cables
}  Dupont al extremo de los cables GND y DATA para
  poder conectarlos a los pines de la placa Arduino. El
void loop() {  cable de 5V no se utiliza aquí, ya que no está
 // wait for first byte of Magic Word 
conectado, de modo que se puede cortar y/o aislar.
 for(i = 0; i < sizeof prefix; ++i) { 
Soldé la resistencia de 500 ohmios entre el cable
 waitLoop: while (!Serial.available()) ;; 
 // Check next byte in Magic Word  DATA y el cable Dupont para que las señales de
 if(prefix[i] == Serial.read()) continue;  control puedan atravesarlo. Todos los puntos de
 // otherwise, start over  soldadura han sido asegurados con tubos termo-
 i = 0;  contraíbles.
 goto waitLoop; 

Inicié HyperCon en mi ordenador y plani qué la de LED en la la n. ° 9. Luego cargué el esquema en la
con guración y el diseño del LED en el televisor, placa Arduino, que solo tardó unos segundos.
asegurándome de medir las dimensiones de mi TV.
Montaje
Estudie otras opciones de con guración en el sitio de
la Wiki de Hyperion y guardé la con guración LED en Utilicé adhesivo en la parte posterior de la tira LED

el archivo hyperion.con g.json. Luego utilicé los para pegarlo a la parte posterior de mi televisor.
números LED calculados para cortar la tira en piezas Necesite algo de adhesivo adicional en algunas zonas

con el tamaño adecuado y utilicé los cables del para que se adhiriera con rmeza. Desconecté la
conector de 3 pines para unirlos entre sí. Los cables placa Arduino de mi PC y la conecté a uno de los

del conector de 3 pines son necesarios para las puertos USB del ODROID-C2. Conecté el jumper del
esquinas del televisor, ya que la tira de LED por sí sola cable Dupont soldado al cable GND de la tira al pin

no se puede doblar para llegar a los 90 grados. GND y el jumper del cable Dupont soldado al cable
DATA de la tira al pin 12 del Arduino. Finalmente,
Ten en cuenta que estas tiras LED tienen una
conecté la fuente de alimentación a la clavija de
dirección. Solo el extremo inicial se puede usar para
potencia soldada al nal de la tira.
los controles de entrada y los distintos LED se
direccionan uno después del otro. Busqué la marca Con guración del software
“DI (Entrada de datos) en la tira, cerca de los LEDs. El LibreElec cargó el módulo CH341 automáticamente al
otro extremo tiene marcado “DO (Data Out). Puedes conectar la placa Arduino a USB, y apareció el
usar Google para localizar las especi caciones dispositivo /dev/ttyUSB0. Sin embargo, esto podría
WS2812b. ser diferente en tu caso Instalé el complemento
Mi experiencia me dice que los conectores de 3 pines Hyperion bajo la interfaz de Kodi, desde el repositorio
no pueden sujetar la tira con demasiada fuerza, así de LibreElec. Abrí el archivo hypercon.con g.json
que ten cuidado a la hora de montarla en la parte previamente guardado en mi ordenador y lo edité en
posterior de tu televisor. Si tiene experiencia con la 3 lugares: device, frame-grabber y e ects. La
soldadura de precisión, puede que sea mejor soldar actualización de la carpeta de efectos es necesario
los cables para conectar las partes de la tira en lugar porque es diferente cuando Hyperion es instalado
de utilizar los conectores de 3 pines. como complemento, en lugar de instalarlo con
HyperCon.
Instalé LibreElec en la tarjeta micro SD siguiendo las
instrucciones de https://libreelec.tv, luego la monté el Ten en cuenta que en otras guías se menciona usar
ODROID-C2 y con guré Kodi a mi gusto. Entre a 100000, 200000, etc. para la tasa de baudios. En mi
Settings -> Services -> Control in Kodi interface, y caso, esto derivo en un repetitivo mensaje de error
habilité tanto “Allow remote control from applications “Unable to open RS232 device (IO Exception (25):
on this system” como “Allow remote control from Inappropriate ioctl for device” en el registro log de
applications on other systems”. Instalé IDE Arduino en Hyperion. Cambiar a una velocidad de 115200
mi ordenador, luego extraje el archivo ZIP de la baudios hizo que el problema se solucionara.
librería FastLed en una subcarpeta independiente ¡Asegúrate de observar el orden del color invertido
bajo la carpeta libraries. Cuando inicié IDE Arduino “GRB”!
después, la librería FastLED aparecía disponible en el
// DEVICE CONFIGURATION 
menú Sketch -> Available libraries. "device" : 
Conecté la placa Arduino a mi ordenador con el cable  { 
 "name" : "MyHyperionConfig", 
USB. Copié el esquema en el IDE Arduino, jé el
 "type" : "adalight", 
número de LED de la tira en la la n. ° 4 (tendrá este
 "output" : "/dev/ttyUSB0", 
número de HyperCon) y el pin utilizado para el control
 "rate" : 115200, 
 "delayAfterConnect" : 0, 
 "colorOrder" : "grb"  ts" 
 },   ] 
   },
"amlgrabber" : 
 {  Cargué mi archivo hyperion.con g.json actualizado en
 "width" : 64,  la carpeta
 "height" : 64,  /storage/.kodi/userdata/addon_data/service.hyperion
 "frequency_Hz" : 20.0,  / en LibreElec. Esta es la carpeta donde el
 "priority" : 880 
complemento Hyperion busca el archivo de
 }, 
con guración. El recurso compartido UserData se
 "framegrabber" : 
 {  puede utilizar para la carga si el servidor SMB está
 "width" : 64,  habilitado. Luego reinicié LibreElec y, fue entonces
 "height" : 64,  cuando el sistema Ambilight funcionó correctamente.
 "frequency_Hz" : 10.0,  Espero no haber olvidado nada y que a alguien le sea
 "priority" : 890  útil esta información. ¡Cualquier comentario o
 }, 
sugerencia para mejorar será bienvenida!
 
"effects" :  Para comentarios, preguntas y sugerencias, visita el
 {  post original del foro en
 "paths" :  https://forum.odroid.com/viewtopic.php?
 [ 
f=144&t=29334.
 "/storage/.kodi/addons/service.hyperion/effec
Divirtiéndonos con GPIO en Android
 January 1, 2018  By Justin Lee  Android, Mecaniqueo

El ODROID-C1/C1+, ODROID-C2 y ODROID-XU4 tienen Puedes encontrar la ubicación del SDK de Android
pines GPIO (Entrada/Salida de Propósito General) que bajo este menú (File → Settings → Appearance &
permiten controlar dispositivos externos a través de Behavior → System Settings → Android SDK)
software. Para acceder correctamente al puerto GPIO,
debes instalar la imagen Android Marshmallow
versión 2.8 o superior en el ODROID-C2, la imagen
Android KitKat versión 3.2 o superior en el ODROID-
C1/C1+, y la imagen Android KitKat versión 6.0 o
superior, o la versión Android Nougat versión 1.3
20171214 o superior en el ODROID-XU4.

Esta  WiKi explica cómo hacer una app Android que


permita acceder a los puertos GPIO. Necesitas
instalar Google Android Studio en tu PC host. Añade
en primer lugar NDK y las herramientas necesarias
antes de empezar con los pasos que se describen a Figura 1 – Ubicación del SDK de Android
continuación. Nosotros probamos estos pasos en
Tras editar el archivo bashrc, debes iniciar sesión
Android Studio 2.3 y NDK R14.
nuevamente o escribir “source ~/.bashrc” en la línea
Ubuntu/Linux de comando. A continuación, descarga la librería
NDK  WiringPi y el código fuente de la aplicación  Windows
desde GitHub. En Windows, con gura la RUTA de entorno para que
apunte a la ruta de la carpeta NDK y luego reinicia
ODROID-C1+/C2
Windows.
$ sudo apt install git 
$ git clone 
https://github.com/codewalkerster/example­
wiringPi ­b odroid­c

ODROID-XU4

$ sudo apt install git 
$ git clone 
https://github.com/codewalkerster/example­
wiringPi ­b odroid­xu

Ejecuta Android Studio y abre el proyecto descargado.

Figura 3: Con gurando la ruta de entorno para que


apunte a la ruta de la carpeta NDK

Figura 2 – Abriendo el proyecto wiringPi

Compilar el proyecto para crear un paquete apk


Selecciona Build -> Make Project desde menú. Verás
un par de mensajes de error y deberás hacer clic en
las siguientes opciones para completar el proceso de
compilación, el cual generará un archivo APK para Figura 4 – Con gurando la ruta de entorno para que
apunte a la ruta de la carpeta NDK
que lo ejecutes en tu ODROID:

Instalar la(s) plataforma(s) que faltan y sincronizar el


proyecto
Instalar Build Tools 25.0.2 y sincronizar el proyecto
Figura 5: Con gurando la ruta de entorno para que
apunte a la ruta de la carpeta NDK

Después, instala el programa cliente Git


desde  https://git-for-windows.github.io/, y clona el
proyecto wiringPi, tal y como se muestra en la Figura
6.

Figura 8 – Instalando el SDK

Figura 6 – Clonando el proyecto

El proyecto está disponible


en  https://github.com/codewalkerster/example-
wiringPi. Selecciona origin/odroid-c o origin/odroid-
xu.

Figura 9 – Instalando el SDK

Características del proyecto de ejemplo


Puedes leer el valor del conversor de señal analógica
a digital (ADC) y mostrar el nivel de voltaje con 19 LED
en la salida de GPIO. Puedes ver un video de
demostración
en https://youtu.be/lGqyhvd3q9U y https://youtu.be
/lGqyhvd3q9U.
Figura 7 – Veri cando la rama de GitHub

Luego, instala el NDK seleccionando Tools -> Android -


> SDK Manager en el menú.

Figura 10 – Lectura del valor ADC en ODROID-C1+/C2


Figura 11 – Lectura del valor ADC en el ODROID-XU4

PWM
La Figura 12 muestra un ejemplo básico de control del Figura 13 – La placa meteorológica de Hardkernel mide
PWM. Puede escoger el número de salidas PWM (1 o las estadísticas medioambientales
2), así como controlar la frecuencia y el índice de
trabajo.

Figura 14 – La placa meteorológica de Hardkernel mide


las estadísticas medioambientales

Figura 12 – Ejemplo básico de control PWM

Ejemplo de noti cador de Gmail


Este es un proyecto muy divertido y útil que utiliza el
puerto PWM. Cuando te encuentras visualizando
videos o jugando a juegos, puedes pasar por alto la
noti cación de un correo electrónico o mensaje
importante. El indicador es accionado por un
servomotor que está conectado a un pin PWM en un
puerto GPIO de 40 pines. El código puede descargarse Figura 15 – Un software demo para enviar y recibir
desde  https://github.com/codewalkerster/GMailNot caracteres a través de la interfaz UART
i er. Se puede ver una demo del proyecto
en https://youtu.be/Vvq77w87RWQ.

I2C
La Figura 15 muestra un ejemplo de código para
acceder a nuestra placa meteorológica para medir la
temperatura, la humedad, la presión atmosférica, la
altitud y la intensidad de luz visible/invisible a través
de la interfaz I2C.
#fatload mmc 0:1 ${loadaddr} Image 
booti ${loadaddr} ­ ${dtbaddr}

Después de editarlo

movi read dtb 0 ${dtbaddr} 
# load kernel from vat or boot partition. 
#movi read boot 0 ${loadaddr} 
fatload mmc 0:1 ${loadaddr} Image 
booti ${loadaddr} ­ ${dtbaddr}

Figura 16 – Software demo para acceder al sensor de Carga la imagen del kernel desde la partición vfat i2c.
temperatura DS18S20 que se comunica con el protocolo
Si no puede encontrar el comando “fatload”, elimina
1-wire
/storage/internal/boot.ini y reinicie el sistema. Para
Kernel para I2C comentarios, preguntas y sugerencias, visita el
Abra la aplicación File Manager y edita el archivo artículo original de la Wiki
/storage/internal/boot.ini tal y como se muestra a en https://wiki.odroid.com/odroid-
continuación: c2/application_note/gpio/enhancement_40pins_on_
android.
Original

movi read dtb 0 ${dtbaddr} 
# load kernel from vat or boot partition. 
movi read boot 0 ${loadaddr} 
UART Daisy Chain: Depuración Avanzada con el ODROID-C2
 January 1, 2018  By Justin Lee  ODROID-C2, Mecaniqueo

Este artículo explica cómo usar múltiples puertos


UART en ODROID-C2 con el sistema operativo
Android. Utilizaremos 3 puertos UART y crearemos un
ujo de datos llamado Daisy Chain. El ujo de datos
básico parte desde TX del UART 1 hacia el RX del UART
2 y luego va a TX UART 2, que enviará los datos a RX
del UART 3. Una vez que RX del UART 3 recibe los
datos, lo envía desde 7. Para esto, necesitas utilizar la
última versión de Android 6.0.1 versión 3.6 o superior
y así poder usar 3 puertos UART de forma simultánea.

Figura 1 – Esquema con anotaciones de un ODROID-C2

Hardware
Antes de empezar, tienes que hacerte con algunas
cosas. Primero, descarga el diagrama Fritzing
desde  https://goo.gl/Q1YhP3. Comprueba el diseño
de los pines J2 2×20 en  https://goo.gl/44XGpB.
PUERTO PIN b/arch/arm64/boot/dts/meson64_odroidc2.dts 
 index e6a25b0..fd41552 100755 
TX RX  ­­­ 
a/arch/arm64/boot/dts/meson64_odroidc2.dts 
UART_A (ttyS1) 8 10  +++ 

UART_B (ttyS2) 3 5 b/arch/arm64/boot/dts/meson64_odroidc2.dts 


 @@ ­31,6 +31,8 @@ 
UART_C (ttyS3) 32 26
aliases { 
 serial0 = &uart_AO; 
Software
 serial1 = &uart_A; 
Necesitas modi car el archivo de Árbol del  + serial2 = &uart_B; 
Dispositivos para habilitar UART_B (ttyS2) y UART_C  + serial3 = &uart_C; 
(ttyS3) ya que Android los usa para otros nes, como }; 
 
GPIO/I2C.
gpu_dvfs_tbl: gpu_dvfs_tbl { 
Deshabilitar I2C  @@ ­459,6 +461,32 @@ 
 pinctrl­0 = <&a_uart_pins>; 
 $ diff ­­git  }; 
a/arch/arm64/boot/dts/meson64_odroidc2.dts   
b/arch/arm64/boot/dts/meson64_odroidc2.dts  + uart_B: serial@c11084dc { 
 index e6a25b0..db09b04 100755   + compatible = "amlogic, meson­uart"; 
 ­­­   + reg = <0x0 0xc11084dc 0x0 0x18>; 
a/arch/arm64/boot/dts/meson64_odroidc2.dts   + interrupts = <0 75 1>; 
 +++   + status = "okay"; 
b/arch/arm64/boot/dts/meson64_odroidc2.dts   + clocks = <&clock CLK_XTAL>; 
 @@ ­813,18 +813,6 @@   + clock­names = "clk_uart"; 
   + fifosize = < 64 >; 
};   + pinctrl­names = "default"; 
   + pinctrl­0 = <&b_uart_pins>; 
­&i2c_a {   + resets = <&clock GCLK_IDX_UART1>; 
 ­ status = "okay";   + }; 
 ­   + 
 ­ /* Hardkernel I2C RTC */   + uart_C: serial@c1108700 { 
 ­ pcf8563: pcf8563@51 {   + compatible = "amlogic, meson­uart"; 
 ­ status = "disabled";   + reg = <0x0 0xc1108700 0x0 0x14>; 
 ­ compatible = "nxp,pcf8563";   + interrupts = <0 93 1>; 
 ­ reg = <0x51>;   + status = "okay"; 
 ­ #clock­cells = <0>;   + clocks = <&clock CLK_XTAL>; 
 ­ };   + clock­names = "clk_uart"; 
 ­};   + fifosize = < 64 >; 
 ­   + pinctrl­names = "default"; 
&i2c_b {   + pinctrl­0 = <&c_uart_pins>; 
 status = "okay";  + resets = <&clock GCLK_IDX_UART2>; 
+ }; 
Añadir las de niciones UART_B y UART_C + 
El archivo canvas { 
 compatible = "amlogic, meson, canvas"; 
kernel/arch/arm64/boot/dts/meson64_odroidc2.dts
 dev_name = "amlogic­canvas";
se puede descargar desde https://goo.gl/Y7c5Wr, tal
y como se muestra a continuación:
Compilar dts hacia dtb
$ diff ­­git 
a/arch/arm64/boot/dts/meson64_odroidc2.dts 
El archivo Meson64_odroidc2.dtd se puede descargar arch/arm64/include/generated/asm/kmap_types.h 

desde https://goo.gl/qha1vx, tal y como se muestra a  WRAP 


arch/arm64/include/generated/asm/kvm_para.h 
continuación:
 WRAP arch/arm64/include/generated/asm/local.h 
$ make odroidc2_[i2c_]defconfig   WRAP 
 KBUILD_CFLAGS_MODULE:­DMODULE  arch/arm64/include/generated/asm/local64.h 
#   WRAP arch/arm64/include/generated/asm/mman.h 
# configuration written to .config   WRAP 
#  arch/arm64/include/generated/asm/msgbuf.h 
   WRAP arch/arm64/include/generated/asm/mutex.h 
#### make completed successfully ####   WRAP arch/arm64/include/generated/asm/pci.h 
   WRAP arch/arm64/include/generated/asm/poll.h 
[~/projects/c2/marshmallow/kernel]$ make dtbs   WRAP 
 KBUILD_CFLAGS_MODULE:­DMODULE  arch/arm64/include/generated/asm/posix_types.h 
 KBUILD_CFLAGS_MODULE:­DMODULE   WRAP 
 scripts/kconfig/conf ­­silentoldconfig  arch/arm64/include/generated/asm/resource.h 
Kconfig   WRAP 
 KBUILD_CFLAGS_MODULE:­DMODULE  arch/arm64/include/generated/asm/scatterlist.h 
 WRAP arch/arm64/include/generated/asm/bug.h   WRAP 
 WRAP arch/arm64/include/generated/asm/bugs.h  arch/arm64/include/generated/asm/sections.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/checksum.h  arch/arm64/include/generated/asm/segment.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/clkdev.h  arch/arm64/include/generated/asm/sembuf.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/cputime.h  arch/arm64/include/generated/asm/serial.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/current.h  arch/arm64/include/generated/asm/shmbuf.h 
 WRAP arch/arm64/include/generated/asm/delay.h   WRAP arch/arm64/include/generated/asm/simd.h 
 WRAP arch/arm64/include/generated/asm/div64.h   WRAP arch/arm64/include/generated/asm/sizes.h 
 WRAP arch/arm64/include/generated/asm/dma.h   WRAP 
 WRAP  arch/arm64/include/generated/asm/socket.h 
arch/arm64/include/generated/asm/emergency­  WRAP 
restart.h  arch/arm64/include/generated/asm/sockios.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/early_ioremap arch/arm64/include/generated/asm/switch_to.h 
.h   WRAP arch/arm64/include/generated/asm/swab.h 
 WRAP arch/arm64/include/generated/asm/errno.h   WRAP 
 WRAP  arch/arm64/include/generated/asm/termbits.h 
arch/arm64/include/generated/asm/ftrace.h   WRAP 
 WRAP  arch/arm64/include/generated/asm/termios.h 
arch/arm64/include/generated/asm/hw_irq.h   WRAP 
 WRAP arch/arm64/include/generated/asm/ioctl.h  arch/arm64/include/generated/asm/topology.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/ioctls.h  arch/arm64/include/generated/asm/trace_clock.h 
 WRAP   WRAP arch/arm64/include/generated/asm/types.h 
arch/arm64/include/generated/asm/ipcbuf.h   WRAP 
 WRAP  arch/arm64/include/generated/asm/unaligned.h 
arch/arm64/include/generated/asm/irq_regs.h   WRAP arch/arm64/include/generated/asm/user.h 
 WRAP   WRAP arch/arm64/include/generated/asm/vga.h 
arch/arm64/include/generated/asm/kdebug.h   WRAP arch/arm64/include/generated/asm/xor.h 
 WRAP   WRAP 
arch/arm64/include/generated/asm/preempt.h 
$ sudo fastboot flash dtb  
 WRAP arch/arm64/include/generated/asm/hash.h 
 out/target/product/odroidc2/obj/KERNEL_OBJ/ar
 WRAP 
ch/arm64/boot/dts/meson64_odroidc2.dtb
arch/arm64/include/generated/uapi/asm/kvm_para
.h  Tienes que editar el archivo /storage/internal/boot.ini
 HOSTCC scripts/dtc/checks.o 
para cargar una imagen alternativa del Kernel. Existe
 HOSTCC scripts/dtc/data.o 
una imagen alternativa del kernel para usar los pines
 SHIPPED scripts/dtc/dtc­lexer.lex.c 
 SHIPPED scripts/dtc/dtc­parser.tab.h 
I2C con la función UART.
 HOSTCC scripts/dtc/dtc­lexer.lex.o 
# movi read boot 0 ${loadaddr} 
 SHIPPED scripts/dtc/dtc­parser.tab.c 
fatload mmc 0:1 ${loadaddr} Image_android
 HOSTCC scripts/dtc/dtc­parser.tab.o 
 HOSTCC scripts/dtc/dtc.o 
Editar ueventd.odroidc2.rc
 HOSTCC scripts/dtc/flattree.o 
 HOSTCC scripts/dtc/fstree.o  Cambia el permiso de ttyS2 y ttyS3 para el acceso del
 HOSTCC scripts/dtc/livetree.o  sistema.
 HOSTCC scripts/dtc/srcpos.o 
 HOSTCC scripts/dtc/treesource.o  shell@odroidc2:/ $ su 

 HOSTCC scripts/dtc/util.o  root@odroidc2:/ # mount ­o rw,remount / 

 HOSTLD scripts/dtc/dtc  [ 1243.002784@2] EXT4­fs (mmcblk0p2): re­

 CC scripts/mod/empty.o  mounted. Opts: (null) 

 HOSTCC scripts/mod/mk_elfconfig  root@odroidc2:/ # vi /ueueventd.odroidc2.rc 

 MKELF scripts/mod/elfconfig.h  ueventd.rc 

 CC scripts/mod/devicetable­offsets.s  root@odroidc2:/ # vi /ueventd.odroidc2.rc 

 GEN scripts/mod/devicetable­offsets.h   

 HOSTCC scripts/mod/file2alias.o  /dev/ttyS* 0666 system system

 HOSTCC scripts/mod/modpost.o 
 HOSTCC scripts/mod/sumversion.o  Con gurar el código de ejemplo de la app de
 HOSTLD scripts/mod/modpost  Android
 HOSTCC scripts/selinux/genheaders/genheaders  Descarga la librería de WiringPi NDK
 HOSTCC scripts/selinux/mdp/mdp  de  https://goo.gl/uuDeys, y el código fuente de la
 HOSTCC scripts/kallsyms 
aplicación desde GitHub en https://goo.gl/YNXTUn.
 HOSTCC scripts/pnmtologo 
 HOSTCC scripts/conmakehash  $ sudo apt install git 
 HOSTCC scripts/bin2c  $ git clone 
 HOSTCC scripts/recordmcount  https://github.com/codewalkerster/example­
 HOSTCC scripts/sortextable  wiringPi ­b odroid­c_3_uart
 DTC arch/arm64/boot/dts/meson64_odroidc2.dtb 
 Warning (reg_format): "reg" property in /spi­
gpio/spi­gpio@0 has invalid length (4 bytes) 
(#address­cells == 2, #size­cells == 1) 
 Warning (avoid_default_addr_size): Relying on 
default #address­cells value for /spi­
gpio/spi­gpio@0 
 Warning (avoid_default_addr_size): Relying on 
default #size­cells value for /spi­gpio/spi­
gpio@0 
 
#### make completed successfully (4 seconds) 
####

 Instalar el archivo dtb modi cado


Figura 4 – Resultados de la prueba UART conectado en
serie

Para comentarios, preguntas y sugerencias, visita el


Figura 2 – Conexión por cable de tres puertos UART post original en https://goo.gl/jteQuV.
conectados en serie

Figura 3 – Probando el UART conectado en serie


escribiendo una cadena de caracteres
Juegos Linux: Mech Warrior 2
 January 1, 2018  By Tobias Schaaf  Juegos, Linux

Uno de mis recuerdos más tiernos de la infancia es la y anime en torno al tema, Mech Warrior es una
serie de juegos Mech Warrior. Recuerdo pasar horas y producción occidental que no está basada en la
horas a mediados y nales de la década de 1990 y cultura mecha japonesa.
principios de la década de 2000 jugando a todos los
Mech Warrior está basado en el universo/franquicia
juegos de la serie que estaban disponibles en ese BattleTech de FASA Corporation. Los diferentes clanes
momento. Al jugar a este juego me viene a la
y la llamada “Inner Sphere” luchan entre sí por
memoria recuerdos de cómo controlaba el joystick y
conquistar territorios y el liderazgo. Aunque al nal
el teclado al mismo tiempo: con gurando el Mech
los clanes están destinados a fracasar, a menudo son
para optimizar mi arma, la refrigeración y la
los propios clanes los que deciden en los juegos.
armadura a su máxima capacidad; y sentir el enorme
Mech Warrior 2 no es diferente. En este caso luchas
contrabajo de fabricación propia, retumbando bajo
como Clan Jade Falcon o Clan Wolf.
mis pies cada vez que mi compañero apretaba el
gatillo de su joystick.

Para los que no lo conozcan, Mech Warrior es un


juego de simulación de combate sobre los llamados
“Mechs”, que son gigantes robot pilotados por un ser
humano. Estos pilotos se llaman “Mech Warriors”. Los
“Mechs”, también conocidos como Mechas, Gundams
o Sentinels, son bastante comunes en la cultura
japonesa. Aunque existe una gran cantidad de manga
Figura 1 – Menú de Mech Warrior 2 – Juega con Clan Jade
Falcon, Clan Wolf, o batallas simuladas

Mech Warrior 2 salió por primera vez para DOS, pero


nalmente fue exportado a Windows 95, PlayStation y Figura 3 – Mech Warrior 2 con resolución de 320×240

Sega Saturn. Puesto que fue relanzado un par de


veces, hay muchas versiones y complementos
disponibles. Se rumorea que hay hasta 38 versiones
diferentes de Mech Warrior 2, el juego fue bastante
popular y llego a impresionar bastante.

Lanzado en 1995, fue una obra maestra técnica para


su tiempo, contenía videos de movimiento completo,
grá cos 3D, resoluciones de hasta 1024 × 768 (más
altas que la mayoría de los juegos disponibles por
aquel entonces), una banda sonora CD y muchas más
cosas que hoy por hoy son muy corrientes pero que
en 1995 no lo eran tanto.
Figura 4 – Mech Warrior 2 con resolución 1024×768

La diferencia es bastante notable, hace que el juego


tenga un aspecto bastante decente incluso hoy en
día.

La versión de software de DOS, a pesar de tener una


resolución muy alta para la época, usaba solo unas
cuantas texturas, lo cual hacía que el mundo se viera
muy plano. Sin embargo, utilizaron una gran cantidad
de graduaciones de colores para crear la atmósfera,
Figura 2 – Distintas variables de combate para Mech incluso creandon un ciclo de noche y día con
Warrior 2 con opciones de trucos incluidas
diferentes graduaciones de color.
Por defecto, el juego tenía una resolución de 320 ×
También había una opción para activar “Chunky
240, que era la más común para los juegos DOS de
Explosions”, lo cual signi caba que cada vez que
esa época. Aunque también admite resoluciones de
explotaba algo, se lanzaban al aire trozos de basura y
640×480 y 1024×768.
de escombros, esto hacía que el juego pareciera más
realista.
pierna, podías inmovilizar al enemigo por completo.
Disparar a un brazo despojaba al enemigo de sus
principales armas. Si tienes suerte o tienes buena
puntería, incluso puedes disparar a la cabina del
Mech, matando al piloto sin in igir apenas daño al
propio Mech.

Esto también signi caba que tu propio Mech


necesitaba ser manejado con mucho cuidado. Si
perdías un brazo, y con él, la mayoría de tu
armamento, podía ser casi imposible continuar la
misión. También necesitabas gestionar la munición
para tus armas. Si te quedabas sin munición, las
Figura 5 – Graduación del color en Mech Warrior 2
armas no te servían para nada.

Si disponías de armas a base de energía que no


requerían ningún tipo de munición, debías asegurarte
de que tu Mech no se sobrecalentara, ya que las
armas basadas en energía producían mucho calor
cuando se disparaban. Para esto, disponías de
módulos de disipador de calor que se supone que
enfriaban tu Mech. Sin embargo, si algunas de tus
partes habían sido destruidas en combate, podías
perder los disipadores de calor y tu Mech se
sobrecalentaría más rápido. También existía la
posibilidad de recibir un disparo crítico que causara
que la munición explotase, dañando tu Mech desde el
Figura 6 – Graduación del color en Mech Warrior 2
interior.

El juego te permitía modi car tu Mech, limitado por


las misiones, el peso, y algunas veces por el espacio
del interior del propio Mech, ya que el
almacenamiento de cada componente requería una
cierta cantidad de espacio. La posibilidad de modi car
tu Mech fue una de las principales razones que hizo
que la serie Mech Warrior fuese tan popular por
aquel entonces.

Cada jugador podía adaptar el mech a su propio estilo


de juego, como escoger armas gigantescas donde con
un único disparo obtenías resultados devastadores,
Figura 7 – Algunas explosiones con restos volando por pero eran más lentas, lo cual hacía más difícil disparar
todos partes
al enemigo; con ar en armas basadas en energía que
Obviamente, la mayoría de los detalles grá cos se no requerían munición y por lo tanto nunca se
aplicaban a los propios Mechs, lo cual no solo les hizo agotaban, pero generaban bastante más calor; o
que se vieran bien, sino que también permitía que el coger una tonelada de armas y un saco lleno de
jugador apuntara mejor a ciertos puntos del enemigo municiones, sin preocuparte por el calor y
para paralizarlo. Por ejemplo, si disparabas a una simplemente disparar mientras te quedara munición .
Otras estrategias incluían el uso de misiles de largo Los controles de este juego pueden ser algo
alcance que podían derribar al enemigo incluso antes complicados, ya que tu personaje tiene la capacidad
de que pudieras alcanzarlo, o misiles de corto alcance de caminar en una dirección y disparar y girar el torso
para disparar al enemigo a distancia cortas. Las en otra, lo que signi ca que podías controlar por
posibilidades eran casi ilimitadas y exibles para dónde caminaba tu personaje y mira al mismo
cualquier estilo de juego que eligieras, lo cual también tiempo. También tenías que manejar tus armas,
hizo que estos y otros juegos fueran bastante alternar entre ellas y dispararlas, todas de una vez o
interesantes en partidas multijugador y online, ya que en grupos, controlar tu velocidad al caminar/correr y,
cada jugador podía tener el mismo Mech con un si contabas con propulsores de salto, controlarlos
manejo, armamento y velocidad de reacción también. También necesita manejar las diferentes
totalmente diferentes. vistas, la información del estado y ese tipo de cosas.

Mech Warrior es uno de esos viejos juegos de


simulación, similar a Wing Commander, Comanche,
Mig 29 o Silent Service, donde llegas a dominar
realmente el juego cuando te haces con los controles.
Poseer un buen joystick con bastantes botones
programables ayuda mucho hoy en día.

La jugabilidad, los grá cos y la compleja simulación,


todo ayudó para que convirtiera en un impresionante
juego, Mech Warrior 2 también orece una memorable
banda sonora CD, repleta de cosas buenas que la
época tenía para ofrecer. El juego contaba con dos
complementos o ciales, cada uno venía con sus
Figura 8 – Personaliza tu propio Mech
propios CD con nuevos videos, nueva música, nuevos
Mechs, nuevos mapas, etc. Los complementos eran
juegos completos, no solo algunos extras que se
instalaban, como es muy común con los DLC en la
actualidad.

Figura 9 – Asegúrate de que puedes colocarlo todo


dentro de tu Mech
Figura 10 – Ghost Bear’s Legacy es un complemento
Las misiones variaban; a veces tenías que salir y o cial para Mech Warrior 2, también disponible para
destruir algunas instalaciones, o tenías que despejar DOS

puntos de Mechs enemigos; en otras ocasiones, se


suponía que debías defender una base, una
estructura o instalaciones, o ayudar a un compañero
Mech Warrior en problemas.
debería funcionar de inmediato. En el caso de los
complementos es algo más complicado

Mech Warrior 2 – Ghost Bear’s Legacy requiere


comprobar tu CD de Mech Warrior 2 antes de que se
instale. Para hacer esto, tienes que montar ambos CD
a la vez (todo en una línea), y hacer el cambio dentro
del juego con CTRL + F4:

$ imgmount d 

Figura 11 – Mercenaries es un complemento o cial para /home/odroid/DOS/CDs/MechWarrior2/GBL_DOSWIN.c


Mech Warrior 2, también disponible para DOS ue 
/home/odroid/DOS/CDs/MechWarrior2/MechWarrior_
Mech Warrior 2 en ODROID 2.cue ­t cdrom ­fs iso

Como hay tantas versiones diferentes de Mech


Esto me funcionó a mí, pude instalar y jugar el
Warrior 2, existen diferentes formas de hacer que
complemento Legacy de Ghost Bear sin problemas.
este juego funcione en ODROID. Decidí usar la versión
Aunque Mech Warrior 2 y GBL funcionaron bien en
de DOS que se ejecuta en DOSBox, puesto que
640 × 480 o 1024 × 768, el complemento Mercenaries
tenemos una versión optimizada de DOSBox que
sí que me iba un poco lento. También es verdad que
también ofrece soporte 3D.
tiene más opciones para el tema de los grá cos, así
Para esto utilicé la siguiente con guración en que supongo que el motor presenta algún tipo de
~/.dosbox/dosbox-SVN.conf: actualización en este sentido.

[sdl]  Lamentablemente, el rendimiento general de Mech


 fullscreen=true  Warrior 2 no es lo que solía ser, o al menos es lo que
 fullresolution=desktop  yo recuerdo. Se ralentiza un poco. No mucho, pero lo
 output=opengl 
notas. Aun así, puedes jugar y disfrutar
 [cpu] 
completamente del juego (al menos Mech Warrior 2 y
 core=dynamic 
 [autoexec]  GBL) pero desearía que fuera un poco más rápido. El
 imgmount d  juego sigue siendo divertido y ya he matado no
/home/odroid/DOS/CDs/MechWarrior2/MechWarrior_ docenas, sino a cientos de Mechs enemigos hasta
2.cue ­t cdrom ­fs iso  ahora. El juego también salió para Sega Saturn y
 mount c /home/odroid/DOS/ Playstation, y aunque no logré que la versión de Sega
Saturn funcionara totalmente, la versión de
Como puedes ver, tengo mi carpeta de juegos DOS en
Playstation sí que funciona bastante bien
/home/odroid/DOS y mis imágenes de CD de Mech
Warrior en /home/odroid/DOS/CDs/.

Como mi versión DOSBox está compilada con gl4es


de @ptitSeb, que es un contenedor para OpenGL a
OpenGL ES, podemos usar OpenGL para escalar la
imagen a nuestra resolución de pantalla actual sin
perder rendimiento. Eso permite que el video, que
originalmente tiene un tamaño de 320×200, se escale
bastante bien a 1080p. Incluso si juegas en 320×240 o
640×480, se sigue adaptando muy bien al tamaño de
escritorio completo y se ve realmente bien. El juego
se puede instalar fácilmente con el instalador del CD y
grá cos están totalmente texturizados, presentan una
resolución bastante más baja, lo que hace que
parezcan “feos” en comparación con la versión de
DOS.

Conclusion
Mech Warrior 2 sigue siendo bastante divertido de
jugar hoy día, y con ODROID es posible, incluso si la
experiencia no es exactamente la misma que en su
día. Desafortunadamente, no pude conseguir una
copia de la versión DOS 3DFx del juego, quizás
habrían mejorado los grá cos y el rendimiento algo
Figura 12 – La versión de Playstation de Mech Warrior 2 más, ya que nuestro DOSBox también tiene soporte
está reducida al mínimo, aunque está completamente Glide (3DFx).
texturizada
Hay muchas versiones diferentes y algunas pueden
La versión de Playstation de Mech Warrior 2 está
funcionar mejor que otras en ODROID. Puede que
totalmente texturizada, aunque por lo general es una
escriba un artículo comentario a éste para ver si el
versión inferior en comparación con las versiones de
resto de versiones pueden ejecutarse en ODROID.
DOS y Windows, porque se redujo al mínimo. Por
Hasta entonces, seguiré destruyendo a otros Mechs
ejemplo, toda la con guración de Mech ha
usando el teclado y el ratón para controlar mi Mech ¡y
desaparecido, dejando solo algunos ajustes
brindar más honor a mi clan!
preestablecidos. Los controles se simpli caron, pero
esto realmente no mejoró la jugabilidad. Aunque los
Conociendo un ODROIDAN: Dongjin Kim
 January 1, 2018  By Rob Roy  Conociendo un ODROIDian

Por favor, háblanos un poco sobre ti.


Soy un ingeniero de software embebido, he
participado en muchos y diferentes proyectos
comerciales desde 1994. Actualmente, estoy
desarrollando el software para un dispositivo móvil
que se ejecuta sobre un procesador ARM y trabaja
principalmente con un driver de dispositivo o capa
HAL/framework. Nací en Corea del Sur, estoy casado y
tengo un hijo de 10 años. Desde diciembre de 2015,
me encuentro vivido lejos de mi familia en Kitchener,
Ontario, Canadá. Mi familia todavía vive en Corea del
Sur, y los visito de vez en cuando. Fui a la universidad
en Corea y tengo dos licenciaturas en informática y
microelectrónica. Estudié microelectrónica tras
algunos años de experiencia como ingeniero de
software en el campo industrial.
Figura 1 – Paseo en bote sobre las Cataratas del Niágara

¿Cómo empezaste con los ordenadores?


No tenía su ciente nota en el instituto como para ir a
la universidad, así que decidí aprender programación
a través de cursos de capacitación laboral que quien realmente hizo cosas y ayudó a extender las
estaban disponibles en mi instituto para estudiantes ideas de Steve Jobs. Siempre he deseado ser como él.
de pre-grado. En realidad, quería aprender dibujo que
era lo que más me gustaba en aquel momento, pero
no estaba disponible entre los cursos que podía
elegir. Cuando tenía 14 años, llegué a memorizar todo
un libro de programación Apple//e BASIC, aunque
nunca escribí una sola línea de código. Durante 6
meses, aprendí diferentes lenguajes de programación
y probé un ordenador de escritorio compatible IBM
XT y un IBM S360.

Como no me podía permitir el lujo de tener mi propio


ordenador antes de conseguir un trabajo, me costó
Figura 2 – Montando Apple Classic como carcasa para el
bastante encontrar un ordenador que me permitiera
ODROID con mi hijo
ejecutar mis programas en MS-DOS. También usé
ordenadores para ayudar a muchos amigos a
completar sus proyectos y tareas escolares. Mi
lenguaje favorito era Pascal, el cual me permitió
familiarizarme aún más con la arquitectura de
programación, pero recurrí a C/C++ para un proyecto
embebido en mi primera empresa en 1994, el cual ha
sido mi principal lenguaje de programación hasta el
momento.

Más tarde, me interesé más por el diseño de sistemas


operativos y hardware, así que hice un curso de
Figura 3 – Diseño de Apple Classic como carcasa para el
microelectrónica en otra universidad. Tuve un
ODROID
proyecto para diseñar el hardware de ordenador de
16 bits con NEC v25 y desarrollar un software para ¿Qué te atrajo de la plataforma ODROID? Me interesa
ejecutar una pantalla LCD y un teclado mono-color. más resolver problemas que usar un hardware para
No podía costear el desarrollo de una PCB un determinado propósito. Muchos de los miembros
personalizada para este proyecto, así que tuve que del equipo de Hardkernel han sido compañeros de
conectar todas las señales con cables de envoltorio trabajo en otra empresa antes de que se fundara
durante 3 días y noches para conseguir el tan ansioso Hardkernel. He ayudado al equipo de Hardkernel a
“¡Hello world!” en la salida serie. Este proyecto me resolver algunos problemas que experimenté en
animó a seguir aprendiendo más a cerca de la otros proyectos con el n de implementar mis ideas
arquitectura de los ordenadores y los sistemas en la plataforma ODROID. ODROID tiene más
operativos. Todavía conservo esas placas originales, potencia de cálculo que otras placas SBC, y me gusta
aunque les faltan muchos componentes, ya que tuve lo que el equipo de Hardkernel está haciendo en
que usarlos para otro proyecto con posterioridad. ODROID para sus usuarios. Espero que ODROID se
vuelva más popular.
¿A quién admiras en el mundo de la tecnología?
Admiro a Steve Wozniak. Muchas personas recuerdan
a Steve Jobs, quien marcó un antes y un después en la
industria TI. Creo que Steve Jobs solo pudo hacer
realidad sus ideas porque conoció a Steve Wozniak,
el Kernel Linux y HAL/framework de Android para
ODROID. La mayoría de ellos están destinados a
adaptar el kernel Linux o la plataforma Android BSP
proporcionada por un proveedor de SoC. El resto es
para ayudar a los usuarios ODROID a usar sus placas
de un modo más cómodo, de esta forma las placas
ODROID podrían llegar a ser más famosas y es
bastante probable que los usuarios utilicen más las

Figura 4 – Diseño de Cloud Shell


placas ODROID que otro tipo de placas SBC.

El dispositivo CloudShell para ODROID-XU4 es una


¿Cómo utilizas tus ODROID? Bueno, generalmente no
demostración de cómo los ODROID funcionan como
uso mis ODROID más que para el desarrollo de
sistemas informáticos normales. He contribuido con
código para ODROID. En contadas ocasiones he
muchos parches en los repositorios de GitHub
Intentado usar ODROID para otros proyectos a modo
ODROID y en mis propios repositorios para mejorar
de prototipo o con una nalidad personal ya que,
las características, aunque muchos de ellos están sin
irónicamente, no soy un gran fan de usar un
terminar o suspendidos. Estoy intentando hacer un
dispositivo electrónico para mi propio interés
parche y contribuir con la línea principal del kernel
personal. Creo que los ODROID tienen grandes
Linux o al repositorio de Hardkernel siempre que
posibilidades de volverse más populares y de poder
disponga de tiempo. Me satisface mucho ayudar a los
ayudar a mucha gente. Por lo tanto, normalmente
usuarios ODROID a resolver sus problemas.
ejecuto ODROID cuando encuentro un problema
interesante en los foros ODROID o cuando algunas
personas me piden ayuda personalmente o por
correo electrónico.

Figura 6 – El primer prototipo de CloudShell

¿Cuál es tu ODROID favorito y por qué?


El ODROID-X es mi favorito, ya que fue el primer
Figura 5 – Ejecutando SNES sobre Apple Classic con el dispositivo que me motivó para enviar un parche a la
ODROID-C1 línea principal del kernel Linux. He enviado algunos
Has creado muchos proyectos de software útiles basados parches para introducir el ODROID-X en el Kernel 2.6
en la tecnología ODROID. ¿Qué te motivó a de Linux, pasé mucho tiempo trabajando en él, así
desarrollarlos? He desarrollado muchos parches para como ayudando al escritorio de Ubuntu a ejecutar el
framebu er de Linux en 2012. Creé y presenté el
archivo de la placa ODROID escrito en C, al kernel ¿Qué pasatiempos e intereses tienes aparte de los
Linux, pero la fusión fue denegada, ya que, en ese ordenadores?.
momento, la mayoría de los desarrolladores de ARM Me gustó la fotografía, aunque ya no tengo tiempo
se movían en el árbol del dispositivo en lugar de un debido a mi vida tan ajetreada
archivo de placa en C. Como resultado, tuve que
¿Qué consejo le darías a alguien que quiere aprender
invertir una gran cantidad de tiempo aprendiendo
más sobre programación?
cosas nuevas, y nalmente mi archivo de árbol de
Me digo a mi mismo todos los días que debo escribir
dispositivo para el ODROID-X fue aceptado en 2013. un código para que otra persona entienda mi idea
¿Qué innovaciones te gustaría ver en futuros productos con una mínima explicación. Solía decir esto a mí
Hardkernel? Me gustaría que los ODROID fuesen tan mismo y a los miembros de mi equipo, no
populares como la Raspberry Pi y que proporcionen alejándome demasiado de lo que realmente era
más potencial de hardware en forma de hardware necesario. La programación es simplemente una
para pequeños dispositivos, y una versión un poco habilidad para trasladar una idea a un ordenador, y lo
más grande para hardware de escritorio. Tal vez importante y difícil es encontrar la razón por la cual el
algún día, muy pronto, ODROID se convierta en el código es necesario y por qué queremos hacer la
estándar para plataformas de escritorio basada en tarea con un ordenador. Si la razón y el objetivo son
ARM para la denominada pequeña informática, pero obvios, las habilidades de programación se deducirán
seguiría siendo lo su cientemente barata para el uso directamente.
corriente.

También podría gustarte