Unlike some other devices the Raspberry Pi does not have any analogue inputs. All 17 of its GPIO pins are digital. They can output high and low levels or read high and low levels. This is great for sensors that provide a digital input to the Pi but not so great if you want to use a sensor that doesn’t.
For sensors that act as a variable resistor such as LDRs (Light Dependent Resistors) or thermistors (temperature sensors) there is a simple solution. It allows you to measure a number of levels using a single GPIO pin. In the case of a light sensor this allows you to measure different light levels.
It uses a basic “RC” charging circuit (Wikipedia Article) which is often used as an introduction to electronics. In this circuit you place a Resistor in series with a Capacitor. When a voltage is applied across these components the voltage across the capacitor rises. The time it takes for the voltage to reach 63% of the maximum is equal to the resistance multiplied by the capacitance. When using a Light Dependent resistor this time will be proportional to the light level. This time is called the time constant :
t = RC where t is time, R is resistance (ohms) and C is capacitance (farads)
So the trick is to time how long it takes a point in the circuit the reach a voltage that is great enough to register as a “High” on a GPIO pin. This voltage is approximatey 2 volts, which is close enough to 63% of 3.3V for my liking. So the time it takes the circuit to change a GPIO input from Low to High is equal to ‘t’.
With a 10Kohm resistor and a 1uF capacitor t is equal to 10 milliseconds. In the dark our LDR may have a resistance of 1Mohm which would give a time of 1 second. You can calculate other values using an online time constant calculator.
In order to guarantee there is always some resistance between 3.3V and the GPIO pin I inserted a 2.2Kohm resistor in series with the LDR.
Here is the sequence of events :
- Set the GPIO pin as an output and set it Low. This discharges any charge in the capacitor and ensures that both sides of the capacitor are 0V.
- Set the GPIO pin as an input. This starts a flow of current through the resistors and through the capacitor to ground. The voltage across the capacitor starts to rise. The time it takes is proportional to the resistance of the LDR.
- Monitor the GPIO pin and read its value. Increment a counter while we wait.
- At some point the capacitor voltage will increase enough to be considered as a High by the GPIO pin (approx 2v). The time taken is proportional to the light level seen by the LDR.
- Set the GPIO pin as an output and repeat the process as required.
For more detail: Reading Analogue Sensors With One GPIO Pin