RE: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
Posted by
John Dammeyer
on 2008-12-13 16:34:44 UTC
Hi Jon,
After sleeping on it this morning I was able to clean up the problem and
run the G-Code with all sorts of different formats. The MACH3 simulation
does a great job of going to each of the places and drilling the holes.
I compiled with Microsoft Visual Studio Express as a c++ command line
project. I've pasted the source with the appropriate changes below.
Changes are marked in comments with "JCD --"
Thanks again Jon.
John Dammeyer
// cvtexc2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
/* This program reads in an Excellon ASCII
drill file and converts it to a standard
RS-274D machine tool program for automatic
Z-axis drilling - using the machine to
position the board for drilling.
This assumes no canned cycles */
/* input format is 2.3 with trailing zeroes supressed*/
/* output coordinate format is 2.4 with radix point*/
/* output feedrate format is 2.3 */
#define file_name_len 40
typedef char file_name_type[file_name_len + 1];
static long i, j, k, line_no, count, lines, iy;
static file_name_type file_name;
static FILE *infile, *OutFile;
static long start, ending, spacing;
//int true = 1;
//int false = 0;
static int done, bflag;
static char achar;
static long scale, xorg, yorg, tool;
static double xmin,xmax,ymin,ymax;
static double ToolList[16];
static double LineNo;
static long x_offset, y_offset;
static char buffer[128];
/* global vars for statistics */
static long hole_count, tool_count;
void OutNum(double RealNum, long SigFrac) {
double i;
int j;
char format[8];
for (i = 1.0, j = 0; j <= 6 && i<= fabs(RealNum); i *= 10.0, j++)
{}
j += SigFrac-1; /* J <= # int digits + 1 for decimal pt + #frac digits
*/
if (RealNum < 0.0 )
j += 1; /* add a position for the minus sign */
sprintf(format,"%%%d.%dlf",j,SigFrac);
fprintf(OutFile, format, (RealNum));
}
void WriteLineNo(void)
{
putc('N', OutFile);
OutNum(LineNo, 0L);
LineNo += 10.0;
putc(' ', OutFile);
}
/* *section - procedures to read input files follow */
static long getnum(FILE **filevar, char *achar, long *NumLen) {
long temp = 0;
int eolflag;
*NumLen = 0;
do { /* skip leading blanks & tabs */
*achar = getc(*filevar);
if (*achar == '\n')
*achar = ' ';
} while (!((*achar > ' ') | feof(*filevar)));
if (feof(*filevar))
return temp;
do {
if (*achar < '0' || *achar > '9')
printf("error in getnum, char =\"%c\"\n", *achar);
temp = temp * 10 + *achar - '0';
(*NumLen)++;
if (*achar != '\n') {
*achar = getc(*filevar);
if (*achar == '\n')
*achar = ' ';
eolflag = false;
} else
eolflag = true;
} while (!((*achar < '0' || *achar > '9' || eolflag) | feof(*filevar)));
--(*NumLen);
return temp;
}
static long read_Excellon(FILE **filevar) {
long line_num = 1, x = -999999L, y = -999999L;
double rx,ry;
char achar;
int p_flag = false;
int x_flag, y_flag;
long dummy, len;
double ToolDiam, ToolDepth, ToolFeed;
double RPlane = 0.1000, RPM = 22500.0, PosFeed = 60.0;
double StackHeight;
printf("Enter Board Stack Height (as real)\n");
scanf("%lg%*[^\n]", &StackHeight);
getchar();
/* the clear plane for moves */
/* spindle RPM */
/* positioning feed, IPM */
while (!feof(*filevar)) {
x_flag = false;
y_flag = false;
achar = getc(*filevar);
printf(" reading input *%c*\n",achar);
if (achar == '\n')
achar = ' ';
switch (achar) {
case 'm':
case 'M':
printf(" ignoring M");
while ((!feof(*filevar)) & !(achar == ' ')) {
achar = getc(*filevar);
if (achar == '\n')
achar = ' ';
putchar(achar);
}
putchar('\n');
break;
/* case M */
case '%':
p_flag = true; /* mark that tool descr is done */
printf(" ignoring %%");
/* while ((!feof(*filevar)) && (achar != ' ')) {
achar = getc(*filevar);
if (achar == '\n')
achar = ' ';
putchar(achar);
} */
/* putchar('\n'); */
break;
/* case % */
case 't':
case 'T':
if (p_flag) {
tool = getnum(filevar, &achar, &dummy);
printf(" Tool is T%2ld (%5.3lf inch)\n", tool,ToolList[tool]);
WriteLineNo();
ToolDiam = ToolList[tool];
fprintf(OutFile, "M01 (MOUNT TOOL T%2ld %5.3lf)\n", tool,
ToolDiam);
tool_count++;
/* brd thick ;into backup;point to flank */
ToolDepth = -(StackHeight + 0.010 + ToolDiam / 4.0);
printf(" ToolDepth = % .5E\n", ToolDepth);
ToolFeed = ToolDiam / 15.0 * RPM; /* best RPM for now */
printf(" Feed = % .5E\n", ToolFeed);
} else { /* scan for 'C' */
tool = getnum(filevar, &achar, &dummy);
achar = ' ';
while (((!feof(*filevar)) && (achar != '\n')) && achar != 'C') {
achar = getc(*filevar);
printf("achar was >%c<\n",achar);
if (achar == '\n')
achar = ' ';
}
/* extract tool size and store in array */
// ToolList[tool] = getnum(filevar, &achar, &dummy);
i = fscanf(*filevar, "%lf",&ToolDiam);
printf("fscan returned %d value was %lf\n",i,ToolDiam);
ToolList[tool] = ToolDiam;
printf(" tool T%2ld is %5.3lf\"\n", tool, ToolList[tool]);
}
break;
/* T */
/* parse tool description */
case 'x':
case 'X':
printf("reading X parameters\n");
x = getnum(filevar, &achar, &len);
printf(" X value is %d, len is %d\n",x,len);
switch (len) {
case 2:
rx =x*0.1;
break;
case 3:
rx = x*0.01;
break;
case 4:
rx = x*0.001;
break;
case 5:
rx = x*0.0001;
break;
case 6: /* pass through */
rx = x*0.00001;
break;
}/* case len */
// printf(" rx is %f\n",rx);
x_flag = true;
if (rx > xmax)
xmax = rx;
if (rx < xmin)
xmin = rx;
if (achar == 'y' || achar == 'Y') {
y = getnum(filevar, &achar, &len);
switch (len) {
case 2:
ry = y*0.1;
break;
case 3:
ry = y*0.01;
break;
case 4:
ry = y*0.001;
break;
case 5:
ry = y*0.0001;
break;
case 6: /* pass through */
ry = y*0.00001;
break;
}/* case len */
y_flag = true;
if (ry > ymax)
ymax = ry;
if (ry < ymin)
ymin = ry;
} /*if begin */
WriteLineNo();
fprintf(OutFile, "X");
OutNum(rx,3L);
if (y_flag) {
fprintf(OutFile, " Y");
OutNum(ry,3L);
}
hole_count++;
fprintf(OutFile, " F");
OutNum(PosFeed, 1L);
putc('\n', OutFile);
break;
/* 'x' */
case 'y':
case 'Y':
printf("reading X parameters\n");
y = getnum(filevar, &achar, &len);
printf(" Y value is %d, len is %d\n",x,len);
switch (len) {
case 2:
ry = y*0.1;
break;
case 3:
ry = y*0.01;
break;
case 4:
ry = y*0.001;
break;
case 5:
ry = y*0.0001;
break;
case 6: /* pass through */
ry = y*0.00001;
break;
}/* case len */
y_flag = true;
if (ry > ymax)
ymax = ry;
if (ry < ymin)
ymin = ry;
if (achar == 'y' || achar == 'Y') {
y = getnum(filevar, &achar, &len);
switch (len) {
case 2:
rx = x*0.1;
break;
case 3:
rx = x*0.01;
break;
case 4:
rx = x*0.001;
break;
case 5:
rx = x*0.0001;
break;
case 6: /* pass through */
rx = x*0.00001;
break;
}/* case len */
x_flag = true;
if (rx > xmax)
xmax = rx;
if (rx < xmin)
xmin = rx;
} /*if begin */
WriteLineNo();
fprintf(OutFile, "Y");
OutNum(ry, 3L);
if (x_flag) {
fprintf(OutFile, " X");
OutNum(rx,3L);
}
fprintf(OutFile, " F");
OutNum(PosFeed, 1L);
putc('\n', OutFile);
hole_count++;
break;
/* 'y' */
}/* case achar */
if (y_flag || x_flag) { /* generate Z stroke */
WriteLineNo();
putc('Z', OutFile);
OutNum(ToolDepth, 4L);
fprintf(OutFile, " F");
OutNum(ToolFeed, 3L);
putc('\n', OutFile);
WriteLineNo(); /* generate return stroke */
putc('Z', OutFile);
OutNum(RPlane, 4L);
putc('\n', OutFile);
}
line_num++;
/* JCD --
These two lines in this format cause the app to skip every second
line
and therefore miss half the holes. Replaced with line below which
is
supposed span over % and * characters up to and including the line
end
character sequence.
fscanf(*filevar, "%*[^\n]");
achar = getc(*filevar);
*/
fscanf(*filevar, "%*[\n]");
}
return line_num;
} /* proc read_gerber */
int _tmain(int argc, _TCHAR* argv[]) {
/* main program */
char *TEMP;
OutFile = NULL;
infile = NULL;
hole_count = 0;
tool_count = 0;
xmin = 1000000.0;
xmax = -1000000.0;
ymin = 1000000.0;
ymax = -1000000.0;
LineNo = 10.0;
printf("Enter name of Excellon Drill File.\n");
fgets(file_name, file_name_len + 1, stdin);
TEMP = strchr(file_name, '\n');
if (TEMP != NULL)
*TEMP = 0;
infile=fopen(file_name,"r");
rewind(infile);
printf("Enter name of RS274 file.\n");
fgets(file_name, file_name_len + 1, stdin);
TEMP = strchr(file_name, '\n');
if (TEMP != NULL)
*TEMP = 0;
OutFile = fopen(file_name,"w");
if (OutFile != NULL)
rewind(OutFile);
else
OutFile = tmpfile();
if (OutFile == NULL)
return(1);
if (!feof(infile)) {
WriteLineNo();
fprintf(OutFile, "G61\n"); /* turn on exact stop mode */
WriteLineNo();
fprintf(OutFile, " G01 F70\n");
lines = read_Excellon(&infile);
printf("%12ld Excellon command lines read in.\n", lines);
printf(" Board Dimensions (without border)\n");
printf(" X Min = %f X Max = %f\n", xmin, xmax);
printf(" Y Min = %f Y Max = %f\n", ymin, ymax);
printf("%12ld holes in drill file.\n", hole_count);
printf("%12ld Tools in drill file.\n", tool_count);
}
WriteLineNo();
fprintf(OutFile, " M02\n"); /*program stop */
WriteLineNo();
fprintf(OutFile, " M30\n"); /*program stop */
printf(" file is done.\n");
if (infile != NULL)
fclose(infile);
infile = NULL;
if (OutFile != NULL)
fclose(OutFile);
OutFile = NULL;
if (infile != NULL)
fclose(infile);
// JCD -- Added pause so Windows DOS CMD session does quit. We want to
see the text results.
printf("Hit Enter to exit\n");
getchar();
return 0;
}
Automation Artisans Inc.
http://www.autoartisans.com/ELS/
Ph. 1 250 544 4950
After sleeping on it this morning I was able to clean up the problem and
run the G-Code with all sorts of different formats. The MACH3 simulation
does a great job of going to each of the places and drilling the holes.
I compiled with Microsoft Visual Studio Express as a c++ command line
project. I've pasted the source with the appropriate changes below.
Changes are marked in comments with "JCD --"
Thanks again Jon.
John Dammeyer
// cvtexc2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
/* This program reads in an Excellon ASCII
drill file and converts it to a standard
RS-274D machine tool program for automatic
Z-axis drilling - using the machine to
position the board for drilling.
This assumes no canned cycles */
/* input format is 2.3 with trailing zeroes supressed*/
/* output coordinate format is 2.4 with radix point*/
/* output feedrate format is 2.3 */
#define file_name_len 40
typedef char file_name_type[file_name_len + 1];
static long i, j, k, line_no, count, lines, iy;
static file_name_type file_name;
static FILE *infile, *OutFile;
static long start, ending, spacing;
//int true = 1;
//int false = 0;
static int done, bflag;
static char achar;
static long scale, xorg, yorg, tool;
static double xmin,xmax,ymin,ymax;
static double ToolList[16];
static double LineNo;
static long x_offset, y_offset;
static char buffer[128];
/* global vars for statistics */
static long hole_count, tool_count;
void OutNum(double RealNum, long SigFrac) {
double i;
int j;
char format[8];
for (i = 1.0, j = 0; j <= 6 && i<= fabs(RealNum); i *= 10.0, j++)
{}
j += SigFrac-1; /* J <= # int digits + 1 for decimal pt + #frac digits
*/
if (RealNum < 0.0 )
j += 1; /* add a position for the minus sign */
sprintf(format,"%%%d.%dlf",j,SigFrac);
fprintf(OutFile, format, (RealNum));
}
void WriteLineNo(void)
{
putc('N', OutFile);
OutNum(LineNo, 0L);
LineNo += 10.0;
putc(' ', OutFile);
}
/* *section - procedures to read input files follow */
static long getnum(FILE **filevar, char *achar, long *NumLen) {
long temp = 0;
int eolflag;
*NumLen = 0;
do { /* skip leading blanks & tabs */
*achar = getc(*filevar);
if (*achar == '\n')
*achar = ' ';
} while (!((*achar > ' ') | feof(*filevar)));
if (feof(*filevar))
return temp;
do {
if (*achar < '0' || *achar > '9')
printf("error in getnum, char =\"%c\"\n", *achar);
temp = temp * 10 + *achar - '0';
(*NumLen)++;
if (*achar != '\n') {
*achar = getc(*filevar);
if (*achar == '\n')
*achar = ' ';
eolflag = false;
} else
eolflag = true;
} while (!((*achar < '0' || *achar > '9' || eolflag) | feof(*filevar)));
--(*NumLen);
return temp;
}
static long read_Excellon(FILE **filevar) {
long line_num = 1, x = -999999L, y = -999999L;
double rx,ry;
char achar;
int p_flag = false;
int x_flag, y_flag;
long dummy, len;
double ToolDiam, ToolDepth, ToolFeed;
double RPlane = 0.1000, RPM = 22500.0, PosFeed = 60.0;
double StackHeight;
printf("Enter Board Stack Height (as real)\n");
scanf("%lg%*[^\n]", &StackHeight);
getchar();
/* the clear plane for moves */
/* spindle RPM */
/* positioning feed, IPM */
while (!feof(*filevar)) {
x_flag = false;
y_flag = false;
achar = getc(*filevar);
printf(" reading input *%c*\n",achar);
if (achar == '\n')
achar = ' ';
switch (achar) {
case 'm':
case 'M':
printf(" ignoring M");
while ((!feof(*filevar)) & !(achar == ' ')) {
achar = getc(*filevar);
if (achar == '\n')
achar = ' ';
putchar(achar);
}
putchar('\n');
break;
/* case M */
case '%':
p_flag = true; /* mark that tool descr is done */
printf(" ignoring %%");
/* while ((!feof(*filevar)) && (achar != ' ')) {
achar = getc(*filevar);
if (achar == '\n')
achar = ' ';
putchar(achar);
} */
/* putchar('\n'); */
break;
/* case % */
case 't':
case 'T':
if (p_flag) {
tool = getnum(filevar, &achar, &dummy);
printf(" Tool is T%2ld (%5.3lf inch)\n", tool,ToolList[tool]);
WriteLineNo();
ToolDiam = ToolList[tool];
fprintf(OutFile, "M01 (MOUNT TOOL T%2ld %5.3lf)\n", tool,
ToolDiam);
tool_count++;
/* brd thick ;into backup;point to flank */
ToolDepth = -(StackHeight + 0.010 + ToolDiam / 4.0);
printf(" ToolDepth = % .5E\n", ToolDepth);
ToolFeed = ToolDiam / 15.0 * RPM; /* best RPM for now */
printf(" Feed = % .5E\n", ToolFeed);
} else { /* scan for 'C' */
tool = getnum(filevar, &achar, &dummy);
achar = ' ';
while (((!feof(*filevar)) && (achar != '\n')) && achar != 'C') {
achar = getc(*filevar);
printf("achar was >%c<\n",achar);
if (achar == '\n')
achar = ' ';
}
/* extract tool size and store in array */
// ToolList[tool] = getnum(filevar, &achar, &dummy);
i = fscanf(*filevar, "%lf",&ToolDiam);
printf("fscan returned %d value was %lf\n",i,ToolDiam);
ToolList[tool] = ToolDiam;
printf(" tool T%2ld is %5.3lf\"\n", tool, ToolList[tool]);
}
break;
/* T */
/* parse tool description */
case 'x':
case 'X':
printf("reading X parameters\n");
x = getnum(filevar, &achar, &len);
printf(" X value is %d, len is %d\n",x,len);
switch (len) {
case 2:
rx =x*0.1;
break;
case 3:
rx = x*0.01;
break;
case 4:
rx = x*0.001;
break;
case 5:
rx = x*0.0001;
break;
case 6: /* pass through */
rx = x*0.00001;
break;
}/* case len */
// printf(" rx is %f\n",rx);
x_flag = true;
if (rx > xmax)
xmax = rx;
if (rx < xmin)
xmin = rx;
if (achar == 'y' || achar == 'Y') {
y = getnum(filevar, &achar, &len);
switch (len) {
case 2:
ry = y*0.1;
break;
case 3:
ry = y*0.01;
break;
case 4:
ry = y*0.001;
break;
case 5:
ry = y*0.0001;
break;
case 6: /* pass through */
ry = y*0.00001;
break;
}/* case len */
y_flag = true;
if (ry > ymax)
ymax = ry;
if (ry < ymin)
ymin = ry;
} /*if begin */
WriteLineNo();
fprintf(OutFile, "X");
OutNum(rx,3L);
if (y_flag) {
fprintf(OutFile, " Y");
OutNum(ry,3L);
}
hole_count++;
fprintf(OutFile, " F");
OutNum(PosFeed, 1L);
putc('\n', OutFile);
break;
/* 'x' */
case 'y':
case 'Y':
printf("reading X parameters\n");
y = getnum(filevar, &achar, &len);
printf(" Y value is %d, len is %d\n",x,len);
switch (len) {
case 2:
ry = y*0.1;
break;
case 3:
ry = y*0.01;
break;
case 4:
ry = y*0.001;
break;
case 5:
ry = y*0.0001;
break;
case 6: /* pass through */
ry = y*0.00001;
break;
}/* case len */
y_flag = true;
if (ry > ymax)
ymax = ry;
if (ry < ymin)
ymin = ry;
if (achar == 'y' || achar == 'Y') {
y = getnum(filevar, &achar, &len);
switch (len) {
case 2:
rx = x*0.1;
break;
case 3:
rx = x*0.01;
break;
case 4:
rx = x*0.001;
break;
case 5:
rx = x*0.0001;
break;
case 6: /* pass through */
rx = x*0.00001;
break;
}/* case len */
x_flag = true;
if (rx > xmax)
xmax = rx;
if (rx < xmin)
xmin = rx;
} /*if begin */
WriteLineNo();
fprintf(OutFile, "Y");
OutNum(ry, 3L);
if (x_flag) {
fprintf(OutFile, " X");
OutNum(rx,3L);
}
fprintf(OutFile, " F");
OutNum(PosFeed, 1L);
putc('\n', OutFile);
hole_count++;
break;
/* 'y' */
}/* case achar */
if (y_flag || x_flag) { /* generate Z stroke */
WriteLineNo();
putc('Z', OutFile);
OutNum(ToolDepth, 4L);
fprintf(OutFile, " F");
OutNum(ToolFeed, 3L);
putc('\n', OutFile);
WriteLineNo(); /* generate return stroke */
putc('Z', OutFile);
OutNum(RPlane, 4L);
putc('\n', OutFile);
}
line_num++;
/* JCD --
These two lines in this format cause the app to skip every second
line
and therefore miss half the holes. Replaced with line below which
is
supposed span over % and * characters up to and including the line
end
character sequence.
fscanf(*filevar, "%*[^\n]");
achar = getc(*filevar);
*/
fscanf(*filevar, "%*[\n]");
}
return line_num;
} /* proc read_gerber */
int _tmain(int argc, _TCHAR* argv[]) {
/* main program */
char *TEMP;
OutFile = NULL;
infile = NULL;
hole_count = 0;
tool_count = 0;
xmin = 1000000.0;
xmax = -1000000.0;
ymin = 1000000.0;
ymax = -1000000.0;
LineNo = 10.0;
printf("Enter name of Excellon Drill File.\n");
fgets(file_name, file_name_len + 1, stdin);
TEMP = strchr(file_name, '\n');
if (TEMP != NULL)
*TEMP = 0;
infile=fopen(file_name,"r");
rewind(infile);
printf("Enter name of RS274 file.\n");
fgets(file_name, file_name_len + 1, stdin);
TEMP = strchr(file_name, '\n');
if (TEMP != NULL)
*TEMP = 0;
OutFile = fopen(file_name,"w");
if (OutFile != NULL)
rewind(OutFile);
else
OutFile = tmpfile();
if (OutFile == NULL)
return(1);
if (!feof(infile)) {
WriteLineNo();
fprintf(OutFile, "G61\n"); /* turn on exact stop mode */
WriteLineNo();
fprintf(OutFile, " G01 F70\n");
lines = read_Excellon(&infile);
printf("%12ld Excellon command lines read in.\n", lines);
printf(" Board Dimensions (without border)\n");
printf(" X Min = %f X Max = %f\n", xmin, xmax);
printf(" Y Min = %f Y Max = %f\n", ymin, ymax);
printf("%12ld holes in drill file.\n", hole_count);
printf("%12ld Tools in drill file.\n", tool_count);
}
WriteLineNo();
fprintf(OutFile, " M02\n"); /*program stop */
WriteLineNo();
fprintf(OutFile, " M30\n"); /*program stop */
printf(" file is done.\n");
if (infile != NULL)
fclose(infile);
infile = NULL;
if (OutFile != NULL)
fclose(OutFile);
OutFile = NULL;
if (infile != NULL)
fclose(infile);
// JCD -- Added pause so Windows DOS CMD session does quit. We want to
see the text results.
printf("Hit Enter to exit\n");
getchar();
return 0;
}
Automation Artisans Inc.
http://www.autoartisans.com/ELS/
Ph. 1 250 544 4950
Discussion Thread
eugenelambe1
2008-12-12 08:05:16 UTC
boxford 160 slant bed
John Dammeyer
2008-12-12 14:55:59 UTC
Excelon Drill file to MACH3 G-Code.
Jon Elson
2008-12-12 20:21:24 UTC
Re: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
Alan Rothenbush
2008-12-12 21:58:00 UTC
RE: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
Peter Homann
2008-12-12 23:12:16 UTC
Re: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
John Dammeyer
2008-12-13 16:34:44 UTC
RE: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
John Dammeyer
2008-12-13 16:34:54 UTC
RE: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
John Dammeyer
2008-12-13 16:35:06 UTC
RE: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
Jon Elson
2008-12-13 17:31:13 UTC
Re: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.
Zoran A. Scepanovic
2008-12-14 02:07:15 UTC
Re: [CAD_CAM_EDM_DRO] Excelon Drill file to MACH3 G-Code.