Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
![]() |
| × | 2 | |||
![]() |
| × | 1 | |||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
| |||||
![]() |
|
A 3D scanner for an end of year project using Processing for designing the model.
1 / 2 • POWER SUPPLY 12V AC/DC 2A
3D scanner that consists of making a 3D model for any small object under 27 cm height
char val; // Data received from the serial port
int ledPin = 13; // Set the pin to digital I/O 13
boolean startCalculatingPointsCoordinations ;
const int stepPiny = 13 ;
const int dirPiny = 12 ;
const int stepPinx = 6 ;
const int dirPinx = 7 ;
int motorStepsX = 36 ; // it will take 36 points in each full rotation
int motorStepsY = 36 ; // the more you make points the better picture // resolution you get
float maxDistance = 150 ;
#define sensor A0
void setup() {
pinMode(stepPiny,OUTPUT) ;
pinMode(dirPiny, OUTPUT) ;
pinMode(stepPinx,OUTPUT) ;
pinMode(dirPinx, OUTPUT) ;
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
startCalculatingPointsCoordinations = false ;
}
void loop() {
if (Serial.available()){ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if (val == '1')
{ // If 1 was received
digitalWrite(ledPin, HIGH); // turn the LED on
startCalculatingPointsCoordinations = true ;
} else {
digitalWrite(ledPin, LOW); // otherwise turn it off
}
if(startCalculatingPointsCoordinations){
//--------------------moving motors--------------------------------------
for(int y = 0 ; y < motorStepsY ; y++){
// horizental axe
for(int x = 0 ; x < motorStepsX ; x++){
calculateDistance() ;
moveMotorX() ;
}
moveMotorY() ;
float actualDistance = calculateDistance() ;
if ((actualDistance > maxDistance)&&(y > 40)){
stopMotors() ;
}
}
//----------------------------------------------------------------
}
delay(10); // Wait 10 milliseconds for next reading
}
void moveMotorX(){
digitalWrite(dirPiny,HIGH) ;
digitalWrite(stepPinx,HIGH);
delay(200);
digitalWrite(stepPinx,LOW);
delay(200);
}
void moveMotorY(){
for (int i = 0 ; i <120; i++){
digitalWrite(dirPiny,HIGH) ;
digitalWrite(stepPiny,HIGH) ;
delay(50) ;
digitalWrite(stepPiny,LOW) ;
delay(50) ;
}
}
void stopMotors(){
digitalWrite(stepPinx,LOW);
digitalWrite(stepPinx,LOW);
}
float calculateDistance(){
float volts = analogRead(sensor)*0.0048828125;
int distance1 = 13*pow(volts, -1);
distance1 = map(distance1,4,45,0,200) ;
int distance2 = constrain(distance1,0,200) ;
delay(200); // 200
Serial.println(distance2);
Serial.flush() ;
return distance2 ;
}
pfa2.pde
Processingfirst , all distance measures will be saved in an array list then processing will use it to draw many points that will form our objects 3d model
/*
i have plenty of ideas to make this code better and easier to use but unfortunately i can't find enough time for that because of study but it's functional so i will be glad to see what is the changes you made
*/
import processing.serial.*;
boolean startScanButtonPressed ;
Serial myPort;
PShape button ;
float y ;
float f ;
float maxVirtualHigh = -40 ;
float stepHigh = 5 ;
float distance ;
int secPass ;
ArrayList <PVector> twod = new ArrayList<PVector>() ;
ArrayList <PVector> threed = new ArrayList<PVector>() ;
int pointIndex ;
float angle ;
float oneStepDegree = 10 ;
boolean startDrawing ;
boolean viewModeOn ;
boolean changeBg ;
void setup()
{
size(800,700,P3D);
myPort = new Serial(this, "COM4", 9600);
angle = 0 ;
startDrawing = false ;
myPort.bufferUntil('\n');
startScanButtonPressed = false ;
viewModeOn = false ;
changeBg = false ;
button() ;
}
void draw() {
if (startScanButtonPressed == true) { //if we clicked in the window
myPort.write('1'); //send a 1
println("receiving data from arduino ...");
delay(200) ;
changeBg = true ;
startScanButtonPressed = false ;
}
else {
if (changeBg){
background(0) ;
}
println("press button to start ...") ;
if ((y<=-20)&&(startDrawing == true))
viewModeOn = true ;
pushMatrix() ;
translate(250,400,f) ;
if (startDrawing == true){
myPort.stop(); // seeME PLEASE
mouseDragged() ;
drawMe() ;
}
popMatrix() ;
programControl(secPass) ;
save("Object.OBG") ;
}
}
//----------------------------------------------------------------------
void mousePressed(){
if ((150 <= mouseX)&&(mouseX <= 350)&&(220 <= mouseY)
&&(mouseY <= 260)){
startScanButtonPressed = true ;
}
else startScanButtonPressed = false ;
}
void button(){
button = createShape() ;
button.beginShape() ;
fill(0,0,250) ;
rect(150,220,200,40) ;
fill(255) ;
textSize(18) ;
text("Start Scanning",190,245) ;
button.endShape() ;
}
float serialEvent(Serial myPort){
distance = float(myPort.readStringUntil('\n')) ;
secPass++ ;
threed.add(new PVector()) ;
twod.add(new PVector()) ;
twod.get(pointIndex).y = distance ;
twod.get(pointIndex).rotate(angle) ;
threed.get(pointIndex).z = twod.get(pointIndex).y ;
threed.get(pointIndex).x = twod.get(pointIndex).x ;
threed.get(pointIndex).y = y ;
angle = oneStepDegree+angle ;
if (angle >= 360)
{
y-=stepHigh ;
angle = 0 ;
if (y <= maxVirtualHigh){
startDrawing = true ;
}
}
pointIndex++ ;
return distance ;
}
void drawMe(){
stroke(255) ;
beginShape(POINTS) ; // QUADS LINES
for(int j = 0 ; j<threed.size() ; j++){
vertex(threed.get(j).x,threed.get(j).y,threed.get(j).z) ;
}
endShape(CLOSE) ; // CLOSE
}
// WATCH DATA
void programControl(int onePercent){
String msg ;
println(" angle = ",angle) ;
println(" startDrawing =",startDrawing) ;
text("pixel number = " + pointIndex,20,20) ;
println("viewModeOn =",viewModeOn) ;
println("distance =",distance) ;
msg = "uploading ... "+percentage(onePercent)+" %" ;
if (percentage(onePercent)>100){
onePercent = 0 ;
msg = "" ;
}
text(msg,20,45) ;
save("model.tif") ;
}
// CAMERA ROTATION
void mouseDragged(){
if (viewModeOn == true){
rotateX(mouseX*0.1) ;
rotateY(mouseY*0.1) ;
}
}
void mouseWheel(MouseEvent event){
float e = event.getCount() ;
f += e*(6) ;
}
int percentage(int secPass){
float huPer = ((360/oneStepDegree)*(-maxVirtualHigh/stepHigh)) ; //100%
int percentage = int((100/huPer)*secPass) ;
return percentage ;
}
Comments
Please log in or sign up to comment.