Arduino - TVOUT y VGAx PDF

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

TUTORIAL

Arduino TVOut y VGAx

TVOut
Hola a todos, en este tutorial vamos a estar viendo como darle vida a monitores VGA y TVs
analógicos que, dada la acelerada implementación de nuevos estándares en materia de calidad de
señal, han comenzado a abundar como e-waste (aunque en realidad funcionen). La idea va a ser la
de darles una nueva vida para nuestros proyectos. Es una buena forma de combatir la obsolescencia
programada y de conseguir una forma barata (y a veces, mucho mas atractiva) de mostrar
información útil sobre nuestros proyectos. En ese sentido, estaremos usando las
librerías TVOut y VGAx para Arduino (UNO en el caso de VGAx, aunque recientemente salió
un port para el ESP8266 con mucha más resolución, pero con problemas de flickereo y la
imposibilidad de usar el Serial y el Wifi del micro). En los ejemplos finales, yo utilizo ambas
librerías con dos Arduino Nano, pero funcionan bien en la UNO, y en el caso de TVOut, en la
Mega2560. Quedará en ustedes probar como anda en el ESP8266 (con mas resolución). Quieren
ver ejemplos andando? Esto hice hace un tiempo en VGAx
VGAx y TVOut corriendo en Arduino Nano
Este tutorial se va a dividir en dos partes. En esta primera parte vamos a estar viendo el
funcionamiento básico de TVOut. En el segundo estaremos viendo VGAx, y en ambos casos
veremos ejemplos de las principales funcionalidades de ambas librerías. La idea de los tutoriales no
es entrar de forma extensiva en la generacion de video compuesto (TVOut) o señal VGA, para eso
pueden consultar tanto los repositorios de ambas librerias o ver proyectos que anteceden a esto
como el de Nick Gammon. Tampoco vamos a estar inventando la rueda (video compuesto se
genera con microcontroladores hace tiempo). La idea es reutilizar, a bajo costo, y darle una
alternativa visual a los proyectos que realicen. Mirá el resultado final .

TVOut
TVOut es una libreria que ya tiene bastante tiempo entre nosotros, pero que no deja de ser
interesante. En el ejemplo final que vamos a ver acá, la idea va a ser msotrar los usos que puede
tener para visualizar datos en pantalla, como los de un sensor de Humedad y Temepratura DHT11.
Pero en este punto tengo que aclarar que en las nuevas versiones del IDE de Arduino (y del core del
mismo), no pude compilar las librerias SimpleDHT y TVOut si utilizaba al mismo tiempo el
Hardware Serial para debugguear. Pero no importa. Sigamos.
1. Bajar la librería.Lo primero que hay que hacer es bajar la librería, ya sea desde su
repositorio e instalarla manualmente o desde el gestor de librerias. Tambien les recomiendo
instalar SimpleDHT desde el mismo gestor, si van a hacer elejemplo con el sensor DHT11.
2. Un paso importante: la libreria nos permite trabajar con fuentes tipograficas pre armadas -muy
util para mostrar datos-, pero para poder usarlas tenemos que entrar a la carpeta
de Arduino\libraries\TVOut\TVoutfonts y mover su contenido a Arduino\libraries\TVOut
3. Diagrama de conexion.Este es el diagrama de conexión que utilizaremos en el tutorial.Las
resistencias se sueldan al pin central de un cable RCA, y son de 470ohms y 1000ohms (1K). El
buzzer es opcional,dado que tanto TVOut como VGAx permiten generar tonos. El pin 9
corresponde al Sync, y el 7 al Video. Pueden prescindir tanto del DHT11 como del buzzer para las

pruebas.
4. La estructura básica. Normalmente, todo programa que utiliza TVOut debe tener la sigueinte
estructura:
#include <TVout.h> //Incluimos la librería.
#include <fontALL.h> // Si vamos a utilzar fuentes tipograficas
TVout TV; //Creamos nuestra instancia de la libreria TVOut.
void setup(){
// Inicializamos la salida devideo compuesta:

TV.begin(NTSC,120,96); // 120×96 es la resolucion maxima soportada.Podemos elegir la norma


PAL o NTSC.
//Listo, a partir de acá hacemos lo que queremos.

void loop(){

//Acá hacemos lo que queremos

5. Conociendo funcionalidades básicas. TVOut tiene muchas funcionalidades que no vamos a


cubrir en este tutorial,pero la idea es que puedan indagar más en ellas utilizando la wiki del
proyecto. Pero vamos a comentar algunas de las mas significativas. Algo MUY IMPORTANTE: la
esquina superior izquierda de la pantalla corresponde al 0,0 de coordenadas. De ahi hacia la
derecha y hacia abajo, tenemos la resolucion.
TV.delay(ms) . Solo podemos utilizar este tipo de demora al utilizar la libreria TVOut. Es igual al
delay clásico (en este ejemplo abusamos del delay, pero en lo posible trabajen con milis() )
TV.clear_screen() . Esta funcion sencillamente limpia la pantalla, dejandola en negro. Ideal para
cuando mostramos ciertos graficos y queremos mostrar otros luego.
TV.set_pixel(x,y,color). Esta funcion coloca un pixel en la pantalla (recuerden la resolucion
máxima). En color, podemos indicar «0» (negro) o «1» (blanco).
TV.draw_line(x_inicio,y_inicio,x_final,y_final, COLOR). Esta función nos permite dibujar
lineas, indicando posición de inicio y fin. en COLOR podemos elegir WHITE o BLACK.
TV.bitmap(x,y,const unsigned char). También podemos mostrar bitmaps simples almacenados en
PROGMEM como arrays de bytes. Ej: const unsigned char mi_imagen[], indicando en los primeros
dos elementos del array las dimensiones de la imagen.
6. Funciones de escritura. En el caso de la escritura, la librería nos va a pedir indicar lo siguiente:
TV.set_cursor(x,y) . La posicion en la pantalla donde escribiremos el texto.
TV.select_font(font6x8). El tipo de fuente que usaremos. La librería incluye los siguientes
tamaños: 4×6, 6×8 y 8×8.
TV.print(x,y,String). Imprime texto en la posición indicada.
TV.println(«Texto de prueba»). Imprime una línea de texto en la última posición dada por
TV.set_cursor(x,y). La próxima llamada a TV.println() se hará en la línea siguiente a la última
llamada.
7. Nuestro ejemplo explicado. Ahora que conocemos las funciones principales de la librería,
vamos a usar todo en un ejemplo concreto: Mostrar los valores de temperatura y humedad de un
sensor DHT11 en un gráfico cartesiano al mejor estilo dashboard IoT low resolution, así como los
valores propiamente mencionados en formato numérico. La estructura básica de nuestro programa
es esta:
#include <TVout.h>
#include <fontALL.h>

#include <SimpleDHT.h> //Para utilizar el DHT11


TVout TV; //Creamos nuestra instancia de la libreria TVOut.
//Datos para conectar el DHT11:
int pinDHT11 = A0; //Pin
SimpleDHT11 dht11(pinDHT11); //Instanciamos
//Variables para almacenar temp y hum:
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
//Variables para graficar
byte map_pix;
byte x_temp=3;
byte x_hum=3;
byte y;
void setup()
{
intro(); //Mostramos texto en pantalla, separados por delays.
}
void loop()
{
leer_sensor(); //Hacemos una lectura del sensor DHT11
escribir_datos(); //Mostramos esos datos en pantalla
grafico_sensor(int(temperature),false); //Graficamos el valor proporcionalmente
grafico_sensor(int(humidity),true);

TV.delay(1500); //Hacemos todo cada 1500ms.


}
Hasta acá, el programa inicializa las librerías TVOut y SimpleDHT, declaramos algunas variables
que vamos a usar, y agrupamos las funciones principales del programa, que se ejecutan
secuencialmente. Pasemos a hablar de cada una de las funciones (intro(), leer_sensor(),
escribir_datos(), grafico_sensor() ).
void intro(){
TV.begin(NTSC,120,96);
TV.select_font(font6x8);
TV.println(«Ciruja Digital 2018\n»);
TV.delay(1000);
TV.select_font(font4x6);
TV.println(«Tutorial: TVOUT y VGAX\n»);
TV.delay(2000);
TV.println(«Grafico de Sensor DHT11\n»);
TV.delay(2000);
TV.clear_screen();
TV.delay(2000);
TV.select_font(font4x6);
}
En la funcion intro(), inicializamos la generación de video compuesto (TV.begin()), y luego
vamos escribiendo diferentes mensajes que se van actualizando. La duración de los mismos la da
el delay() que coloquemos. Finalmente limpiamos la pantalla y seleccionamos otro tamaño de
fuente para desplegar los datos a continuación.
void leer_sensor(){
if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
return;
}
}
En esta función encapsulamos la lectura del sensor DHT11. Buscando capturar posibles errores,
colocamos un return -que se dispara cuando hay un error de lectura. Colocamos esta función al
principio del loop, por lo que ante un error, no se intenta graficar nada (queda en pantalla lo ultimo
graficado). Los parámetros de dht11.read() se corresponden con las
variables temperature y humidity previamente declaradas.
void escribir_datos(){
TV.set_cursor(0,0);
TV.println(«Temperatura y humedad DHT11\n»);
TV.set_cursor(4,10);
TV.print(«T: «);
TV.print(int(temperature));
TV.print(» oC H: «);
TV.print(int(humidity));
TV.println(» o/o «);
}
Esta función nos escribe en pantalla los valores de temperatura y humedad previamente leídos. Es
importante mencionar que no pueden pasarse como parámetros las variables y texto en formato
cadena sumándolos, pero sí pueden enviarse individualmente. Los valores de temperatura y
humedad en este caso tienen que pasarse a enteros (int), dado que en formato byte no se visualizan.

void grafico_sensor(int sensor, boolean linea_punteada)


{
//Dibujamos los ejes
TV.draw_line(2,93,2,14,WHITE); //eje Y
TV.draw_line(2,93,110,93,WHITE); //ejeX
//Mapeamos los valores a la región de pantalla donde los mostraremos.
map_pix= map(sensor, 0,95, 14,92);

//Para una mejor visualización, reflejamos respecto a la resolución total de pantalla vertical.
y= TV.vres()-map_pix;
if (linea_punteada)
{
x_temp=x_temp+1;

TV.set_pixel(x_temp,y,1);
x_temp=x_temp+1;
TV.set_pixel(x_temp,y,0);

}
else
{
x_hum=x_hum+1;
TV.set_pixel(x_hum,y,1);
x_hum=x_hum+1;
TV.set_pixel(x_hum,y,1);

}
if(x_temp>110 || x_hum>110)
{
x_temp= 3;
x_hum=3;
TV.clear_screen();
}
}

Finalmente algunos comentarios sobre la función que grafica (la parte mas relevante del código).
La misma toma como parámetros la variable a medir y si la misma se graficará con linea punteada
o no. Por un lado, las funciones draw_line grafican los ejes cartesianos donde dibujaremos. Luego
mapeamos los valores leidos por el sensor a la región en pantalla donde los mostraremos.
Con TV.vres() obtenemos la resolución vertical en pixeles, a la cual le restamos el valor mapeado.
Esto nos dará la posición en pantalla en la región «desde abajo» (es decir, en relación a los ejes
cartesianos que graficamos). Luego tenemos dos casos: si llamamos a la función
con linea_punteada=true, se graficaran dos pixeles por valor, uno blanco y otro negro. De lo
ccontrario, ambos serán blancos. Finalmente, cuando las variables que cuentan la cantidad de pixels
en X superen el valor 110 (120 es el maximo de ancho de pantalla), la pantalla se limpia y las
variables que cuentan los pixels en X vuelven a la altura X de los ejes graficados, X=3 en este caso.
Ahora sí, el código completo, algunas fotos y en la próxima parte, VGAx.
/ / DEM O P ARA EL TUTOR I AL DE TVOUT - CI RUJ A DI GI TA L 2 01 8

/ / RESI STENCI A DE 4 70 R: AL P I N 7

/ / RESI STENCI A DE 1 K : AL PI N 9

# I NCLUDE <TVOUT.H> / / LIBRERÍ AS NECES ARI A S

# I NCLUDE <F ONTALL.H> / / SI VAM OS A UTI LZA R F UEN TES TI P OGRAF I C AS

# I NCLUDE <SI M PLEDHT. H>

TVOUT TV; / / CREAM OS NUE STRA I NSTAN CI A DE LA LI BRERI A TVOUT.

/ / DATOS P ARA CONECTA R E L DHT1 1

I NT P I NDHT11 = A0 ; / / PI N

SI MP LEDHT11 DHT11 (P I NDHT1 1 ); // I NSTANCI A M OS

/ / VARI AB LES P ARA ALM ACENAR TEM P Y HUM .

B YTE TEM P ERATURE = 0 ;

B YTE HUMI DI TY = 0 ;

I NT ERR = SI MP LEDHTE RRSUCCESS;

/ / VARI AB LES P ARA GRA F I CAR

B YTE M AP _P I X;

B YTE X_ TEM P=3 ;

B YTE X_ HUM =3 ;

B YTE Y;

VOI D SETUP ()

I NTRO();

VOI D LOOP ()

leer_sensor();

escribir_datos();

GRAF I CO_ SENSOR(I NT(T EMP ERATURE),F ALSE);


GRAF I CO_ SENSOR(I NT(H UM I DI TY),TRUE);

TV.DELAY(1 5 0 0 );

VOI D GRAF I CO_ SENSOR( I NT SENSOR, B OOLEAN LI NEA_ P UNTEADA)

//Dibujamos

TV.draw_line(2,93,2,14,WHITE); //eje Y
TV.draw_line(2,93,110,93,WHITE); //ejeX

map_pix= map(sensor, 0,95, 14,92);


//y=map_pix;
y= TV.vres()-map_pix;

if (linea_punteada)
{
x_temp=x_temp+1;
//y= TV.vres()-map_pix;

TV.SET_ P I XEL(X_ TEMP , Y,1 );

X_ TEMP =X_ TEM P +1 ;

TV.SET_ P I XEL(X_ TEMP , Y,0 );

}
else
{
x_hum=x_hum+1;
TV.set_pixel(x_hum,y,1);
x_hum=x_hum+1;
TV.set_pixel(x_hum,y,1);

}
I F (X_ TEM P>11 0 || X_H UM >1 10 )

X_ TEMP = 3 ;

X_ HUM =3 ;

TV.CLEAR_ SC REEN();

VOI D ESCRI B I R_ DATOS( ){

TV.SET_ CURSOR(0 ,0 );

TV.P RI NTLN(« TEMP ERAT UR A Y HUM EDAD DHT1 1 \ N» );

TV.SET_ CURSOR(4 ,1 0 );

TV.P RI NT(« T: « );

TV.P RI NT(I NT(TEM PERA TU RE));

TV.P RI NT(» OC H: « );

TV.P RI NT(I NT(HUM I DI T Y));

TV.P RI NTLN(» O/ O « );

VOI D LEER_ SENSOR(){

I F ((ERR = DHT1 1.REA D(&TE M P ERATURE, &HUM I DI TY, NULL)) != SI M P LEDHTERRSUCCESS) {

RETURN ;

VOI D I NTRO(){

TV.B EGI N(NTSC,1 20 ,9 6 );

TV.SELECT_ F ONT(F ONT6 X8 );

TV.P RI NTLN(« CI RUJ A DI GI TAL 2 0 18 \ N» );

TV.DELAY(1 0 0 0 );

TV.SELECT_ F ONT(F ONT4 X6 );

TV.P RI NTLN(« TUTORI AL : TVOUT Y VGA X \ N» );

TV.DELAY(2 0 0 0 );

TV.P RI NTLN(« GRAF I CO DE SENSOR DHT1 1 \ N» );

TV.DELAY(2 0 0 0 );

TV.CLEAR_ SC REEN();
TV.DELAY(2 0 0 0 );

TV.SELECT_ F ONT(F ONT4 X6 );

VGAx
En la entrega anterior, pudimos visualizar en un TV de TRC, mediante una señal de video
compuesto generada por Arduino, el gráfico de un sensor DHT11. Ahora vamos a explorar
las potencialidades de VGAx. La librería, en su versión para Arduino UNO al menos, soporta
una resolución de 120×60 y ofrece la posibilidad de brindar imágenes a color en Video
graphics array (osea, vga) en monitores que soporten este formato de imagen. La versión para
ESP8266 soporta más resolución, pero aún así limita otras funciones como la conectividad
Wifi. A fines de no complejizar de más este tutorial, es una visita obligada la documentación
que figura en el repositorio del proyecto VGAx, dado que allí está explicada la forma en la que
trabaja la librería, el esquema de conexiones, qué podemos hacer y que no, cómo generar el
color (no se pueden generar todos los colores, hay que elegir en grupos de a 4 según las
resistencias que pongamos). Desde el vamos, vamos a neceistar un conector hembra
DSUB15 para VGA, 2 resistencias de 470ohms y 2 de 68ohms.

A la izquierda, imagen a 4 colores generada en VGAx apartir de un bitmap convertido a array de


bytes
¿Qué podemos hacer con VGAx?
 Poner pixeles en pantalla (de a uno, o de a 4)
 Poner texto y datos en pantalla usando fuentes personalizadas.
 Generar bitmaps y mostrarlos en pantalla, o sprites.
 Generar tonos de audio simples.
 Como les dije en su momento, esto fue lo que hice con la librería antes.
Algunas consideraciones particulares de VGAx
 La misma ocupa mucho espacio, particularmente en SRAM, si estan pensando en optimizar
sus programas, háganlo. Si estan pensando en utilizar librerias pesadas como Wire para usar
I2C, olvídenlo. En general, el código suele compilar «a tope», aunque nunca da problemas
de inestabilidad. ¿Optimizable? Quizás.
 El autor -Sandro Maffiodi- nos comenta que el PORTD del Atmega328 se encuentra
totalmente reservado por la librería, y por ende no es posible usarlo para otra cosa. Pero los
pines 10 al 13 están disponibles para comunicación SPI (en teoría).
 La señal de video opera por interrupciones. No se pueden agregar más interrupciones o se
corta la señal.
 Los 3 timers del Atmega328 se utilizan en la generación de sincronismo horizontal y
vertical, y en la eliminación de saltos molestos (jittering). Dado que el TIMER0 se usa para
las funciones de demora en Arduino (millis(), delay(), micros(), delayMicroseconds() ), en
lugar de esas funciones hay que usar las que provee la librería.
 Intentando hacer el ejemplo para mostrarles, la idea era usar el DHT11 y graficar lo mismo
que en el tutorial anterior. Pero dado que la libreria SimpleDHT trabaja con las funciones
mencionadas arriba -Y PARA NO COMPLICARLA PARA UDS.- decidí leer sencillamente
un LDR en una entrada analogica (K.I.S.S. = keep it simple and stupid).¿Se puede modificar
la libreria SimpleDHT para poder trabajar con VGAx? Seguro, y se podria crear otra
también para leer los 40bits del DHT11, pero el objetivo de este tutorial no es ese.
 Cada pixel ocupa dos bits. Los posibles valores de los colores son 00, 01, 01 y 11. El color
asignado a cada par de bits va a depender de cómo conecten las resistencias de 470 ohms. En
particular, veremos que VGAx posee una función para colocar 4 pixels en línea (pueden ser
de diferentes colores), por lo que deberemos sumarlos y escribirlos en Hexadecimal (no lo
duden, vayan acá). Por ejemplo, si nuestros colores son negro(00), rojo(01), verde(10) y
amarillo (11), entonces si quisieramos poner una linea donde tuvieramos un pixel negro, otro
verde, y dos amarillos, nos quedaría así: 00101111, que en hexadecimal es 2F ( y que al
usarlo al programar, debemos colocarle 0x delante, es decir 0x2F )
Uso de la librería.

En esta parte, si bien Sandro Maffiodo lo explica bastante bien en la documentación, no está
de más volverlo a escribir. La libreria se incluye y se inicializa de la siguiente manera:

#include <VGAX.h>

VGAX vga; //creamos una instancia de la clase VGAX

void setup() {
vga.begin(); //Inicializamos la generacion de imagen VGA

A partir de acá, podemos empezar a hablar de las funciones principales que tiene la librería:

vga.putpixel(x, y, color) Esta función coloca un pixel en pantalla en las coordenadas


especificadas, con el color que le asignemos (podemos escribirlo en el orden que tienen en la
secuencia de bits (0 primer color, 1 segundo color,etc.)
vga.delay(ms) como el delay comun, pero usar este con la libreria
vga.putpixel4(x, y, suma de los 4 pixels en hex) pone 4 pixels en linea. El ultimo numero es la
suma de los valores de cada pixel en un byte 00 01 10 11.
vga.clear(color) Esto limpia la pantalla llenándola de un color (00 para negro).
VGAX_HEIGHT Constante con la resolución vertical
VGAX_WIDTH Constante con la resolución horizontal.
VGAX_BWIDTH Constante con ancho de pantalla para pixeles agrupados en bytes (4
pixels por byte). Entonces si la resolución horizontal es 120 pixeles, BWIDTH=30. Esto es se
usa al momento de mostrar mapas de bits donde hay que leer lineas de 4 pixeles.
vga.tone(freq) Permite generar un tono en la frecuencia asignada. Los sonidos salen por el
pin A0
vga.noTone() Detiene la generacion de tonos
Escribiendo texto y variables en pantalla
En la carpeta de la libreria vgax en la carpeta tools, Sandro Maffiodo nos provee de 2
herramientas para generar fuentes tipograficas y pasar archivos de imagen a arrays de bits.
Si trabajan con bitmaps, es muy importante que los escalen a la resolución de pantalla antes
de trabajarlos. Para poder escribir, hay que incluir las fuentes generadas. La librería incluye
un tipo de fuente pequeña -que es la que usaremos- Para más detalles sobre esta parte, ver
acá. Las fuentes se deben incluir en un char array, junto con dos definiciones sobre su altura en
pixels y la cantidad de símbolos incluidos.
Dado que el manejo de la RAM es muy limitado, los textos estáticos deben declararse al
inicio del programa con esta estructura, guardandolos en PROGMEM (es decir, en memoria
de programa, no en la memoria volátil).

static const char cadena_texto[] PROGMEM=» VGAX Hello World!»;


¿Y como las mostramos en pantalla? usamos la función vga.printPROGMEM():
VGA.PRINTPROGMEM(BYTE *FNT, BYTE GLYPHSCOUNT, BYTE FNTHEIGHT, BYTE
HSPACE, BYTE VSPACE, CONST CHAR *STR, CHAR DX, CHAR DY0, BYTE COLOR)

Así:
VGA.P RI NTP ROGM EM ((B Y TE* )F NT_ NANOF ONT_ DAT A, F NT_ NANOF ONT_ SYMB OLS_COUNT, F NT_ NANOF ONT_ HEI GHT, 2 , 3 ,

CADEN A_ TEXTO, 1 0 , 1 0 , 0 );

El primer parámetro nos pide el nombre del array donde esta guardada la fuente, el segundo
las definiciones donde guardamos la cantidad de símbolos del array y la altura en pixeles de
los mismos, luego el espacio horizontal y vertical entre ambos, el char array a mostrar, la
posición X e Y, y finalmente el color. En este caso la fuente está guardada en el arrayde
bytes fnt_nanofont_data, la cantidad de símbolos en la
definición FNT_NANOFONT_SYMBOLS_COUNT, la altura en FNT_NANOFONT_HEIGHT, el
espaciado horizontal es 2 pixeles, el vertical 3, la cadena de texto sale de la constante de
caracteres cadena_texto, y la posición X e Y es 10 en ambos casos. El color en este caso es
negro (ocupa la posición 0 en todos los casos).
¿Y si queremos mostrar una variable? Primero tenemos que convertirla a un char array. En
este caso, usamos sprintf para convertir una variable byte a un char array:

sprintf(tiemp,»%03u»,tiempo_contador); //convierto el byte al char array con el que anda


printSRAM.

El primer parámetro es el char array, y el segundo la variable «de origen». Luego


utilizamos vga.printSRAM() de forma similar al texto estático:
vga.printSRAM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT,
FNT_NANOFONT_HEIGHT, 1, 1, tiemp, 25, 5, 2); //var tiemp en pantalla

Algo muy importante: Si actualizan texto en un mismo lugar, tengan en cuenta que si no
borran el fondo, el texto comienza a pisarse hasta no entenderse nada. Una opción sería
utilizar vga.clear(0), pero nos borraría toda la pantalla. ¿Que se puede hacer? En el ejemplo
final, usamos vga.putpixel4 dentro un bucle for y llenamos todo el espacio ocupado por el texto,
pero con el color de fondo, justo antes de reescribirlo. Esto nos «limpia» el espacio de escritura
en cada ciclo, sin borrar toda la pantalla.
Desplegando bitmaps
Como se ve en la primera imagen de esta entrada, podemos desplegar bitmaps según la
escala de colores elegida. Primero tenemos que ir a Arduino\libraries\vgax\tools y abrir
2bitimage en un browser. Luego tendremos que elegir la imagen a transformar en un array
de bits. La imagen debe contener o parecerse lo mayor posibles a la combinación de colores
elegida.
Como output nos dará el array de bytes de la imagen, junto con definiciones sobre el alto,
ancho y el ancho en bytes (BWIDTH).

¿Como lo mostramos en pantalla? Sencillo:

vga.copy((byte*)varname);
¿Y como centramos la imagen? Si ponen una imagen menor al tamaño de la resolución, les
saldra en la esquina superior izquierda. Si quieren centrarla, tienen que crear una imagen del
ancho de la pantalla (y del alto), y centrar en el medio o donde sea la imagen que desean
(todo esto con otro software). Y luego generar el array. Con esa imagen que ocupe toda la
pantalla.

¿Sprites? Se los dejo a ustedes, no es muy difícil, sólo que deberan indagar sobre masked blit y
otras cosas.
Nuestro ejemplo completo
Para nuestro ejemplo vamos a necesitar un LDR conectado de A2 a +5V, y una resistencia de
10K (o de otro valor) conectada de A2 a GND. Acá pueden ver la conexión tanto de TVOut
como de VGAx en Arduino Nano. Miralos andando.
Chaos, pero funciona
El código del ejemplo:

# I NCLUDE <VGAX.H>

VGAX VG A; / / CREAM OS UN A I NSTANCI A DE LA CLASE VGAX

/ / F ONT GENERATED F RO M B ITF ONZI – B Y SANDRO M AF FI ODO

# DEF I NE F NT_ NANOF ONT _ HEI GHT 6

# DEF I NE F NT_ NANOF ONT _ SYM BOLS_ COUNT 9 5

/ / DATA SI ZE=5 7 0 B YTE S

CONST UNSI GNED CHAR F N T_ NANOF ONT_ DATA[F N T_ NANOF ONT_ SYMB OLS_ C OUNT][1 +F NT_ NANOF ONT _ HEI GHT]

P ROGM EM ={

{ 1 , 12 8, 12 8 , 1 28 , 0 , 12 8, 0 , }, // GLYP H ‘!’ CODE=0


{ 3 , 16 0, 16 0 , 0 , 0 , 0, 0 , }, // GLYP H ‘» ‘ CODE=1

{ 5 , 80 , 2 48 , 80 , 2 4 8 , 80 , 0 , }, / /GLYP H ‘# ’ CODE=2

{ 5 , 12 0, 16 0 , 1 12 , 4 0 , 2 40 , 0 , }, / / GLY P H ‘$ ’ CODE=3

{ 5 , 13 6, 16 , 32 , 6 4 , 1 36 , 0 , }, / /GLYP H ‘% ’ CODE=4

{ 5 , 96 , 1 44 , 10 4, 1 4 4 , 1 04 , 0 , }, / / GLY P H ‘&’ CODE=5

{ 2 , 12 8, 64 , 0, 0 , 0 , 0 , }, / / GLYP H » ’ CODE=6

{ 2 , 64 , 1 28 , 12 8, 1 2 8 , 6 4, 0 , }, // GLYP H ‘(‘ CODE=7

{ 2 , 12 8, 64 , 64 , 6 4 , 1 28 , 0 , }, / /GLYP H ‘)’ CODE=8

{ 3 , 0, 16 0 , 6 4, 16 0 , 0 , 0 , }, / / GLYP H ‘ * ’ CODE=9

{ 3 , 0, 64 , 22 4, 64 , 0, 0 , }, // GLYP H ‘+’ CODE=1 0

{ 2 , 0, 0 , 0 , 0 , 12 8 , 64 , }, / / GLYP H ‘,’ CODE=1 1

{ 3 , 0, 0 , 2 24 , 0 , 0 , 0 , }, // GLYPH ‘ -‘ CODE=1 2

{ 1 , 0, 0 , 0 , 0 , 12 8 , 0 , }, // GLYPH ‘.’ CODE=1 3

{ 5 , 8, 16 , 32 , 6 4 , 1 28 , 0 , }, / / GLYP H ‘ / ’ CODE=1 4

{ 4 , 96 , 1 44 , 14 4, 1 4 4 , 9 6, 0 , }, // GLYP H ‘0 ’ CODE=1 5

{ 3 , 64 , 1 92 , 64 , 6 4 , 2 24 , 0 , }, / /GLYP H ‘1 ’ CODE =16

{ 4 , 22 4, 16 , 96 , 1 2 8 , 24 0, 0 , }, // GLYP H ‘2 ’ CODE=1 7

{ 4 , 22 4, 16 , 96 , 1 6 , 2 24 , 0 , }, / /GLYP H ‘3 ’ CODE=18

{ 4 , 14 4, 14 4 , 2 40 , 1 6 , 1 6, 0 , }, // GLYP H ‘4 ’ CODE=1 9

{ 4 , 24 0, 12 8 , 2 24 , 1 6 , 2 24 , 0 , }, / / GLY P H ‘5 ’ CODE=20

{ 4 , 96 , 1 28 , 22 4, 1 4 4 , 9 6, 0 , }, // GLYP H ‘6 ’ CODE=2 1

{ 4 , 24 0, 16 , 32 , 6 4 , 6 4, 0 , }, // GLYP H ‘7 ’ CODE=22

{ 4 , 96 , 1 44 , 96 , 1 4 4 , 96 , 0 , }, / /GLYP H ‘8 ’ CODE=23

{ 4 , 96 , 1 44 , 11 2, 1 6 , 96 , 0 , }, / /GLYP H ‘9 ’ CODE=24

{ 1 , 0, 12 8 , 0 , 1 28 , 0, 0 , }, // GLYP H ‘:’ CODE=2 5

{ 2 , 0, 12 8 , 0 , 0 , 1 2 8, 64 , }, / / GLYP H ‘;’ CODE=2 6

{ 3 , 32 , 6 4 , 1 28 , 6 4 , 3 2, 0 , }, // GLYP H ‘<‘ CODE=2 7

{ 3 , 0, 22 4 , 0 , 2 24 , 0, 0 , }, // GLYP H ‘=’ CODE=2 8

{ 3 , 12 8, 64 , 32 , 6 4 , 1 28 , 0 , }, / /GLYP H ‘>’ CODE=2 9

{ 4 , 22 4, 16 , 96 , 0 , 64 , 0 , }, / / GLYP H ‘? ’ CODE=30

{ 4 , 96 , 1 44 , 17 6, 1 2 8 , 1 12 , 0 , }, / / GLYP H ‘@ ’ CO DE=31

{ 4 , 96 , 1 44 , 24 0, 1 4 4 , 1 44 , 0 , }, / / GLY P H ‘A’ CODE=3 2

{ 4 , 22 4, 14 4 , 2 24 , 1 44 , 22 4, 0 , }, / / GL YP H ‘B ’ CODE=3 3

{ 4 , 11 2, 12 8 , 1 28 , 1 28 , 11 2, 0 , }, / / GL YP H ‘C’ CODE=3 4

{ 4 , 22 4, 14 4 , 1 44 , 1 44 , 22 4, 0 , }, / / GL YP H ‘D’ CODE=3 5
{ 4 , 24 0, 12 8 , 2 24 , 1 28 , 24 0, 0 , }, / / GLYP H ‘E’ CODE=3 6

{ 4 , 24 0, 12 8 , 2 24 , 1 28 , 12 8, 0 , }, / / GL YP H ‘F ’ CODE=37

{ 4 , 11 2, 12 8 , 1 76 , 1 44 , 11 2, 0 , }, / / GL YP H ‘G’ CODE=3 8

{ 4 , 14 4, 14 4 , 2 40 , 1 44 , 14 4, 0 , }, / / GL YP H ‘H’ CODE=3 9

{ 3 , 22 4, 64 , 64 , 6 4 , 2 24 , 0 , }, / /GLYP H ‘I ’ CODE=40

{ 4 , 24 0, 16 , 16 , 1 4 4 , 96 , 0 , }, / /GLYP H ‘J ’ CODE=41

{ 4 , 14 4, 16 0 , 1 92 , 1 60 , 14 4, 0 , }, / / GL YP H ‘K’ CODE=4 2

{ 4 , 12 8, 12 8 , 1 28 , 1 28 , 24 0, 0 , }, / / GL YP H ‘L’ CODE=4 3

{ 5 , 13 6, 21 6 , 1 68 , 1 36 , 13 6, 0 , }, / / GL YP H ‘M ’ CODE=4 4

{ 4 , 14 4, 20 8 , 1 76 , 1 44 , 14 4, 0 , }, / / GLYP H ‘N’ CODE=4 5

{ 4 , 96 , 1 44 , 14 4, 1 4 4 , 9 6, 0 , }, // GLYP H ‘O’ CODE=46

{ 4 , 22 4, 14 4 , 2 24 , 1 28 , 12 8, 0 , }, / / GL YP H ‘P ’ CODE=47

{ 4 , 96 , 1 44 , 14 4, 1 4 4 , 9 6, 16 , }, / / GLY P H ‘Q’ CODE=4 8

{ 4 , 22 4, 14 4 , 2 24 , 1 60 , 14 4, 0 , }, / / GL YP H ‘R’ CODE=4 9

{ 4 , 11 2, 12 8 , 9 6, 1 6 , 22 4, 0 , }, // GLYP H ‘S’ CODE=50

{ 3 , 22 4, 64 , 64 , 6 4 , 6 4, 0 , }, // GLYP H ‘T’ CODE=5 1

{ 4 , 14 4, 14 4 , 1 44 , 1 44 , 96 , 0 , }, / / GLY P H ‘U’ CODE=5 2

{ 3 , 16 0, 16 0 , 1 60 , 1 60 , 64 , 0 , }, / / GLY P H ‘V’ CODE=5 3

{ 5 , 13 6, 16 8 , 1 68 , 1 68 , 80 , 0 , }, / / GLY P H ‘W’ CODE=5 4

{ 4 , 14 4, 14 4 , 9 6, 1 4 4 , 1 44 , 0 , }, / / GLY P H ‘X’ CODE=5 5

{ 3 , 16 0, 16 0 , 6 4, 6 4 , 64 , 0 , }, / /GLYP H ‘Y’ CODE=5 6

{ 4 , 24 0, 16 , 96 , 1 2 8 , 24 0, 0 , }, // GLYP H ‘Z’ CODE=5 7

{ 2 , 19 2, 12 8 , 1 28 , 1 28 , 19 2, 0 , }, / / GL YP H ‘[‘ CODE=5 8

{ 5 , 12 8, 64 , 32 , 1 6 , 8 , 0 , }, / / GLYP H ‘ \ ’ CODE=5 9

{ 2 , 19 2, 64 , 64 , 6 4 , 1 92 , 0 , }, / /GLYP H ‘]’ CODE=6 0

{ 5 , 32 , 8 0 , 1 36 , 0 , 0, 0 , }, // GLYP H ‘^ ’ CODE=6 1

{ 4 , 0, 0 , 0 , 0 , 24 0 , 0 , }, // GLYPH ‘_ ’ CODE=6 2

{ 2 , 12 8, 64 , 0, 0 , 0 , 0 , }, / / GLYP H ‘`’ CODE=6 3

{ 3 , 0, 22 4 , 3 2, 22 4 , 2 24 , 0 , }, / /GLYP H ‘A’ COD E=6 4

{ 3 , 12 8, 22 4 , 1 60 , 1 60 , 22 4, 0 , }, / / GL YP H ‘B ’ CODE=6 5

{ 3 , 0, 22 4 , 1 28 , 1 2 8 , 22 4, 0 , }, // GLYP H ‘C’ CODE=6 6

{ 3 , 32 , 2 24 , 16 0, 1 6 0 , 2 24 , 0 , }, / / GLY P H ‘D’ CODE=6 7

{ 3 , 0, 22 4 , 2 24 , 1 2 8 , 22 4, 0 , }, // GLYP H ‘E’ CODE=68

{ 2 , 64 , 1 28 , 19 2, 12 8 , 1 28 , 0 , }, / / GLYP H ‘F ’ CODE= 69

{ 3 , 0, 22 4 , 1 60 , 2 2 4 , 32 , 2 24 , }, / / GLY P H ‘G’ CODE=7 0


{ 3 , 12 8, 22 4 , 1 60 , 1 60 , 16 0, 0 , }, / / GL YP H ‘H’ CODE=7 1

{ 1 , 12 8, 0 , 1 28 , 1 2 8 , 12 8, 0 , }, // GLYP H ‘I ’ CODE=72

{ 2 , 0, 19 2 , 6 4, 64 , 64 , 1 28 , }, / /GLYP H ‘J ’ CODE=73

{ 3 , 12 8, 16 0 , 1 92 , 1 60 , 16 0, 0 , }, / / GL YP H ‘K’ CODE=7 4

{ 1 , 12 8, 12 8 , 1 28 , 1 28 , 12 8, 0 , }, / / GL YP H ‘L’ CODE=7 5

{ 5 , 0, 24 8 , 1 68 , 1 6 8 , 16 8, 0 , }, // GLYP H ‘M ’ CODE=7 6

{ 3 , 0, 22 4 , 1 60 , 1 6 0 , 16 0, 0 , }, // GLYP H ‘N’ CODE=7 7

{ 3 , 0, 22 4 , 1 60 , 1 6 0 , 22 4, 0 , }, // GLYP H ‘O’ CODE= 78

{ 3 , 0, 22 4 , 1 60 , 1 6 0 , 22 4, 12 8 , }, / / GL YP H ‘P ’ CODE=79

{ 3 , 0, 22 4 , 1 60 , 1 6 0 , 22 4, 32 , }, / / GLY P H ‘Q’ CODE=8 0

{ 3 , 0, 22 4 , 1 28 , 1 2 8 , 12 8, 0 , }, // GLYP H ‘R’ CODE=8 1

{ 2 , 0, 19 2 , 1 28 , 6 4 , 1 92 , 0 , }, / /GLYP H ‘S’ CODE=8 2

{ 3 , 64 , 2 24 , 6 4 , 6 4 , 6 4, 0 , }, // G LYP H ‘T’ CODE=8 3

{ 3 , 0, 16 0 , 1 60 , 1 6 0 , 22 4, 0 , }, // GLYP H ‘U’ CODE=8 4

{ 3 , 0, 16 0 , 1 60 , 1 6 0 , 64 , 0 , }, / /GLYP H ‘V’ CODE=8 5

{ 5 , 0, 16 8 , 1 68 , 1 6 8 , 80 , 0 , }, / /GLYP H ‘W’ CODE=8 6

{ 3 , 0, 16 0 , 6 4, 16 0 , 1 60 , 0 , }, / /GLYP H ‘X’ CODE=8 7

{ 3 , 0, 16 0 , 1 60 , 2 24 , 32 , 2 24 , }, / / GLYP H ‘Y’ CODE=8 8

{ 2 , 0, 19 2 , 6 4, 12 8 , 1 92 , 0 , }, / /GLYP H ‘Z’ CODE=8 9

{ 3 , 96 , 6 4 , 1 92 , 6 4 , 9 6, 0 , }, // GLYP H ‘{‘ CODE=9 0

{ 1 , 12 8, 12 8 , 1 28 , 1 28 , 12 8, 0 , }, / / GL YP H ‘|’ CODE=9 1

{ 3 , 19 2, 64 , 96 , 6 4 , 1 92 , 0 , }, / /GLYP H ‘}’ CODE=9 2

{ 3 , 96 , 1 92 , 0, 0 , 0 , 0 , }, / / GLYP H ‘~’ CODE=93

{ 4 , 48 , 6 4 , 2 24 , 6 4 , 2 40 , 0 , }, / /GLYP H ‘£ ’ CODE=94

};

/ / IM AGE GENERATED F R OM 2B I TI M AGE – B Y SANDRO M AFF I ODO

# DEF I NE IM G_ CI RUJ A_ W I DTH 1 20

# DEF I NE IM G_ CI RUJ A_B WIDTH 3 0

# DEF I NE IM G_ CI RUJ A_ H EI GHT 6 0

/ / DATA SI ZE=1 8 0 0 B YTES

CONST UNSI GNED CHAR I M G_ CI RUJ A_ DATA[I M G_ CI RUJ A_ HEI GHT][IM G_ C I RUJ A_BWI DTH] P ROGM E M ={

{ 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 7 0, 17 0 , 1 71 ,

2 5 5, 25 5 , 2 55 , 2 55 , 25 5, 25 5 , 2 55 , 19 2 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 1 0, 17 0 , 1 70 , 1 70 , 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 17 0 , 1 70 ,

1 7 0, 17 0 , 1 28 , 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 17 0 , 1 7 0, 17 0 , 1 70 , 1 70 , 17 0, 1 7 0 , 1 70 , 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 2 8, 0 , 0 , 0 , 0,

0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0, 1 70 , 17 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 17 0 , 1 70 , 1 70 , 1 7 0, 1 70 , 12 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0, 0 , 0, 0 , 0 , 0 ,
0 , 0 , 1 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0, 1 70 , 17 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 17 0, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 17 0 , 1 70 , 17 0,

1 7 0, 17 0 , 1 70 , 1 70 , 17 0, 17 8 , 1 70 , 17 0 , 1 70 , 1 70 , 17 0, 12 8 , 0 , 0 , 0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 10 , 1 70 , 17 0 , 17 0 , 1 70 , 1 70 , 1 7 0, 17 0 , 1 71 ,

2 5 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 28 , 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 1 70 , 17 0, 17 0 , 1 70 , 17 0 , 1 70 , 1 60 , 2 5 5, 25 0 , 1 70 , 1 7 0, 1 7 0 , 1 70 ,

1 7 0, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 1 0 , 1 70 , 1 70 , 1 7 0, 17 0 , 1 70 , 1 28 , 42 , 1 91 , 2 4 2, 1 70 , 17 0, 17 0 , 1 70 , 1 70 , 12 8, 0, 0 , 0, 0 , 0 , 0 ,

}, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 17 0, 1 7 0 , 17 0, 17 0 , 1 68 , 4 2 , 1 70 , 1 70 , 24 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 2 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,

1 0 , 1 70 , 17 0, 17 0 , 1 70 , 1 62 , 17 0, 1 70 , 1 7 0, 16 0 , 4 2, 17 0 , 1 70 , 1 70 , 17 0 , 1 28 , 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 10 , 1 70 , 170 , 17 0 , 1 70 ,

1 0 , 1 70 , 17 0, 17 0 , 1 70 , 1 30 , 17 0, 1 70 , 1 7 0, 17 0 , 1 28 , 0 , 0, 0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0, 1 70 , 17 0, 17 0 , 1 68 , 4 2 , 1 70 , 1 70 , 17 0 , 1 70 ,

1 6 8, 17 0 , 1 70 , 1 70 , 17 0, 12 8 , 0 , 0 , 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0, 17 0 , 1 70 , 1 70 , 16 8, 17 0, 1 70 , 17 0, 17 0 , 1 70 , 1 70 , 42 , 1 70 , 17 0 , 1 70 ,

1 2 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 10 , 17 0, 17 0 , 1 70 , 1 6 2, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 42 , 17 0, 17 0 , 1 70 , 1 28 , 0, 0 , 0 , 0 , 0 , 0 , }, {

0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 10 , 1 70 , 170 , 42 , 13 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 13 8, 17 0 , 1 70 , 1 70 , 12 8, 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0, 0 , 0, 0 , 1 0,

1 7 0, 17 0 , 5 8, 17 8 , 1 70 , 1 70 , 17 0, 1 70 , 1 7 0, 17 0 , 1 62 , 1 70 , 1 7 0, 17 0 , 1 28 , 0, 0 , 0 , 0 , 0 , 0 , }, { 0 , 0, 0 , 0 , 0 , 0 , 0 , 0, 10 , 17 0, 17 0 , 19 1 , 2 50 , 17 0,

1 7 0, 17 1 , 2 34 , 1 70 , 17 0, 16 2 , 1 70 , 17 0 , 1 70 , 1 28 , 0, 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 10 , 170 , 17 0 , 1 75 , 2 34 , 17 0, 17 0 , 2 55 , 2 5 0, 17 0 , 1 70 ,

1 7 0, 17 0 , 1 70 , 1 70 , 12 8, 0 , 0 , 0 , 0 , 0 , 0 , }, { 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 1 0 , 1 70 , 1 7 0 , 17 5 , 23 4 , 1 70 , 1 7 1 , 25 5 , 2 55 , 2 55 , 17 0, 16 8 , 1 70 , 1 7 0, 17 0 , 1 28 ,

0 , 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 1 70 , 1 70 , 17 5, 23 4 , 1 7 0, 17 5 , 2 51 , 2 55 , 25 5, 23 4 , 1 68 , 17 0 , 1 70 , 1 70 , 12 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0,

0 , 0 , 0 , 0 , 0, 0 , 1 0 , 17 0 , 1 70 , 1 71 , 17 0 , 1 70 , 1 91 , 17 0, 25 0 , 1 75 , 2 5 0, 16 8 , 1 70 , 1 70 , 17 0, 12 8 , 0 , 0 , 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0, 17 0 ,

1 7 0, 17 1 , 1 70 , 1 71 , 25 4, 17 0 , 2 50 , 17 1 , 2 50 , 1 68 , 17 0, 17 0 , 1 70 , 1 2 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 10 , 17 0, 17 0 , 1 68 , 1 7 0, 17 1 , 2 50 ,

1 7 0, 25 0 , 1 91 , 2 34 , 16 8, 17 0 , 1 70 , 17 0 , 1 28 , 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 10 , 1 70 , 170 , 16 8 , 1 70 , 1 75 , 23 4, 17 0 , 2 51 , 2 5 5, 17 0 , 1 71 ,

1 7 0, 17 0 , 1 70 , 1 28 , 0, 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 1 0 , 1 7 0, 17 0 , 1 68 , 1 70 , 19 1, 17 0 , 1 70 , 25 5 , 2 50 , 1 70 , 17 1, 23 4 , 1 70 , 1 7 0, 12 8 , 0 , 0 ,

0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 17 0, 17 0 , 1 68 , 1 70 , 19 1, 23 8 , 1 71 , 2 5 5, 23 4 , 1 70 , 1 75 , 2 3 4, 1 70 , 17 0, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 ,

0 , 0 , 0 , 0 , 10 , 1 70 , 17 0, 17 0 , 1 70 , 17 5 , 2 55 , 1 75 , 25 4, 17 0 , 1 70 , 1 7 5, 23 4 , 1 70 , 1 70 , 12 8, 0 , 0 , 0 , 0 , 0 , 0 , }, { 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 1 0 , 1 70 , 1 70 ,

1 7 0, 42 , 17 1, 25 5 , 1 75 , 2 50 , 17 0, 1 70 , 1 7 5, 25 0 , 1 70 , 1 70 , 1 2 8, 0, 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0, 0 , 0, 10 , 17 0, 17 0 , 1 70 , 4 2 , 1 70 , 17 0 , 1 70 ,

1 7 0, 17 0 , 1 70 , 1 91 , 25 0, 17 0 , 1 70 , 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 1 0, 17 0 , 1 70 , 1 70 , 13 8 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 10 , 16 2,

1 7 0, 17 0 , 1 28 , 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 17 0 , 1 7 0, 17 0 , 1 38 , 1 70 , 17 0, 17 0 , 1 70 , 17 0 , 1 70 , 1 0 , 1 70 , 1 70 , 17 0, 12 8 , 0 , 0, 0 , 0 ,

0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0, 1 70 , 17 0, 17 0 , 1 62 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 17 0 , 4 2, 17 0 , 1 7 0 , 1 7 0, 12 8 , 0 , 0 , 0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0,

0 , 0 , 1 0, 17 0 , 1 70 , 1 70 , 16 8, 17 0, 1 70 , 17 0, 17 0 , 1 70 , 1 68 , 17 0, 17 0 , 1 70 , 17 0, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 17 0 , 1 70 , 17 0,

1 7 0, 42 , 17 0, 17 0 , 1 70 , 1 70 , 16 2, 1 70 , 1 7 0, 17 0 , 1 70 , 1 28 , 0 , 0 , 0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 17 0, 17 0 , 1 70 , 1 70 , 13 8, 17 0 , 1 70 , 17 0,

1 7 0, 13 8 , 1 70 , 1 70 , 17 0, 17 0 , 1 28 , 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 1 70 , 17 0, 17 0 , 1 70 , 16 0 , 5 8, 17 0 , 1 7 0 , 1 68 , 42 , 1 70 , 17 0 , 1 70 ,

1 7 0, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 1 0 , 1 70 , 1 70 , 1 7 0, 17 0 , 1 70 , 6 3 , 1 70 , 1 70 , 13 0, 1 70 , 1 7 0, 17 0 , 1 70 , 1 70 , 1 2 8, 0, 0 , 0, 0 , 0 , 0 ,

}, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 17 0, 1 7 0 , 17 0, 17 0 , 1 70 , 1 9 1 , 25 2, 0, 4 2 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 28 , 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 ,

1 7 0, 17 0 , 1 70 , 1 70 , 17 0, 19 1 , 2 50 , 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 1 0 , 1 70 , 1 70 , 1 7 0, 1 7 0 , 1 70 ,

1 9 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 17 0 , 1 70 , 1 28 , 0, 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 10 , 170 , 17 0 , 1 70 , 1 70 , 17 0, 42 , 17 0, 17 0 , 1 70 , 17 0,

1 7 0, 17 0 , 1 70 , 1 70 , 12 8, 0 , 0 , 0 , 0 , 0 , 0 , }, { 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 1 0 , 1 70 , 1 70 , 17 0 , 17 0 , 1 70 , 1 70 , 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 17 0 , 1 28 ,

0 , 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 1 70 , 1 7 0 , 17 4, 17 0 , 1 7 0, 17 0 , 1 70 , 1 70 , 23 4, 17 0 , 1 70 , 17 0 , 1 70 , 1 7 0 , 12 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0,

0 , 0 , 0 , 0 , 0, 0 , 1 0 , 17 1 , 2 38 , 2 55 , 23 5 , 1 70 , 2 34 , 23 4, 17 5 , 2 51 , 1 7 5, 23 9 , 2 54 , 1 75 , 18 6, 12 8 , 0 , 0 , 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0, 17 4 ,

2 3 8, 23 9 , 2 39 , 1 71 , 23 5, 2 3 4 , 1 71 , 18 7 , 1 91 , 1 74 , 25 0, 19 0 , 2 50 , 1 2 8, 0 , 0 , 0 , 0, 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 10 , 18 6, 19 0 , 2 39 , 1 7 4, 18 7 , 1 75 ,
2 3 4, 17 5 , 1 91 , 2 50 , 19 0, 23 4 , 2 54 , 23 4 , 1 28 , 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 10 , 2 50 , 187 , 25 1 , 1 74 , 2 51 , 25 5, 23 4 , 1 74 , 2 5 4, 23 9 , 1 86 ,

2 3 5, 25 4 , 2 34 , 1 28 , 0, 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 1 0, 2 5 0, 18 7 , 1 87 , 1 90 , 23 9, 25 1 , 1 70 , 19 1 , 2 39 , 2 39 , 18 7, 17 1 , 1 91 , 2 5 4, 12 8 , 0 , 0 ,

0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 10 , 25 4, 19 1 , 1 87 , 2 50 , 25 4, 17 1 , 1 70 , 19 1, 17 5 , 2 54 , 2 35 , 17 0, 1 91 , 25 4, 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 ,

0 , 0 , 0 , 0 , 10 , 1 70 , 17 0, 17 0 , 1 70 , 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 1 7 0, 17 0 , 1 70 , 1 70 , 12 8, 0 , 0 , 0 , 0 , 0 , 0 , }, { 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 1 0 , 1 70 , 1 70 ,

1 7 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 17 0 , 1 70 , 1 70 , 17 0 , 17 0 , 1 28 , 0 , 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 7 0, 17 0 , 1 70 ,

1 7 0, 17 0 , 1 70 , 1 70 , 17 0, 17 0 , 1 70 , 12 8 , 0 , 0 , 0, 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 1 0, 17 0 , 1 70 , 1 70 , 17 0 , 1 70 , 1 7 0 , 17 0, 17 0 , 1 70 , 1 7 0, 17 0 , 1 70 ,

1 7 0, 17 0 , 1 28 , 0 , 0, 0 , 0 , 0 , 0, }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,

0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0, 0 , 0 , 0 , 0, 0 , }, { 0 , 0 , 0 , 0, 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , }, { 0 , 0 ,

0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0 , 0 , }, { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0 , 0 , 0, 0 , 0, 0 , 0 , 0 ,

0 , 0 , 0 , 0 , }, };

STATI C CONST CHA R ST R0 [] P ROGM EM =» CI RUJ A DI GI TAL 2 0 18 -VGAX LDR» ;

I NT LDR;

I NT M AP_ PI X;

I NT X_ TEMP =36 ;

I NT Y;

VOI D SETUP () {

VGA.B EGI N(); / /I NI CI ALI ZAM OS LA GENERACI ON DE I M AGEN VGA

VGA.COP Y((B YTE* )IM G_ CI RUJ A_ DATA); / / M OST RAM OS UNA I M AGEN GUAR DA DA E N UN A RRA Y DE B YTES

VGA.P RI NTP ROGM EM ((B Y TE* )F NT_ NANOF ONT_ DAT A, F NT_ NANOF ONT_ SYMB OLS_COUNT, F NT_ NANOF ONT_ HEI GHT, 1 , 1 ,

STR0 , 2 , 5 5 , 1 ); // T EXTO I NI CI AL

VGA.DELAY(6000);
VGA.CLEAR(0);
}

VOI D LOOP () {

LDR = ANALOGREAD(A2);
ESCRIBIR_DATOS();
GRAFICO_SENSOR(LDR);
VGA.DELAY(100);
}
VOI D GRAF I CO_ SENSOR( I NT SENSOR){

/ / DIB UJ AM OS LOS EJ ES

F OR (B YTE I =2 ; I < V GAX_ WI DTH; I ++) { / / EJ EX

VGA.P UTP I XEL(I ,VGAX_ HEIGHT -2 ,1 );

F OR (B YTE I =2 ; I < V GAX_ HEI GHT; I ++) { / / EJ EY

VGA.P UTP I XEL(3 ,I,1 ) ; //

M AP _P I X= M AP (SENSOR, 0 ,10 2 3, 2 ,6 0 );

Y= VGAX_WIDTH-MAP_PIX;

X_ TEMP =X_ TEM P +1 ;

VGA.P UTP I XEL(X_ TEMP , Y,3);

IF(X_TEMP>154) {
X_TEMP= 36;

VGA.CLEA R(0 );

VOI D ESCRI B I R_ DATOS( ){

CHAR CH AR_ TEM P [4 ];

F OR (I NT I =1 2 ; I < =16 ;I ++) / /CON ESTO LI MP I AMOS CONSTANTEM ENTE LOS P I XELS DOND E SE ACT UALI ZA LA V A RI AB LE.

{ VGA.P UTP I XEL4 (I ,10 ,0 XFF );

VGA.P UTP I XEL4 (I ,1 1,0 XFF );

VGA.P UTP I XEL4 (I ,1 2,0 XFF );

VGA.P UTP I XEL4 (I ,1 3,0 XFF );

VGA.P UTP I XEL4 (I ,1 4,0 XFF );

SP RI NTF (CHAR_ TEMP ,»% 03U» ,LDR); / / C ONVI ERTO EL BYTE AL CHAR ARR AY CO N EL QU E ANDA P RI NTSR AM .

SP RI NTF (CHAR_ ARRA Y;» % 03 U» ,VARI AB LE B YTE)


VGA.PRINTPROGMEM((BYTE*)FNT_NANOFONT_DATA,
FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 1, 1, STR0, 4, 2, 2);
//IMPRIME CHAR ARRAY EN PROGMEM

VGA.PRINTSRAM((BYTE*)FNT_NANOFONT_DATA,
FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 1, 1, CHAR_TEMP,
50, 10, 2); //VALOR

También podría gustarte