Sensing the light
Lesson #5—Introducing analog inputElectronics theory
The Arduino contains a voltage meter called an analog-to-digital converter. This instrument measures the voltage between an analog pin (A0 .. A5) and ground.
The analog-to-digital converter does not work in units of volts. Instead it uses integers in the range of 0 to 1023. The significance of this range is that the Arduino uses 10 binary digits to represent analog values, and there are 1024 unique combinations of 10 binary digits (\(2^{10} = 1024\)).
The relationship between the voltage and the analog-to-digital converter output is given by $$v = n \times \frac{5}{1023},$$ where \(v\) is the voltage and \(n\) is the integer value returned by the analog-to-digital converter.
Light sensor theory
A light dependent resistor (LDR) is a light sensor that acts like a resistor. The resistance varies with the amount of light that shines onto it.
An Arduino cannot measure resistance directly, but it can measure voltage. Therefore we need a circuit whose voltage is related to the resistance of the sensor. Such a circuit is called a voltage divider.
In the circuit shown above in Fig. 2, the voltage on pin A0 is related to the resistances of R2 and R3 via the equation $$V_{A0} = 5\times\frac{R_3}{R_2 + R_3}.$$
Wiring
We will use a light dependent resistor (shown below) to create an analog signal to measure.
Build the circuit of Figs. 2 – 3 on your breadboard:
Code
TYpe the following code into the Arduino IDE. Don’t forget to save your code into a new file so that you don’t overwrite your previous work.
void setup() {
// put your setup code here, to run once:
// Set the baud rate
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
// Create an integer variable called "ldr"
int ldr;
// Create a floating point variable called "voltage"
float voltage;
// Read from pin A0
ldr = analogRead(A0);
// Tell the user what value we read
Serial.print("Analog value: ");
Serial.print(ldr);
// Calculate the corresponding voltage
voltage = ldr * 5.0 / 1023.0;
Serial.print("\t");
Serial.print("Voltage: ");
Serial.print(voltage);
Serial.println();
// Delay
delay(250);
}
Topics for workshop discussion
float
is a variable type that allows for decimal points. Theint
type only permits integers (whole numbers).- Writing
5.0
instead of5
means that “floating point” arithmetic will be used instead of integer arithmetic. Division between integers is defined to always round down.
Exercise
Add in a flashing LED (as per Lesson 3). Adjust the code such that the LED flashes at different speeds depending upon the light incident upon the sensor.
- Hint: The amount of delay in your LED flashing will be related to the analog value read from the sensor. You might consider subtracting some scaling factor from your analog value to convert it into a desired delay in milliseconds.
Extension topics
The value of the fixed resistance (R3 in Fig. 2) depends upon the properties of the LDR. Ideally you want \(R_2 \approx R_3\) near the midpoint of the range of light intensities that you expect to measure. You can check this for any particular LDR using a multimeter to measure its resistance under typical illumination.
If \(R_3\) is poorly matched to the particular sensor, the range of achievable voltages will be small and the measurement precision will be poor. Mathematically minded people might be interested in considering the limiting cases of \(R_3 \to 0\) and \(R_3 \to \infty\) in the voltage divider equation $$V_{A0} = 5\times\frac{R_3}{R_2 + R_3}.$$