Code to drive a CNC machine via a PC LPT port lookalike 25 pin 'D', experiment in 'PC/Mach3' replacement. Designed to compile and run on mbed LPC1768, Freescale KL25Z and Freescale KL46Z. Proved on LPC1768 and KL25Z, problem with serial port on KL46Z. Reads subset of 'G Codes' through usb/serial port and drives 3 stepper/servo drives for X, Y and Z, also similar Step/Dir outputs for spindle motor control. Emulates PC LPT, outputs 'charge pump', proved driving Seig KX3 CNC mill

Dependencies:   MODSERIAL mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cnc.h Source File

cnc.h

00001 /**
00002 Programme   "cnc__machine_driver_3"
00003 Author      Jon Freeman
00004 
00005 Accepts subset of 'G Code' CNC machine instructions as input from USB serial
00006 Generates 'Step' and 'Direction' signals for X, Y and Z axes, signals suit
00007 standard stepper / servo drive systems.
00008 Also generates similar Step and Dir for spindle
00009 Intended to connect to 25 pin 'D' connector to emulate old PC 'LPT' port
00010 for easy swap with PC/Mach driven CNC systems.
00011 Tested driving Sieg KX3 CNC mill.
00012 
00013 Designed to compile and run on:
00014     Mbed LPC1768
00015     Freescale KL25Z
00016     Freescale KL46Z
00017 */
00018 using namespace std;
00019 
00020 typedef float  fl_typ;  //  
00021 const   signed long
00022                 motor_step_per_rev  =   200,    //  KX3 has 200 step per rev steppers
00023                 micro_steps         =   10,      //  Arc Eurotrade choice 2,4,5,8,10,16,20,25,32,40,50,64,100,125,128
00024                 interrupt_period_us =   25, //32, //24.0, //16 is possible with Mbed LPC1768
00025                 interrupt_freq_Hz   =   1000000 / interrupt_period_us,  //  Serious limit when doing all in software, no real limit with FPGA
00026                 spindle_factor      =   interrupt_period_us * 4280, //  Derived empirically
00027                 spindle_max         =   5000;                       //  Stated in KX3 spec
00028 
00029 const   fl_typ  ball_screw_pitch_mm =   4.0,    //  KX3 has 4mm pitch ball screws
00030                 pulses_per_mm       =   micro_steps * motor_step_per_rev / ball_screw_pitch_mm,
00031                 n_for_onemmpermin   =   pulses_per_mm * interrupt_period_us * pow(2.0,31) / 60000000.0; //  n pir to produce 1mm/min travel
00032 
00033 const   signed long
00034                 max_pulse_freq_Hz   =   interrupt_freq_Hz * 4 / 13, // / 3.25,  //  strictly 2.0, but allow a good margin
00035                 feed_rate_max       =   60 * max_pulse_freq_Hz / pulses_per_mm;   //  units mm per minute
00036 //The output frequency F<sub>out</sub> = 'Kernel Speed (Hz)' * n / (2 to the power of 32)
00037     
00038 //#define Fourth_Axis
00039 //#define SPI_Enable
00040 #define I2C_Enable
00041 #define ESTOP   0x100   //  bits used in input reading KX3 limit and EStop switches
00042 #define XLIM    1
00043 #define YLIM    2
00044 #define ZLIM    4
00045 #define UNKN    8
00046 
00047 const   fl_typ  TWO_PI = 8.0 * atan(1.0);
00048 const   fl_typ  epsilon = 1e-5;
00049 struct  pirbufgrain {
00050     fl_typ  x,
00051             y,
00052             z,
00053             distance_code,
00054             f_rate;
00055     }   ;
00056 
00057 struct  singleGparam    {   //  Place to put all we know about 'x' or 'j' etc parameter from G Code line
00058     fl_typ          flt;
00059     unsigned long   ul;
00060     int         i,  c;
00061     bool            changed;      // Flagged true when new value for this axis found in Gcode line, false otherwise 
00062 }   ;
00063 
00064 struct  Gparams {  //  Where possibly messy G code line gets ordered and sorted into
00065     struct  singleGparam   x, y, z, i, j, r, a, b, c, d;   //  After sorting, know where to find any X, Y etc values !
00066 }   ;
00067