ADVERTISEMENT

pcb-gcode-3.6.0.4.zip

Frezowanie PCB zaprojektowanych w Eagle

Postanowiłem napisać ten poradniczek, bo słabo co można o tym znaleźć w necie (albo słabo mi idzie szukanie). Sporo jest o jakiś dziwacznych pośrednich metodach z użyciem oprogramowania, które nie wiadomo skąd wziąć. A ta metoda jest prosta i skuteczna. Poradnik jest efektem końcowym całego sztapla zmarnowanych płytek, ale nie żałuję, odbiję sobie na chemikaliach :) Do rzeczy 1. Ściągnąć ze strony Artsoft (albo z załącznika) wtyczkę pcb-gcode.ulp. http://www.cadsoftusa.com/downloads/ulps?language=en Działa z programem Eagle w wersji 5 i 6. 2. Rozpakować i skopiować do katalogu Eagle/ulp 3. Uruchomić Eagle, w systemach Vista i 7 uruchomić jako administrator. 4. O projektowaniu ani słowa, zakładam, że mamy już gotowy projekt płytki - otwieramy go. 5. Z płytki pcb zaprojektowanej w programie Eagle usuwamy zbędne warstwy, zostawiamy tylko bottom, pads i vias (przelotki pewnie się przydadzą). Oczywiście zakładam, że frezujemy stronę bottom. 6. Naciskamy file i wybieramy polecenie run - otworzy się okno z wtyczkami ulp (można na pasku głównym nacisnąć ikonkę ULP). 7. Teraz wybieramy pcb-gcode-setup.ulp - to nam pozwoli ustalić parametry frezowania. 8. W zakładce Machine ustawiamy jednostki milimetry, i przechodzimy do zakładki Generation Options. 9. W pierwszym okienku Generation Options wybieramy stronę, którą będziemy frezować. W tym wypadku zaznaczamy Generate bottom outlines, i Generate bottom drils, a odznaczamy Generate top outlines i Generate top drils. Zaznaczamy też Mirror. Wprowadzamy parametry w oknie board : show preview (niekoniecznie), spot drill holes -0.254, minimum 0.00254 mm ; Maximum - 0.01 mm ; Step size - 0.127 mm. Nie stosujemy przecinków, tylko kropki - system amerykański. 10. Zakładka Machine. Z High - wysokość bezpiecznego transportu narzędzia, może być 5 mm. Z Up - na ile będzie się podnosić narzędzie przy zmianie pozycji bez frezowania dajemy 2 mm. Z Down - jak będzie głęboko frezować miedź - , ja ustawiam na -0,17 mm. Można ustawić głębiej, ale tak cienkie frezy są stożkowe, więc poszerzą obszar frezowany, i płytka może nie wyjść. Drill depth (głębokość wiercenia) ustawiamy na -1.8 mm (powinno wystarczyć, jakbyśmy mieli grubszy laminat, ustawiamy więcej). Drill dwell - 0.1 (czas zatrzymania frezu w otworze w sekundach). Position X i Y zero. Position Z 10. 11. Zakładka GCode style zaznaczamy Mach. 12. Naciskamy Accept, i koniec ustawiania. Potwierdzamy jeszcze OK i jeszcze raz Accept. Reszta parametrów zostaje domyślna. 13. Znajdujemy pcb-gcode.ulp i klikamy 2 razy. 14. Za chwilę program wygeneruje dwa pliki umieszczone w tym samym katalogu, w którym był projekt płytki projekt.brd. Będą to pliki : projekt.bot.drill.tap oraz projekt.bot.etch.tap. Są to pliki przyjmowane już przez program Mach. Najlepiej zamiast kropek w środku nazwy wstawić podkreślniki, bo mach wtedy widzi je od razu. 15. Teraz dobrze byłoby podejrzeć płytkę, czy nie ma błędów. Do tego użyłem starszej, darmowej wersji programu CamBam. Obsługa bardzo prosta, przynajmniej, jeżeli chodzi o podgląd. Jeżeli szanowna komisja błędów nie stwierdziła, przystępujemy do frezowania płytki. Nie lekceważmy tego sprawdzania, szczególnie jeżeli odległości między ścieżkami są w projekcie niewielkie. Wtedy sąsiednie ścieżki, czy pady potrafią się "zlać" ze sobą. Trzeba wtedy skorygować projekt. 16. Najpierw wgrywamy plik projekt_bot_etch.tap i zakładamy frez 0,2 mm. Skąd G-code wystartuje to trzeba sprawdzić na "sucho". Z reguły jest to z okolic dolnego lewego narożnika. Ustawimy frez na "0" i dalej jak w Mach'u - zerujemy wszystkie pozycje i start. Frezarka zastąpi kuwetę z chemikaliami. 17. Jak już skończy, podnosimy narzędzie tak, by móc je wymienić na frez do wiercenia. Następnie ustawiamy na zero w osiach X i Y (miejsce, gdzie program zaczynał frezowanie). Oś Z zerujemy od nowa po zmianie narzędzia. Żeby nie ustawiać ręcznie zera w osiach X i Y, można dopisać w pliku projekt_bot_etch.tap (w drugiej linijce nod końca za pozycją Z, X00.0000 Y00.0000). Jak mamy wszystko ustawione, wgrywamy plik projekt_bot_drill.tap i start. Teraz frezarka wykona wszystkie otwory. A oto przykład wykonanej przed chwilą płytki drukowanej do Atmega_fusebit_doctor kolegi manekinen (podziękowania), którego to doktorka mam właśnie zamiar spreparować. Płytka frezowana frezem 0,2 mm, czoło płaskie. Otwory wiercone frezem 0,7 mm. Jak trzeba będzie któreś powiększyć, zrobię to malutką ręczną wiertareczką. Jak są otwory prowadzące, to już żaden problem. Po całej operacji wygładzamy płytkę papierem ściernym 1000, żeby pozbyć się gradu na brzegach ścieżek. Porobiłem zdjęcia, i dopiero się zorientowałem, że nie zaznaczyłem opcji mirror, więc płytka wyszła źle - w lustrze. Ale teraz, jak już metoda jest dopracowana, zaraz zrobię nową płytkę. Tylko nie sfotografuję, bo oddałem aparat. Zdjęcia z komórki nie nadają się do publikacji. Wadą metody są pozostające pomiędzy ścieżkami pola niewyfrezowanej miedzi. Na razie nie wiem jak tego się pozbyć, może coś wymyślę, wtedy umieszczę dalszy ciąg. Muszę tylko dokupić laminatu :). Na eksperymenty poszedł cały zapas. W załączniku program CamBam, który w wersji darmowej jest już trudny do zdobycia. Autor wycofał go ze swojej strony, ma tam teraz tylko wersje płatne. W drugim wtyczka do Eagle'a. http://obrazki.elektroda.pl/5728798500_1387178238_thumb.jpg http://obrazki.elektroda.pl/1517340000_1387178491_thumb.jpg


Download file - link to post
  • pcb-gcode-3.6.0.4.zip
    • rakefile.rb
    • pcbgcode.tmproj
    • pcb-gcode-setup.ulp
    • README
    • plugins
      • calculator.plugin
      • square_z.plugin
      • filenames.plugin
      • square_x_and_y.plugin
      • plugin_loader.h
      • calculator.plugin.h
      • plugin_headers.h
    • profiles
      • generic.pp
      • turbocnc.pp
      • emc.pp
      • mach.pp
      • isel.pp
    • settings
      • pcb-machine.h
      • user-gcode.h
      • pcb-gcode-options.h
      • gcode-defaults.h
      • pcb-defaults.h
      • default.drl.txt
    • pcb-gcode.ulp
    • viewer
      • viewer.pde
      • application.macosx
        • viewer.app
          • Contents
            • PkgInfo
            • Resources
              • Java
                • viewer.jar
                • core.jar
              • sketch.icns
            • Info.plist
            • MacOS
              • JavaApplicationStub
        • source
          • viewer.java
          • viewer.pde
        • data
          • BankGothic-Light-14.vlw
          • BankGothic-Light-24.vlw
          • optimize_me.txt
      • applet
        • viewer.java
        • viewer.pde
        • viewer.jar
        • index.html
        • loading.gif
        • data
          • BankGothic-Light-14.vlw
          • BankGothic-Light-24.vlw
          • optimize_me.txt
      • viewer.tmproj
      • application.windows
        • viewer.exe
        • lib
          • args.txt
          • viewer.jar
          • core.jar
        • source
          • viewer.java
          • viewer.pde
        • data
          • BankGothic-Light-14.vlw
          • BankGothic-Light-24.vlw
          • optimize_me.txt
      • data
        • BankGothic-Light-14.vlw
        • BankGothic-Light-24.vlw
        • optimize_me.txt
      • application.linux
        • lib
          • viewer.jar
          • core.jar
        • viewer
        • source
          • viewer.java
          • viewer.pde
        • data
          • BankGothic-Light-14.vlw
          • BankGothic-Light-24.vlw
          • optimize_me.txt
    • docs
      • changelog.txt
      • examples
        • 04151_lcdi2c.bot.drill.tap
        • 04151_lcdi2c.sch
        • 04151_lcdi2c.top.text.tap
        • 04151_lcdi2c.bot.mill.tap
        • 04151_lcdi2c.brd
        • enabtmr.top.text.tap
        • 04151_lcdi2c.bot.text.tap
        • enabtmr.bot.text.tap
        • enabtmr.top.drill.tap
        • 04151_lcdi2c.top.mill.tap
        • 04151_lcdi2c.drl
        • enabtmr.top.mill.tap
        • 04151_lcdi2c.bot.etch.tap
        • enabtmr.bot.etch.tap
        • enabtmr.sch
        • enabtmr.drl.txt
        • enabtmr.bot.drill.tap
        • 04151_lcdi2c.top.etch.tap
        • enabtmr.bot.mill.tap
        • enabtmr.top.etch.tap
        • 04151_lcdi2c.top.drill.tap
        • enabtmr.brd
      • pcbgcode.tex
      • homepage.jpg
      • lstlang0.sty
      • images
        • z_axis.svg
        • isolation_settings_300.gif
        • z_axis.gif
        • pcbgcode-600.gif
      • pcbgcode.pdf
      • Array
      • artistic-license.txt
    • safe_options
      • user-gcode.release.h
      • pcb-machine.h
      • pcb-gcode-options.release.h
      • user-gcode.h
      • pcb-gcode-options.h
      • pcb-defaults.release.h
      • pcb-machine.release.h
      • pcb-defaults.h
    • source
      • pcb-gcode-menu.scr
      • pcb-file-utils.h
      • filename_subs.h
      • stack.h
      • math.ulp
      • string.ulp
      • viewer.linux.sh
      • filecopy.h
      • pcb-gcode.h
      • pcb-gcode-stack.h
      • library.h
      • pcb-gcode-prg.scr
      • math.h
      • string.h
      • stack.ulp
      • test_nonvolatile.h
      • nonvolatile.h
      • library.ulp
      • test_nonvolatile.ulp
      • drill.h
      • drill_sizes.h
    • plugin_headers.h


pcb-gcode-3.6.0.4.zip > pcb-machine.h

//
// For ease of use, and to avoid overwritting your settings,
// use pcb-gcode-setup to make changes to these settings.
//

real DEFAULT_Z_HIGH = 0.500000;
real DEFAULT_Z_UP = 0.100000;
real DEFAULT_Z_DOWN = -0.007000;
real DRILL_DEPTH = -0.032000;
real DRILL_DWELL = 1.000000;
real SPINDLE_ON_TIME = 3.000000;
real MILLING_DEPTH = -0.010000;
real TEXT_DEPTH = -0.005000;
real TOOL_CHANGE_POS_X = 0.000000;
real TOOL_CHANGE_POS_Y = 0.000000;
real TOOL_CHANGE_POS_Z = 0.000000;
real FEED_RATE = 20.000000;
real FEED_RATE_Z = 10.000000;
real DEFAULT_WIDTH = 0.007000;
real X_OFFSET = 0.000000;
real Y_OFFSET = 0.000000;
real X_HOME = 0.000000;
real Y_HOME = 0.000000;
real EPSILON = 0.000100;


pcb-gcode-3.6.0.4.zip > plugin_loader.h

/*
* Generate g-code for milling PC boards.
*
* Copyright 2004-2009 by John Johnson Software, LLC.
* See readme.html for copyright information.
*
*/

// BEGIN_PLUGIN_INCLUDES
dlgVBoxLayout {
dlgHBoxLayout {
/* dlgVBoxLayout {
dlgGroup( " Square X and Y (doesn't do anything) " ) {
#include " square_x_and_y.plugin "
}
dlgStretch(1);
}
dlgVBoxLayout {
dlgGroup( " Square Z " ) {
#include " square_z.plugin "
}
dlgStretch(1);
}
dlgVBoxLayout {
dlgGroup( " Filenames " ) {
#include " filenames.plugin "
}
dlgStretch(1);
}*/
}
dlgHBoxLayout {
dlgStretch(1);
dlgVBoxLayout {
#include " calculator.plugin "
}
dlgStretch(1);
}
dlgStretch(1);
}
// END_PLUGIN_INCLUDES


pcb-gcode-3.6.0.4.zip > calculator.plugin.h

/**********************************************************
*
* A basic calculator.
*
* Plugin Definitions
* NAME = calculator
* DESC = Basic calculator
* AUTHOR = John Johnson
* TAB_NAME = Plugins
**********************************************************/

int UNARY_BEGIN = 0x80;
int ANGLE_IN = 0x40;
int ANGLE_OUT = 0x20;

enum {
OP_INVALID,
OP_CLEAR,
OP_ENTER,
OP_ADD,
OP_SUBTRACT,
OP_DIVIDE,
OP_MULTIPLY,
OP_RADIAN,
OP_DEGREE
};

enum {
OP_MEMORY_PLUS = 0x80 /* UNARY_BEGIN */,
OP_MEMORY_STORE,
OP_MEMORY_RECALL,
OP_MEMORY_CLEAR
};

enum {
OP_SINE = 0xC0 /* UNARY_BEGIN + ANGLE_IN */,
OP_COSINE,
OP_TANGENT,
OP_ARC_SINE,
OP_ARC_COSINE,
OP_ARC_TANGENT
};

enum {
OP_INV_SINE = 0xA0 /* UNARY_BEGIN + ANGLE_OUT */,
OP_INV_COSINE,
OP_INV_TANGENT
};

enum {
ANG_INVALID,
ANG_RADIAN,
ANG_DEGREE
/* ANG_GRADIANS - sorry */
};

int m_angle_mode;
string g_angle_mode_str;
int g_memory;

real accum;
real depth;
int passes;
string nc_file;
int unit_metric;
real length;
string result;

string m_result = " 0 " ;
string m_entry = " 0 " ;

string format_number(real n)
{
string tmp;

sprintf(tmp, " %f " , n);
return tmp;

}

real set_accum(string s)
{
accum = strtod(s);
return accum;
}

string set_result(real r)
{
m_result = format_number(r);
// set_nv_param( " calc_result " , m_result);
return m_result;
}

real set_angle_mode(int mode)
{
real result;
string num;
int used_entry;

result = strtod(m_result);

if (m_entry != " " ) {
num = m_entry;
used_entry = 1;
}
else if (m_result != " " ) {
num = m_result;
}
else {
num = m_result;
}

if (m_angle_mode == ANG_DEGREE & & mode == ANG_RADIAN) {
result = strtod(num) / 180 * PI;
}
else if (m_angle_mode == ANG_RADIAN & & mode == ANG_DEGREE) {
result = strtod(num) / PI * 180;
}
m_angle_mode = mode;

switch (m_angle_mode) {
case ANG_RADIAN:
g_angle_mode_str = " rad " ;
break;
case ANG_DEGREE:
g_angle_mode_str = " deg " ;
break;
}

// set_nv_param( " calc_angle_mode " , g_angle_mode_str);

// if (used_entry) {
m_entry = format_number(result);
// }
// else {
set_result(result);
// }*/
return result;
}

string get_mode_str()
{
return (m_angle_mode == ANG_RADIAN) ? " rad " : " deg " ;
}

real rad(real n)
{
return (m_angle_mode == ANG_RADIAN) ? n : n / 180 * PI;
}

real unrad(real n)
{
return (m_angle_mode == ANG_RADIAN) ? n : n / PI * 180;
}

int is_unary(int op)
{
return (op & UNARY_BEGIN) ? 1 : 0;
}

void set_memory(real n)
{
string tmp;

g_memory = n;
// set_nv_param( " calc_memory " , format_number(n));
}

real get_memory()
{
return g_memory;
}

void clear_memory()
{
g_memory = 0;
}

int m_entering;
void calc_enter(string n)
{
if (!m_entering) {
m_entry = n;
m_entering = 1;
}
else {
m_entry += n;
}
}

real calc(string a, int OPERATION)
{
real ra;
int no_clear;

m_entering = 0;

ra = strtod(a);
if (m_entry == " " & & m_result != " " & & is_unary(OPERATION))
ra = strtod(m_result);

if (OPERATION & ANGLE_IN) {
ra = rad(ra);
}

switch(OPERATION) {
case OP_ENTER:
accum = ra;
set_result(accum);
break;
case OP_ADD:
accum = accum + ra;
break;
case OP_SUBTRACT:
accum = accum - ra;
break;
case OP_DIVIDE:
accum = accum / ra;
break;
case OP_MULTIPLY:
accum = accum * ra;
break;
case OP_DEGREE:
accum = set_angle_mode(ANG_DEGREE);
break;
case OP_RADIAN:
accum = set_angle_mode(ANG_RADIAN);
break;

case OP_MEMORY_PLUS:
set_memory(ra + get_memory());
accum = ra;
break;
case OP_MEMORY_STORE:
set_memory(ra);
accum = ra;
break;
case OP_MEMORY_RECALL:
m_entry = format_number(get_memory());
no_clear = 1;
accum = ra;
break;
case OP_MEMORY_CLEAR:
clear_memory();
accum = ra;
break;

case OP_COSINE:
accum = cos(ra);
break;
case OP_SINE:
accum = sin(ra);
break;
case OP_TANGENT:
accum = tan(ra);
break;

case OP_ARC_COSINE:
accum = acos(ra);
break;
case OP_ARC_SINE:
accum = asin(ra);
break;
case OP_ARC_TANGENT:
accum = atan(ra);
break;

case OP_CLEAR:
accum = 0;
break;
default:
dlgMessageBox( " Invalid OPERATION " );
}

if (OPERATION & ANGLE_OUT) {
accum = unrad(accum);
}

set_result(accum);
if (!no_clear) m_entry = " " ;
return accum;
}

/**********************************
* Initialization.
**********************************/

set_angle_mode(ANG_DEGREE);


//~ set_memory(strtod(get_nv_param( " calc_memory " , " 0.0 " , 0 /* don't abort */)));
//~ if (get_nv_param( " calc_angle_mode " , " deg " , 0 /* don't abort */) == " deg " )
//~ set_angle_mode(ANG_DEGREE);
//~ else
//~ set_angle_mode(ANG_RADIAN);
//~ set_result(strtod(get_nv_param( " calc_result " , " 0.0 " , 0 /* don't abort */)));


pcb-gcode-3.6.0.4.zip > plugin_headers.h

#include " nonvolatile.h "

#include " plugins/calculator.plugin.h "


pcb-gcode-3.6.0.4.zip > pcb-machine.h

//
// For ease of use, and to avoid overwritting your settings,
// use pcb-gcode-setup to make changes to these settings.
//

real DEFAULT_Z_HIGH = 0.500000;
real DEFAULT_Z_UP = 0.100000;
real DEFAULT_Z_DOWN = -0.007000;
real DRILL_DEPTH = -0.032000;
real DRILL_DWELL = 1.000000;
real SPINDLE_ON_TIME = 3.000000;
real MILLING_DEPTH = -0.010000;
real TEXT_DEPTH = -0.005000;
real TOOL_CHANGE_POS_X = 0.500000;
real TOOL_CHANGE_POS_Y = 0.600000;
real TOOL_CHANGE_POS_Z = 1.000000;
real FEED_RATE = 20.000000;
real FEED_RATE_Z = 10.000000;
real DEFAULT_WIDTH = 0.007000;
real X_OFFSET = 0.000000;
real Y_OFFSET = 0.000000;
real X_HOME = 0.000000;
real Y_HOME = 0.000000;
real EPSILON = 0.000100;


pcb-gcode-3.6.0.4.zip > default.drl.txt

# -*- Mode: Eagle -*-
#
# Sample drill rack file.
#
# drill_size is the size of the drill bit.
# minimum is the smallest hole the bit will be used for.
# maximum is the largest hole the bit will be used for.
#
# Each value can have a " unit of measure " added to it,
# such as 0.500mm . If you do not provide the unit of measure,
# values over 0.250 are considered millimeters, and
# values under 0.250 are considered inches. For example:
# 0.400 would be considered 0.400 mm.
# 0.125 would be considered 0.125 inches.
#
# Please note that you must use a TAB character
# between each setting on a line.
#
# Tip: Set the TAB size of your editor to 12 characters.
#
tool drill_size minimum maximum length
T01 0.500mm 0.000in 0.025in 1.5in
T02 0.032in 0.025in 0.035in 1.5in
T03 0.040in 0.035in 0.039in 1.5in
T04 0.050in 0.045in 0.055in 1.5in
T05 0.062in 0.055in 0.070in 1.5in
T06 0.125in 0.100in 0.125in 1.5in


pcb-gcode-3.6.0.4.zip > user-gcode.h

//
// Define your own gcode sequences in this file.
//
// The settings are listed from most general, to most specific. The settings
// at the top of this file go into every file created, while the settings
// at the end of this file have to do with tool changes only.
//
// Note that each line ends with \n this is Geek Speak for newline.
// In other words, it's like hitting the Enter key at the end of a line.
// Notice also that the lines have a ; at the end.
//
// See the bottom of this file for an example of using multiple lines.
//

// Inserted into bottom, top or all files.
string FILE_BEGIN[] = { " " , " " , " " , " " };
string FILE_END[] = { " " , " " , " " , " " };

FILE_BEGIN[ALL] = " (Beginning of every file)\n " ;
FILE_END[ALL] = " (End of every file)\n " ;

FILE_BEGIN[BOTTOM] = " (Beginning of every bottom file)\n " ;
FILE_END[BOTTOM] = " (End of every bottom file)\n " ;

FILE_BEGIN[TOP] = " (Beginning of every top file)\n " ;
FILE_END[TOP] = " (End of every top file)\n " ;

// Inserted into outline files (track milling).
string OUTLINE_BEGIN[] = { " " , " " , " " , " " };
string OUTLINE_BETWEEN[] = { " " , " " , " " , " " };
string OUTLINE_END[] = { " " , " " , " " , " " };

OUTLINE_BEGIN[ALL] = " (Outline Begin)\n " ;
OUTLINE_BETWEEN[ALL] = " (Between Passes)\n " ;
OUTLINE_END[ALL] = " (Outline End)\n " ;

OUTLINE_BEGIN[BOTTOM] = " (Bottom outline Begin)\n " ;
OUTLINE_BETWEEN[BOTTOM] = " (Bottom between passes)\n " ;
OUTLINE_END[BOTTOM] = " (Bottom outline End)\n " ;

OUTLINE_BEGIN[TOP] = " (Top outline Begin)\n " ;
OUTLINE_BETWEEN[TOP] = " (Top between passes)\n " ;
OUTLINE_END[TOP] = " (Top outline End)\n " ;

// Inserted into drill files.
string DRILL_BEGIN[] = { " " , " " , " " , " " };
string DRILL_END[] = { " " , " " , " " , " " };

DRILL_BEGIN[ALL] = " (Beginning of All Drill files)\n " ;
DRILL_END[ALL] = " (End of all Drill Files)\n " ;

DRILL_BEGIN[BOTTOM] = " (Bottom Drill Begin)\n " ;
DRILL_END[BOTTOM] = " (Bottom Drill End)\n " ;

DRILL_BEGIN[TOP] = " (Top Drill Begin)\n " ;
DRILL_END[TOP] = " (Top Drill End)\n " ;

// Inserted into fill files.
string FILL_BEGIN[] = { " " , " " , " " , " " };
string FILL_END[] = { " " , " " , " " , " " };

FILL_BEGIN[ALL] = " (Fill Begin)\n " ;
FILL_END[ALL] = " (Fill End)\n " ;

FILL_BEGIN[BOTTOM] = " (Bottom Fill Begin)\n " ;
FILL_END[BOTTOM] = " (Bottom Fill End)\n " ;

FILL_BEGIN[TOP] = " (Top Fill Begin)\n " ;
FILL_END[TOP] = " (Top Fill End)\n " ;

// Inserted into milling files.
string MILL_BEGIN[] = { " " , " " , " " , " " };
string MILL_END[] = { " " , " " , " " , " " };

MILL_BEGIN[ALL] = " (MILL Begin)\n " ;
MILL_END[ALL] = " (MILL End)\n " ;

MILL_BEGIN[BOTTOM] = " (Bottom MILL Begin)\n " ;
MILL_END[BOTTOM] = " (Bottom MILL End)\n " ;

MILL_BEGIN[TOP] = " (Top MILL Begin)\n " ;
MILL_END[TOP] = " (Top MILL End)\n " ;

// Tool change code.
string TOOL_CHANGE_BEGIN[] = { " " , " " , " " , " " };
string TOOL_CHANGED[] = { " " , " " , " " , " " };
string TOOL_ZERO_BEGIN[] = { " " , " " , " " , " " };
string TOOL_ZERO_END[] = { " " , " " , " " , " " };
string TOOL_CHANGE_END[] = { " " , " " , " " , " " };

TOOL_CHANGE_BEGIN[ALL] = " (Tool Change Begin)\n " ;
TOOL_CHANGED[ALL] = " (Tool changed)\n " ;
TOOL_ZERO_BEGIN[ALL] = " (Tool zero begin)\n " ;
TOOL_ZERO_END[ALL] = " (Tool zero end)\n " ;
TOOL_CHANGE_END[ALL] = " (Tool Change End)\n " ;

TOOL_CHANGE_BEGIN[BOTTOM] = " (Bottom Tool Change Begin)\n " ;
TOOL_CHANGED[BOTTOM] = " (Bottom Tool changed)\n " ;
TOOL_ZERO_BEGIN[BOTTOM] = " (Bottom Tool zero begin)\n " ;
TOOL_ZERO_END[BOTTOM] = " (Bottom Tool zero end)\n " ;
TOOL_CHANGE_END[BOTTOM] = " (Bottom Tool Change End)\n " ;

TOOL_CHANGE_BEGIN[TOP] = " (Top Tool Change Begin)\n " ;
TOOL_CHANGED[TOP] = " (Top Tool changed)\n " ;
TOOL_ZERO_BEGIN[TOP] = " (Top Tool zero begin)\n " ;
TOOL_ZERO_END[TOP] = " (Top Tool zero end)\n " ;
TOOL_CHANGE_END[TOP] = " (Top Tool Changed End)\n " ;

//
// An example of using more than one line of gcode.
// Note that only the last line has a ; at the end.
//
string THIS_ISNT_USED[] = { " " , " " , " " , " " }; // Don't change lines like this
THIS_ISNT_USED[BOTTOM] = " G20\n "
" G90\n "
" G01 Z0\n "
" G00 X0 Y0\n "
" M06 T2 ; 0.060\n "
" G04 P5\n " ;

/*
* The functions below should make it easier for folks outputing their own code, etc.
*
*/

/*
* Called after the gcode file has been opened.
* Mode can be
* " wt " (write a text file) when the file is first opened.
* " at " (append a text file) if the file is added to.
*
* You might want to check g_side to see which " side " you are working on.
* g_side can be TOP, BOTTOM or MILL.
*
*/
void user_file_opened(string name, string mode)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* Just before the gcode file is closed.
*
*/
void user_file_closing()
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* Just after the gcode file is closed.
* See user_file_opened for information on the mode parameter.
*
*/
void user_file_closed(string name, string mode)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* The beginning of the outline of a track.
*
*/
void user_track_begin(real start_x, real start_y, real end_x, real end_y)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* An intermediate point on the outline of a track.
*
*/
int user_coord_cnt;
void user_track_continue(real start_x, real start_y, real end_x, real end_y)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* The end of the outline of a track.
*
*/
void user_track_end(real start_x, real start_y, real end_x, real end_y)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* The beginning of an arc.
*
*/
void user_arc_begin(real start_x, real start_y, real end_x, real end_y)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}

/*
* The end of an arc.
*
*/
void user_arc_end(real start_x, real start_y, real end_x, real end_y)
{
if (USER_GCODE == NO) {
return;
}

// your code here
}


pcb-gcode-3.6.0.4.zip > pcb-gcode-options.h

//
// General Options // Your edits to this file will be overwritten by the setup program.
//
int SHOW_PROGRESS = NO;
string RESTORE_MENU_FILE = " pcb-gcode-menu.scr " ;
int NC_FILE_COMMENT_FROM_BOARD = YES;
int NC_FILE_COMMENT_DATE = YES;
int NC_FILE_COMMENT_MACHINE_SETTINGS = YES;
int NC_FILE_COMMENT_PCB_DEFAULTS_SETTINGS = YES;
int USER_GCODE = NO;
int g_debug_flag = YES;
int COMPACT_GCODE = NO;
int USE_LINE_NUMBERS = NO;
string LINE_NUMBER_FORMAT = " N%05d " ;
int SHOW_PREVIEW = YES;
string FILENAME_BASE = " $BOARD_PATH/$BOARD_NAME " ;
string FILENAME_TOP_ETCH_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_TOP_DRILL_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_TOP_MILL_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_TOP_TEXT_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_TOP_FILL_FILE = " " ;
string FILENAME_BOT_ETCH_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_BOT_DRILL_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_BOT_MILL_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_BOT_TEXT_FILE = " .$SIDE.$FILE.$EXT " ;
string FILENAME_BOT_FILL_FILE = " " ;
string ETCH_FILE_NAME = " etch " ;
string DRILL_FILE_NAME = " drill " ;
string MILL_FILE_NAME = " mill " ;
string TEXT_FILE_NAME = " text " ;
string TOP_FILE_NAME = " top " ;
string BOT_FILE_NAME = " bot " ;
string DEFAULT_EXTENSION = " tap " ;
string DEFAULT_DRILL_FILE = " " ;


pcb-gcode-3.6.0.4.zip > gcode-defaults.h

//
// Options for pcb-gcode.ulp.
// Often used options are at the top of the file.
// Copied to gcode-defaults.h by the setup program.

//
// author=John Johnson
// description=Mach3 - EMC for Windows
//

int FILENAMES_8_CHARACTERS = NO;

//
// Comments.
//
string COMMENT_BEGIN = " ( " ;
string COMMENT_END = " ) " ;

//
// Format strings for coordinates, etc.
//
string EOL = " \n " ; /* standard line ending */
string PARAM = " P " ; /* some use P, some # for parameters */
string FORMAT = " %-7.4f " ; /* coordinate format */
string FR_FORMAT = " F%-5.0f " ; /* feedrate format */
string IJ_FORMAT = " I " + FORMAT + " J " + FORMAT;

//
// Modes
//
string INCH_MODE = " G20 " + EOL;
string INCH_MODE_COMMENT = COMMENT_BEGIN + " Inch Mode " + COMMENT_END + EOL;
string METRIC_MODE = " G21 " + EOL;
string METRIC_MODE_COMMENT = COMMENT_BEGIN + " Metric Mode " + COMMENT_END + EOL;
string MIL_MODE = " M02 (Please setup MIL_MODE in gcode-defaults.h) " + EOL;
string MICRON_MODE = " M02 (Please setup MICRON_MODE in gcode-defaults.h) " + EOL;
string ABSOLUTE_MODE = COMMENT_BEGIN + " Absolute Coordinates " + COMMENT_END + EOL + " G90 " + EOL;

//
// G codes
//
string RAPID = " G00 " ;
string FEED = " G01 " ;
string ARC_CW = " G02 " ;
string ARC_CCW = " G03 " ;
string DWELL = " G04 " + PARAM + " %f " + EOL;

//
// M codes
//
string SPINDLE_ON = " M03 " + EOL + DWELL;
string SPINDLE_OFF = " M05 " + EOL;
string END_PROGRAM = " M02 " + EOL;
string OPERATOR_PAUSE = " M06 " ;

//
// Coordinates
//
string MOVE_X = " X " + FORMAT;
string MOVE_Y = " Y " + FORMAT;
string MOVE_XY = " X " + FORMAT + " Y " + FORMAT;
string MOVE_Z = " Z " + FORMAT;
string MOVE_XYZ = MOVE_XY + MOVE_Z;

//
// Rapids
//
string RAPID_MOVE_X = RAPID + MOVE_X;
string RAPID_MOVE_Y = RAPID + MOVE_Y;
string RAPID_MOVE_XY = RAPID + MOVE_XY;
string RAPID_MOVE_XY_HOME = RAPID + " X0 Y0 " ;
string RAPID_MOVE_Z = RAPID + MOVE_Z;
string RAPID_MOVE_XYZ = RAPID + MOVE_XYZ;

//
// Feeds
//
string FEED_MOVE_X = FEED + MOVE_X;
string FEED_MOVE_Y = FEED + MOVE_Y;
string FEED_MOVE_XY = FEED + MOVE_XY;
string FEED_MOVE_XY_WITH_RATE = FEED + MOVE_XY + FR_FORMAT;
string FEED_MOVE_Z = FEED + MOVE_Z;
string FEED_MOVE_Z_WITH_RATE = FEED + MOVE_Z + FR_FORMAT;
string FEED_MOVE_XYZ = FEED + MOVE_XYZ;

//
// Drilling holes
//
// G82 Xx.xxx Yy.yyy Z.zzz Fff.f Rr.rrr #dwell
//
string DRILL_CODE = " G82 " ;
string RELEASE_PLANE = " R " + FORMAT;
string DWELL_TIME = PARAM + " %f " ;
string DRILL_FIRST_HOLE = DRILL_CODE + MOVE_XYZ + FR_FORMAT + RELEASE_PLANE + DWELL_TIME + EOL;
string DRILL_HOLE = DRILL_CODE + MOVE_XY + EOL;

//
// Tool change
//
string TOOL_CODE = " T%02d " ;
string TOOL_MM_FORMAT = " %1.3fmm " ;
string TOOL_INCH_FORMAT = " %1.4fin " ;
string TOOL_CHANGE = OPERATOR_PAUSE + TOOL_CODE + " ; " + FORMAT + EOL;

string TOOL_CHANGE_TABLE_HEADER = COMMENT_BEGIN +
" Tool| Size | Min Sub | Max Sub | Count " + COMMENT_END + EOL;

string TOOL_CHANGE_TABLE_FORMAT(int tool_number, real size_mm, real size_inch, real min_drill, real max_drill, int count)
{
string formatted;

sprintf(formatted, COMMENT_BEGIN + " " +
TOOL_CODE + " | " + TOOL_MM_FORMAT + " " +
TOOL_INCH_FORMAT + " | " + TOOL_INCH_FORMAT + " | " +
TOOL_INCH_FORMAT + " | " +
" %4d " + " " +
COMMENT_END + EOL,
tool_number, size_mm, size_inch, min_drill, max_drill, count);
return(formatted);
}

//
// Circles / Arcs
//
string CIRCLE_TOP = ARC_CW + MOVE_XY + IJ_FORMAT + EOL;
string CIRCLE_BOTTOM = ARC_CCW + MOVE_XY + IJ_FORMAT + EOL;


pcb-gcode-3.6.0.4.zip > pcb-defaults.h

//
// Default values for generating gcode from a PCB.
//
// These settings were last changed with pcb-gcode-setup: 12/28/12 11:21 PM
//
//
// Changes you make in this file will be overwritten if you use pcb-gcode-setup.
//

int SINGLE_PASS = NO;
real ISO_MIN = 0.001000;
real ISO_MAX = 0.020000;
real ISO_STEP = 0.005000;

int GENERATE_TOP_OUTLINES = NO;
int GENERATE_TOP_DRILL = NO;
int GENERATE_TOP_FILL = NO;

int GENERATE_BOTTOM_OUTLINES = YES;
int GENERATE_BOTTOM_DRILL = YES;
int GENERATE_BOTTOM_FILL = NO;
int MIRROR_BOTTOM = NO;
int SIMPLE_DRILL_CODE = NO;

int GENERATE_MILLING = NO;

int GENERATE_TEXT = NO;

int SPOT_DRILL = YES;
real SPOT_DRILL_DEPTH = -0.011000;

int DO_TOOL_CHANGE_WITH_ZERO_STEP = YES;

int FLIP_BOARD_IN_Y = NO;

//int OUTPUT_UNITS = U_MICRONS;
//int OUTPUT_UNITS = U_MILLIMETERS;
//int OUTPUT_UNITS = U_MILS;
int OUTPUT_UNITS = U_INCHES;


pcb-gcode-3.6.0.4.zip > optimize_me.txt

# board=.../examples/04151_lcdi2c.bot.text.tap
# tool size=0.005000
# pass=1
-2.58002, 0.14068,-2.67009, 0.14068
-2.67009, 0.14068,-2.69261, 0.16319
-2.69261, 0.16319,-2.69261, 0.20823
-2.69261, 0.20823,-2.67009, 0.23075
-2.67009, 0.23075,-2.58002, 0.23075
-2.58002, 0.23075,-2.55750, 0.20823
-2.55750, 0.20823,-2.55750, 0.16319
-2.55750, 0.16319,-2.58002, 0.14068
-2.58002, 0.14068,-2.67009, 0.23075
-2.55750, 0.34635,-2.69261, 0.34635
-2.69261, 0.34635,-2.62506, 0.27879
-2.62506, 0.27879,-2.62506, 0.36887
-2.64757, 0.41691,-2.69261, 0.46194
-2.69261, 0.46194,-2.55750, 0.46194
-2.55750, 0.41691,-2.55750, 0.50698
-2.69261, 0.64509,-2.69261, 0.55502
-2.69261, 0.55502,-2.62506, 0.55502
-2.62506, 0.55502,-2.64757, 0.60006
-2.64757, 0.60006,-2.64757, 0.62257
-2.64757, 0.62257,-2.62506, 0.64509
-2.62506, 0.64509,-2.58002, 0.64509
-2.58002, 0.64509,-2.55750, 0.62257
-2.55750, 0.62257,-2.55750, 0.57754
-2.55750, 0.57754,-2.58002, 0.55502
-2.64757, 0.69313,-2.69261, 0.73817
-2.69261, 0.73817,-2.55750, 0.73817
-2.55750, 0.69313,-2.55750, 0.78321
-2.55750, 0.96936,-2.64757, 0.96936
-2.64757, 0.96936,-2.69261, 1.01440
-2.69261, 1.01440,-2.64757, 1.05944
-2.64757, 1.05944,-2.55750, 1.05944
-2.62506, 0.96936,-2.62506, 1.05944