Low Cost Accurate 3D Positioning





Introduction: Low Cost Accurate 3D Positioning

(The above video demonstrates the water potentiometer technique used in this project and practically verifies the differential equations above.)

Project Summary

A ridiculously low cost water-based 3D sensor for real-time tracking of precise coordinates of the tip of a stylus, in confined 3D space.

External Links

The Challenge

The 3D positioning and gesture tracking technology incorporated in all of today's sensors, such as the Kinect Sensor or Leap Motion Controller, as well as the camera/sensor included in the VR bundles of Oculus Rift or HTC Vive, is based on IR.

The challenge that this project addresses is to develop a sensor device, alternative to the 3D IR camera/sensor, which -

  1. costs merely 6.4%, ($7.6, i.e, counterfeit Arduino Uno + plastic gear motor) compared to 2 x Oculus Sensor (2 x $59 as stated in https://www.oculus.com/accessories/), and also much less than other IR cameras/sensors.
  2. has completely open source hardware (an Arduino project), software and tracking algorithms, as opposed to the hardware and tracking algorithms of those IR cameras/sensors.
  3. is precise up to 1 mm, along all 3 dimensions, as opposed to a resolution of around 1 cm provided by today's IR camera/sensors.
  4. can be reconstructed from scratch in a mere 10 minutes, and has very simple schematics and build design.
  5. as opposed to IR cameras/sensors is able to see beyond opaque obstruction, and whose tracking precision is not compromised owing to white or shiny surfaces.

Brief Explanation of Tracking Algorithm

  1. Water potentiometer gives the voltage at tip of the stylus.
  2. Voltage gives a plane containing the tip of the stylus.
  3. Gear motor rotates the sensor to give 3 different voltages for 3 different angular positions, for the same fixed stylus tip.
  4. 3 different voltages implies 3 non-parallel plane equations.
  5. 3 non-parallel planes intersect at a unique point.
  6. x, y, z coordinates of that point is the stylus tip's location.

Detailed Explanation of Tracking Algorithm

The basic idea behind this sensor is the use of a parallelopiped water container as a water potentiometer
device. It is similar to a 3-pin slide pot used in electronic circuits, with the 2 aluminum electrodes equivalent to the 2 end pins of a slide pot, and the stylus is equivalent to the middle pin (voltage output) of a slide potentiometer.

A parallel pair of aluminum sheet electrodes are attached to the water container at two opposite faces, and inclined at an angle 'alpha' (= 75 degrees or (5/12)*PI radians) to the horizontal base of the parallelopiped container. These two apply a voltage drop of 5 volt across the water. A metal pin, connected to Arduino Uno's ADC input, is attached to the tip of the stylus. This pin tracks the voltage at the tip of the stylus, i.e., output voltage of the water potentiometer, when dipped into the water.

By knowing the output voltage, the plane equation (with respect to lab reference frame) can be derived, which is the locus of all points, inside water, which are at the same voltage as the tip of the stylus. The sensor is constantly rotating anticlockwise in the horizontal plane, with a small constant angular velocity. The axis of rotation is parallel to the z-axis and passes through the intersection of diagonals of the horizontal base of the parallelopiped container.

The sensor reads the output voltage of the water potentiometer at 3 different angular positions. Thus, 3 different output voltages are read for the same fixed stylus tip (fixed with respect to lab reference frame). A plane equation (with respect to lab reference frame) is derived for each of these 3 output voltages. These 3 planes are non-parallel due to the rotation of the sensor. Moreover, this system of 3 non-homogeneous equations is consistent, and has one unique solution (i.e one point), since it can be proved that matrix 'A' (refer derivation image in images section), is non-singular, i.e., its determinant is non-zero.

In simple terms, the 3 non-parallel planes intersect at one unique point. Solving this system of equations (3 equations for 3 unknown variables), using matrix equations, the x, y and z coordinates (with respect to lab reference frame) of the intersection point is obtained. This is the precise position vector of the stylus tip.

Extended Applications

  1. Sculpting in Virtual Reality ( interfaced with a VR headset such the Google Cardboard, Oculus Rift, or HTC Vive ).
  2. Painting in Virtual Reality ( interfaced with a VR headset such the Google Cardboard, Oculus Rift, or HTC Vive ).
  3. Modelling in Virtual Reality ( interfaced with a VR headset such the Google Cardboard, Oculus Rift, or HTC Vive ).
  4. Interacting with holograms viewed from devices such as Microsoft Hololens.
  5. CGI designing.
  6. Virtually building models to be 3D printed.

A World Changing Idea and How it Benefits the Society

  1. This sensor can be quickly and easily be constructed even by non-engineers and high school students. So it can be used for a more interactive and fun way of learning science by interacting with holograms.
  2. This sensor is a low cost alternative to IR cameras/sensors for amateur or professional artists.
  3. Since its tracking algorithms and hardware is completely open source, it can be developed by researchers around the world to further minimize its cost and achieve a greater deal of precision.
  4. Imagine one of this low cost DIY sensor at every home on the planet. It is surely going to revolutionize the way we think and begin a new era of computing since it enables 3D interaction with computers.

Step 1: Gather All Components

  1. Arduino Uno Rev3 (counterfeit Arduino Uno board costing $6.2)
  2. plastic gear motor (5V, 30 RPM)( Buy one from Nex Robotics online store)
  3. aluminum foil (kitchen foil)
  4. plastic container (rectangle-base or square-base)
  5. 5V 2A AC-DC power adapter
  6. 1 circular metallic ring
  7. 9V heavy-duty battery

NOTE - The sensor is rotated by a plastic gear motor rather than a servo, since, it would cause frequent jerks, which would fluctuate the voltage at a fixed point (fixed with respect to sensor reference frame) in water.

Step 2: Upload C++ Code to Arduino Uno

Download the Arduino IDE from https://www.arduino.cc/en/Main/Software. Download 3d_sensor.ino and MatrixMath-master ziparchive from the Files section. Open 3d_sensor.ino in Arduino IDE and select Include Library from the Sketch menu option. Select Add .ZIP Library and browse and select the MatrixMath-master zip archive. Now Verify and Upload the C++ code to the Arduino Uno's microcontroller.

MatrixMath C++ library - licensed under GPL2. Github repository - https://github.com/codebndr/MatrixMath

Since water is an electrolyte, its composition, hence, conductivity does not remain uniform on passing current through it. Thus, to retain uniform composition, electrolysis must be minimized. In order to minimize electrolysis, the following adaptations have been made -

  1. The microcontroller C++ code constantly keeps swapping over the polarity of voltage drop across the water, to cancel out the disturbance in its composition.
  2. The microcontroller C++ code has been optimized for minimum cycle time period, to maximize the frequency of swapping of the voltage drop polarity.

Owing to the above adaptations, the water always has uniform composition and hence, uniform conductivity at all points inside water. Thus, the voltage drops linearly with respect to the displacement from one electrode.

Step 3: Construct the Sensor

Cut 2 square pieces from the aluminum foil having breadth equal to that of the plastic container and having height a little greater than that of the container. Stick each square lamina on a cardboard base of exactly equal dimensions as the lamina. Fix these 2 electrodes inside the plastic container at an angle of 75 degrees or (5/12)*PI radians to the horizontal base.

Step 4: Hook Up the Sensor Wires

Connect a wire from from one of those electrode plates to digital pin 2 of the Arduino Uno. Now this electrode plate becomes ELECTRODE_0.

Connect another wire from from the other of those electrode plates to digital pin 3 of the Arduino Uno. Now this electrode plate becomes ELECTRODE_1.

Due to electroplating on the aluminum electrodes, some voltage drop is consumed at the 2 electrodes, so this offset in voltage at the ends of the potentiometer needs to be corrected, or else voltage would not be linear, i.e., directly proportional to the horizontal displacement. In other words, the voltage drops linearly between the 2 offset pins (and NOT between the 2 electrodes, due to electroplating at the 2 electrodes).

Now, fix one wire to the inner side of the plastic cuboidal container box at some distance from ELECTRODE_0. Connect this wire to analog pin A1 of the Arduino Uno. Now, this pin becomes OFFSET_0.

Now, fix another wire to the inner side of the plastic cuboidal container box at some distance from ELECTRODE_1. Connect this wire to analog pin A2 of the Arduino Uno. Now, this pin becomes OFFSET_1.

Next, power the Arduino Uno with a 9 volt battery.

Step 5: The Stylus

I used a thin wooden stylus. But you can use a sturdy stylus of any non-conductive material. The stylus must be as thin as possible to minimize ripples and disturbance in the water. Fix an insulated wire along its length and strip off just a tiny portion at one end. The coordinates of this tip will be tracked by the 3D sensor. Connect the other end to analog pin A0 of the Arduino Uno. Be sure to that the wire is tightly attached to the non-conductive stick and is not separated from the stick at any point. This is to eliminate unnecessary disturbance in the water.

Step 6: Assemble the Components

Attach the Arduino Uno on the lower face of the plastic water container box. Now fix this box on a plastic gear motor such that the axis of rotation is perpendicular to the horizontal base and passes through the intersection of the diagonals of the horizontal base of the parallelopiped formed by the electrode plates (diagonals of the parallelopiped base and not of the container base). Connect the gear motor to a 5V 2A AC-DC power adapter.

Wipe the 2 aluminum electrodes and the interior of the plastic water container with a wet cloth to clean it of dust and impurities. Fill the water container with water from your home water purifier The water must be at room temperature. Salt or any other substances/impurities must NOT be added to it.

Measure the RPM of the gear motor. Convert the angular velocity of
the motor from RPM units to radians per microsecond units and replace this value with the default value of the ANGULAR_VELO constant in the Arduino C++ code in 3d_sensor.ino. Move the stylus slowly in water to minimize ripples and disturbances in the water.

Step 7: Install 2 Android Apps

Arduino Uno, then, prints these x, y and z coordinates to the Serial USB Terminal Android App, serially, via USB OTG. The Android smartphone is attached to the rotating sensor, along with Arduino Uno. Connect it to Arduino Uno via a USB OTG cable. The AirMore Android App then casts the Android screen to Mozilla Firefox browser running on my laptop, via the phone's WiFi Hotspot.

The format of serial output from Arduino Uno is as follows -




DATATYPE: x, y, z are all in float.

BAUDRATE: 115200 bits per sec


-128.00 <= x <= +127.00 ,

-128.00 <= y <= +127.00 ,

0.00 <= z <= +255.00 ,

When the tip of the stylus is removed from water, only then, x=y=z= +257.00

258 is the code for "start of coordinates".



    • Epilog Challenge 9

      Epilog Challenge 9
    • Pocket-Sized Contest

      Pocket-Sized Contest
    • Pro Tips Challenge

      Pro Tips Challenge

    We have a be nice policy.
    Please be positive and constructive.

    2 Tips

    Many people are confused regarding the use of slant electrodes instead of perpendicular electrodes in my 3D sensor.
    Well, here's the deal.
    In case of cuboid, the normal vector to the 3 planes will be parallel to the horizontal base. So the angle between normal vector and z-axis equals pi/2 radians. So the 'n' direction cosine of normal vector equals 0. So the 3rd column of the matrix of direction cosines of the 3 planes is a column of 0s . The determinant of a matrix is 0 if any of its rows or columns are 0. So matrix 'A' is a singular matrix. For a non-homogenous system of 3 unknowns, if matrix 'A' is singular, it implies that the system of equations will have either no solution or infinity number of solutions.Since, 3rd column of matrix is 0, so its matrix of cofactors is a null matrix. Transpose of a null matrix is a null matrix. So adjA is a null matrix. So adjA.B is also a null matrix. This will prove that the system of equations is consistent and has infinity number of solutions.
    This issue is not present in case of slant electrodes.

    If you face any issues while reconstructing this water-based 3D sensor, feel free to ask here.



    You MUST have maximum surface of contact between aluminium foil and water.

    the reason is that the current density vector must be normal to the end
    planes at all points on the plane. This can only be made possible if the
    ENTIRE end plane is an equipotential surface. Since aluminium has
    negligible resistivity compared to water, it acts as an equipotential
    surface and must cover the entire end planes

    This is great!
    What would be the consequences, on the tracking accuracy, of having solid non-conductive objects inside the water container?

    If u wanna map an object, u must attach a 3D version of the Jefferson polygraph to the stylus.

    solid non-conductive or conductive objects (other than stylus) must NOT be submerged into the water because -

    In simple terms - The voltage won't drop linearly with displacement. So the water potentiometer principle won't work.

    In not-so-simple terms - Due to solid non-conductive objects submerged in water, the area of cross-section of water (above the submerged object) will decrease, so the magnitude of current density (dI/dA) vector will increase, so the magnitude of potential gradient / electric field intensity (J x p) vector will not be constant with respect to horizontal position. Thus, first derivative (dV/dx) of output voltage with respect to position will not be constant. In other words, the "output voltage will NOT be directly proportional to horizontal position". This violates the basic principle of a potentiometer.

    That is really cool. Do you think that you could scale this up and make a larger sensor like this.

    absolutely, but with a larger sensor, portability issues come in due to the weight of water. I mean with a larger sensor you'll have to empty the water, shift it to its new place, and the fill it again with water. But no issues if you've decided on keeping it in one place.