Previously...
Cheap 3D scanner based on Arduino and Processing
I used the base project seen on http://www.instructables.com/id/Lets-cook-3D-scanner-based-on-Arduino-and-Proces/?&sort=ACTIVE&limit=40&offset=40#DISCUSS
If you want to use these programs, you will need the Arduino IDE (for compiling and uploading), and an Arduino Uno compatible devel board for the hardware. For the Processing program, you will need the Arduino up and running to execute the 3d-scanner. I set up the line_processor as a stand-alone. Just dump the sample images with the program and run it in Processing. It doesnt display content, but it does generate line drawings for each image, and generates a pointcloud file that MeshLab can read.
==============================================================
The scanner bed software is the Arduino solution for the 3D scanner I am making
The commands: | |
M-commands set variables or allow you read the set variables. | |
M1 : Creates stepper device. The value is the gearing of the stepper you use. I assume you are using pins 7,8,9,10. M1? outputs the value you previously set. | |
M2 : Sets the speed of the stepper, via the .setSpeed() call on the stepper device. M2? gives the previously set value. | |
M3 : This number is the amount of steps to rotate the final scanning platform. For example, I'm using a gear belt to move the platform. The amount of steps my motor has to rotate to give 1 full revolution of the big platform is 15360. Yours will be different. M3? gives the previously set value. | |
M4 : This number is a positive integer that represents how many subdivisions to break the circle into. For example, if you run "M4 180." , you will get 2 degree subdivisions ( as 360/180 = 2). I chose to do this to avoid floats on the input. | |
The ? does something different. In this case, if you give a "M4?" , you will get 3 different numbers. The first is the number you initially gave M4. The second number is how many degrees is a 'slice' as a float to 6 decimals. The third number is how many steps will be passed directly to the .step() . | |
G-commands do motion. G-commands don't have a ? operation. | |
G0 : The value you pass makes the motor go that many steps in a positive direction. | |
G1 : The value you pass makes the motor go that many steps in a negative direction. | |
G2 : This makes the motor go the amount of steps that would equal a subdivision from the value you set in M4. For example, if you set M3 as 1000 and M4 as 4, you would get 250 steps for a "G2 1." command. The formula is (G2 value)*(M3 value)/(M4 value) . | |
G3 : This does what G2 does, but in the opposite direction. | |
L-commands work with the laser(s). | |
L0 : You can either turn on or off the laser. 0 turns it off, and 1 turns it on. A ? reports the current on status. The defualt Arduino pin for this is 11. | |
L1 : You can either turn on or off the laser. 0 turns it off, and 1 turns it on. A ? reports the current on status. The defualt Arduino pin for this is 12. | |
Miscellaneous commands. | |
POS : This command simply gives you the steps away from the initial starting position. | |
RESET : Sends the platter back to wherever the initial starting position is. | |
ZERO : This is for the case where you want to start wherever you're currently at and treat it as the new starting position. This also means that RESET will send the platter back to this new position. | |
************************************************************** | |
Example code. Open up the Arduino serial port at 9600 baud. The commands I type, and the responses in parenthesis are beneath it. | |
M1 48. [creates a stepper motor of 48 steps/rotation on pins 7,8,9,10] | |
(OK) | |
M2 192. [sets speed of stepper to 192] | |
(OK) | |
M3 15360. [sets platter full rotation to 15360 steps] | |
(OK) | |
M4 360. [sets dividing the circle in to 360 pieces, or 1 deg per slice] | |
(OK) | |
M4? [query the settings on M4] | |
(360 1.00000 42) | |
POS. [queries position] | |
(0) | |
L0 1. [turns on first laser] | |
(OK) | |
G0 1000. [1000 steps in positive direction] | |
(OK) | |
G1 400. [400 steps in negative direction] | |
(OK) | |
POS. | |
(600) | |
G2 3. [We passed 3, so it's 42 steps * 3, or 126 steps. It is also 3 degrees] | |
(OK) | |
POS. | |
(726) | |
ZERO. [Does nothing to motors. Just treats this position as 0.] | |
(OK) | |
POS. | |
(0) | |
M2 3000. [3000 steps in a negative direction] | |
(OK) | |
POS. | |
(-3000) | |
RESET. [Platter moves back to where 0 is] | |
(OK) | |
POS. | |
(OK) |
#include <Stepper.h> | |
char incomingByte; // a variable to read incoming serial data into | |
String incomingCommand; // Varible to store the command | |
int stepperGearing; | |
int stepperSpeed; | |
long int totalSteps; // This varible is the complete steps around the rotational platter. | |
int circleSubdivide; // Takes in a number, which is then 360/X ; equals the angle to increment | |
long int location = 0; // Stores absolute location of motor. | |
int laserPin0 = 11 ; // Hook the laser up to pin 13 | |
bool laserOn0 = 0 ; // varible to query state of laser | |
int laserPin1 = 12 ; // Hook the laser up to pin 13 | |
bool laserOn1 = 0 ; // varible to query state of laser | |
int ledPin = 13; | |
// 15360 steps per full external plate revolution using my motor, indicates 320:1 gearing. | |
// Your gearing will be different. | |
void setup() { | |
Serial.begin(9600); | |
pinMode(laserPin0, OUTPUT); | |
pinMode(laserPin1, OUTPUT); | |
pinMode(ledPin, OUTPUT); | |
digitalWrite(laserPin0, LOW); | |
digitalWrite(laserPin1, LOW); | |
digitalWrite(ledPin, LOW); | |
} | |
void loop() { | |
if (Serial.available() > 0) { | |
incomingByte = Serial.read(); | |
incomingCommand.concat(String(incomingByte)); | |
} | |
if ( incomingCommand.endsWith(".") || incomingCommand.endsWith("?") ){ | |
executeCode(incomingCommand); | |
incomingCommand.remove(0); | |
} | |
if ( incomingCommand.length() > 11 ){ | |
Serial.println("Length of command exceeded."); | |
incomingCommand.remove(0); | |
} | |
} | |
void executeCode(String code) { | |
long int value ; | |
int spaceIndex = code.indexOf(' '); // Figure out where the space is in the command, else -1 | |
String command; | |
if (spaceIndex == -1){ | |
value = -1; | |
if(code.endsWith(".")){ | |
command = code.substring(0,code.indexOf('.')); | |
} | |
else{ | |
command = code.substring(0,code.indexOf("?")); | |
} | |
} | |
else { | |
value = code.substring((spaceIndex+1), code.length()).toInt(); | |
command = code.substring(0,spaceIndex); | |
} | |
if(command == "M1"){ // Creates Stepper | |
if(code.endsWith(".")) { | |
stepperGearing = value; | |
Stepper motor(stepperGearing,7,8,9,10); | |
Serial.println("OK");} | |
if(code.endsWith("?")) { | |
Serial.println(stepperGearing);} | |
} | |
if(command == "M2"){ // Sets speed of stepper | |
if(code.endsWith(".")) { | |
stepperSpeed = value; | |
Serial.println("OK");} | |
if(code.endsWith("?")) { | |
Serial.println(stepperSpeed);} | |
} | |
if(command == "M3"){ // Sets how many total steps to rotate platter one revolution | |
if(code.endsWith(".")) { | |
totalSteps = value; | |
Serial.println("OK");} | |
if(code.endsWith("?")) { | |
Serial.println(totalSteps);} | |
} | |
if(command == "M4"){ // Sets how many parts to divide the circle. If you want 100 parts, set this as 100 | |
if(code.endsWith(".")) { | |
circleSubdivide = value; | |
Serial.println("OK");} | |
if(code.endsWith("?")) { | |
Serial.print(circleSubdivide); | |
Serial.print(" "); | |
Serial.print(360.0/circleSubdivide, 6); | |
Serial.print(" "); | |
Serial.println((int)(totalSteps / circleSubdivide));} | |
} | |
if(command == "G0"){ // Absolute forward, increments stepper by value | |
Stepper motor(stepperGearing,7,8,9,10); | |
motor.setSpeed(stepperSpeed); | |
digitalWrite(ledPin, HIGH); | |
motor.step(value); | |
digitalWrite(ledPin, LOW); | |
location = location + value; | |
Serial.println("OK"); | |
} | |
if(command == "G1"){ // Absolute backward, decrements stepper by value | |
Stepper motor(stepperGearing,7,8,9,10); | |
motor.setSpeed(stepperSpeed); | |
digitalWrite(ledPin, HIGH); | |
motor.step(-1*value); | |
digitalWrite(ledPin, LOW); | |
location = location - value; | |
Serial.println("OK"); | |
} | |
if(command == "G2"){ // Increments steps to do part of circle | |
int stepCalculate = value * (totalSteps/circleSubdivide); | |
Stepper motor(stepperGearing,7,8,9,10); | |
motor.setSpeed(stepperSpeed); | |
digitalWrite(ledPin, HIGH); | |
motor.step(stepCalculate); | |
digitalWrite(ledPin, LOW); | |
location = location + stepCalculate; | |
Serial.println("OK"); | |
} | |
if(command == "G3"){ // Decrements steps to do part of circle | |
int stepCalculate = value * (totalSteps/circleSubdivide); | |
Stepper motor(stepperGearing,7,8,9,10); | |
motor.setSpeed(stepperSpeed); | |
digitalWrite(ledPin, HIGH); | |
motor.step(-1*stepCalculate); | |
digitalWrite(ledPin, LOW); | |
location = location - stepCalculate; | |
Serial.println("OK"); | |
} | |
if(command == "L0"){ //laser toggle | |
if(code.endsWith(".")) { | |
if(value == 0){ | |
digitalWrite(laserPin0, LOW); | |
laserOn0 = 0; | |
Serial.println("OK"); | |
} else{ | |
digitalWrite(laserPin0, HIGH); | |
laserOn0 = 1; | |
Serial.println("OK"); | |
} | |
} | |
if(code.endsWith("?")) { | |
if(laserOn0 == 1){Serial.println("ON");} | |
else{Serial.println("OFF");} | |
} | |
} | |
if(command == "L1"){ //laser toggle | |
if(code.endsWith(".")) { | |
if(value == 0){ | |
digitalWrite(laserPin1, LOW); | |
laserOn1 = 0; | |
Serial.println("OK"); | |
} else{ | |
digitalWrite(laserPin1, HIGH); | |
laserOn1 = 1; | |
Serial.println("OK"); | |
} | |
} | |
if(code.endsWith("?")) { | |
if(laserOn1 == 1){Serial.println("ON");} | |
else{Serial.println("OFF");} | |
} | |
} | |
if(command == "RESET"){ | |
Stepper motor(stepperGearing,7,8,9,10); // Resets position to 0 | |
motor.setSpeed(stepperSpeed); | |
while(location >= totalSteps){ | |
location = location - totalSteps;} | |
while(location < totalSteps){ | |
location = location + totalSteps;} | |
if(location < totalSteps*.5){ | |
digitalWrite(ledPin, HIGH); | |
motor.step(-1*location); | |
digitalWrite(ledPin, LOW);} | |
else{ | |
digitalWrite(ledPin, HIGH); | |
motor.step(totalSteps-location); | |
digitalWrite(ledPin, LOW);} | |
location = 0; | |
Serial.println("OK"); | |
} | |
if(command == "POS"){ // prints position | |
Serial.println(location); | |
} | |
if(command == "ZERO"){ | |
location = 0 ; | |
Serial.println("OK"); | |
} | |
return ; | |
} |
Ref : https://github.com/jwcrawley/3D-scanner