Let's Make Robots!

Making an IR object tracking system

Tracks an objects position
MPSA13.pdf154.35 KB
MPSA14.pdf43.7 KB

In an earlier tutorial on IR object detection sensors I mentioned that they could be used for object tracking. Now I show you how and my progress so far. I've also posted a challenge based on object tracking to squirt pets with a waterpistol. Object tracking with these sensors is more complicated than object detection so I'm going to try and explain it in more detail here including problems I've had as this is still a work in progress. I got the idea for this system after reading Mintvelt's post on "smooth object tracking". Frits also had a hand in inspiring this idea with his Amanda LDR of which this is basically an IR version.

The theory: The method of tracking used here is very simple. The software simply moves the servo until both phototransistors get the same amount of IR. If the object moves to one side then one sensor will get more IR than another and the servo turns to correct the imballance. If you want to track up/down as well as left/right then just make a second unit and mount it vertically instead of horizontally.


My success: This was my prototype object tracker. It was a bit jerky at first as can be seen in the 2nd video. After Rik installed a warpdrive in my code it bacame quite fast and smooth. Unfortunately I lost the video so you'll have to take my word for it. The improved code is OBJECT_TRACKER_V1.7.BAS in the attachments.

The tracking software reads the ambiant light and then turns on the IR LEDs to read the refected light. It subtracts the ambiant light from the reflected light to stop iR coming from a window causing the tracker to turn towards the light. The inputs are then calibrated to allow for component variation. Adjustment is made to the servo position depending on the difference between the calibrated readings. The main changes to my original software to prevent jerkiness was to turn off the servo between adjustments which is really compensating for the picaxe's dodgy bootstrap code. This was V3 of the firmware. 


My failures: After the success of this tracker I decided to make a larger dual axis tracker with greater range! It was a spectacular failure. It had plenty of range but was impossible to callibrate as I had not considered the optical side of the design.


The problem I believe was that light from the LEDs overlapped at different distances depending on where the object (my hand) was relative to the unit. If I calibrated it with my hand 2 meters from it then it really only worked ok with my hand at that distance.


IR_tracking_sensor_2.jpgMy newest array, with navy blue IR LEDs works better as I've gone back to a single phototransistor for the sensor instead of two in parallel. The idea is that fewer lenses are better. The domed end of a LED or a phototransistor is a lens that focuses the light sent or received. The IR LEDs I'm using have a viewing angle of about 30 degrees. Check you datasheet of both LEDs and phototransistor as it can vary.

This design still has problems. After looking at it shining IR onto a sheet of paper through my camera I relised that once again I was getting light from different LEDs reflecting back to a  phototransistor depending on how far away the paper was. You can see the amplifier mounted seperately at the base of the cannon.

So back to the drawing board. First thing I want to change is the way my LEDs and phototransistors are mounted as they are at a fixed position and angle.


In my original prototype, overlapping light wasn't an issue. The diagram below shows why.


In comparison, the diagram of my last design shows where my problem lays. Up close the phototransistor only gets light reflected back from the LEDs next to it but at a greater distance it starts to recieve light from nearby sensors. The best solution I can think of is to have a central, compact light source that reflects back to all the phototransistors.



Mechanical callibration: By adjusting the angle and position of my sensors I should be able to do some of the calibration mechanically which means less math for your processor and a faster response time. It is also better if you can have one single lightsource to eliminate the problem of overlapping light. If you need more than one LED to get more range then cluster them as close as possible in the centre and mount your sensors around the outside facing outward slightly. If your tracker seems to be looking off centre to the object being tracked, try adjusting the angle of the sensors by small increments.

Software callibration: If this is not enough then you will need to calibrate it through software. I did this by disabling the servos and holding my hand at the maximum detection range of the sensors. Using debug to get the readings from the sensors I then divided down the larger numbers so that all readings were the same when the tracker was looking directly at my hand.

New amplifier design: My original amplifier design was based loosly on a one transistor amplifier I was taught at colledge (16 years ago). Since it worked first go I didn't mess with it but really it's not a good design as the original design was for AC signals. I've now simplified it as you can see below.


 The phottransistor and amplification diode form a simple darlington transistor. The 2Kresistor was chosen as the datasheets suggested that the BC549 has the most gain with about 2mA flowing through it. The resistors could be anything from about 1K through to 10K. I would not go less than 1K because you would only waste power. More than 10K could affect the accuracy of the processors ADC due to it's input impedance. More sensitivity could be obtained using your ADC in 10bit mode but I think 8bit should be adequate and simplifies the maths.

Below is the LED array driver circuit. It is very simple and could easily be made with a NPN transistor instead of a FET with no change to component values.



IR_LED_array_Schematic.jpgThis is what I used with my last design. The current is limmited to about 50mA per LED so that I didn't have to worry about damaging the LEDs if they stayed on too long due to a fault in the software while debugging.

Boosting range: So far I have used more LEDs to increase range but this has caused troubles with callibration when the LEDs were not clustered together. The LEDs I've used do have a peak current rating of 1.2A but at this intesity they could be damaged if left on for more than 100uS. I would probably use a 555 timer to control the pulse if I resort to that method of increasing range as this would protect the LEDs from faulty code. The biggest problem with this idea is that the LEDs can only be on for about 100uS. I don't think this will be enough time for the processor to read 4 ADC inputs. I can get a 2.4W IRLED that will handle 1A continuous current but that will cost me $30 AUD plus P&H. At this stage I've ordered some High intensity IR LEDs that will handle 100mA continuous. Because I'm only going to have them on long enough to read my ADC inputs I can possibly push that to 200mA or more as long as the dutycycle is low enough.



Hardware protection: This is a circuit I've designed to protect the IR LEDs if you want to push them to their limit.


This uses a 555 timer to control the timing of the pulse to my IR LEDs. With the component values shown it should pulse the LEDs for just under 100uS and then canot be retriggered for at least 200uS. This means that the LEDs cannot be damaged even if the signal from the processor stays high due to a fault in the code. In this circuit, the computer triggers a pulse by pulling pin 2 which is held high by a 100K resistor down below 2/3rds of the 5V supply. This will only happen if the 1uF timing capacitor is suitably discharged which needs at least 200uS to occur. Once triggered, pin 3 goes high. This turns on the FET to power the LEDs and begins charging the timing capacitor via a diode and the 1K3 resistor. At this point the processor can no longer trigger a pulse. Once the timing capacitor and thus pin 6 exceeds 2/3 of the 5V supply, the 555 timer changes pin 3 to a low state. The LEDs are turned off and the timing capacitor discharges by the 2K7 resistor and it's diode. After aprox. 200uS the timing capacitor should have discharged back below 1/3rd of the 5V supply and the circuit is now ready to be triggered again.


This circuit is not essential. The picaxe basic language for example has a pulsout command that can send out a pulse in multiples of 10us with a 4MHz clock. One reason you might choose to use a circuit like this, even with good code is that if an interupt occurs during a pulseout then it could cause the LEDs to be on longer than normal.


Udate: 19-1-2009
I've been experimenting with improving the sensitivity of the IR detector using a high gain darlington transistor MSPA13 which has a gain of 5000+. The BC549 only had a gain of between 200-800 depending on the individual transistor. Below is a picture of my test platform. There is a MPSA14 that has a hfe of 10000. That should be better again. These transistors can be obtained world wide from Futurlec. The MPSA13 cost 14c US and the MPSA14 is only 6c US at the time of this update.


This is a 14M with my new detection circuit on an analog input. The maximum current through the IR LED is only 25mA although the multimeter registers less than 10mA total current draw since the LED is only on very briefly. Using this setup and using the readadc10 command to maximise sensitivity the picaxe could detect the wall from about 1 meter and my hand from about 400mm. This is running on a 3.7V LiPo battery (on the right) from a toy helicopter as I'm looking at using this circuit in a micro wall racer.It would be more sensitive on 5V.








Below is the schematic for the new IR detection circuit.


 I tried several resistors to increase gain. With a 100 ohm resistor I got less range but I also got less range with a 470 ohm resistor. The 220 ohms could probably be fine tuned better but was good enough for this experiment.



















IR_obstacle_detector_3_Schematic.jpgThis is a version you may want to try as it's gain can be adjusted by the 500 ohm trimpot allowing it to be callibrated easily.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the if, else, ifelse is set up properly will catch any variables automatically whereas the case switches when a variable equals something. Like I said the if, else, ifelse catches all crazy statements.
what do you mean by catch?
what he means by catch is trigger or what it should do if nothing elses matches the varible
Do you guys realise this node is about hardware? I don't care about the software except as far as getting around the faulty firmware that causes the servo to jitter.

I think, though misguided, they are trying to help with your code's response time via optimization.

Anyhoo,  from a look at the video, I'd say response time isn't the jitter issue. I think it's actually over-sensitivity that's the issue. I'd wager it's less jittery if you use white circle of cardboard at a consistent angle to the sensors. If that's the case, then your software needs some smoothing logic.

I sincerely believe that's your jitter issue. It's reacting to every movement that it perceives (e.g the shadows between your fingers), rather than deciding if there's actual motion going on. I think you need a sliding average of say the last 5 (or 3 or 20, I don't know how fast your loop is) readings from the sensors to see if there's a trend toward a direction and decide your motion from that. It'll cause some lag, but I don't think too much.

I don't think you have faulty firmware, I think you've got firmware that's doing what you tell it too. :)

Good luck! Great Project! I've learned a lot...

The jitter was eliminated in V1.7 and the response was perfect. (prototype held by Junior).Remember that the video was an earlier version of the software. The jitter was a result of picaxes faulty firmware that forces you to turn off the servos when not changing their position. The servopos command is supposed to allow position change without jitter but only reduces it compared to using the servo command.

In the video of SplatBot, the problem is callibration.

Well! There. You. Go.

I stand corrected!


I appreciate the interest. Perhaps I need to explain things better in my post or drink less coffee.

So far I've been to busy trying to get the hardware working. When I do optimise the software I look at two things depending on whats more important, speed or memory conservation. Usually less memory equals more speed anyway so I only use the second method on rare occasions, once to be honest.

1. Which command uses the least memory. The syntax checker tells me the amount of memory used.

2. Which command is faster. I use an oscilloscope to monitor a digital output.

You also need to think about the order the comparisons are executed in. You want the most likely differentiator first and the least likely last.