I am trying to build an IR range/proximity detector. It sort of works, but there seems to be an issue with external light sources and what appears to be noise and I am unsure how to proceed.
The circuit looks like this:
2 IR LEDs in series connected to each pin 10, 11 and 12.
12 ----|>|--|>|--+
11 ----|>|--|>|--+
10 ----|>|--|>|--+
_|_
-
'
A voltage divider with a 40k? resistor on one side, and what appears to be a IR photodiode (value of A1 changes
significantly if I reverse this element, I originally thought that this was a IR photo-resistor and is the reason why
I wired it in this way. It still appears to work as I expected anyway. :D).
+----- A1
|
+5V -+-./\/'-+-|>|--+
| _|_
+- AREF -
'
Now please be gentle, I'm a programmer dammit, not an engineer!
I know that I do not have a current limiter resistor on the LEDs, but from what I've gleaned from the web, this can work (and does). However, this may (most likely will) reduce the life of the LEDs. I'm thinking about using a transistor to switch them all on and off by going through the main supply.
But that is not my main concern at the moment (though if you want to comment on it, please feel free). My main concern is that I'm getting extra values when an external IR source hits the receiver. I've tried to compensate by reading in values when the LED source is off, turn them on, read more values and do this repeatedly, averaging them out and subtracting the on values from the off values.
Here's the code:
template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
static char const endl = '\n';
template<int I>
void pinMode(int const (&pins)[I], int state)
{
for(int i = 0; i < I; ++i)
pinMode(pins[i], state);
}
template<int I>
void digitalWrite(int const (&pins)[I], int state)
{
for(int i = 0; i < I; ++i)
digitalWrite(pins[i], state);
}
void setup()
{
Serial.begin(115200); //start serial communications for test purposes
pinMode(transPins, OUTPUT);
digitalWrite(transPins, LOW);
pinMode(displayRefPin, OUTPUT);
digitalWrite(displayRefPin, HIGH);
//analogReference(DEFAULT);
analogReference(EXTERNAL);
pinMode(transmitPin, OUTPUT);
Serial << "START" << endl;
}
// offavg = (off0+off1+...off19)/20
// onavg = (on0-offavg+on1-offavg+...+on19-offavg)/20
// = (on0+on1+...+on19)/20 - offavg
void loop()
{
static int const innerLoopMax = 20, outerLoopMax = 20;
long onValue = 0, offValue = 0, sample;
int register value, samples = 0;
for (int i=0; i < outerLoopMax; ++i)
{
for (int o=0; o < (sample = random(10,30)); ++o)
{
offValue += 1023-analogRead(recvrPin);
}
digitalWrite(transPins, HIGH);
samples += sample;
analogRead(recvrPin); // reset recvrPin
for (int o=0; o < (sample = random(10,30)); ++o)
{
onValue += value = 1023-analogRead(recvrPin);
}
digitalWrite(transPins, LOW);
samples += sample;
}
Serial << value << " - " << (double)onValue/samples << ", " << (double)offValue/samples << ", " << ((double)onValue - offValue)/samples << endl;
}
As I've stated, this does work, I can actually get about a foot range detection doing this, but I seem not to be able to subtract the on value from the off value which is a problem in varying light conditions. I'm thinking that the photo-diode receiver is not giving a linear value based on the amount of received IR light? If so, I'm not sure how I can characterize this function. The other alternative is that my driving the LEDs in this manner are causing noise in the system.
Any suggestions?
Thanks,
Adrian
EDIT: FYI, I'm using an UNO.