Medidor de luz con LDR y Arduino

El proyecto consiste en realizar un sencillo medidor de luz con nuestro Arduino, utilizaremos una fotoresistencia LDR y mostraremos el resultado en la computadora así como en un grupo de leds.

El objetivo de este tutorial es aprender como conectar sensores que varían su resistencia dependiendo de una magnitud física. Un ejemplo de este tipo de sensores es el LDR o fotoresistencia, estudiaremos el funcionamiento de este componente y su conexión con la tarjeta Arduino UNO R3 mediante un divisor resistivo.

Conceptos básicos 

Para entender como funciona este circuito y el programa que corre en la tarjeta Arduino debemos conocer 3 conceptos clave:

Fotoresistencia LDR: Componente cuya resistencia varía sensiblemente con la cantidad de luz percibida. La relación entre la intensidad lumínica y el valor de la resistencia no es lineal. Se utiliza ampliamente para medir la iluminación en dispositivos electrónicos que requieren un precio agresivo. Su comportamiento es el siguiente:
  • Mas luz = menor resistencia eléctrica 
  • Menos luz = mayor resistencia eléctrica 

Divisor de tensión: Mediante un par de resistencias en serie con una LDR, es posible repartir la tensión suministrada por la fuente entre los terminales de estas, en nuestro caso, el divisor se utiliza con la LDR para obtener un voltaje variable de acuerdo a la cantidad de luz recibida.



Conversión Analógico-Digital (ADC): Es el proceso mediante el cual se convierte una magnitud física como un voltaje, corriente, temperatura, etc. en un número binario (o señal digital) con el propósito de facilitar su manejo por circuitos digitales como una CPU. El Arduino realiza este proceso para conocer la cantidad de luz percibida por el LDR y poder procesarla numéricamente.

Materiales necesarios

  • Arduino UNO R3 
  • Fotoresistencia (LDR) 
  • Resistencia de 10 Kohm 1/4 W 
  • 3 Resistencias de 220 o 330 ohm 1/4 W 
  • 3 Leds 5mm
  • Cables para protoboard 
  • Protoboard

Esquema eléctrico

Recordar que los LED tienen polaridad y hay que respetarla. El pin más largo va conectado a la tarjeta Arduino, mientras que el pin más corto va con una resistencia a tierra.


Programa realizado (sketch)

La explicación para el código es la siguiente: Primero se preparan los pines de salida donde están conectados los leds, el pin de entrada donde se conecta el divisor resistivo y el puerto serie para la comunicación. A continuación se ejecuta un ciclo infinito en el que se lee el valor del voltaje en el pin del LDR y se accionan los leds según correspondan. También transmitimos el valor leído por el ADC del ATMEGA328 al PC a través del puerto serie de nuestra tarjeta arduino.

Valores leídos por el puerto serie




//Pin donde se conectan los leds
int pinLed1 = 2;
int pinLed2 = 3;
int pinLed3 = 4;
// Pin analógico de entrada para el LDR
int pinLDR = 0;

// Variable donde se almacena el valor del LDR
int valorLDR = 0; 

void setup()
{
  // Configuramos como salidas los pines donde se conectan los led
  pinMode(pinLed1, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  pinMode(pinLed3, OUTPUT);
 
  //  Configurar el puerto serial
  Serial.begin(9600);
}

void loop()
{
  // Apagar todos los leds siempre que se inicia el ciclo
  digitalWrite(pinLed1, LOW);
  digitalWrite(pinLed2, LOW);
  digitalWrite(pinLed3, LOW);

  // Guardamos el valor leído del ADC en una variable
  // El valor leído por el ADC (voltaje) aumenta de manera directamente proporcional con respecto a la luz percibida por el LDR
  valorLDR= analogRead(pinLDR);
 
  // Devolver el valor leído a nuestro monitor serial en el IDE de Arduino
  Serial.println(valorLDR);

  // Encender los leds apropiados de acuerdo al valor de ADC
  if(valorLDR > 590)
  {
    digitalWrite(pinLed1, HIGH);
  }
  if(valorLDR >650)
  {
    digitalWrite(pinLed2, HIGH);
  }
  if(valorLDR > 768)
  {
    digitalWrite(pinLed3, HIGH);
  }
  // Esperar unos milisegundos antes de actualizar
  delay(200);
}

El H Bridge L293D

El L293D, es un pequeño integrado que incluye dos puentes H-Bridge que podemos usar para gobernar simultáneamente dos motores.


Si buscáis el manual del L293D, veréis que aunque el funciona a 5V internamente, puede conmutar tensiones de hasta 36V para tus motores.

El patillaje del chip es así:

Veamos que son los diferentes pines del L293D:
  • El pin 16, Vcc1, son los 5V con los que alimentamos el chip y el pin 8, Vcc2, es la tensión con la que alimentamos el motor. 
  • Los pines del 1 al 7 controlan el primer motor y los pines 9 a 15 controlan el segundo motor. 
  • El pin 1, Enable1, Activa el uso del motor 1. Con un valor HIGH, el motor puede girar dependiendo del valor de 1A y 2A. Si es LOW se para independientemente de los valores del resto de pines. Los pines "enable" (1,9) admiten como entrada una señal PWM, y se utiliza para controlar la velocidad de los motores con la técnica de modulación de ancho de pulso.
  • Los pines 2 y 7 son los pines de control para el motor 1, e irán conectados a nuestros Arduino para controlar el sentido de giro.
  • Los pines 3 y 6 son la salida a la que se conecta el motor 1, cuya polaridad se invierte en función los valores de 2 y 7. En el diagrama de arriba veis que hay pines equivalentes para el motor 2 y cuales son. 
  • Los pines 4, 5,12 y 13 van a GND.

Podemos hacer una tabla para mostrar la lógica que sigue el giro del motor en función de los tres pines:

Por tanto tenemos que activar el pin enable para que el motor gire y después usamos los pines Input1 e Input2 con valores opuestos para hacer girar el motor en una dirección o en la contraria. Veamos cómo hacer el montaje con Arduino.

Esquema de protoboard

El diagrama de protoboard del chip L293D a nuestro Arduino será algo así:

El programa que vamos a usar para controlar este motor será el siguiente:

Vamos a usar los 3 pines de la tabla anterior. Arduino Pin 10 es el enable del

Motor 1 y usamos los pines 8 y 9 para controlar el sentido de giro. Por tanto:

//Control del sentido de giro de un motor de CC

#define E1 10 // Enable Pin para el motor 1
#define I1 8 // Control pin 1 para el motor 1
#define I2 9 // Control pin 2 para el motor 1

void setup()
 {
   for (int i=8; i<=11; i++)
   pinMode (i, OUTPUT);
 }

void loop ()
{
digitalWrite (E1, HIGH); //Activar el motor 1
digitalWrite (I1, HIGH);  //Iniciar el giro
digitalWrite (I2, LOW);
delay (3000);

digitalWrite (E1, LOW); //Parar el motor 1
delay (1000);

digitalWrite (E1, HIGH); //Activar el motor 1

digitalWrite (I1, HIGH);  //Iniciar el giro con cambio de dirección
digitalWrite (I2, LOW);
delay (3000);


digitalWrite (E1, LOW); //Parar el motor 1
delay (1000);
}

Descripción del programa

Activar el Enable1 para arrancar Motor 1, y luego usar I1 e I2 con valores invertidos. El motor arranca y se para a los 3 segundos. Transcurrido un segundo se activa de nuevo el Enable1 y al intercambiar los valores de I1 e I2 el giro del motor se inicia y en la dirección contraria.

En el taller de tecnología el control del sentido de giro de un motor de CC, se usa en multitud de ocasiones, he aquí un ejemplo de una grúa construida con barritas de papel reciclado, automatizada con Arduino y un L293D.

Para el control del sentido de giro del motor (subida o bajada), se han utilizado dos pulsadores.



El diagrama de protoboard del chip L293D a nuestro Arduino será así:


Programa


//Control del sentido de giro de un motor de CC

#define E1 10 // Enable Pin para el motor 1
#define I1 8 // Control pin 1 para el motor 1
#define I2 9 // Control pin 2 para el motor 1
int estadoPulsadorSubir=0;
int estadoPulsadorBajar=0;
int pinPulsadorSubir=0;
int pinPulsadorSubir=0;

void setup()
 {
   for (int i=8; i<=11; i++)
   pinMode (i, OUTPUT);

 }
pinMode (pinPulsadorSubir, INPUT);
pinMode (pinPulsadorBajar, INPUT);
}
void loop()
{
estadoPulsadorSubir = digitalRead (pinPulsadorSubir); //Leer estado del pusador de subida
estadoPulsadorBajar = digitalRead (pinPulsadorBajar); //Leer estado del pusador de bajada

if ( estadoPulsadorSubir == HIGH && estadoPulsadorBajar == LOW )
 {
   while (estadoPulsadorSubir==HIGH)
   {
    digitalWrite(E1, HIGH); //Activamos giro de subida
    digitalWrite(I1, HIGH); //Se inicia la subida

    digitalWrite(I2, LOW); //Activamos giro de subida
    estadoPulsadorSubir = digitalRead (pinPulsadorSubir);
   }
 }

if ( estadoPulsadorSubir == LOW && estadoPulsadorBajar == HIGH )
 {
   while (estadoPulsadorSubir==HIGH)
   {
    digitalWrite(E1, HIGH); //Activamos giro de subida
    digitalWrite(I1, LOW); //Se inicia la subida

    digitalWrite(I2, HIGH); //Activamos giro de subida
    estadoPulsadorBajar = digitalRead (pinPulsadorSubir);
   }
 }
 digitalWrite(E1, LOW); //Motor desactivado
}