jueves, 17 de diciembre de 2015

Uso de Librería u8glib para Raspberry Pi con OLED SSD1306

Como parece que me gustan los retos (¿para qué hacerlo fácil, si puedo investigar un poco?), investigué la forma de utilizar la biblioteca u8glib en el Raspberry Pi, para utilizar el OLED que compré en dx.com:
Esta biblioteca permite utilizar directamente una gran variedad de pantallas LCD monocromáticas sin usar X u otras bibliotecas como SDL, pudiendo usar fonts distintos y dibujar líneas, rectángulos, círculos, etc. Tiene un repositorio en Github para el código fuente y manejo de versiones y wiki para la documentación.
Logo U8glib
Aunque en sus orígenes estaba orientada a Arduino, requiriendo poca memoria en esos sistemas, actualmente funciona también en otras plataformas como AVR y ARM.
Esto último es interesante, pues los Raspberry Pi tienen CPU ARM aunque funcionando sobre Linux. Supuestamente no está soportando oficialmente el Raspberry Pi (esto está marcado como mejora en futuras versiones), pero no hay una incompatibilidad en realidad. Al investigar encontré que se le han estado haciendo cambios para soportar al Raspi, ¡y sí funciona!

El módulo OLED en cuestión tiene una resolución de 128 x 64 pixeles, y aunque supuestamente es monocromático, en realidad es bicolor: 16 pixeles (1/4 de pantalla) son amarillos y el resto de color celeste. Aquí va una foto para ilustrar esto:
El módulo permite conexiones SPI (4 y 3 pines) e I2C, cambiando soldando o desoldando pines en su placa, lo que aunque no es difícil, no es como llegar y cambiar.

La biblioteca tiene bastante soporte para este módulo SSD1306, permitendo variedades de OLED con resoluciones 128x64 (como la mía), 128x32 y 64x48, conectándose por SPI e I2C, tanto emuladas por software como usando el soporte de hardware nativo del Raspi. Aunque en la wiki no está muy claro, también permite el uso de doble buffer para ambos tipos de conexiones, lo que en teoría permitiría mostrar animaciones en forma fluida (sin "tearing effect").
Hasta ahora lo he probado solo con SPI por hardware con buffer simple usando 5 pines de datos (más 2 de energía), y no he visto que consuma mucha CPU, que era lo que quería.

Conexiones al Módulo SSD1306

Este es el esquema de conecciones que he usado, mostrando las distintas notaciones para los pines que utiliza la biblioteca.

Pin Módulo OLED Función RPi / Número notación BCM Pin en conector RPi Pin notación WiringPi Función en biblioteca u8gli (Arduino)
1-VCC
+3.3V
pin 17
-
-
2-GND
GND
pin 20
-
-
3-NC
no conectado
-
-
-
4-DIN (data input)
MOSI / GPIO10
pin 19
12
MOSI
5-CLK (clock)
SCLK / GPIO11
pin 23
14
SCK
6-CS (select)
CE0# / GPIO8
pin 24
10
CS
7-D/C (data/command)
GPIO24
pin 18
5
A0
8-RES (reset)
GPIO25
pin 22
6
RESET

La biblioteca 8glib en su sabor Arduino, que es la que probé en su versión del 2/nov/2015, obviamente utiliza notación Arduino. Las personas que están haciendo la implementación para el Raspi utilizaron la biblioteca WiringPi, que tiene orientación similar, pero hay que hacer traducciones entre las distintas notaciones. No me gustó mucho la complicación, pero se puede vivir con eso, especialmente mirando las notaciones de WiringPi y las de Raspberry Pi.

Compilación de biblioteca u8glib en Raspi

Conseguí compilar la biblioteca en el Raspi, usando el siquiente procedimiento:
  • Instalar prerequisitos de compilación en Raspi:
    Me costó al principio la compilación pues yo no detectaba que me faltaban tener instalados los paquetes autoconf y libtool.
    $ sudo apt-get install build-essential autoconf libtool libsdl1.2-dev
  • Clonar el código fuente desde el repositorio:
    En este caso estoy usando la más reciente desde la versión 1.18.1.
    $ sudo git clone https://github.com/olikraus/u8glib.git
    $ cd u8glib/
  • Modificar los programas de ejemplo para que compilen considerando mis conecciones:
    Cambié los siguientes archivos:
    $ sudo nano sys/arduino/Chess/Chess.cpp
    $ sudo nano sys/arduino/U8gLogo/U8gLogo.cpp
    $ sudo nano sys/arduino/GraphicsTest/GraphicsTest.cpp
    buscando la línea que contenía la inicialización del SSD1306 que usara el wardware de SPI :
    //U8GLIB_SSD1306_128X64 u8g(10, 9); 
    // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
    para cambiarla a utilizar mis conexiones:
    U8GLIB_SSD1306_128X64 u8g(10, 5, 6); 
    // HW SPI Com: CS = 10 @wiringpi (8 @BCM_GPIO), A0 = 5 @wiringpi (24 @BCM_GPIO), RESET = 6 @wiringpi (25 @BCM_GPIO) (Hardware Pins are SCK = 14 @wiringpi (11 @BCM_GPIO) and MOSI = 12 @wiringpi (10 @BCM_GPIO))
  • Configurar la biblioteca y compilar:
    $ sudo ./autogen.sh
    $ sudo ./configure
    $ sudo make
    $ sudo make install
  •  Ejecutar el programa de ejemplo:
    $ sudo ./u8gwpi_logo


Cosas por explorar

  • Cambiar la velocidad de conexión SPI, pues como viene el código fuente invocando a la librería WiringPi, la velocidad es de 100kHz. Esto se cambia en el archivo csrc/u8g_com_raspberrypi_hw_spi.c, dentro de la función u8g_com_raspberrypi_hw_spi_fn, en la línea 77:
    case U8G_COM_MSG_INIT:
    ...
      if (wiringPiSPISetup (0, 100000) < 0)
      {
          printf ("Unable to open SPI device 0: %s\n", strerror (errno)) ;
          exit (1) ;
      }

    Según lo mostrado en la documentación del RPI, en la tabla de velocidades, existen velocidades más altas a las que debería funcionar como 3.2MHz o 7.8MHz. Según la documentación del SSD1306, el límite de velocidad sería 10MHz (parametro mínimo de tSCLK de 100ns. de la tabla 13-4 de características de conexión SPI-4 de esa documentación).
    Sin embargo, en los últimos kernels RPI sobre 3.18, ya está implementado un parche que permite funcionar a velocidades intermedias, mientras sean múltiplos de 2 (post de foro RPI "SPI has more speeds"). ¿Cómo andará a 10Mhz?
  • Medir rendimiento y ver si las animaciones corren en forma fluída usando la invocación con doble buffer.

jueves, 28 de mayo de 2015

Esperanzas para Sintonizador ISDB-T (SMS1140): ¿corre en Android?

Esperanzas para Sintonizador ISDB-T (SMS1140): ¿corre en Android?

Mirando una noticia en Fayerwayer (Cómo ver los partidos de la Copa América desde tu celular), encontré sintonizadores compatibles con Android para ISDB-T, DVB-T y ATSC (Geniatech PT275 y otros), y encontré allí que también tienen un sintonizador basado en el chip SMS1140: S936 ISDB-T.
No estaba muy seguro de que era el mismo chip, hasta que bajé el driver para linux dentro de la sección de soporte al S936 y vi dentro del ZIP: el directorio principal se llamaba "siano1140linuxdriver" y dentro de este estaba el mismo archivo de firmware "dvb_nova_12mhz_b0.inp", junto con que las instrucciones para compilar el driver para Linux, indica que se debe agregar el mismo identificador "SMS1XXX_BOARD_SIANO_NOVA_B" que se utiliza en el driver que ya está en LinuxTV (ver artículo anterior Configuración de Sintonizador ISDB-T en Linux Mint).
@@ -301,6 +299,9 @@
     case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
     case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
     case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+    case SMS1XXX_BOARD_SIANO_NOVA_B:


Lo otra cosa interesante es que en la página del producto en Geniatech indican que se puede utilizar en Android! Habrá que investigar esto también...

Lo que sí ocurre es que en DX.COM tienen a la venta uno que se parece mucho:  Micro USB DVB-T ISDB-T Digital Mobile Phone TV Tuner Receiver Stick for Android Tablet/ Mobile Phone.

En la noticia de Faywerwayer mostraban ese y por lo que indican en el foro de dx.com, se podría usar en Android la app PadTV o PadTV HD. De hecho en Geniatech tienen los APK para bajar versiones para ellos. Habrá que probar...

jueves, 26 de marzo de 2015

Haciendo funcionar el conversor USB-Serial Prolific PL2303HX en Windows 8.1 o 10

Como parece que me gustan los desafíos, me compré en dx.com un conversor a USB a RS232 TTL para usarlo como debug de la consola desde mi Raspberry Pi, pues estaba muy barato. 
Conversor USB a Serial, enchufado en el notebook. El led prendido es realmente de color rojo y no media fucsia como aparece en la foto que tomé con el celular. ¿Falta de filtro IR?


La tarjeta se ve simple de usar, pues la salida serial tiene simplemente las señales TXD (datos transmitidos hacia el dispositivo desde el PC) y RXD (datos recibidos desde el dispositivo hacia el PC), junto con las de energía como 5V y 3.3V y GND (tierra). Estas últimas aunque parecen bien convenientes, no me atrevería a usarlas así no más con el Raspberry Pi, pues tengo que averiguar si con ello se setea el voltaje de operación de la puerta serial hacia el dispositivo, o si las saca desde la puerta USB y son para energizar el dispositivo. ¡A revisar el Datasheet!

 Aparecen los problemas

Sin embargo no funcionó en el notebook con Windows 8.1 x64: al enchufarlo me aparecía el diálogo de instalación, pero luego de esto quedaba con error en el Administrador de Dispositivos:
 
 


Mirando el porqué, el mensaje de error hablaba de que el dispositivo no se podía iniciar (código 10).

Buscando en internet, me topé con muchos casos en que conversores con chip Prolific PL2303 no funcionaban, en Windows 7, 8 y 8.1. En algunos se buscaban soluciones como ir al sitio del fabricante (http://www.prolific.com.tw) y bajar drivers.

Eso intenté, bajando los últimos drivers pero tampoco andaba. Sin embargo leyendo las notas del Driver (a veces es bueno detenerse y leer ;-), indican que este funciona para chips modelo PL2303 HXA, XA, HXD, EA, RA, SA, TA y TB, pero con la importante salvedad que no funciona para Windows 8, 8.1 y 10 para las versiones PL-2303HXA y PL-2303X que están EOL ,End-of-Line, o sea que ya no se fabrican mas ni se soportan: o sea están obsoletos (programadamente).


Identificando el Chip

Bueno, me dije ¿como tendré tan mala suerte para justo tener los chips obsoletos?

Bueno, verifiqué que correspondiera al mismo dispositivo, pues en la página se indica que tiene identificadores USB VID_067B&PID_2303 y PID_2304.
Mirando en las propiedades del dispositivo, veo que corresponde al primero:



Mirando el chip mismo, tenía la inscripción PL-2303HX, lo que no parecía muy concluyente, pues no estaba en la lista ni incluida ni excluída, por lo que pasé susto de que no fuera siquiera un producto original, como advertían en el sitio de prolific, sobre ciertas tarjetas hechas en China y que decían ser este chip y no lo eran.
Foto del chip en la tarjeta de conversión, hecha con mi microscopio digital USB. Se aprecia parte del texto en chino que trae la tarjeta. ¿Mala señal?
Para salir de la duda, busqué los datasheet del chip en la página respectiva, para buscar que tipo de marcas tenían las versiones HXA revisión D y la antigua que sospechaba yo tener. Ojo: para entrar hay que usar el usuario GUEST y password GUEST, como lo sugiere la misma página.

Imagen del Chip revisión D, desde el datasheet.
Bajé los archivos "ds_pl2303HXD_v1.4.4.pdf" para la versión D sí soportada, y el archivo "ds_pl2303HX_v1.6.pdf" para la antigua versión A obsoleta, que se encuentra al final de la página.
Mirando en este último archivo en la sección 11 Ordering Information, aparecen descritas las marcas del chip, concordando completamente, como un modelo PL2303HX revisión 3A, versión sin plomo, fabricado el 2010 en la semana 19 de ese año (a mediados de Mayo).

Mirando el otro archivo en la sección correspondiente, el chip tiene tres líneas y no dos como el mío, junto con que la especificación del modelo en la segunda línea termina en D. ¡Así que el mío era justo el descontinuado!
 

Solución para Windows 8 y 10: usar driver antiguo

Cuando ya me estaba resignando a que funcionaría solo en linux, pues la página de drivers de Prolific señalaba que el kernel incluía el driver desde la versión 2.4.31, volví al sitio donde lo compré y dentro del foro para el producto se mencionaba para Windows 8.1 que se podía usar una versión antigua para Windows Vista y así andaba.
Actualización Abril 2016: Lo mismo funciona para Windows 10, aunque las pantallas mostradas aqui son las de Win8.


Busqué qué versión del driver se estaba usando, y en las propiedades del dispositivo aparece como 3.4.67.325.

Uhmm, esa parece que es la última. Así, buscando en internet, encontré la mejor guía para resolver el problema, dentro del sitio http://www.miklor.com/COM/UV_Drivers.php. Este sitio lo conocía, pues está dedicado a la programación (y hackeo en buen sentido) de Walkie Talkies, que en varios casos utilizan un conversor serial a USB.

Lo que indican es que se puede bajar una versión antigua para Windows Vista (version 3.2.0.0), y que no tiene el bloqueo para el dispositivo.

La bajé e instalé, pero con eso no basta, pues hay que seguir las instrucciones siguientes, adaptadas desde su sitio (sección "Installing the Proper Older Prolific PL-2303 Driver 3.2.0.0"):
  1. Bajar el instalador del driver desde la página y guardarlo en el disco duro en el directorio que nos guste más (o nos acordemos).
  2. Desenchufar el conversor.
  3. Instalar el driver completamente haciendo doble click en el archivo que bajamos.
  4. Ahora sí enchufar el conversor y esperar que aparezca y termine la detección del dispositivo. A diferencia de las instrucciones de Miklor que por las imágenes parece que se hacían en Windows 7 o Vista, en mi Windows 8.1 nunca me apareció el mensaje de que la instalación había fallado.
  5. Abrir el Administrador de Dispositivos y revisar el estado del conversor. Ahí sí tenía lo mismo, pues aparecía con el dichoso código de error 10.
  6. Al hacer doble click en el dispositivo, y abriéndose sus propiedades, hay que ir a la pestaña "Controlador" y apretar el botón "Actualizar controlador...".
  7. Ahí aparece una ventana para actualizar el driver, dentro de la cual hay que elegir la opción de "Buscar software de controlador en el equipo".
  8. Aunque el asistente ofrece buscar en algún directorio, se debe elegir la opción "Elegir en una lista de controladores de dispositivo en el equipo".

  9.  Si todo anda bien, aparece dentro de la lista de drivers disponibles el driver antiguo (versión 3.2.0.0), debiendo elegir ese y apretar el botón siguiente.
  10. Tras un poco de malabares de instalación, se llega al final de la instalación exitosa.
  11. Verificar en las propiedades del dispositivo que el driver utilizado es ahora el correcto (versión 3.2.0.0) y que no aparezca con error en el Administrador de dispositivos.
     
¡Ahora sí aparece correcto el dispositivo! :-)

Limitaciones de la Solución

Como nota final, hay que hacer notar que todo funcionará bien si es que siempre utilizamos el mismo puerto USB para enchufar el conversor. Si se nos olvida, y usamos otro puerto, el administrador de dispositivos lo intentará detectar por su cuenta, utilizando siempre el driver más reciente y de nuevo dará error. Ocurrido es, aunque volvamos a enchufarlo al puerto original, igual se usará el driver más reciente, perdiéndose el ajuste que habíamos hecho antes.

Sin embargo, esto no es tan terrible, puesto que el driver antiguo no se ha perdido, solo tenemos que "Actualizar controlador", partiendo desde el paso 5 del procedimiento, sin tener que reinstalar nada más.


martes, 17 de marzo de 2015

Configuración de Sintonizador ISDB-T en Linux Mint

Voy a inaugurar esta serie de notas, documentando los avances para usar un sintonizador de TV Digital en Linux Mint. Me costó bastante encontrar información sobre este aparato, pero toda en inglés. Por eso me animo a dejar algún testimonio en español.

El sintonizador es un EzTV ISDB-T, en formato dongle usb, que funcionaba originalmente solo en Windows. Lo compré en DX.COM.

Copio algunas características técnicas desde la tienda:
  • Cumple con estandar ISDB-T, para 1 Segmento (ver wikipedia para emisiones para celulares) y 3 Segmentos (emisiones para canales en definición estandar SDTV).
  • Rango de Frecuencia:  470~806MHz.
  • Sensitividad: -95dBm.
  • Decodificadores: video H.264 (MPEG-4 AVC) y audio MPEG-4 HE-AAC.
  • Soporta control remoto infrarojo.
  • Soporta lista de canales y radios (aunque sospecho que describe el programa en Windows).
 El aparato funciona bien en Windows 7, pero junto con renovar mi notebook, y que pasé a un boteo dual con Win 8.1 + Linux Mint 17.1, me puse a investigar que se necesitaba para hacerlo andar en Linux. A todo esto en 8.1 no pude instalar los drivers, pues me decía que era para una versión anterior de Windows...

Al buscarlo por ese nombre en internet no llegué muy lejos, así que me decidí y lo abrí. Me encontré con lo siguiente:

A la izquierda se ve el conector USB. A la derecha, el conector para la antena, y junto a este algo más abajo, el sensor infrarojo para el control remoto. Al centro se ve el chip en que está basado: SIANO SMS1140. Acá un detalle del mismo:
Sin embargo esto no me llevó muy lejos pues la búsqueda me llevó a un diseño de referencia para TV Digital. En el sitio del fabricante del chip, aparece mencionado, pero en la sección de soporte no está listado, por lo que me parece que está obsoleto. Sin embargo buscando dentro del sitio (gracias a san google), logré encontrar una hoja de especificaciones para China con otros datos técnicos adicionales:
  • Soporta ISDB-T 1/3-Seg, pero también DVB-T, T-DMB, DAB, DAB+, DAB V.2
  • Bandas de frecuencias 170-240MHz y 470-862MHz.



Sin embargo por el otro lado de la placa madre aparece la inscripción EZTV926, que sí me llevó mas lejos pues encontré en el sitio de LinuxTV que había algunos similares: Dongle Smart Plus.

Mi problema es que al enchufarlo no cargaba, dándome errores como los descritos en ese artículo.

Lo que rescaté es que se debe utilizar un archivo como firmware, pero no sale el vínculo sino que hay que rescatar la imagen desde instalación de windows. En mi caso el nombre del archivo que el kernel estaba esperando es "isdbt_nova_12mhz_b0.inp".

Ahí volví al sitio donde lo compré, y ví que en el foro sobre el producto una pregunta hablaba de algo similar, y entregaban un archivo para bajar.
Probé con ese archivo, siguiendo las instrucciones, renombrándolo y copiándolo a /lib/firmware/ pero no me funcionó. Sin embargo, ahí mencionaban que había que inicializar el driver para que partiera en modo ISDB-T, creando un archivo y agregando la instrucción correspondiente:

$ sudo nano /etc/modprobe.d/siano_dtv.conf
Agregar la línea:
   options smsmdtv default_mode=6
y grabarlo.
Luego lo que hice fue recuperar desde el notebook con Windows 7 el archivo original de mi instalación (isdbt_nova_12mhz_b0.inp), que encontré en C:\Windows\System32\drivers y traspasé al Linux vía un pendrive:
$ sudo cp isdbt_nova_12mhz_b0.inp /lib/firmware/isdbt_nova_12mhz_b0.inp
Luego reinicié el notebook sin enchufar el dongle, y luego de que cargó completamente Linux Mint, sí lo enchufé. Ahora sí lo reconoció:
$ dmesg
...
[ 280.809288] usb 2-3: new high-speed USB device number 8 using xhci_hcd
[ 280.826010] usb 2-3: New USB device found, idVendor=187f, idProduct=0201
[ 280.826019] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 280.826024] usb 2-3: Product: MDTV Receiver
[ 280.826027] usb 2-3: Manufacturer: MDTV Receiver
[ 280.987654] smscore_set_device_mode: firmware download success: isdbt_nova_12mhz_b0.inp
[ 281.300890] DVB: registering new adapter (Siano Nova B Digital Receiver)
[ 281.301105] usb 2-3: DVB: registering adapter 0 frontend 0 (Siano Mobile Digital MDTV Receiver)
...
[ 281.301580] usbcore: registered new interface driver smsusb
Sin embargo, en los otros sitios tienen el problema que no funciona el infrarojo, y yo también quedé igual. Así que continuaré esta investigación...
Como todavía no termino con la sintonización de canales, también escribiré otro post cuando lo tenga más listo.