Electrónica y Programación en Personal
«Si no se soluciona con un script en Python entonces no es viable»

por Yeison Cardona el 15 de agosto de 2011 a las 19:42 UTC
La mayoría (no los conozco todos) de los displays LCD tienen a disposición del usuario 8 caracteres para ser definidos, en Pinguino (lo que nos importa) estos caracteres se generan de una forma muy simple y sin ninguna complicación, hasta que se me ocurre hacer un generador de caracteres en Python para pinguino y su librería de LCD.

CG RAM (Character Generator RAM)
Comencemos describiendo la función de los displays LCD para guardar caracteres personalizados.
La CG RAM es la memoria que contiene los caracteres definibles por el usuario. Está formada por 64 posiciones, con direcciones $00-$3F. Cada posición es de 5 bits. La memoria está dividida en 8 bloques, correspondiendo cada bloque a un carácter definible por el usuario. Por ello el usuario puede definir como máximo 8 caracteres, cuyos códigos van del 0 al 7. Cada carácter está constituido por una matriz de 5 columnas por 8 filas. Para definir un carácter y asignarle por ejemplo el código 0 habrá que almacenar en las posiciones $00-$07 los valores binarios de las 8 filas del carácter del usuario. Un bit con valor 1 representa un punto encendido. Un bit con valor 0 es un punto apagado.
(archivo original)


CG RAM en Pinguino
En pinguino la forma de generar nuestros caracteres es la siguiente:

command(0x40); //Indica que se guardará en la primera posición

write(0b10001); //La primera fila del caracter 1:pixel encendido 0:pixel apagado
write(0b11111); //segunda fila
write(0b10101); //... 
write(0b10001); 
write(0b11111);
write(0b01110); 
write(0b00100); 
write(0b00000); //Última filas de nuestro caracter 

//Para llamar nuestro caracter sólo debemos ejecutar 
write(0);
La anterior es la forma mas obvia de crear el caracter, pero no la mas simple, igualmente podríamos:
//Guardamos en caracter la información de cada una de las filas
unsigned caracter[8]={0x11, 0x1f, 0xf, 0x15, 0x1f, 0xe, 0x4, 0x0};

int i;

command(0x40); //Indica que se guardará en la primera posición
for(i=0;i<8;i++)
write(caracter[i]); //Recorremos y guardamos cada fila 
muchos mas "económico" no creen.
Ahora, si se quisiera asignar los demás espacios sólo tendríamos que cambiar el parámetro de command() así:
command(0x40); //Para el primer caracter 
command(0x48); //Para el segundo caracter 
command(0x50); //... 
command(0x58); 
command(0x60); 
command(0x68); 
command(0x70); 
command(0x78); //Para el octavo caracter 
Programa en Python El programa en Python consta de una sencilla interfaz gráfica y dos espacios para visualizar el código de salida.
Captura CharGen en Ubuntu, Radiance
En el lado derecho se muestra el código extenso para crear el caracter asociado y en la parte inferior se crea una lista para simplificar la creación del caracter, ambas salidas de pueden usan sin ningún problema.
El programa actualiza el código de salida en tiempo real, es decir, si se cambia un pixel el programa se renovará inmediatamente. La interfaz gráfica esta hecha en PyQt, el archivo.ui se incluye en la descarga del programa. Acerca del Código
Sólo por diversión comentaré el código, que en realidad es muy simple, está hecho con 3 funciones solamente. El truco consiste en crear una matriz de 5x8 constituida por unos y ceros la cual representa el caracter que se está creando, esta matriz se construye de la siguiente manera: Los pixeles están echos con CheckBox y existe un método checkState() que nos retorna un 1 si se encuentra resaltado y un 0 si se encuentra vacío. Los pixeles están organizados en una matriz con la misma distribución de la real. Este método es llamado cada que se cambia un pixel:
def crearcodigo(self):
    #Creamos una lista vacía que contendrá la matriz del caracter
    self.caracter=[]  
    
    #La matriz que contiene todos los CheckBoxs se llama self.allpixels
    for fila in self.allpixels:        #Recorremos sus filas
        self.caracter.append([])       #Añadimos una fila para nuestro caracter
        self.fila=self.caracter[-1]    #Y la referenciamos en self.fila
        for pixel in fila:
            #Recorremos cada pixel para guardar su estado en forma de cadena,
            #la lista referenciada anteriormente hará parte de la matriz
            #final
            self.fila.append(str(pixel.checkState()))
Después de ejecutarse el anterior método ya se tiene una matriz que contiene la información del caracter visualizado, ahora se necesita visualizar el código: para el panel lateral:
def mostrar_lateral(self):
    self.ventana.plainTextEdit.clear()    #Limpiamos el texto anterior

    for fila in self.caracter:            #Recorremos sólo las filas

        #La funcion join retorna una cadena de una lista, le anteponemos '0b' para
        #indicar que es binario y completamos la línea con 'write(' y la cerramos
        #con ');\n'
        self.ventana.plainTextEdit.insertPlainText("write(0b"+"".join(fila)+");\n")
para el panel inferior:
def mostrar_inferior(self):
    self.ventana.plainTextEdit_2.clear()                 #Limpiamos el texto anterior

    cont=0
    self.ventana.plainTextEdit_2.insertPlainText("{")    #Iniciamos con un corchete
    for fila in self.caracter:                           #Recorremos sólo las filas
        cont+=1

        #Partimos del mismo arreglo anterior para crear una cadena de la forma
        #'0bxxxxx' para convertirla en entero con int() y después en hexadecimal
        #con hex()
        self.ventana.plainTextEdit_2.insertPlainText(hex(int("0b"+"".join(fila),2)))
        
        #Utilizamos la variable cont para saber si estamos en el final del código
        #y entonces cerrar el corchete o de lo contrario imprimirá una coma
        if cont<8: self.ventana.plainTextEdit_2.insertPlainText(", ")
        else: self.ventana.plainTextEdit_2.insertPlainText("};")
Ejemplo Tomemos la salida de la imagen mostrada y generémosla en un display LCD con pinguino. Sabemos que {0x11, 0x1f, 0x1f, 0x15, 0x1f, 0xe, 0x4, 0x0}; representa nuestro caracter y lo deseamos guardar en la posición 1 es decir en 0x40, el código sería el siguiente:
int contraste, i;
unsigned caracter[8]={0x11, 0x1f, 0x1f, 0x15, 0x1f, 0xe, 0x4, 0x0};

void setup(){
contraste=12; //conectando la terminal de contraste al pin 12

lcd(8, 9, 0, 1, 2, 3, 4, 5, 6, 7); // RS, E, D0 ~ D7
lcd.begin(2, 0);
pinMode(contraste,OUTPUT);
analogWrite(contraste,300);
}

void loop(){

//Para crear el caracter
lcd.command(0x40);
for (i=0;i<=7;i++)
lcd.write(caracter[i]);

lcd.clear();
lcd.home();
lcd.write(0); //Mostramos el caracter

delay(1000);
} 

Descargar

Descargar desde
Google Code





También podría interesarte:

Comentarios:
HenryLaredoQ dijo:
7 de septiembre de 2012 18:48
Interesante material, ese programa en python tambien puede correr bajo win7?
Responder a HenryLaredoQ
Respuesta de Yeison Cardona:
7 de septiembre de 2012 18:53
Claro que si, con la dependencia adecuada, en éste caso PyQt, lo puedes descargar desde aquí http://www.riverbankcomputing.co.uk/software/pyqt/download Hasta pronto.
Responder a Yeison Cardona
Añadir un nuevo comentario:
Si desean una respuesta para su comentario sólo deben agregarme en G+ y hacer una mención a Yeison Cardona, así les podré responder lo antes posible.