Fork me on GitHub

Lector de RSS con Arduino y Raspberry Pi

July 30, 2013

Luego de un par de meses de darle vueltas finalmente llegué a una versión usable de este lector de RSS. El display del lector está hecho con un Arduino UNO y una matriz de LEDs A-5570E que está soldada sobre un proto shield. Los mensajes los recibe por serial. Esto se hace desde la Raspberry Pi, que tiene un servidor hecho con Tornado y el cual tiene una interfaz web desde la que cualquier usuario puede encolar sus propios mensajes y ver los mensajes del resto mediante WebSockets. Esto es, mientras no haya mensajes de usuarios se lee algún feed. Así que el display siempre está mostrando algo.

Arduino and Raspberry Pi

El servidor está permanentemente leyendo el serial. Si el display le envía un 1 significa que está listo para recibir un nuevo mensaje. El servidor revisa la cola de mensajes de usuario primero y la cola de RSS después así que es posible intercalar un mensaje en cualquier momento.

Aquí los programas que se ejecutan de uno y otro lado: sketch.ino y server.py. Aquí la interfaz web con WebSockets: publisher.html

El display

La matriz de LEDs usa una técnica llamada clarlieplexing de la cual ya escribí algo acá y acá. El diagrama de conexiones es el siguiente

Así me quedó conectado el display, usando 12 pines, del 2 al 13

Arduino Proto Shield
const int cols[5] = {9, 10, 11, 12, 13};
const int rows[7] = {2, 3, 4, 5, 6, 7, 8};

Al darle tensión a una fila se prenden todos los LEDs de la misma. Luego tenés que poner en HIGH cada columna que querés apagar. Por ejemplo si quisiéramos prender lo siguiente en la primer fila

1  0  1  0  1

Tendríamos que escribir algo así

digitalWrite(rows[0], HIGH);
digitalWrite(cols[1], HIGH);
digitalWrite(cols[3], HIGH);

Para dibujar la siguiente fila tenemos que apagar la anterior y repetir el proceso. Así vas dibujando mediante barridos. Por eso el tiempo en que mostrás un caracter es producto de n barridos simultáneos.

Para codificar los caracteres usé arrays de 5 bytes, ya que necesitaba 35 bits (5x7) para cada uno. Era muy difícil codificarlos directamente así que hice un script en Python que traduce una lista de tuplas a un array de chars en C. De esa forma cambiar un caracter es fácil. Basicamente traduce de esto

_A = (
    (0,1,1,1,0),
    (1,0,0,0,1),
    (1,0,0,0,1),
    (1,0,0,0,1),
    (1,1,1,1,1),
    (1,0,0,0,1),
    (1,0,0,0,1) 
)

_B = (
    (1,1,1,1,0),
    (1,0,0,0,1),
    (1,0,0,0,1),
    (1,1,1,1,0),
    (1,0,0,0,1),
    (1,0,0,0,1),
    (1,1,1,1,0) 
)

charset = [_A, _B]

A esto

const char charset [][5] = {
    {0x74, 0x63, 0x1f, 0xc6, 0x20},
    {0xf4, 0x63, 0xe8, 0xc7, 0xc0}
};
Arduino and Raspberry Pi

El display puede mostrar los mensajes de dos formas distintas. Una es caracter a caracter, y la otra es en forma de marquesina. Para esto último el primer caracter del mensaje debe ser un ~. La función que lo hace es la siguiente

void marquee_chars(const char *c1, const char *c2, int times)

La función recibe dos punteros a char, que son los caracteres entre los que se hará la transición. Esto genera una secuencia de 6 frames que son los pasos posibles entre c1 y c2, dejando una columna de espacio entre ambos y sin mostrar completamente c2. El tercer parámetro es la cantidad de veces que se dibujará cada frame.

En el array de C están representados todos los caracteres ascii imprimibles, del 32 (espacio) al 126 (~). Así que para obtener cualquier caracter simplemente hay que restar 32 al caracter recibido.

c1 = (int) message[0] - 32;
c2 = (int) message[1] - 32;
marquee_chars(charset[c1], charset[c2], 50);

Así muestra la interfaz web los mensajes en cola y el mensaje actual en el display

Screenshot

El código completo en Github.

Arduino Python Raspberry Trabajos Video