Sunday, 21 July 2013

Analog Inputs - What, Where & How? - Working with the on-board LDR

Analog Inputs


There are 6 dedicated Analog Input pins on the Induino R3 that can be used for connecting Analog Input devices like sensors to the Induino R3 Board. These are the pins marked A0 - A5.

There are sensors which produce a voltage value as output to indicate the quantity being measured. The Analog Input Pins are connected to an internal Analog to Digital Converter, that will then convert these voltages to digital values. The resolution for Analog Input is 10-bits.  (if you did not go through the previous tutorial, please go through it to understand resolution). So voltage values from 0 to 5 volts are represented using a numerical value in the range of 0 to 1023. If a sensor outputs, 1 volts, we would be getting a numerical value of  204.  Owing to the 10-bit resolution, we can measure changes greater than 4.9 millivolts.

There is a LDR on the Induino R3 Board that is connected to pin A3. The LDR acts as a simple on-board light sensor.

LDR - Light Dependant Resistor - is a type of a variable resistor whose resistance varies with light incidence.  Resistance of the LDR is inversely proportional to the light incident upon the LDR. When there is more light, resistance is less and when there is less light resistance is more. There are a lot of sensors out there that are variable resistors - Thermistor, Force Sensitive Resistor, etc.

Connecting Variable Resistors to the Induino R3 / Arduino Board

When connecting a variable resistor type sensor, we need to convert the change in resistance to change in voltage and then give this voltage as input to our microcontroller (same with all the microcontrollers) We can achieve this by using a potential divider configuration as in the following image. The Vout from the following circuit needs to be connected to the Analog Input pin. Vin is +5Volts. You can use the same configuration in connecting all variable resistor types of sensors. just replace the LDR in the circuit.
The LDR on the Induino R3 Board is connected using the First Setup in the above image. So you would get a Lesser Voltage Value when there is more light on top of the LDR and Higher Voltage Value when there is less light on top of the LDR.

Now Let's see how to program the LDR.  Lets write a simple program to get the LDR value printed to the Serial Port. We would need a new function to achieve this

analogRead(pin number) - The analogRead() function will read the voltage value of the given pin and give us a value in the range of 0 to 1023.

Here's our program
 /* Induino R3 User Guide - Program 5.0 - Simple LDR Value */

int ldr_val = 0; // variable to store the LDR value

void setup()
{
  // No pinMode Statement required for Analog Pins :)
  Serial.begin(9600); // Initialise Serial Communication
}

void loop()
{
  ldr_val = analogRead(3); // Read the ldr value and store it in the variable
  Serial.print("Current LDR Value : ");
  Serial.println(ldr_val); // print the ldr value to serial monitor
  delay(1000); // a delay - do not remove this delay (you can change it) as otherwise the serial monitor will get flooded with data and might crash
}

Now Lets build a Simple Lighting Level Controller using the LDR and the 3 on-board LEDS[11,12 & 13]. We will try and increase / decrease the number of lights that are ON based on changing Light Intensity Levels Measured by the LDR.

Make note of the values shown in the serial monitor for various levels of light intensity. Use these values as threshold and every time the LDR value increases above one of the thresholds, switch On a LED and every time it decreases below the threshold, switch Off the LED.

Here's our program
 /* Induino R3 User Guide - Program 5.1 - LDR Based Lighting Level Controller
  This is a simple program where 3 LEDS are switched ON / OFF one by one as the Light Intensity Sensed by the LDR Decreases / Increases  
  */  
 #define threshold1 650 // First Threshold Value of Darkness above which the first LED is switched ON  
 #define threshold2 750 // Second Threshold Value of Darkness above which the second LED is switched ON  
 #define threshold3 950 // Third Threshold Value of Darkness above which the third LED is switched ON  
 int val = 0; // A Variable to Store the Light Value from the LDR  
 void setup()  
 {  
  pinMode(11,OUTPUT); // LED 1   
  pinMode(12,OUTPUT); // LED 2  
  pinMode(13,OUTPUT); // LED 3  
  Serial.begin(9600);// Start a Serial Connection  
 }  
 void loop()  
 {  
  val = analogRead(3);// Reads a 10-bit value corresponding to the voltage applied on analog input pin 3.  
  Serial.print("Light Intensity is : ");// Prints the given string / value to the serial monitor  
  Serial.println(val);// prints the value of the variable val to the serial monitor and moves the cursor to the next line (the ln part of println does this  
  if(val > threshold1) // Checks & Turns the First LED ON / OFF based on Light Intensity  
   digitalWrite(11,HIGH);  
  else  
   digitalWrite(11,LOW);  
  if(val > threshold2) // Checks & Turns the Second LED ON / OFF based on Light Intensity  
   digitalWrite(12,HIGH);  
  else  
   digitalWrite(12,LOW);  
  if(val > threshold3) // Checks & Turns the Thirdf LED ON / OFF based on Light Intensity  
   digitalWrite(13,HIGH);  
  else  
   digitalWrite(13,LOW);  
 }  

Connecting Other Variable Resistors - Using the Internal Pullup Resistor

We can capitalize on the Internal Pull-up Resistor to connect variable resistance sensors. The Internal Pull-up resistance on the Atmega328 is 20k. This is a pull up (connected between the IO and Supply Voltage - +5V). To use this, we need to connect our sensor between the Analog Input Pin and GND and enable the Internal Pull-up on the corresponding pin in our program.

Here's our Program for the LDR if it were to be connected using the Internal Pull up resistor


/* Induino R3 User Guide - Program 5.2 - Simple LDR Value using Internal Pull-Up */

int ldr_val = 0; // variable to store the LDR value

void setup()-
{
  pinMode(15,INPUT_PULLUP);  // enabling the Internal Pull-Up on Pin 15 (A2)
  Serial.begin(9600); // Initialise Serial Communication
}

void loop()
{
  ldr_val = analogRead(2); // Read the ldr value and store it in the variable
  Serial.print("Current LDR Value : ");
  Serial.println(ldr_val); // print the ldr value to serial monitor
  delay(1000); // a delay - do not remove this delay (you can change it) as otherwise the serial monitor will get flooded with data and might crash
}


Thats It For This Part! Enjoy... and feel free to drop us an email with questions you might have -> info@simplelabs.co.in

Visit www.simplelabs.co.in for more interesting products

Back to List of Contents

6 comments:

  1. I did not understand program 5.2. What's the point of using Internal Pullup Resistor? Is it only the fact that you could write analogRead(2) instead of analogRead(3) in program 5.1?

    While running program 5.2, I don't seem to notice any change in voltage reading with changing intensity of light.

    BTW, I get a compiler error because of typo in "ldr_value".

    ReplyDelete
    Replies
    1. No.. It means you can use either an externally connected resistor R for constructing the potential divider or use the internal pull-up resistor as R. however if you use the internal pull up resistor, Only the first configuration shown in the circuit above is achievable.

      Delete
  2. in program 5.2.A2 represents pin 16...but you have mentioned pin 15

    ReplyDelete
    Replies
    1. This is because there is already an on-board ldr present on pin 16, when using pin15, you need to connect a resistor externally.

      Delete
  3. No matter what the value of val, it will always satisfy first if condition. So why the other two if conditions? (Thresh hold values)

    ReplyDelete
  4. how will it satisfy the first condition always? it will depend upon the value you assign which should depend on the light falling on the LDR

    ReplyDelete