Introduction: DIY 3D Scanner | 3D Scan Any Object at Home | 3D Plot With Python MatplotLib | Arduino With Python | Arduino Ultrasonic Sensor, Servo Motor& DC Motor
This project is about making a 3d scanner at home. Which can scan any object & provide its X, Y & Z coordinates. These coordinates can then be imported for 3D printing. To replicate any old/broken object.
Supplies
- Arduino UN
- Ultrasonic Sensor - HC-SR04
- SG90 Micro-servo motor
- Geared DC Motor, 12 V
- Texas Instruments Dual H-Bridge motor drivers L293D
- 9V 1A Switching Wall Power Supply
Step 1: Why Did You Decide to Make It?
I made this to ease my work. I had an object that I wanted to replicate by 3D printing. I want it to be a little bigger. That object was very complex to take its dimensions physically. This scanner helped me in scanning that complex object.
Step 2: How Does It Work?
This scanner is powered by an Atmega328p microcontroller onboard Arduino Uno. There is an ultrasonic sensor that provides the distance between itself & the object in front of it. This sensor is attached to a servo motor in such a way that the sensor is rotated from 45° to 135°. This gives us a 1 line scan of the object. Then the object is rotated 18° anticlockwise with the help of a dc motor connected. This motor rotates 20 times. Thus providing a full 360° scan of the object.
Step 3: Physical Design of the 3d Scanner
The Ultrasonic sensor (HC-SR04) is attached to the horn of a servo motor (SG-90). The sensor takes the distance reading whereas the motor rotates the sensor simultaneously.
Step 4:
The object to be rotated is placed on the gear. This gear is driven by a worm attached to a DC motor. This arrangement reduces the speed & increases the torque. One more advantage is that the object to be rotated stays in position even if there is a loss of power.
After each top to bottom scan of the object, this motor rotates the object 18° anticlockwise.
Step 5:
The above image shows the whole setup of the 3D Scanner.
Step 6: Plotting the Scanned Coordinates With Python Matplotlib
The Arduino code provides the X, Y& Z coordinates. These coordinates are then plotted with the help of the matplotlib library in the python programming language.
The following libraries need to be imported.
import matplotlib.pyplot as plt from mpl_toolkits import mplot3d from mpl_toolkits.mplot3d import Axes3D
Below code 3D plots the coordinates
fig = plt.figure()
ax = plt.axes(projection ='3d')
ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5)
ax.set_title('3D Plot Of The Scan')
plt.show()
X, Y & Z are the lists containing respective coordinates.
Step 7: Input Object for 3D Scanner
The above object needs to be scanned by the 3D Scanner.
Step 8: The Output of the 3D Scanner
The above images show the plot of the scanned object.
Step 9: Issue and Improper Result
The scan is not perfect due to inaccurate & cheap components. The worm gear arrangement had some engagement issues. But, this is just a technology demonstration. It will require many modifications to be accurate.
That's how we made a 3d scanner at home with off-the-shelf components & plotted/visualized it with the help of matplotlib (python).
Step 10: Code for 3D Scanner in Arduino C/C++
#include <Servo.h>
#include <math.h>
Servo m;
int t = 7;
int e= 6;
int n;
void setup() {
pinMode(t, OUTPUT); //trigger pin
pinMode(e, INPUT); //echo pin
pinMode(8,OUTPUT); //pin to control DC motor, goes to mosfet
m.attach(10); //servo motor pin
Serial.begin(9600);
}
int distance(){
long duration, cm;
digitalWrite(t, LOW);
delayMicroseconds(2);
digitalWrite(t, HIGH);
delayMicroseconds(5);
digitalWrite(t, LOW);
duration = pulseIn(e, HIGH);
cm = duration/ 29 / 2;
return cm; //returns distance in centimeters
}
void revolve(){ // rotates motor 18 degree
digitalWrite(8,HIGH);
delay(120);
digitalWrite(8,LOW);
}
void scan(){
int i;
for(i=70;i<=120;i+=1){
m.write(i);
delay(25);
float d= distance();
if (d<30){
Serial.print(n);
Serial.print(",");
Serial.print(d*cos((i-90)*3.14/180));
Serial.print(",");
Serial.print(d*sin((i-90)*3.14/180));
Serial.println();
}
}
for(i=120;i>=70;i-=1){
m.write(i);
delay(20);
}
}
void loop() {
int i;
Serial.println("Start");
for(i=0;i<20;i+=1){ // scan 20 times, every revolution is 18° i.e. 20x18° = 360°
n=i;
scan(); //scan top to bottom
revolve(); // revolve the object
delay(50); //repeat
}
Serial.println("End");
delay(50);
}







