lunes, 15 de agosto de 2011

Miniproyecto: Controlando un LED RGB (I)


Me encantan las luces de colores... ¿Y a quién no? :)


Hace unos días compré un par de LEDs RGB. Al parecer, con ellos se puede obtener una amplia gama de colores e intensidades. Tienen 4 patillas. Una de ellas es el cátodo común (la más larga) y el resto pertenece cada una a un color (sí, Red, Green y Blue :P).


Para mayor detalle, éste es el conexionado interno del LED RGB:


De modo que habrá que conectar el cátodo común a tierra (0V) y las patillas correspondientes a los colores a salidas de nuestro microcontrolador (en este caso, Arduino) con algunas resistencias de por medio. Dado que por el LED deben pasar unos 20mA, las salidas de Arduino son TTL (5V), y usando la Ley de Ohm, deberíamos poner resistencias de:

R = 5V / 0.02A = 250Ω

Como no tengo de 250Ω, usaré de 330Ω (siempre por encima para proteger el LED). La corriente que pasará por los LED será como máximo de:

I = 5V / 330Ω = 15mA




Una vez conectado todo, es momento de programar un poco. Se me ocurre hacer un programa que nos permita elegir un color en formato RGB para el LED usando el Serial Monitor de Arduino. Por simplificar un poco, el programa admitirá número de tres cifras. La primera indicará el nivel de Red, la segunda el nivel de Green y la tercera el nivel de Blue. Así, nuestro programa será capaz de reconocer y representar 1000 colores.


Ejemplo - Abriendo el Serial Monitor e introduciendo 900, el LED debería encenderse en rojo con intensidad máxima. Con 050 debería hacerlo en verde con intensidad media, y con 001 en azul con intensidad baja. Introduciendo otros valores, como 385, deberíamos obtener los 997 colores e intensidades restantes. Por último, introduciendo 000 el LED debería apagarse.


En el código (más abajo) se leen primero las tres cifras que se introduzcan en el Serial Monitor. He tenido que poner un par de delay(50) porque si no había problemas de lectura (por ir con prisas ;) ). Luego se convierten a formato numérico los valores leídos (los introducimos con el teclado y el programa las recibe en código ASCII). Después de imprime una confirmación de los datos recibidos para verla en el Serial Monitor y, por último, se enciende el LED.


Al recibir valores para cada color comprendidos entre 0 y 9, hay que hacer un ¿cambio de escala? a los valores de analogWrite, que van de 0 a 255. Por simplificar (no me apetecía usar calculadora), he realizado la conversión:

valor_0-255 = (valor_0-9 / 10) x 255 = valor_0-9 x 25.5


Ejemplo - Si introducimos un valor de 9 para el color rojo, después de la conversión el valor que le estaremos dando a analogWrite es de 9 x 25.5 = 229.5


---

Posibles mejoras:

- Parece que el LED recibe demasiada corriente. Quizás convendría poner resistencias algo mayores.

- Se podrían añadir al proyecto tres potenciómetros que controlasen los niveles de color. Así no necesitaríamos un PC y podríamos hacer una lámpara muy cuca para nuestra habitación :P

- Mejor todavía: podríamos simplificar la lámpara y dejar un único potenciómetro que fuese recorriendo toda la gama de colores.

---


Código:

/*

Miniproyecto: Controlando un LED RGB

Autor: Jose Alberto
http://creando-el-mundo.blogspot.com/



*/

const int pinRed = 9;
const int pinGreen = 10;
const int pinBlue = 11;

int redByte = 0; // Para leer los datos de entrada
int greenByte = 0; // Para leer los datos de entrada
int blueByte = 0; // Para leer los datos de entrada

void setup()
{
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop()
{

// Leemos datos solo cuando los haya
if (Serial.available() > 0)
{
// Guardamos los datos en orden RGB
redByte = Serial.read();
delay(50);
greenByte = Serial.read();
delay(50);
blueByte = Serial.read();
// Pasamos de ASCII a numerico
redByte = redByte - 48;
greenByte = greenByte - 48;
blueByte = blueByte - 48;

// Confirmamos la recepcion
Serial.print("Datos recibidos: RGB = ");
Serial.print(redByte, DEC);
Serial.print(greenByte, DEC);
Serial.println(blueByte, DEC);
// Y encendemos el LED
analogWrite(pinRed, redByte*25.5);
analogWrite(pinGreen, greenByte*25.5);
analogWrite(pinBlue, blueByte*25.5);
}

}

No hay comentarios:

Publicar un comentario