Introduction: Ultrasonic 3D Maps With Processing and Arduino

About: An Electronics Engineering Student at VIT University, Vellore, I am an avid prototyper and DIY enthusiast. I really lie to work on challenging problems and I enjoy solving them using tools and instruments that…

Aim:

The aim of this project is to design and develop a mechanism to compute a 3D map in a 3m range and an height factor of 1ft.

Process:

We will be using data collected from an Ultrasonic Sensor (SR04) and communicate that data back to a host system, preferably a laptop and supply the sensor data to a python script which will compute the directional data and plot a graph for an XY-plane.This process results in a 2D feature for any given plane. By adding an actuator mechanism to vary the height of the sensor assembly, we will add a Z-component to the measurements.

A stepper(or servo motor) will be used to align the sensor in a specific direction. For each step taken, the sensor will capture data and plot a 360-degree view of an XY region. Then, another motor system is initiated to vary the height while the sensor aligns back to its original position. This process when repeated across various Z-axis domains yields various XY planes. By extrapolation of each data a 3D view is generated.

Depending on our need, this data can simply be displayed or even saved for future use.

With the basic objective of the instructable made clear, let's dive head into our project!!!

Step 1: Collect All Project Materials

Before we can begin with exploiting the full extent of our resources, it is essential to first collect them. The following are a list of items essential for the project and all of these can easily be purchased at any online hobby store like Amazon, eBay or Flipkart.

Note : I however prefer to order my components from www.electroncomponents.com . I am not sure if they ship outside the Indian sub-continent, but one advantage I find in using this site is that my entire order is shipped as a whole rather than in parts as in case of Amazon or eBay. But in the end, it is really your choise.

Electronic Components:

  • Arduino UNO - preferably one with the aTMega328P processor. ---- 1x
  • HC-SR04 Ultrasonic Sensor ---- 2x
  • 6-wire Stepper Motor ---- 1x (A 5 wire one will also do, but it will have a different configuration methodology which I will not be providing here. I will give a link for the 6-wire model configuration)
  • Instead of a Stepper, you can use a Servo motor. I will be using a Servo motor since it is easier toconfigure and use.
  • ULN2004A - Darlington Array ---- 1x (IC to amplify and control the motor. It also prevents any potential backflow from the motor and helps keep your Arduino safe)
  • 10k POT ---- 1x
  • Jumper Wire (Male-Male and Male-Female) PS: If you want to extend connections, Female-Female wires may be needed.
  • 9V cells and battery caps.

Softwares:

With that, we are ready to begin our project. Just one more thing needed. We need to design a mechanism to vary the height of observation of our sensor assembly. This can be done either manually as I prefer, or we can automate the process. For that, the following materials will be needed.

  • Ice-Cream Sticks, to make an assembly for the Sensor and to mount the Sensor on the Stepper Motor
  • Cardboard Frames to make the project structure
  • Some gears (if necessary to control the apparatus height)
  • Glue Gun

Step 2: Develop Logic Scheme and Design Paradigm

Now that we have all components ready, we have to start putting it all together. However, before we get to that, we have to ensure a logical sequence in which the project should progress. This is essential as we are working on integrating various sensors and motors into a single code, hence, for error-free execution, putting the entire project in a mock algorithm will simplify our task.

  1. Initialize all electronic components and set current state to zero.
  2. Set angle variable 'theta' to zero.
  3. for theta = 0 to theta = 180
    1. read ultrasonic sensor data
    2. send the serial data to processing
    3. store the theta and distance data in a python list( We use the cylindrical co-ordinate system)
    4. theta = theta + 1
  4. Ask user to enter z-level value.
  5. Add z-value to each co-ordinate list. Each list now has [distance, theta, z]
  6. Pause sensor system.
  7. Reset the servo motor back to initial state ie: 0 rotation
  8. Ask user to modify height.

Repeat the process 1-8 for 10 readings. We now have 10 lists, each list having 360 lists representing points in the plane. We now call upon the matplotlib module in python to compute the collected data and form the 3D representation of the data. Thus, we have a clear picture of how our project should proceed from here.

Note: The HC-SR04 Ultrasonic Sensor module has a range of up to 3mts with accuracy diminishing with distance to obstacle. Thus, we can expect some distortions in our data and the resulting 3D structure.

Step 3: Electronic Assembly

Servo Motor:

A servo motor has a motor driver built into it. The only thing that you will have to keep in mind is the color coding of the wires of the servo motor. There are 3 wires, red, orange and brown. The red is the 5V VCC socket, the brown is the GND socket. The orange socket wire is the data socket which is used for serial data transfer from the Arduino and motor. Since, the sensor and the motor both use the VCC and GND lines of the Arduino, it is best that you use a mini-breadboard to make the connections.

Ardruino UNO and HC-SR04:

Connect the trig pin of the Ultrasonic sensor to the the 7th-Digital IO pin on Arduino. Also, connect the echo pin to the 6th Pin in Arduino. The 5V pin on the sensor can be directly connected to the Arduino, or you can connect the 5V to a breadboard and make multiple connections. All these connections can be made using jumper wires.

That's it. We have connected our system and are ready to test it. Now we move on the penultimate step where we develop our code to complete the system.

Step 4: Control Codes

Ardunio Code:

#include<Servo.h>

#include<Ultrasonic.h>

Servo serv;

int trig = 13;

int echo = 11;

Ultrasonic utr(trig, echo);

float pingTime;

float targetDistance;

float speedOfSound = 776.5;

int th;

float dist;

void setup() {

// put your setup code here, to run once:

Serial.begin(9600);

//pinMode(trig, OUTPUT);

//pinMode(echo, INPUT);

serv.attach(9);

th=0;

serv.write(th);

establishContact();

}

void loop() {

// put your main code here, to run repeatedly:

if(Serial.available()>0){

th = Serial.read();

serv.write(th);

dist = utr.distanceRead();

//dist = readDist();

Serial.println(dist);

delay(100);

}

}

float readDist(){

digitalWrite(trig, LOW);

delayMicroseconds(2000);

digitalWrite(trig, HIGH);

delayMicroseconds(15);

digitalWrite(trig, LOW);

delayMicroseconds(10);

pingTime = pulseIn(echo, HIGH);

pingTime = pingTime/1000000;

pingTime = pingTime/3600;

targetDistance = speedOfSound*pingTime;

targetDistance = targetDistance/2;

targetDistance = targetDistance*63360;

return targetDistance;

}

void establishContact(){

while(Serial.available()<=0){

Serial.println("A");

delay(300);

}

}

Step 5: Setting Up Processing

Before you can use processing for the project there are some libraries that need to be installed in the IDE first.

You can install the libraries by going to the tools-> libraries-> add lib...

A new pop-up window will appear. You will have to install this. If you have used Arduino IDE, then you will find that the Processing IDE is almost similar in its use. In the search bar of the popup, type the following keywords and you will know which libraries to download

The libraries to install are:

  • arduino
  • stats giUtils
  • serial

That should be all. With these libraries installed, we can go ahead to write the Processing code. It is pretty simple and self explanatory...

import processing.serial.*;

import org.gicentre.utils.stat.*;

XYChart lineChart;

import cc.arduino.*;

import org.firmata.*;

Serial myPort;

String val;

int th = 0;

float x[] = new float[181];

float y[] = new float[181];

boolean firstContact = false;

void setup(){

size(800, 400);

//initialize port myPort = new Serial(this, Serial.list()[0], 9600);

myPort.bufferUntil('\n');

//Line Chart Initialization

lineChart = new XYChart(this);

lineChart.showXAxis(true);

lineChart.showYAxis(true);

lineChart.setMaxY(250);

lineChart.setMinY(0);

lineChart.setMinX(-400);

lineChart.setMaxX(400);

x[0] = 0;

y[0] = 0;

lineChart.setData(x , y);

lineChart.setPointColour(color(180,50,50,100));

lineChart.setPointSize(5);

lineChart.setLineWidth(2);

}

void draw(){

//serialEvent(myPort);

background(255);

textSize(9);

lineChart.draw(0,0, width-30, height-30);

}

void serialEvent(Serial myPort){

val = myPort.readStringUntil('\n');

if(val!=null&th<=180){

if(firstContact == false){

if(val.equals("A")){

myPort.clear();

myPort.write(th);

firstContact = true;

th++;

}

firstContact = true;

}else{

myPort.write(th);

float d = float(val);

float dx = d*cos((3.1415/180)*th);

x[th] = dx;

float dy = d*sin((3.1415/180)*th);

y[th] = dy;

println(dy);

//lineChart.setData(x, y);

if(th==180){

//println(

lineChart.setData(x, y);

//redraw();

}

th++;

}

}

}

Step 6: CAUTION

While the codes are now ready, there is one thing you will have to keep in mind. Read the Ardunio code and make the connections on the arduino as it is written. If for example the trig pin goes into the 13th socket and you connect the sensor wrong, you will not get the correct output.

Also, when you connect the Arduino to a power source, make sure it is placed on an insulating surface. If you are not careful, the Ardunio may short out due to current flow flow from the connections on its bottom.

Step 7: Upload and Test

Place the Sensor on top of servo motor and upload the code into the arduino. It is important for you to remember that the servo will start working immediately but your actual program will begin from the Processing IDE.

Hit run in the processing library with the Ardunio connected and you will see that a plot will spring up showing the measured distance of the sensor. The sensor data will plot in the polar co-ordinate system, from 0 to pi angle. The limit of the plot is set at 2.5m so, if the sensor reads more than that distance, then the reading will be clipped and a red dot will appear on the brink of the plot window.

Simple... And with that you have achieved the primary target... You are getting a 2D plot of the sensor data. By taking various data at a chosen height, you can now plot a 3D graph as well by making some minor changes to the Processing code.

I will try to upload the z-axis code also, but since that is not my objective, I will most likely wrap-up this instructable here..

Hope you guys have fun making it...

First Time Author Contest

Participated in the
First Time Author Contest