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



File content as of revision 3:7aaf0072cc22:

Programme   "cnc__machine_driver_3"
Author      Jon Freeman

Accepts subset of 'G Code' CNC machine instructions as input from USB serial
Generates 'Step' and 'Direction' signals for X, Y and Z axes, signals suit
standard stepper / servo drive systems.
Also generates similar Step and Dir for spindle
Intended to connect to 25 pin 'D' connector to emulate old PC 'LPT' port
for easy swap with PC/Mach driven CNC systems.
Tested driving Sieg KX3 CNC mill.

Designed to compile and run on:
    Mbed LPC1768
    Freescale KL25Z
    Freescale KL46Z
using namespace std;

typedef float  fl_typ;  //  
const   signed long
                motor_step_per_rev  =   200,    //  KX3 has 200 step per rev steppers
                micro_steps         =   10,      //  Arc Eurotrade choice 2,4,5,8,10,16,20,25,32,40,50,64,100,125,128
                interrupt_period_us =   25, //32, //24.0, //16 is possible with Mbed LPC1768
                interrupt_freq_Hz   =   1000000 / interrupt_period_us,  //  Serious limit when doing all in software, no real limit with FPGA
                spindle_factor      =   interrupt_period_us * 4280, //  Derived empirically
                spindle_max         =   5000;                       //  Stated in KX3 spec

const   fl_typ  ball_screw_pitch_mm =   4.0,    //  KX3 has 4mm pitch ball screws
                pulses_per_mm       =   micro_steps * motor_step_per_rev / ball_screw_pitch_mm,
                n_for_onemmpermin   =   pulses_per_mm * interrupt_period_us * pow(2.0,31) / 60000000.0; //  n pir to produce 1mm/min travel

const   signed long
                max_pulse_freq_Hz   =   interrupt_freq_Hz * 4 / 13, // / 3.25,  //  strictly 2.0, but allow a good margin
                feed_rate_max       =   60 * max_pulse_freq_Hz / pulses_per_mm;   //  units mm per minute
//The output frequency F<sub>out</sub> = 'Kernel Speed (Hz)' * n / (2 to the power of 32)
//#define Fourth_Axis
//#define SPI_Enable
#define I2C_Enable
#define ESTOP   0x100   //  bits used in input reading KX3 limit and EStop switches
#define XLIM    1
#define YLIM    2
#define ZLIM    4
#define UNKN    8

const   fl_typ  TWO_PI = 8.0 * atan(1.0);
const   fl_typ  epsilon = 1e-5;
struct  pirbufgrain {
    fl_typ  x,
    }   ;

struct  singleGparam    {   //  Place to put all we know about 'x' or 'j' etc parameter from G Code line
    fl_typ          flt;
    unsigned long   ul;
    int         i,  c;
    bool            changed;      // Flagged true when new value for this axis found in Gcode line, false otherwise 
}   ;

struct  Gparams {  //  Where possibly messy G code line gets ordered and sorted into
    struct  singleGparam   x, y, z, i, j, r, a, b, c, d;   //  After sorting, know where to find any X, Y etc values !
}   ;