system
February 13, 2010, 6:45pm
1
Hi, this is my first post.
I made a small CNC using 2 arduino + 2 motor shield + 3 stepper motor. The drill is a dremel plus extension cord. The work flow is:
1)MecSoft FreeMill reads stl file and out put G-code text file
2)A C# program reads first line of G-code and send to Arduino board A
3)Arduino A reads G-code and tells motor shield A to move motor X and Y
4)Arduino A tells Arduino B to move motor Z through soft serial
5)Arduino A reports to C# program if it reaches destination
6)C# program reads the next line and whole steps repeat
I start with cutting soft materials then gradually switching to harder ones. I am still refining it but right now all the parts together are working well.
system
February 13, 2010, 6:52pm
3
Very nice! Any chance you could share the code?
system
February 13, 2010, 6:57pm
4
Will be glad to post the code after cleaning it up
system
February 13, 2010, 9:38pm
5
Never mind cleaning too much, this is brilliant!
Joachim
system
February 14, 2010, 2:11pm
6
Part 1
#include <WString.h>
#include <AFMotor.h>
#include <SoftwareSerial.h>
AF_Stepper motorx(48, 2);
AF_Stepper motory(48, 1);
#define rxPin 9
#define txPin 10
#define ledPin 13
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
String inString = String(50);
String units = String(2);
String xstr = String(10);
String ystr = String(10);
String zstr = String(10);
float xstring;
float ystring;
float zstring;
float posx;
float posy;
float posz = min(posz, 0);
float targetx;
float targety;
float targetz;
float linex;
float liney;
float linez;
float DX;
float DY;
float DZ;
float dx;
float dy;
float dz;
float stepx = 341.759; // # of steps per mm
float stepy = 362.834;
float stepz = 121;
boolean command;
boolean zmark;
int type;
byte pinState = 0;
float scale = 1;
int zdirection = 1;
void setup() {
Serial.begin(4800);
motorx.setSpeed(60);
motory.setSpeed(60);
delay (1000);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
mySerial.begin(4800);
command = false;
}
void AcquireXYZ(){
if(Serial.available() > 0) {
char inChar = Serial.read();
if (inChar == '!'){
char firstChar = inString.charAt(0);
if (firstChar == 'G'){
GCodeParse();
}
else{
}
inString = 0;
}
else{
inString.append(inChar);
}
}
}
void GCodeParse(){
if (inString.startsWith("G0")){
type = 0;
}
if (inString.startsWith("G1")){
type = 1;
if (inString.contains("X") && inString.contains("Y") && inString.contains("Z")){
int xcharloc = inString.indexOf('X'); //find where the X code starts
int ycharloc = inString.indexOf('Y'); //find where the Y code starts
int zcharloc = inString.indexOf('Z'); //find where the Z code starts
xcharloc = xcharloc + 1;
ycharloc = ycharloc - 1;
xstr = inString.substring(xcharloc, ycharloc);
ycharloc = ycharloc + 1;
ycharloc = ycharloc + 1;
zcharloc = zcharloc - 1;
ystr = inString.substring(ycharloc, zcharloc);
zcharloc = zcharloc + 1;
int zlast = inString.length();
zcharloc = zcharloc + 1;
zstr = inString.substring(zcharloc, zlast);
zcharloc = zcharloc - 1;
xstring = atof(xstr);
ystring = atof(ystr);
zstring = atof(zstr);
targetx = xstring * scale;
targety = ystring * scale;
targetz = -1 * zstring * zdirection * scale;
DX = targetx - posx;
DY = targety - posy;
DZ = targetz - posz;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
if (inString.contains("X") && inString.contains("Y") && !inString.contains("Z")){
int xcharloc = inString.indexOf('X'); //find where the X code starts
int ycharloc = inString.indexOf('Y'); //find where the Y code starts
xcharloc = xcharloc + 1;// Code for finding what X is in the code
ycharloc = ycharloc - 1;
xstr = inString.substring(xcharloc, ycharloc);
ycharloc = ycharloc + 1;
int ylast = inString.length();
ycharloc = ycharloc + 1;
ystr = inString.substring(ycharloc, ylast);
ycharloc = ycharloc - 1;
xstring = atof(xstr);
ystring = atof(ystr);
targetx = xstring * scale;
targety = ystring * scale;
targetz = posz;//posz + DZ;
DX = targetx - posx;
DY = targety - posy;
DZ = 0;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
if (inString.contains("X") && !inString.contains("Y") && inString.contains("Z")){
int xcharloc = inString.indexOf('X');
int zcharloc = inString.indexOf('Z');
xcharloc = xcharloc + 1;
zcharloc = zcharloc - 1;
xstr = inString.substring(xcharloc, zcharloc);
zcharloc = zcharloc + 1;
int zlast = inString.length();
zcharloc = zcharloc + 1;
zstr = inString.substring(zcharloc, zlast);
zcharloc = zcharloc - 1;
xstring = atof(xstr);
zstring = atof(zstr);
targetx = xstring * scale;
targety = posy;
targetz = -1 * zstring * zdirection * scale;
DX = targetx - posx;
DY = 0;
DZ = targetz - posz;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
if (!inString.contains("X") && inString.contains("Y") && inString.contains("Z")){
int ycharloc = inString.indexOf('Y');
int zcharloc = inString.indexOf('Z');
ycharloc = ycharloc + 1;
zcharloc = zcharloc - 1;
ystr = inString.substring(ycharloc, zcharloc);
zcharloc = zcharloc + 1;
int zlast = inString.length();
zcharloc = zcharloc + 1;
zstr = inString.substring(zcharloc, zlast);
zcharloc = zcharloc - 1;
ystring = atof(ystr);
zstring = atof(zstr);
targetx = posx;
targety = ystring * scale;
targetz = -1 * zstring * zdirection * scale;
DX = 0;
DY = targety - posy;
DZ = targetz - posz;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
if (!inString.contains("X") && !inString.contains("Y") && inString.contains("Z")){
int zcharloc = inString.indexOf('Z');
int zlast = inString.length();
zcharloc = zcharloc + 1;
zstr = inString.substring(zcharloc, zlast);
zcharloc = zcharloc - 1;
zstring = atof(zstr);
targetx = posx;
targety = posy;
targetz = -1 * zstring * zdirection * scale;
DX = 0;
DY = 0;
DZ = targetz - posz;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
if (!inString.contains("X") && inString.contains("Y") && !inString.contains("Z")){
int ycharloc = inString.indexOf('Y');
ycharloc = ycharloc + 1;
int ylast = inString.length();
ystr = inString.substring(ycharloc, ylast);
ycharloc = ycharloc - 1;
ystring = atof(ystr);
targetx = posx;
targety = ystring * scale;
targetz = posz;
DX = 0;
DY = targety - posy;
DZ = 0;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
if (inString.contains("X") && !inString.contains("Y") && !inString.contains("Z")){
int xcharloc = inString.indexOf('X');
int xlast = inString.length();
xcharloc = xcharloc + 1;
xstr = inString.substring(xcharloc, xlast);
xcharloc = xcharloc - 1;
xstring = atof(xstr);
targetx = xstring * scale;
targety = posy;
targetz = posz;
DX = targetx - posx;
DY = 0;
DZ = 0;
linex = posx;
liney = posy;
delay (1000);
command = true;
};
}
}
void plotting(){
if (type == 1){
if (DX == 0 && DY != 0){
DrawY();
posz = targetz;
Reportz();
}
else if (DX != 0 && DY == 0){
DrawX();
posz = targetz;
Reportz();
}
else if (DX != 0 && DY != 0 && abs(DY) >= abs(DX)){
DrawYX();
posz = targetz;
Reportz();
}
else if (DX != 0 && DY != 0 && abs(DX) > abs(DY)){
DrawXY();
posz = targetz;
Reportz();
}
else if (DX == 0 && DY == 0){
posz = targetz;
Reportz();
report();
delay (abs(1000*scale));
}
}
report();
}
void DrawY(){
dy = 1 ;
if (DY > 0) {
if (posy < targety ) {
motory.step(dy, BACKWARD, SINGLE);
posx = posx;
posy = posy + dy / stepy;
report();
}
}
else {
if (posy > targety ){
motory.step(dy, FORWARD, SINGLE);
posx = posx;
posy = posy - dy / stepy;
report();
}
}
}
void DrawX(){
dx = 1;
if (DX > 0) {
if (posx < targetx) {
motorx.step(dx, BACKWARD, SINGLE);
posx = posx + dx / stepx;
posy = posy;
report();
}
}
else {
if (posx > targetx){
motorx.step(dx, FORWARD, SINGLE);
posx = posx - dx / stepx;
posy = posy;
report();
}
}
}
system
February 14, 2010, 2:13pm
7
Part 2
void DrawXY(){
//unit on y
float slope = abs(DX / DY);
dy = 1;
if (DY > 0){
if (DX > 0){
if (posy < targety){
motory.step(dy, BACKWARD, SINGLE);
posy = posy + dy / stepy;
linex = linex + dy * slope / stepy;
int dx = (int) ((linex - posx) * stepx);
motorx.step(dx, BACKWARD, SINGLE);
posx = posx + dx / stepx;
report();
}
}
else {
if (posy < targety){
motory.step(dy, BACKWARD, SINGLE);
posy = posy + dy / stepy;
linex = linex - dy * slope / stepy;
int dx = (int) (abs(linex - posx) * stepx);
motorx.step(dx, FORWARD, SINGLE);
posx = posx - dx / stepx;
report();
}
}
}
else{
if (DX > 0){
if (posy > targety){
motory.step(dy, FORWARD, SINGLE);
posy = posy - dy / stepy;
linex = linex + dy * slope / stepy;
int dx = (int) ((linex - posx) * stepx);
motorx.step(dx, BACKWARD, SINGLE);
posx = posx + dx / stepx;
report();
}
}
else {
if (posy > targety){
motory.step(dy, FORWARD, SINGLE);
posy = posy - dy / stepy;
linex = linex - dy * slope / stepy;
int dx = (int) (abs(linex - posx) * stepx);
motorx.step(dx, FORWARD, SINGLE);
posx = posx - dx / stepx;
report();
}
}
}
}
void DrawYX(){
//unit on x
float slope = abs(DY / DX);
dx = 1;
if (DX > 0){
if (DY > 0){
if (posx < targetx){
motorx.step(dx, BACKWARD, SINGLE);
posx = posx + dx / stepx;
liney = liney + dx * slope / stepx;
int dy = (int) ((liney - posy) * stepy);
motory.step(dy, BACKWARD, SINGLE);
posy = posy + dy / stepy;
report();
}
}
else {
if (posx < targetx){
motorx.step(dx, BACKWARD, SINGLE);
posx = posx + dx / stepx;
liney = liney - dx * slope / stepx;
int dy = (int) (abs(liney - posy) * stepy);
motory.step(dy, FORWARD, SINGLE);
posy = posy - dy / stepy;
report();
}
}
}
else{
if (DY > 0){
if (posx > targetx){
motorx.step(dx, FORWARD, SINGLE);
posx = posx - dx / stepx;
liney = liney + dx * slope / stepx;
int dy = (int) ((liney - posy) * stepy);
motory.step(dy, BACKWARD, SINGLE);
posy = posy + dy / stepy;
report();
}
}
else{
if (posx > targetx){
motorx.step(dx, FORWARD, SINGLE);
posx = posx - dx / stepx;
liney = liney - dx * slope / stepx;
int dy = (int) (abs(liney - posy) * stepy);
motory.step(dy, FORWARD, SINGLE);
posy = posy - dy / stepy;
report();
}
}
}
}
void report(){
Serial.print ("X:");
Serial.println (posx);
Serial.print("\t");
Serial.print ("Y:");
Serial.println (posy);
Serial.print("\t");
Serial.print ("Z:");
Serial.println (posz);
Serial.print ("\n");
}
void CheckArrive(){
if (abs(targetx-posx) + abs(targety-posy) + abs(targetz-posz)< 0.01 && command == true){
command = false;
Serial.print("*");
}
}
void Reportz(){
int intposz = (int)(posz * 100);
mySerial.print("@");
mySerial.print (intposz);
mySerial.print("#");
}
void loop() {
AcquireXYZ();
if (command == true){
plotting();
}
CheckArrive();
}
I'm looking for something like this for my 2 axis cnc, I'm struggling with the program to comunicate between arduino and my pc, any chances you could upload your C program too?
system
November 14, 2010, 2:03pm
9
very nice! any estimation on accuracy yet? and what materials do you think you can manage? Id say with adjusting the speeds, feed rates and using cutting fluid it'll be quite the versatile setup! More pics of what you make!
Tested it and works cool, any plan on implementing G2 and G3 commands?
system
November 15, 2010, 4:09pm
11
system
November 15, 2010, 4:45pm
12
wow!!! That's amazing work! I will be doing something similar soon