miércoles, 1 de febrero de 2012

Pintando con 8 bits


Después de las pruebas de color explicaré un poco como voy a pintar con una profundidad de color de 8 bits.

8 bits = 1 byte = 256 colores

Un color de 24 bits lo representamos utilizando un byte para cada uno de los componentes de la siguiente forma: RGB(255,255,255) o HEX(FFFFFF) para el blanco y RGB(0,0,0) o HEX(000000) para el negro. Y uno de 32 bits: ARGB(255,255,255,255) o HEX(FFFFFFFF) para el blanco opaco y ARGB(0,0,0,0) o HEX(00000000) para el negro transparente. Entonces ¿Cómo se consigue un color de 8 bits? De la siguiente forma:

Rojo: 3 bits
Verde: 3 bits
Azul: 2 bits

Así que 255 sería el blanco y 0 en negro. Si lo descomponemos en bits: BIN(11111111) y BIN(00000000).

Rojo: 11100000
Verde: 00011100
Azul: 00000011

 
Para representar esto con Arduino necesitamos utilizar un puerto de 8 bits (8 pins) para escribir todo el byte a la vez. Arduino Duemilanove y Arduino UNO cuentan con 3 puertos:

PORTB: Pins 8 .. 13 (6 bits)
PORTC: Pins A0 .. A5 (6 bits)
PORTD: Pins 0 .. 7 (8 bits)
 
Podríamos utilizar el puerto D y obtener 8 bits, pero los pins 0 y 1 se utilizan en la comunicación serie y perderíamos esta funcionalidad. Otras placas como el Arduino Nano, cuentan con 2 pins analógicos más, A6 y A7, por lo tanto tenemos:

PORTC: Pins A0 .. A7 (8 bits)

Pero si utilizamos este puerto para pintar 256 colores perderemos todas las entradas analógicas, y seguro que en el futuro las necesitamos para conectar mandos analógicos como por ejemplo dos potenciómetros para jugar al Pong.

Mi elección es Arduino Mega ya que cuenta con 11 puertos, del puerto A al puerto L, excepto el puerto I (Más info). Además de 16 pins analógicos dividido en 2 puertos (F y K), cuatro puertos serie y 8K de memoria RAM.


Arduino MEGA raw CPU port names
Imagen original (Westfw - CC BY-SA 2.0)


Utilizaré de momento el puerto C que es el que he estado utilizando hasta ahora y cuenta con 8 bits, del pin 30 al 37, para generar la señal de video y el bit 0 del puerto B para generar la sincronía (pin 53).


Y ¿Cómo convertimos los 8 bits de información digital a 3 componentes de señal analógica? Pues con un DAC (Digital to analog converter), concretamente con el método de las "resistencias ponderadas". Utilizando un número de resistencias igual al número de bits que queramos convertir y conectadas en paralelo. El bit más significativo tendrá la menor resistencia, el siguiente bit tendrá una resistencia del doble de valor y así sucesivamente hasta el menos significativo.


Veamos el ejemplo de Arduino Pong:

Se utilizan 2 bits para generar los valores de sincronía, negro, gris y blanco; siendo el gris el término medio entre el blanco y el negro:

 
// Video out voltage levels
#define _SYNC 0x00
#define _BLACK 0x01
#define _GRAY 0x02
#define _WHITE 0x03
 

En el siguiente esquema vemos que el bit más significativo (pin 9) tiene una resistencia de 450Ω y el menos significativo una de 900Ω, el doble. La resistencia de 75Ω es la resistencia de impedancia, que va conectada en paralelo a tierra. La impedancia para televisiones y monitores es de 75Ω.

Arduino Pong Schematic
(Alastair Parker)

Aquí dejo un link de la web de Javier Valcarce donde viene todo clarísimamente explicado.

Es hora de aplicar el DAC al código de ejemplo que utilicé en el post anterior. Para ello voy a utilizar los mismos valores de resistencias que utiliza Uzebox: 3K, 1K5 y 750Ω, además de la resistencia de impedancia de 75Ω.

Uzebox SCART Interface
Imagen original (Belogic - CC BY-SA 3.0)
 
Los canales rojo y verde se componen de 3 bits cada uno, o sea que tienen 8 valores posibles, desde B000 hasta B111. El canal azul sólo utiliza 2 bits, así que sus valores irán desde B00 hasta B11.

Esquema de conexión
Resultado en el monitor


El código de ejemplo muestra una paleta de 256 colores a toda pantalla.
Lo podéis descargar aquí.


Para el próximo post: Más resolución…

No hay comentarios:

Publicar un comentario