GP2D12 distance sensor
October 2001 update:
Patil manufactures and sells a nifty
GP2D12 sensor interface more or less
based on this design. See it here.
2002 update: Brian Bagnall's Core
lego Mindstorms programming book
contains - among various interesting
topics - a full chapter on the construction
of this sensor. Complete step by step
instructions are provided !
I long thought that a distance sensor would be a nice addition
to Mindstorms robots, but ultrasonic ones were bulky and power
hungry (I've since found Robot
Range Finder that can perhaps be used), and simple infrared
method like the one I used in my radar
car detects obstacles but don't give true distance measurement.
The solution came from Andreas
Peter (thanks Andreas for showing me these devices !) who
interfaced a Sharp GP2D02 to RCX.
These small and rather inexpensive infrared devices are able
to measure distance between 10 and 80 cm with reasonable precision
and good immunity to variations of obstacles reflectivity and
ambient light. For more informations, read GP2D12 datasheet
and Acroname article:
the Sharp IR Detectors.
Andreas sensor interface has a few drawbacks though. The
GP2D02 he could find has a digital serial output not well suited
to RCX analog input, thus requiring a rather complex design,
big and power hungry.
So I decided to try to connect the analog output GP2D12 sensor
using the simplest design possible - and use only power coming
from sensor input. This was a real challenge since GP2D12 used
35 mA under 5 V, while RCX sensor input is current limited to
about 14 mA ! (look at voltage versus current of sensor input
power supply: ).
The main concept to achieve this goal was quickly imagined:
store energy in a capacitor while GP2D12 is not powered, then
release it during measure. Of course there is a penalty with
this technique: conversion time is longer. GP2D12 requires 50
ms per measure, while my circuit needs 300 ms... there is no
The first designs I imagined were rather complex, with timers
and sample-and-hold amplifier, then I slowly came to this streamlined
250 ms, sensor is configured as a light sensor (powered), C1
charges through D1 up to SENSOR+ voltage. Low drop regulator
U1 generates a 5V regulated supply. Q1 is blocked by D2 (D2
maintains base to a voltage higher or equal to its emitter voltage),
so GP2D12 is not powered. Q3 is non-conducting too, preventing
current flow through D3/R5/Q2. So the only significant current
diverted from C1 charging is through R1 (less than 2 mA), and
at the end of this phase C1 is fully charged.
the following 50 ms, sensor is configured as a touch sensor
(passive). SENSOR+ is now only pulled up to +5V through 10Kohm
(inside RCX), insufficient to block Q1. Q1 and Q3 are then conducting,
and GP2D12 is powered. Q2, mounted as an emitter follower, buffers
GP2D12 output and its value is available to RCX through D3 and
Sample code to read sensor:
SetSensor(SENSOR_1,SENSOR_LIGHT); //Enable C1 charge as soon as possible
D1 prevents destroying the sensor
in case of reverse connexion. I didn't use the full bridge
rectifier used in Lego sensor that enables sensors to work
when connected backwards (number of needed diodes jumps
from 3 to 8 !). I considered that someone able to build
this sensor is also able to connect it in the right way...
For those who want it, here is the diagram
with full bridge rectifier.
I used 1 Amp. Shottky diode
for D1, inexpensive and readily available. Its low forward
drop foltage is less than 0.1V for the current that flow
through it, this enables to charge C1 to the highest voltage
C1 stores energy that will be used
during measure phase, it must provide 5V at the end of this
stage. Assuming typical values for GP2D12 (I=35mA, conversion
time=50ms) and an initial 7.5V across C1, its value is C
= I * dT / dV = 35 * 50 / (7.5-5) = 700 µF. Small
margin with 1000 µF...
U1 is a low drop out 5V regulator
in TO92 case. I used a Telcom/Microchip TC55RP5000
but other regulators will probably work, such as STMicroelectronics
L4931-50. Standard regulators such as 78L05 will NOT work
because they require more than 7V at input to get a 5V output.
Take care with some low drop regulators such as LM2931 that
require more than 25 mA when powered at 1V. With RCX current
limitation, this hog eats all energy. (I was caught with
Q1 switches power on and off for GP2D12.
At 35 mA current, I originally used a plain-vanilla BC548.
My sensor began to work with it, but exhibited strange behavior.
Looking to GP2D12 power supply I then discovered 2V dips
! I then looked at GP2D12 consumption and discovered that
it was pulsed (220mA pulses 1/8th of time, supperposed to
a 8mA constant current. See oscilloscope captures here
At such a current, BC548 has a low gain, and since I couldn't
lower base resistor R1 (main current drain during capacitor
charge) I used a high performance Zetex transistor, ZTX718
that offers high gain at high current (other similar devices
C2 stabilizes U1 and helps absorb
peaks of current. A low ESR version would be better (see
"grass" on 5V output when GP2D12 works).
components datasheets (.pdf documents)
to buy GP2D12 ?
GP2D12 can be bought from Acroname
(Part Number: R48-IR12) or from Conrad
(Part Number: 0185309)
Oscilloscope screen captures
See them here.
sensor interface module: photo gallery
The interface module is build on a 1" square
Top view, with components identification
Bottom view. A notch in circuit is cut for big C1.
A single layer circuit board would be very easy
Everything fits in 3 hollowed 4x2 bricks
Pretty tight !
Complete module. GP2D12 fixations were cut to match
Lego brick width.
Ready to work !
A much more ugly circuit...
...mounted on a test vehicle
real application: a wall follower
See it here
test programs (requires
RCX 2.0 firmware that you can get here)
- testGP2D12.nqc reads
GP2D12 sensor output and displays raw value on RCX display.
- measure.nqc reads
GP2D12 sensor output and displays distance (in cm) on RCX
display. Value read is proportionnal to inverse of distance
with some offset (see above old GP2D12
documentation), you can find here
the Excel sheet I used to find the equation converting raw
values to centimeters.
vs. sensor read
Linearized curve: 1000/(distance-2)
vs. sensor read
+ best fit line