How to use LED's as photodiodes (light sensors)
Posted: Fri Sep 03, 2010 10:46 pm
Hi everyone, I must say - this is a topic that has got me quite excited!
This came about from a combination of bitfogavs 24 x 24 led matrix display and also from some people at work who were asking me about making an LED coffee table.
I remember seeing on youtube how people have made some 'touch sensative' LED coffee tables by using a whole heap of LED's. When I say touch sensative, it looks as though by touching the LED's you are turning them on but infact when you touch it - you are just covering up the light going into it (more on this later)
So how about some theory!
As I am sure you are aware, to turn on an LED you need to overcome the depletion region (which is typically 2volts for a red LED) so if we were to use a 5 volt supply, we would add a series resistor to firstly drop the rest of the voltage and secondly, to limit the current.
Having said that, any reverse biased PN junction has some capacitance. So if we reverse bias our led (I.E. connect it in reverse to how we would normally connect it to make it light up) then we can actually charge up this internal LED capacitance. We then allow it to discharge and time how long it takes to discharge. We do this by waiting until we get a logic 0 on the port pin that the LED is connected to.
Now, the interesting thing here is that the internal LED capacitance will discharge FASTER if there is light coming into the LED - more light = more current due to light energy (photons) If we were to do this in a dark room then there is less light energy which gives you less current and therefor the LED capacitance takes longer to discharge.
Why not just use photodiodes which are designed for this purpose?
I am glad that you asked! The answer is simple - cost effectiveness, circuit simplicity and board size. The cool thing is that you can use the very same LED's that you light up - as sensors as well! you just do it on a time sharing basis. It is all happening so fast that you never actually see the LED's turn off.
Having said all of that, here's how we do it:
I have this simple circuit here which is great for testing. I am using a pic18f4685 just because it's my pic of choice at the moment, but is easily ported to most other pics.
There are two LED's in the above image - oh by the way, the resistors would be fine if they are around 150 ohm. One LED is used as the sensor (it is connected in reverse bias. The other LED is an indicator LED that shows us when we have covered the sensor.
Here is the swordfish sourcecode:
Now the code is a little bit involved, but it's due to the calibration routine. The calibration routine ensures that it will work correctly regardless of where you use this project. It checks the ambient light over a period of time and saves the ambient light data for use as a comparison. During the calibration if the light makes quite a large change (by someone shining a light on it or covering light then the calibration starts again. It only takes a few seconds to calibrate.
Then it just checks to see if the sensor data is quite a bit off the calibrated data, if it is then it must mean that we have covered the LED sensor.
I have also included an LCD display in my test version which gives me real time info as to the exact condition of the light during calibration and also after calibration.
I will post code and pics of this tomorrow. Because I am off to bed!
In closing - check out this video, it shows you what someone else has done and sums it up beautifully!
http://vimeo.com/3135519
This came about from a combination of bitfogavs 24 x 24 led matrix display and also from some people at work who were asking me about making an LED coffee table.
I remember seeing on youtube how people have made some 'touch sensative' LED coffee tables by using a whole heap of LED's. When I say touch sensative, it looks as though by touching the LED's you are turning them on but infact when you touch it - you are just covering up the light going into it (more on this later)
So how about some theory!
As I am sure you are aware, to turn on an LED you need to overcome the depletion region (which is typically 2volts for a red LED) so if we were to use a 5 volt supply, we would add a series resistor to firstly drop the rest of the voltage and secondly, to limit the current.
Having said that, any reverse biased PN junction has some capacitance. So if we reverse bias our led (I.E. connect it in reverse to how we would normally connect it to make it light up) then we can actually charge up this internal LED capacitance. We then allow it to discharge and time how long it takes to discharge. We do this by waiting until we get a logic 0 on the port pin that the LED is connected to.
Now, the interesting thing here is that the internal LED capacitance will discharge FASTER if there is light coming into the LED - more light = more current due to light energy (photons) If we were to do this in a dark room then there is less light energy which gives you less current and therefor the LED capacitance takes longer to discharge.
Why not just use photodiodes which are designed for this purpose?
I am glad that you asked! The answer is simple - cost effectiveness, circuit simplicity and board size. The cool thing is that you can use the very same LED's that you light up - as sensors as well! you just do it on a time sharing basis. It is all happening so fast that you never actually see the LED's turn off.
Having said all of that, here's how we do it:
I have this simple circuit here which is great for testing. I am using a pic18f4685 just because it's my pic of choice at the moment, but is easily ported to most other pics.
There are two LED's in the above image - oh by the way, the resistors would be fine if they are around 150 ohm. One LED is used as the sensor (it is connected in reverse bias. The other LED is an indicator LED that shows us when we have covered the sensor.
Here is the swordfish sourcecode:
Code: Select all
Device = 18F4685
Clock = 8
Config OSC = IRCIO67
// variable declaration
Dim x As Byte
Dim sensor_enable As TRISE.bits(1)
Dim check_sensor As PORTE.bits(1)
Dim sensor_data As word
dim sensor_calibration as word
// Sub Routines
sub calibrate()
for x = 0 to 50
sensor_data = 0
sensor_enable = 0
delayus(100)
sensor_enable = 1
while check_sensor = 1
delayus(300)
inc(sensor_data)
wend
if x = 5 then
sensor_calibration = sensor_data
endif
if x > 5 and sensor_data > sensor_calibration + 30 then
x = 0
elseif x > 5 and sensor_data < sensor_calibration - 30 then
x = 0
endif
next
sensor_calibration = sensor_data
end sub
sub sensor_check()
sensor_data = 0
sensor_enable = 0
delayus(100)
sensor_enable = 1
while check_sensor = 1
delayus(300)
inc(sensor_data)
wend
end sub
Sub do_led()
if sensor_data > sensor_calibration + 100 then
porte.bits(0) = 1
elseif sensor_data < sensor_calibration + 100 then
porte.bits(0) = 0
endif
End Sub
// Start Of Program...
OSCCON = %01111111
SetAllDigital
TRISE = %00000010
PORTE.bits(1) = 1
sensor_data = 0
calibrate
// Main Loop
While True()
sensor_check
do_led
Wend
Then it just checks to see if the sensor data is quite a bit off the calibrated data, if it is then it must mean that we have covered the LED sensor.
I have also included an LCD display in my test version which gives me real time info as to the exact condition of the light during calibration and also after calibration.
I will post code and pics of this tomorrow. Because I am off to bed!
In closing - check out this video, it shows you what someone else has done and sums it up beautifully!
http://vimeo.com/3135519