Arduino + Processing – 3D Sensor Data Visualisation

Arduino 3D scan

So following on from my previous posts about visualising sensor data in Processing, I’m now looking at drawing 3D representations of the data recorded from the Sharp IR sensor – although can be any kind of range finder.

I started by rigging 2 servos, one to pan left to right, the other up to down. The latter is limited to only 60 degrees of movement. I’m going to represent each servo position in a grid to start with, so a grid 180 wide (x) by 60 tall (y). The distance measured from the sensor will form the z index position so how far/ close a point will appear.

The setup is pretty much the same, Arduino records and sends the sensor data to the serial port buffer along with the X and Y position of the servos. Processing then picks this up and populates an array. Now this time I’m using multi-dimensional arrays, that is one array that stores other arrays. I could make just one array of 10800 items (180 * 60) but its far more efficient to make an array of 180 items, each item being another array of 60 items to store the distance measured. So for every 1 degree I move left to right, I record the 60 positions of the up/ down servo and the reading taken.

To visualise this I started drawing squares using the QUAD_STRIP shape to produce a grid layout (image at the top of the post). Of course because I’m actually using polar co-ordinates (degrees) instead of cartesian (x, y) then what the sensor is reading can’t really be translated to a flat grid. Because when it measures something vertical the measurements will all be different and when translated to my flat grid, it would make anything vertical look slanted. Trouble is now we’re trying to view something in 3D space so it doesn’t look all that great – so I’ve added in some animation to rotate the object slightly, looks fine when you zoom in close enough to one section but otherwise it’s just a random shape.

There are 2 ways around this, firstly we can convert our co-ordinates to cartesian. Or we can alter the grid used to display our data, the shape needed is basically a 60 degree arc thats lathed 180 degrees – so it kind of looks like a tyre wall. The radius used to draw our 60 degree arc is calculated by the distance taken from the sensor.

Arduino 3D Sensor Data Parts

SRF05 Ultrasonic range finder or Sharp GP2Y0A02 IR sensor (basically any kind of distance sensor)
Arduino Deumilanove w/ ATMEGA328
Breadboard / Prototyping board
Jumper/ Connector wires
2x Servos (has to need no more than 5v supply)
C shaped Servo brackets (If anyone can make these cheap enough let me know!)

Arduino 3D Plotter Circuit

Using the below posts you should be able to figure out how to wire the sensor and how to use the servos. I use digital pins 9 and 10 for the servos and analog pin 1 for the sensor reading.

Arduino SRF-05 Tutorials
Arduino Servo Tutorials
How to use the Sharp IR range finder

Arduino Sketch

We use the servo libary and a couple of FOR loops to control 2 servos, for every degree panned we tilt the other servo through 60 degrees taking a series of sensor readings for each position and averaging them. We output these values with the X and Y position in degrees to the serial port buffer. At the end of each loop we reset the servo position. If the sensor reading is outside the range of operation of the servo we also handle this.

3D Scan Visualisation for Sharp GP2Y0A02 IR range finder
Sends sensor readings for every degree moved by the servo
values sent to serial port to be picked up by Processing
#include             // include the standard servo library
Servo leftRightServo;         // set a variable to map the servo
Servo upDownServo;
int leftRightPos = 0;         // set a variable to store the servo position
int upDownPos = 0;
const int numReadings = 10;   // set a variable for the number of readings to take
int index = 0;                // the index of the current reading
float total = 0;              // the total of all readings must be a float to allow totaling of float values
int average = 0;              // the average
int IRpin = 1;                // analog pin for reading the IR sensor

/* setup the pins, servo and serial port */
void setup() {
  // initialize the serial port:

/* begin rotating the servo and getting sensor values */
void loop() {
 for(leftRightPos = 0; leftRightPos < 180; leftRightPos++)

  for(upDownPos = 60; upDownPos < 120; upDownPos++)

      for (index = 0; index<=numReadings;index++) {            // take x number of readings from the sensor and average them
        float volts = analogRead(IRpin)*0.0048828125;   // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
        float distance = 65*pow(volts, -1.10);          // worked out from graph 65 = theretical distance / (1/Volts)S -
        total = total + distance;                              // update total
    average = (int) total/numReadings;                               // create average reading
        if (average < 20) {
         average = 20;
        if (average > 150) {
         average = 150;
        //average = 0 - average;
    if (index >= numReadings)  {                               // reset the counts when at the last item of the array
      index = 0;
      total = 0;





[ad#Google Ad in content]

Processing Sketch

We now listen to the serial port and each time there is an event we take the values and populate an array based on the X and Y values sent from the Arduino code. We add this value on to the existing value and then for each complete mapping we work out the average value – so the longer it runs for the more normalised the results should appear.

Using some basic trigonometry we have a class that makes an arc. Our draw() method calls this arc and translates/ rotates it for each of the 180 degrees. The arc itself is calculated from using the distance reading from the sensor as its radius.

If using a grid instead of this shape then we just say at point X,Y set the Z value instead of worrying about radius’s etc…

3D Scan Visualisation for Sharp GP2Y0A02
Maps out an area of what the GP2Y0A02 sees into a 3D view
import processing.serial.*;     // import serial library
Serial myPort;                  // declare a serial port
int x, y, z;                     // variable to store x and y co-ordinates for vertices
int value = 0;                  // value from sensor
int[][][] data = new int[181][61][1];  // create an array to store each new sensor value for each servo position
int count;
int average = 1;
PFont myFont;                   // setup fonts in Processing
int numberOfSegments = 179;
createArc Arc;                  // create an instance of the Arc class
float radius = 150;
float angle = 0;

void setup(){
  size(640, 360, P3D);
  Arc = new createArc();        // assign the Arc classes to an object
  myFont = createFont("verdana", 12);
  // setup the serial port and buffer
  myPort = new Serial(this, Serial.list()[1], 9600);


void draw(){
  float tempX = 0, tempY = 1, tempZ = 0;
  translate(width/2, 200, 110);
  angle = 180.0 / numberOfSegments;
  rotateY(count * PI/10800);
  for (int j = 0; j < numberOfSegments; j++){
      tempZ = cos(radians(angle))*radius;
      tempX = sin(radians(angle))*radius;
      translate(tempX, tempY, tempZ); // move each instance we create of the arc object to a slightly new position and rotation
      angle += 180.0/numberOfSegments;

// creates an arc object using QUAD_STRIP
class createArc {
// pass values to create method to know which array to load 1 to 180...
  void create(int degree){
    for(int a=60; a < 120;a++) {
      float x1 = cos(radians(((90+a))))*(data[degree][a-60][0]/average);
      float y1 = sin(radians(((90+a))))*(data[degree][a-60][0]/average);
      float x2 = cos(radians(((90+a))))*(data[degree+1][a-60][0]/average);
      float y2 = sin(radians(((90+a))))*(data[degree+1][a-60][0]/average);

/* get values from serial port */

void serialEvent (Serial myPort) {
  String xString = myPort.readStringUntil('\n');  // read the serial port until a new line
    if (xString != null) {  // if theres data in between the new lines
    	xString = trim(xString); // get rid of any whitespace just in case
    	String getY = xString.substring(1, xString.indexOf("X")); // get the value of the servo position
        String getX = xString.substring(xString.indexOf("X")+1, xString.indexOf("Z")); // get the value of the sensor reading
        String getZ = xString.substring(xString.indexOf("Z")+1, xString.length()); // get the value of the sensor reading
    	x = Integer.parseInt(getX); // set the values to variables
    	y = Integer.parseInt(getY);
        z = Integer.parseInt(getZ);
        data[x][y][0] += z;
        //println(z); // for debugging
        if (count > 10800) {
          count = 0;

[ad#Google Ad in content]

So here’s a quick screen grab of the 3D object that represents what the sensor sees, looks pretty confusing but if you zoom in and take a small section of it then it’s a bit better. Other than that its just a random shape!



  • Hey Larry,
    This is very cool stuff! I had made something similar to your 2d sensor, but hadn’t thought to try 3d. What is the run time on one complete sweep? As I was trying to do this from a robot platform and was having issues getting enough quality samples quick enough to be able to react to the data before it was stale… ran in to wall before discovering it was there. Slow down you might say? Where is the fun in that!
    Thanks for the article!

    • Hi Nate,

      It takes a while for a full 180 sweep – it all depends on how accurate you want the data, mine takes about 3 minutes, which is a 10 20ms scans with the sensor and then averaged, even then its still very erratic. But it is interesting to see what the sensor is reading, helps me understand just how poor one sensor is for object detection.

      The IR range finder is much better placed to detect smaller objects than the Ultrasound one but even then its still not great.

      What I would like to do is use a laser/ barcode scanner to see if I can get better accuracy but it’d require more processing power than I can stick on a robot. Or alternatively build an array of sensors to get the time down as I wouldnt need to take multiple readings, the idea being lots of sensor look at the same area to build a better picture.

      However, I want also to spend a bit of time investigating sending data wirelessly which may help and then get on to getting robots to build maps of their area.

  • Hi Larry, see you are taking it further. How about letting go of the radarbeam plot and instead only plot a rectangle in the location you measure ‘something’, ie. the ‘end’ of the radar beam?
    And then center the image as if looking from where your scanner is. This would give you some roman-theatre-seat-rows image looking as if photographed from its stage. You will need to z-buffer the data and plot the farthest rectangles first, overlaying them with rectangles positioned closer to the center of scanning. Maybe you can also brighten the color if you are closer to the scanner, so you get a color-depth cue too.

    • What this code does is plot the distance measured as a rectangle and draws this as a 3d object but in an arc- but it doesnt center on where the sensor is looking at which would be cool.

      So instead of an arc and extruding faces from the arc towards the center, just plot arbitary boxes with where an object is detected?

      Like the idea of the colour changing as well :) cheers for the ideas.

  • Look here: I did not see this when I posted my previous comments. Scout’s honour.

    • oh cool… doubt the IR sensor will do things that well :( I’d have to make a sensor array out of many of them to get a decent resolution.
      But I do have a laser – I’ll need to get some sort of scanning done with that and a camera I guess… I think I could just find the laser line then try converting that to 3d spaces.

  • The word “coordinates” does not have a hyphen.

    • Hi Alex,

      As one pedant to another thanks for pointing that out but why are you using double quotes around the word coordinates, what are you quoting? Thats surely just as bad for grammar and punctuation as is my spelling? :)


  • Hi Larry,

    I was trying to rebuild it, using your code, but the Arduino code seems incomplete. You talk of using 2 servo’s, but I cannot find 2.

    Could you explain this?

    • well noticed – I’ll amend the code when I get in tonight.

      Looks like I added the wrong code! D’oh!

      • LOL. I was allready afraid that I did something wrong, but it just didnt seem okay. Nice project, cant wait to test it tonight.

        • OK, I’ve updated that now :) Its just a another FOR loop. Let me know how you get on and if you get better results.

          • It’s working. Great sketch! I made an exportfunction to .STL for edditing. I cant eddit it, because its no filled shape… just a vertex.

            I’m looking for ways to “unflat” them…. turn them in to 3d shapes. I’m going to dig in to it.

          • I wasnt sure what to do with the vertexs afterwards – it makes a quadstrip but other than that I’ve not much idea, let me see the results when you’re done :)

  • Larry, Your Radar fits perfectly with what I need when I’m out there in the field! MASSIVELY!!
    I built the unit, but it’s not for a robot, it’s for a stationary post. Actually two to four posts.
    I’m into wildlife research, and IR might not work for me, I’m going for the Parallax Ping sensor.
    The servo’s scan, the ping sensor reads and my laptop displays it in basic text.
    I am a newbie to arduino.
    But what program is used to “visualize” the Radar screen? To “see” the Radar Screen showing the data?
    And where do I go to get it?
    Is it a second program that I run on my pc that intakes the data from the arduino?

    Thanks a million, and if this new digital tool works, I’ll be sure to remember the people who helped me!

    Bigfoot Researcher,
    aka YouTube UserName: “azbirddog”

    • Hey Vic,

      the program I used is called Processing – its the same kind of deal as Arduino. download it from and run my sketch – it takes data from the serial port the Arduino is plugged in to.

      One note of caution: you can only run one program at a time with the serial port so you do your code for Arduino, shut that down and with the Arduino board still connected to your serial port run the Processing program.

      You can make Processing do other things as well to help log the data you get – the Ping sensor your using will have a range of about 4 metres and the further out it gets the wider the detection range (Its conical) so you may need to adjust for this – It depends on how much variance you have in your environment – e.g. wind blowing plants around etc.. will register as a change.

      Send me the link when you’re done (if you blog about it) and I’ll chuck a link to you etc.. I’d be really interested in the outcome since I have friends who study Zoology.

  • I hit a brick wall of my own making. lol.
    The sensor i’m using is a Parallax Ping sensor with gnd, 5v and signal.
    It’s digital, not analog, and I also can’t seem to find out how to mod the code to adjust to using this setup. Any help would be cool.

    And one other question. Is it possible to have the arduino track that item that is within a certain range, using this sensor? Because to have a camera snapping a picture at something that is being tracked, would be kind of awesome. lol.

    • Hi Vic,

      The ping sensor should be fine on digital and works much the same way as the SRF-05 I would assume. Basically you have a trigger and an echo pin, in my sensor they’re separate but in others they can be combined to use just one pin. I’ll have a look at the Parallax Ping sensor to see if I can help you out.

      To track an item, remember that you need to know its position and how its moving and how fast you want to track. For any decent accuracy you would need multiple sensors and the Ping would not be the best for this.

      I would lay a grid of infrared sensors for tracking, how big an area are you wanting to track? This sounds interesting to me so I’m happy to help :)

  • LOL, if you’re into wildlife, especially the “unknown” wildlife, then it should grab your attention.
    You can check me out on youtube, username “azbirddog”.
    If you believe me, then I’ll go into detail.

    I’m out in the wilderness inside of my blazer zr2. Its night time, its so dark outside, you can’t see your hand in front of your face. There is a tree canopy.
    In this position, alls that I have been able to record thus far are footsteps, snapping twigs, low frequency thudding, grunting and some unknown language.
    And yes, I do have this digitally recorded.

    It’s hard to get position, of what is outside of my Blazer.
    So, sonar is my best ticket.
    IR has been known to keep these “creatures” away.
    I have several IR cameras posted on top of my Blazer.

    So I thought of sonar ping when I seen your youtube radar/sonar video.
    At the least, I would like to have a cheap nokia screen on an arduino mega, letting me know of distances within 11 feet around my truck.
    Let’s say, when something comes into that 11 foot range, I get the sensor reporting that something is in my immediate parimeter, and which sensor is reading it.
    I don’t need to know the distance, but it would be nice, if possible.
    At the least, I would have 2 ping sensors, one in front, 1 to the rear.

    This info would tell me in what direction to point my IR camera so I can turn it on and start recording. Actually, 2 cameras, one infrared, the other gen 2 NV on an HD Canon videocam.

    Because if I was looking around using the vehicle mounted cams, the movement would keep the away.

    And it wouldn’t have to be a nokia display, but it would be somewhere near that price range.
    I already have about 3k into cameras and NV. LOL

    So, a little notification monitor would be priceless.

    And yes, they are real.
    100% guaranteed!

    • Hey Vic,

      I can see why you want the sonar detection instead :)

      So you can wire up multiple sensors and write their distance to an LCD screen, just building a simple notification screen, 8 of them would be ideal and they should be able to form an 11 foot perimeter and each direction is covered. Even a seriees of rings of LED’s to notify you is pretty simple to do.

      You can then also use these sensors to remote trigger your cameras quite easily depending upon the range. You could also try building a trip wire system to set the cameras off – i’ve seen some nice potos done this way, so camera pointing towards the tripwire to get a photo/ film of whatever it is (keeping the camera out of smashing range!)

      If there’s a noticeable/ repeating trail then you could set these trip wires around there which may get you some decent results.

      I’ve definitey go to try this out :) thanks for the inspiration.

  • I just want one little monitor like the nokia screen to tell me which direction, or which sensor got triggered.
    I’m hoping for 4 sensors.
    It’s also sooo dark out there, that one small red LED shines alot.
    So the little display would be easier to hide.

    Even the dim red from IR keeps them away.
    I just posted another video on youtube.
    It came out pretty good.

    I’m into electronics and working mechanical stuff, I’m just barely getting into programming the arduino, and I’ve made alot of headway.
    The problem with the camera trip, is that I don’t have a camera that has a remote trigger.
    And this really really bugs me bad. Because I would have already had photo’s of these guys at my vehicle 3 years ago.
    It’s hard to believe, but it’s all real and true.
    If you want, I’ll even direct you to the only thermal photo’s of one of these creatures.
    It’s on the net, but I don’t have copyright to them, the rightful owner does. But I was there when he got the thermals.
    If you inspect the thermals, you’ll discover that there are others in the photo’s. Problem with thermal imagers is that these animals have long hair, about 2 to 3 inches in length. The ends of the hair become the ambient temperatures, thus hiding from the thermal. And the small 240 displays really don’t give any clarity or definition at the time of the viewing.

    LOL. I can go on and on.
    But that’s what I really need.
    I have an Archos 404 portable media player that died on me.
    The display has to still be good.
    But I’m not sure how you connect the ribbon contacts, or whatever they’re called.

  • Hey Larry this is pretty cool, been working on something similar myself and you’ve explained your code very well. I think I may be able to make your servo brackets for a lot less than retail.

    I will see if I can get around to posting a video of the display I end up using for this, because I think that was the hardest area for me. I intend to use this i r display stationary, so in processing I have a map of what doesn’t move and measure the distance kind of like what you have with the exception of some walls and doors in the way.

    Shoot me an email if your interested in the brackets (or machinable wax)…

  • Hi, Larry
    Great reading! very cool project, i’m following you and i hope you will find the way to flatten the image.
    Also adding a color depht schema should be dazzling! imho :)

    • Thanks. Colour depth would be interesting, the only thing I think I reeally need to do is to gain more resolution in the scan – so multiple sensors perhaps in a linear motion would provide the best result

Join the Discussion

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>