En este tutorial vamos a ver cómo cambiar la intensidad de un LED con una fotorresistencia.
Cuando la intensidad de la luz ambiental sea menor, el LED se iluminará con mayor intensidad. Y cuando la luz ambiental tenga mayor intensidad, el LED reducirá la suya.
Materiales
Los materiales que necesitamos para realizar este proyecto son estos:
Una placa Arduino (Yo usaré Arduino UNO) | ||
Un led de 5 mm | ||
Una resistencia de 330Ω | ||
Una resistencia de 10KΩ | ||
Una fotorresistencia (LDR) | ||
Cables | ||
Una protoboard | ||
Un ordenador con el IDE de Arduino instalado |
Conexiones
Debes conectar el LED y la fotorresistencia con Arduino de la siguiente forma:
Utilizamos el mismo circuito en un tutorial anterior de fotorresistencias: Encender un LED con una fotorresistencia.
La conexión de la fotorresistencia con Arduino queda así:
R1 es la fotorresistencia y R2 es la resistencia de 10KΩ. Van conectadas en serie para conseguir, en el punto A, un divisor de tensión. Esto ya lo vimos anteriormente aquí: Cómo conectar una fotorresistencia con Arduino.
El punto A, es decir, la conexión entre ambas resistencias, va conectado con un pin analógico de Arduino. En este caso el pin A3. Si lo prefieres puedes utilizar otro, pero que sea analógico.
El otro extremo de la fotorresistencia va conectado a 5V y el extremo opuesto de la resistencia de 10kΩ va a tierra.
Por otro lado tenemos el LED. Esto no tiene mucho misterio, ya hemos visto anteriormente cómo conectar un LED con Arduino.
Utiliza la resistencia de 330Ω para el LED. Lo único que debes tener en cuenta en esta ocasión es que el pin digital que elijas para el LED debe soportar PWM, para poder regular la intensidad, así que elige uno que tenga una virgulilla (~) al lado.
Sketch
El sketch que necesitamos es el siguiente:
//declaraciones
const int FR = A3;
const int LED = 3;
const int MAX = 500;
const int MAX_PWM = 255;
int entrada = 0;
int valor = 0;
//configuración
void setup() {
pinMode(LED, OUTPUT);
}
//función loop
void loop() {
entrada = analogRead(FR);
if (entrada > MAX){
entrada=MAX;
}
valor = MAX_PWM-((long(entrada) * MAX_PWM) / MAX);
analogWrite(LED, valor);
delay(500);
}
Vamos a revisarlo por partes para que lo entiendas sin problema.
Declaraciones
Como puedes ver, necesitamos unas cuantas cosas para que funcione el sketch correctamente.
Por un lado las siguientes constantes enteras:
- FR es el pin analógico en el que está conectada la fotorresistencia. En este caso el pin A3, por eso le tenemos que asignar ese valor. Si estás usando otro pin cámbialo por el valor correcto.
- LED representa el pin digital en el que está conectado el LED. En este caso el pin 3.
- MAX representa el valor máximo que puede entrar por el pin analógico cuando la resistencia recibe la máxima iluminación. Para conocer este valor sigue este tutorial: Valor máximo de una fotorresistencia. Yo obtuve valor 519, pero para redondear usaré 500. Utiliza el valor que se ajuste a tus necesidades.
- MAX_PWM representa el valor máximo que se puede enviar a un pin digital PWM, es decir 255.
Por otro lado, necesitamos dos variables enteras:
- entrada: Esta variable nos servirá para leer los valores de la fotorresistencia que entren por el pin analógico FR.
- valor: Nos servirá para calcular el valor que debemos enviar el pin PWM del LED.
Configuración
En cuanto a la configuración, solo tenemos que configurar el pin digital del LED como salida utilizando la instrucción pinMode(LED, OUTPUT).
No necesitamos nada más porque los pines analógicos siempre son entrada y no hace falta configurar el modo dentro de la función setup.
Función loop
Vamos a analizar la funicón loop. Para que te resulte más sencillo de entender la voy a dividir en dos partes: lectura de la entrada analógica (valor de la fotorresistencia) y encendido del LED.
- Lectura de la entrada analógica:
entrada = analogRead(FR);
if (entrada > MAX){
entrada=MAX;
}
Con analogRead(FR) leemos el valor que entra a través del pin analógico en el que está conectada la fotorresistencia. El resultado se asigna a la variable entrada.
Lo siguiente es comprobar si el valor leído no supera el máximo que definimos en las declaraciones (MAX). Para eso utilizo la instrucción if. En mi caso redondeé el máximo real a 500 y todas las operaciones posteriores las haré sobre este valor, por lo que si entra algo superior lo voy a acotar. Por eso asigno el valor de MAX (en mi caso 500) a la variable entrada si esta superase el máximo que establecí.
- Encendido del LED:
valor = MAX_PWM-((long(entrada) * MAX_PWM) / MAX);
analogWrite(LED, valor);
La primera línea parece compleja porque hay unas cuantas operaciones, pero en realidad no lo es. Deja que te lo explique.
Los valores posibles que entrarán de la fotorresistencia están comprendidos entre 0 y 500. 0 es oscuridad total y 500 es el valor de máxima luz que hay en la habitación en la que estoy haciendo el proyecto. Recuerda que tenemos una constante que representa el valor 500: MAX.
Por otro lado, los posibles valores que se pueden enviar a un pin digital PWM están comprendidos entre 0 y 255. Esto es así siempre. También tenemos una constante que representa el valor 255: MAX_PWM.
Si los valores de la fotorresistencia los quiero «convertir» a valores PWM para enviarlos al pin digital del LED, tengo que hacer una regla de tres que relacione los valores recibidos de la fotorresistencia y los posibles de PWM.
Quedaría algo así:
MAX ——- MAX_PWM
entrada ——- X
Si despejas X queda así:
X = (entrada * MAX_PWM) / MAX
Esto estaría bien si la equivalencia fuese directa, es decir, a máximo valor de la fotorresistencia, máxima intensidad del LED, pero en realidad lo queremos al revés. Cuanto más alto es el valor de la resistencia significa que más intensa es la luz ambiental, por lo que menor debe ser la intensidad del LED. Para conseguir esto solo tenemos que conseguir el valor complementario. Es tan sencillo como restar el valor obtenido en X al valor máximo de PWM.
Quedaría así:
MAX_PWM – ((entrada * MAX_PWM) / MAX)
¿Te suena? Mira la línea del sketch el la que estamos haciendo la operación:
valor = MAX_PWM-((long(entrada) * MAX_PWM) / MAX);
Es exactamente la misma operación. La única diferencia que ves es esto: long(entrada). Esto convierte el tipo de la variable entrada a long para que el resultado de la multiplicación con MAX_PWM sea long. ¿Por qué? Pues porque el tipo int en Arduino en placas basadas en ATmega solo soporta valores hasta 32767. Si entrada es 500 y lo multiplicas por 255 el resultado es 127500, muy superior al máximo permitido. Si usas int obtendrás resultados raros. Usando long se soluciona el problema.
El resultado final de la operación es lo que tenemos que enviar el pin PWM, por eso lo asignamos a la variable valor, para usarlo después con analogWrite(LED, valor).
Vamos a ver un ejemplo para que quede 100% claro.
Supongamos que la estancia está con la máxima intensidad lumínica, en mi caso entrará 500 por el pin FR. Si hago la operación con el valor 500 el resultado que envío al pin PWM será:
255 – ((500 * 255) / 500) = 0
Al entrar la máxima intensidad lumínica tiene sentido que el LED se apague. Enviando 0 al pin PWM lo conseguimos.
Vamos a ver ahora otro ejemplo en el que la intensidad no es la máxima.
Por ejemplo, supongamos que entra por el pin FR valor 350. El valor que se envía al pin PWM será este:
255 – ((300 * 255) / 500) = 102
Enviar 102 al LED a través del pin PWM hará que el LED se ilumine, pero no a máxima intensidad. Es una intensidad proporcional a la intensidad lumínica que recibimos de la fotorresistencia.
¿Y si el entorno está en oscuridad total? Exacto, el valor que enviamos al LED es el máximo: 255. Vamos a comprobarlo:
255 – ((0 * 255) / 500) = 255
Ahora te toca a ti. Monta el circuito y haz varias pruebas: Tapa la resistencia, enciende una lámpara, usa solo la luz ambiental, etc. A ver qué pasa.
Videotutorial
Aquí te dejo todo el proceso en vídeo por si te quedan dudas. Además, te cuento otra forma diferente de obtener el valor PWM utilizando la función map().
¡Suscríbete a la newsletter y no te pierdas nada!
Te avisaré cuando publique nuevo contenido en paraarduino.com y en mi canal de YouTube (@ParaArduino).