There are a lot of sensors out there that can tell you the distance to an object, but sometimes what you really need to know is the angle. For that, the options aren't very good. I designed a device that I call the Protractor, which is great at telling the angle between the sensor and a nearby object. It is based on Dale's obstacle detector and I have added a number of upgrades over several iterations to make it easy to use on any type of robot.
The sensor has an array of infrared LED emitters spaced around the perimeter of a semi-circular PCB. Each of the LEDs is pulsed in sequence, and the reflected light is picked up by phototransistors. The amount of light reflected from each LED is measured and used to calculate the angle between the object and the sensor. The selection of components, circuit design and physical layout are all critical to achieve good results.
The latest design has a range of around 8" to 16" depending on the reflectivity of the nearby object and the ambient lighting. It has a 180 degree field of view and is generally good to within 10 degrees or better. The sensor is fast - completing a full scan every 12 ms. It can communicate over Serial or I2C. It operates from 6.4 to 14V, but can be modified using jumpers to operate down to 5V. The average current draw is around 80 mA with a peak around 500 mA. The PCB is a semicircle with a 90mm diameter so it is small enough to install on a mini sumo robot. Best of all, the sensor has two LEDs on top to provide immediate feedback when an object is seen.
At the heart of the Protractor is an ATMEGA168 chip. The chip turns the LEDs on and off at the appropriate time, measures the output of the phototransistors, sets the brightness of the feedback LEDs and communicates the result to a host microcontroller. The I2C interface is buffered so it can communicate with either a 3.3V or 5V master. GPIO pins are used to turn each LED on and off. One ADC pin is used to sense the reflected light from the phototransistors and another is used to sense the input voltage.
The board has its own 5V regulator for the micro-controller and can be powered with 6.4 to 14 volts. The entire circuit can operate using as little as 5 volts, provided the external 5V supply is robust with low resistance wiring and can handle fast transients without brown-out. To power the board from 5 volts, R24 should be populated with a 0 ohm resistor. There are two jumpers shown, SJ3 and SJ4 which connect the power ground to the digital ground. These jumpers are physically connected on their footprint and are placed close to the regulator to keep the noisy power ground isolated from the micro-controller ground over the rest of the board. A voltage divider circuit allows the micro-controller to monitor the input voltage and can send out an alert if it drifts a little out of range.
IR LED Emitters
The latest design of the Protractor uses a total of 8 SFH4655 LEDs as the emitters. For simplicity, only three of the LED emitters are shown in the circuit below. These right angle surface mount LEDs help keep the circuit board profile thin. The SFH4655 has a narrow viewing angle which increases the range of the sensor and reduces the amount of noise from stray reflections off the robot and the floor.
To achieve the maximum possible sensing range the infrared LEDs are pulsed with very high current. Power LEDs can be pulsed with high currents if the duty cycle is kept low and the current is controlled to not exceed the maximum rated limit. I wanted the Protractor to accommodate a wide range of input voltages so it could be used on different projects. A resistor in series with an LED works fine for current limiting if the input voltage is fixed, but if the input voltage is variable then an more active form of current control is needed. The LEDs will be turned on and off in about 100 micro-seconds which is too fast to use a switching regulator as they typically take a few milli-seconds to stabilize. A linear regulator would be fast enough provided that the heat can be dissipated. While a standard adjustable voltage regulator such as the AP1117 can be wired up as a current regulator, my preferred circuit for linear current regulation uses a MOSFET as the primary element. The MOSFET circuit requires a few more components, but FETs can withstand higher temperatures and typically have lower thermal resistance than a voltage regulator of the same size.
The easiest way to turn a power LED on and off is to place a small logic-level n-channel MOSFET between the LED cathode and ground. An n-channel MOSFET can be controlled directly by the ATMEGA168 I/O pins. The choice of NFET is not critical here as long as it can handle at least 1A current and has a miller plateau in the 2-3V range, I've used both the Si2308BDS and IRLML6344 with good results. If one of the LEDs is accidentally left on for too long it will burn up due to the high current. To prevent this from happening, an RC circuit is placed between each I/O pin and the gate of the n-channel MOSFET. When the I/O pin is set high, the capacitor between the I/O pin and the MOSFET gate is charged, turning on the MOSFET. Under normal circumstances, the software will set the I/O pin low after 100 micro-seconds which will quickly discharge the capacitor and turn off the MOSFET. If the I/O pin is left high for too long, the pull-down resistor will discharge the capacitor within a few hundred micro-seconds, turning off the MOSFET and saving the LED from certain death.
Given the switching circuitry between the LED and ground, it is easiest to install a current regulator on the high side of the LED, i.e. between the LED and the positive voltage supply. Since only one LED will be turned on at a time, they can all share a single current regulator circuit. All of the anodes of the LEDs are wired together and connected to the drain of a p-channel power MOSFET. This MOSFET will be responsible for dissipating any excess energy in order to regulate the current flow through the LEDs. The gate of the PFET is held in a normally on state by a resistor connected to ground. A current sense resistor is placed between the PFET source and the positive voltage supply. A bipolar transistor is wired across the current sense resistor so that it turns on when the voltage across the resistor reaches approximately 0.6V. As the bipolar transistor turns on with increased current, the voltage on the PFET gate increases which chokes off the current flow thereby regulating the current. The amount of current can be set by choosing the proper value for the current sense resistor. The SFH4655 LEDs used in this circuit can handle a maximum of 1A if pulsed at low duty cycles. Operating components at their absolute maximum ratings is not a good idea, so a current of 800 ma is more reasonable. To achieve 0.6V drop at 800 mA, the value of the current sense resistor should be 0.75 ohms.
For reasons discussed later, the LEDs should be pulsed on for about 100 micro-seconds and then held off for about 1000 micro-seconds before pulsing the next LED. With a total of 8 LEDs, each LED will have a duty cycle of 100/(8*1000) = 1.3%. Checking the SFH4655 datasheet, we see that this is within the permissible pulse handling capability of the LEDs. Since the current regulator is shared between all of the LEDs, it must dissipate power during each pulse. The regulator will operate 100/1000 = 10% of the time. At 800 mA, the voltage drop across the SFH4655 LED will be around 2.2 V and there will be 0.6V drop across the current sense resistor. The positive supply voltage V+ can be as high as 14V so the PFET will need to absorb and dissipate 11 Volts * 800 ma * 10% = 0.88 Watts of power. MOSFETs are available in many different sizes which can dissipate this amount of power, such as DPAK, D2PAK, SOIC8, and SOT223. The smallest of these is the SOT223. The ZXMP6A13 PFET was used in the latest design and performed well.
Turning large currents on and off can generate a lot of electrical noise. To reduce the noise, a large capacitor is added close to the current regulator. If we assume 0.2 ohm of resistance between this capacitor and the power source, the peak current draw of the Protractor would be about 480 mA.
LEDs are an obvious choice for the infrared emitters, but the choice of the detector to measure the reflect light is not as easy. PIN photodiodes are sensitive and fast, but require additional circuitry to boost the very low output currents before they can be input to the micro-controller. In contrast, phototransistors can be connected to a single resistor and input directly into a micro-controller, but they are much slower to respond and aren't quite as sensitive. I had used phototransistors in the past but not photodiodes, so I decided to stick with phototransistors after Dale gave me a tip on how to increase the response time using a cascode circuit.
The VEMT2023SLX phototransistors have high sensitivity, a daylight blocking filter and are available in a right angle surface mount package. With a +/- 35 degree viewing angle, it takes at least 3 to cover the 180 degree field of view of the Protractor. I decided to use four of them so that the angular spacing of the detectors could be symmetrical with the spacing of the 8 emitters. The four phototransistors are placed on the underside of the PCB so they are shielded from the LED emitters which mount on top. The phototransistors and are wired in parallel and connected to a cascode circuit as seen below. The PNP transistor maintains an almost constant bias voltage on the phototransistor emitters regardless of the current flowing through them, reducing the effect of their capacitance on the rest of the circuit. With the reduced capacitance, the output voltage can change quickly as the current through the pull-down resistor changes. Alternatively, the value of the pull down resistor can be increased for higher sensitivity.
For the circuit shown above, testing showed that pulsing the LED for durations less than 50 micro-seconds provided almost unusable sensing distance, while durations over 120 micro-seconds provided little additional benefit. Further testing showed that once a pulse was over, it took about 1000 micro-seconds for the output voltage to drop back to a steady value. These timing characteristics informed the design of the LED current regulator as mentioned above.
Whew! That was a lot of details. If you have Eagle installed you can download the Schematic and Board files at the bottom of this page to see it all together. Now on to the PCB Layout!
Not only does a semi-circular board shape lend itself to optimal placement of the emitters and phototransistors, it also makes the PCB look like a protractor! I wanted the board to fit on a mini sumo robot, so it needed to be less than 100mm across but also not too small otherwise the light might reflect off a robot's internal facets and generate noise. I played around with the component placement and decide to try to squeeze everything into a semicircle 90mm in diameter. Five mounting holes would be needed. Two of these holes are placed in the perfect location to sit on top of an upside down Arduino Uno sitting on top of a Pololu Zumo - my test platform. The other three mounting holes are placed on a 0.25" grid for convenient mounting to anything else.
The LEDs and Phototransistors need to be placed around the perimeter of the PCB. The micro-controller is best placed in the middle to keep the signal traces as short as possible. The 5V voltage regulator was placed in the lower right and the current regulator circuitry was placed in the lower left. Most of the connectors are located along the mid-section of the straight edge, close to the micro-controller.
Since the LEDs need to be spaced around the perimeter, I decided to route the V+ and power ground signals around the perimeter too, side by side on the bottom layer underneath the LEDs. The top layer has a trace running around the perimeter which carries the switched and regulated current between the PFET and the LED anodes. Beside each LED is its NFET which conducts power to the power ground trace directly below when pulsed. Having the LED power traces routed directly on top of each other keeps the area of the high power current loop low to minimize emissions and noise.
The micro-controller is placed in the middle of the board, with I/O signals extending outwards to the NFETs and phototransistors. In general the 5V power is routed point to point through the center section and a DGND plane is poured on the top and bottom throughout the center of the board with generous vias and gridding. The 5V power for the phototransistors is routed alongside the phototransistor return signal traces to minimize cross-talk on this sensitive analog signal. Signal traces are routed on the top layer as much as possible, allowing the majority of the bottom layer to serve as a ground plane.
The spacing of the LEDs and Phototransistors is very important. Previous versions of the Protractor had odd numbers of LEDs and phototransistors, some of which were positioned directly on top of each other. The sensitivity as a function of the angle was erratic and there was a lot of light which bled through the PCB. In the latest design, the LEDs are clustered together in groups of two halfway between the phototransistors below. Great care is taken during the layout to ensure there is enough copper on the top or bottom layer to prevent any direct line of sight between the LEDs and the phototransistors through the translucent FR4. This arrangement allowed the sensor to function properly without coloring the whole PCB with a black sharpie, and the sensitivity as a function of the angle is very flat.
The PCBs were ordered from iTead Studios. They charge around $15 + shipping to make 10 copies of a 2-layer green PCB with dimensions 5x10 cm or less. The quality is more than adequate to handle the 0.5 mm pad spacing of the ATMEGA168 chip in a TQFP-32 package. All the components all came from Mouser. I bought enough parts to make 10 boards and the component cost came out to around $15 per board.
It took about 3 hours to populate the first board using a soldering iron. Just a few years ago I thought I was incapable of soldering. I had no idea what flux was and I only had a 25W iron with no temperature control and an old nasty tip - but hey it was free! I bought a cheap 50W iron from eBay a few years ago and started to realize that soldering wasn't too hard with decent equipment. The cheap eBay iron stopped working after a year and I now use a 40W variable Weller iron. Soldering surface mount parts is different than through hole, but after an hour or two of watching Youtube videos about SMT soldering and a little bit of practice and its really not that hard. Before powering up any new board, I always check the power and ground nets with a meter to make sure there are no short circuits.
There is no USB connector or FTDI chip on the Protractor so the code must be uploaded using the ICSP port. I use a USBtinyISP to upload the code using the Arduino ISP. I updated the code from a previous version to handle 8 LEDs and on initial glance everything seemed to be working OK.
As a side project I recently attempted to turn an old toaster oven into a reflow oven. I tried assembling the second protractor board in the oven - it turned into a mass graveyard of tombstoned components, some even jumped across and off the board! Perhaps it was the cheap solder paste, my inconsistent application of solder paste with a syringe, non-uniform heating of the toaster oven, or a dozen other potential pitfalls which can cause trouble with a reflow oven. I went back to the soldering iron and populated a few more boards by hand. If I laid out all the parts before I started it took about 2 hours per board.
Every time the Protractor pulses an IR LED, it takes two readings from the phototransistors. The first reading occurs before the LED is turned on and measures the amount of ambient light. The second reading occurs once the LED has been on for 100 micro-seconds and measures the ambient light in addition to any reflected light. By subtracting the first reading from the second, we have a measure of how much light was reflected off a nearby object. The Protractor is constantly pulsing the 8 LEDs in turn, determining the amount of light reflected from each direction, and then uses the Centroid algorithm to calculate the angle from which the most amount of light was reflected. The angle is output as a single byte ranging from 0 = far left to 255 = far right. If requested by the master, the protractor will output a second byte which represents the intensity of the reflected light. In some circumstances this value can serve as a very rough estimation of the distance to the object.
Typically we would take readings from all directions before calculating the angle, but as mentioned earlier the Protractor must wait at least 1000 micro-seconds between pulsing each LED. To speed things up a bit, the angle is calculated after every single pulse. The reading from each direction is stored in an array, and the angle is calculated using the latest reading available for each direction. Not only does this make the sensor output faster to respond to new conditions, but it provides a bit of smoothing similar to averaging. If the sensor's master only queries the sensor every 12 milliseconds or slower, then the smoothing would not be noticeable.
There are two green LEDs on top of the board which provide visual feedback of what the Protractor sees. Each LED is connected to a PWM pin of the ATMEGA168 micro-controller to control its brightness. If an object is on the left or right side, then the left or right side LED is on, and if an object is in the front then both LEDs are on. The brightness of each LED is varied according to the intensity of the reflected light and the angle. Figuring out the right balance of LED brightness that corresponds to the objects angle took some time since human perception of LED brightness must be considered. Check out the short video below to see it in action!
If you like this project or have any suggestions, send me a note, I'd be glad to hear from you.