For the PIE Mini Project 2, we designed a 3D scanner using an Arduino, two servo motors, and a Sharp GP2Y0A02YK0F infrared distance sensor. Our mechanical design consists of a pan-and-tilt mechanism that allows the sensor to capture distance measurements from multiple angles, which are then processed using Python to generate 3D point cloud visualizations of scanned objects.
The mechanical design includes:
The Arduino controls the servo motors and reads distance measurements from the IR sensor, sending data over serial communication to Python for processing.
// Arduino scanning control
#include <Servo.h>
Servo panServo, tiltServo;
void loop() {
for (int pan = 0; pan <= 180; pan += 5) {
panServo.write(pan);
for (int tilt = 0; tilt <= 90; tilt += 5) {
tiltServo.write(tilt);
delay(100);
int distance = analogRead(A0);
Serial.print(pan); Serial.print(",");
Serial.print(tilt); Serial.print(",");
Serial.println(distance);
}
}
}
Python receives the scan data, converts sensor readings to distances, and transforms spherical coordinates to Cartesian coordinates for 3D visualization.
# Python data processing and visualization
import numpy as np
import matplotlib.pyplot as plt
def spherical_to_cartesian(r, theta, phi):
x = r * np.sin(np.radians(phi)) * np.cos(np.radians(theta))
y = r * np.sin(np.radians(phi)) * np.sin(np.radians(theta))
z = r * np.cos(np.radians(phi))
return x, y, z
# Process scan data
points = []
for pan, tilt, sensor in scan_data:
distance = 29.988 * pow((sensor * 5.0/1023.0), -1.173)
x, y, z = spherical_to_cartesian(distance, pan, tilt)
points.append([x, y, z])
# 3D visualization
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(points[:,0], points[:,1], points[:,2])
plt.show()
The Sharp GP2Y0A02YK0F infrared distance sensor provides an analog voltage output that correlates to the distance of an object. The relationship between voltage and distance is non-linear and follows an inverse power law.
Sensor Calibration Equation:
distance (cm) = 29.988 × V-1.173
Where V is the sensor voltage (0-5V). The Arduino's 10-bit ADC converts this to a digital value (0-1023), requiring:
V = (ADC_value × 5.0) / 1023
This calibration was determined empirically by measuring known distances and fitting a power-law curve to the voltage readings. The sensor's effective range is 20-150 cm, with optimal accuracy between 30-100 cm.
The scanner operates in a spherical coordinate system (r, θ, φ) but 3D visualization requires Cartesian coordinates (x, y, z). The transformation involves:
Spherical to Cartesian Transformation:
These equations derive from the geometric relationship between spherical and Cartesian systems. The polar angle φ measures from the z-axis (vertical), while the azimuthal angle θ measures rotation around the z-axis from the x-axis.
IR distance sensors are susceptible to noise from ambient light, surface reflectivity variations, and electrical interference. Several filtering techniques were implemented:
The scanning resolution is determined by the angular step size of the servo motors. A 5° increment was chosen to balance scan density with acquisition time:
Finer angular resolution (e.g., 2°) increases point cloud density but extends scan time proportionally. The 5° step provides adequate detail for objects 20-50 cm in size while maintaining reasonable scan duration.
Key achievements: