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

Revision:
2:b3c668ec43ac
Parent:
1:66ee619f206b
Child:
3:7aaf0072cc22
--- a/command_interpreter.cpp	Thu Feb 06 08:45:02 2014 +0000
+++ b/command_interpreter.cpp	Thu Feb 20 09:27:18 2014 +0000
@@ -1,17 +1,21 @@
 #include "mbed.h"
 #include "rtos.h"
+#include "MODSERIAL.h"
 #include "cnc.h"
 using namespace std;
 
-extern  Serial pc;
-extern  bool    liss_active;
-extern  unsigned long pir_s;
-extern  int spindlefwdrev;
+extern  MODSERIAL pc;
+//extern  Serial pc;
+//extern  bool    liss_active;
 extern  struct  Gparams    last_position;
-extern  int PutMoveOnList   (struct pirbufgrain & s)    ;
-extern  struct  digital_readouts    dro;    //
+extern  void    move_to_XYZ   (struct pirbufgrain & ins)   ;
+//extern  struct  digital_readouts    dro;    //
+//extern  void    scmd (struct singleGparam * a)   ;
+extern  void    flags_report_cmd (struct singleGparam * a)   ;
+extern  void    report_inputs   ()  ;
 
-double  feed_rate = 1.0;  //  global scope, mm per minute. DEFAULTS to 1.0mm per min, very slow.
+double  feed_rate = 1.0,  //  global scope, mm per minute. DEFAULTS to 1.0mm per min, very slow.
+        spindle_rpm = 0.0;  //  global scope
 
 bool    isdigit (int a)
 {
@@ -122,29 +126,6 @@
     }
 }
 
-const   double  duration_multiplier =   60000000.0 /  interrupt_period_us;
-
-void    mover   (struct pirbufgrain & ins)   {
-    struct  pirbufgrain outs;
-    double  distx   = ins.x - last_position.x.dbl,
-            disty   = ins.y - last_position.y.dbl,
-            distz   = ins.z - last_position.z.dbl,
-            distT   = sqrt ((distx * distx) + (disty * disty) + (distz * distz)), // 3D Pythag !
-            temp    = n_for_onemmpermin / distT;
-    if  (distT < 0.01)  {
-        pc.printf("Very small move %.4f, Ignoring!\r\n", distT);
-        return;
-    }
-    last_position.x.dbl   = ins.x;     //  Update global last_position record
-    last_position.y.dbl   = ins.y;
-    last_position.z.dbl   = ins.z;
-    outs.f_rate = ins.f_rate;
-    outs.c  = duration_multiplier * distT;   //  Duration ticks subject to feed rate compo
-    outs.x = temp * distx;
-    outs.y = temp * disty;
-    outs.z = temp * distz;  //  Have assembled data ready to put onto queue of move instructions
-    PutMoveOnList   (outs);
-}
 
 void    g2g3cmdcore (struct singleGparam * source_array, int twoorthree) {
     struct  Gparams tmp;
@@ -222,6 +203,8 @@
                 next_point.z += z_step; 
                 pc.printf("X %.3f, Y %.3f\r\n", next_point.x, next_point.y);
                 Thread::wait(300);
+                next_point.f_rate = feed_rate;
+                move_to_XYZ (next_point);
             }
         break;  //  end of case    2:  //  Centre format arc ** OFFSETS ARE RELATIVE ** Abs coordinates not catered for
         default:    //  Input error detected
@@ -232,8 +215,7 @@
 
 void    g0g1cmdcore (struct singleGparam * source_array, double f_rate)    //  Updates any / all of x, y, z NCOs
 {   //  Only get here when some G0 or G1 input has been read.  G0 or G1 determined by f_rate
-    struct  pirbufgrain ins, outs;
-    double  distx, disty, distz;//, outx, outy, outz, outtimefactor;
+    struct  pirbufgrain ins;//, outs;
     struct  Gparams tmp;
     get_codepositions   (source_array, tmp);  //  will overwrite with new where entered
     if  (!tmp.x.changed && !tmp.y.changed && !tmp.z.changed)    {
@@ -244,41 +226,7 @@
     ins.y  = tmp.y.dbl;
     ins.z  = tmp.z.dbl;
     ins.f_rate = f_rate;
-    distx  = ins.x - last_position.x.dbl;     //  All doubles
-    disty  = ins.y - last_position.y.dbl;
-    distz  = ins.z - last_position.z.dbl;
-    double  distT = sqrt ((distx * distx) + (disty * disty) + (distz * distz));
-    if  (distT < 0.01)  {
-        pc.printf("Very small move %.4f, Ignoring!\r\n", distT);
-        return;
-    }
-    if  (f_rate > feed_rate_max)   {
-        pc.printf("WARNING Stupid feed rate in G0/G1 of %f, setting to %f\r\n", f_rate, feed_rate_max);
-        f_rate = feed_rate_max;
-    }
-    if  (f_rate < 0.0)  {
-        pc.printf("Bonkers neg feed rate %f, setting to 0");
-        f_rate = 0.0;
-    }
-    double  temp    = n_for_onemmpermin / distT;
-//    pc.printf("\nG0--G1 Moving to  X %4.4f, Y %4.4f, Z%4.4f, distT %f\r\n", px, py, pz, distT);
-//    pc.printf("Moving From pos'n X %4.4f, Y %4.4f, Z%4.4f\r\n", last_position.x.dbl, last_position.y.dbl, last_position.z.dbl);
-//    pc.printf("Distances to move X %4.4f, Y %4.4f, Z%4.4f\r\n", distx, disty, distz);
-//    pc.printf("mm per sec req'd  X %4.4f, Y %4.4f, Z%4.4f\r\n", xmmps, ymmps, zmmps);
-    pc.printf("Total move distance %4.4f, at feed rate %.2f, run time SECs = %f\r\n", distT, f_rate, 60.0 * distT / f_rate);
-//    pc.printf("This time maps to %f interrupt ticks\r\n", run_secs * 1000000.0 / interrupt_period_us);
-    last_position.x.dbl   = ins.x;     //  Update global last_position record
-    last_position.y.dbl   = ins.y;
-    last_position.z.dbl   = ins.z;
-    outs.f_rate = ins.f_rate;
-    outs.c  = duration_multiplier * distT;   //  Duration ticks subject to feed rate compo
-    outs.x = temp * distx;
-    outs.y = temp * disty;
-    outs.z = temp * distz;
-//    pc.printf("Dists Scaled for angle, X%f, Y%f, Z%f\r\n", outs.x, outs.y, outs.z);
-//    pc.printf("Last position X%f, Y%f, Z%f\r\n", last_position.x.dbl, last_position.y.dbl, last_position.z.dbl);
-//    outs.a.dbl = 0.0;     // not used axis
-    PutMoveOnList (outs);
+    move_to_XYZ (ins);
 }
 
 void    g0cmd (struct singleGparam * a)    //  Updates any / all of x, y, z NCOs
@@ -291,36 +239,59 @@
     g0g1cmdcore (a, feed_rate);     //  Settable feed_rate
 }
 
+void    g2cmd (struct singleGparam * a)   { //  Clockwise arc
+    g2g3cmdcore (a, 2);
+}
+
+void    g3cmd (struct singleGparam * a)   { //  Counter clockwise arc
+    g2g3cmdcore (a, 3);
+}
+
 void    fcmd (struct singleGparam * a)   {  //  Set Feed Rate command
     if  (a[1].dbl < 0.0)    {
-        pc.printf("feed rate %f ? Setting to 0\r\n", a[1].dbl);
+        pc.printf("feed rate %.1f ? Setting to 0\r\n", a[1].dbl);
         a[1].dbl = 0.0;
     }
     if  (a[1].dbl > feed_rate_max)    {
-        pc.printf   ("Error, can't set feed rate to %f, max is %f, ", a[1].dbl, feed_rate_max);
+        pc.printf   ("Error, can't set feed rate to %.1f, max is %.1f, ", a[1].dbl, feed_rate_max);
         a[1].dbl = feed_rate_max;
     }
-    pc.printf   ("Setting feed_rate to %f\r\n", a[1].dbl);
+    pc.printf   ("Setting feed_rate to %.1f\r\n", a[1].dbl);
     feed_rate = a[1].dbl;
 }
+extern  void    spindle_control (double ss)  ;
+extern  bool    spindle_running ()  ;
 
-void    sfcmd (struct singleGparam * a)   {pc.printf("Spindle Fwd\r\n"); spindlefwdrev = 0;}
-void    srcmd (struct singleGparam * a)   {pc.printf("Spindle Rev\r\n"); spindlefwdrev = 4;}
-void    stopcmd (struct singleGparam * a)   {pc.printf("Stop ! er, not working yet\r\n");}
+void    M3cmd (struct singleGparam * a)   { spindle_control (spindle_rpm);  }
+void    M5cmd (struct singleGparam * a)   { spindle_control (0.0);  }
 
 void    scmd (struct singleGparam * a)   {
-    pc.printf("pir_s=0x%x\r\n", pir_s);
-    if  (a[1].dbl < 0.0 || a[1].dbl > spindle_max)    {
-        pc.printf   ("Errror setting spindle RPM, can't set to %f, ignoring request\r\n", a[1].dbl);
-//        return;
+    if  (fabs(a[1].dbl) > spindle_max)    {
+        pc.printf   ("Errror setting spindle RPM, can't set to %.0f, ignoring request\r\n", a[1].dbl);
+        return;
     }
-    pc.printf   ("Setting spindle RPM to %f\r\n", a[1].dbl);
-//    feed_rate = a[1].d;   //  ****TO DO****
-    pir_s = (unsigned long) (a[1].dbl * 4096);
-    pc.printf("pir_s=0x%x\r\n", pir_s);
+    pc.printf   ("Setting spindle RPM to %.0f Can set Pos or Neg for fwd/rev\r\n", a[1].dbl);
+    spindle_rpm = a[1].dbl;
+    if  (spindle_running())
+        spindle_control (spindle_rpm);
+/*
+
+    pir_spin = (signed long) (a[1].dbl * spindle_factor);
+    t = ticks;
+    while   (t == ticks)    {}  //  wait until just after next interrupt
+    p = mysteppers;
+    if  (pir_spin & 0x80000000)
+        p |= SDi;
+    else
+        p &= ~SDi;
+    mysteppers = p;
+*/
+
 }
 
-//void    stopcmd (struct grain * a)   {pc.printf("Stop !\r\n");}
+extern  void    target_cmd (struct singleGparam * a)   ;
+
+void    stopcmd (struct singleGparam * a)   {pc.printf("Stop ! er, not working yet\r\n");}
 void    m1cmd (struct singleGparam * a)   {pc.printf("m1 Optional Programme Stop\r\n");}
 void    m3cmd (struct singleGparam * a)   {pc.printf("m3 Rotate Spindle Clockwise\r\n");}
 void    m4cmd (struct singleGparam * a)   {pc.printf("m4 Rotate Spindle Counter Clockwise\r\n");}
@@ -341,16 +312,14 @@
 void    g53cmd (struct singleGparam * a)   {pc.printf("g53 Move in Absolute Coordinates\r\n");}
 void    g90cmd (struct singleGparam * a)   {pc.printf("g90 Absolute Distance Mode\r\n");}
 */
-void    g2cmd (struct singleGparam * a)   { //  Clockwise arc
-    g2g3cmdcore (a, 2);
-    }
-void    g3cmd (struct singleGparam * a)   { //  Counter clockwise arc
-    g2g3cmdcore (a, 3);
-    }
-void    g4cmd (struct singleGparam * a)   {pc.printf("g4 Dwell\r\n");}
-void    g91p1cmd (struct singleGparam * a)   {pc.printf("g91.1 \r\n");}
+//void    g4cmd (struct singleGparam * a)   {pc.printf("g4 Dwell\r\n");}
+//void    g91p1cmd (struct singleGparam * a)   {pc.printf("g91.1 \r\n");}
 
-void    tasktstone    (void const * name)
+//void    report_inputs   ()  {
+void    report_ins_cmd  (struct singleGparam * a)  {
+   report_inputs();
+}
+/*void    tasktstone    (void const * name)
 {
     static int i = 0;
     pc.printf("Arrived at tasktstone\r\n");
@@ -359,7 +328,7 @@
         Thread::wait(9500);
         osThreadYield();
     }
-}
+}*/
 
 /*void    tasktestcmd (struct singleGparam * a)   {
     pc.printf("At tasktestcmd\r\n");
@@ -367,16 +336,19 @@
     pc.printf("Leaving tasktestcmd\r\n");
 }
 */
+extern  void    lissajous   (double)  ;
+
 void    lisscmd (struct singleGparam * a)   {
-    if(liss_active) {
+    lissajous   (feed_rate);
+/*    if(liss_active) {
         pc.printf("Can not add Lissajous, already running.\r\n");
     }
     else    {
         pc.printf("Adding Lissajous task\r\n");
         liss_active = true;
-    }
+    }*/
 }
-
+/*
 void    drooncmd    (struct singleGparam * a)
 {
     dro.dro_output = true;     //  Enable continuous dro display update
@@ -385,9 +357,9 @@
 {
     dro.dro_output = false;    //  Disable continuous dro display update
 }
-
+*/
 
-void    g90p1cmd (struct singleGparam * a)
+/*void    g90p1cmd (struct singleGparam * a)
 {
     pc.printf   ("Arrived at function fredcmd with %d parameters\r\n", a[0].i);
     for (int i = 1; i <= a[0].i; i++)   {
@@ -397,7 +369,7 @@
     }
     pc.printf   (" endof param list\r\n");
 }
-
+*/
 void    menucmd (struct singleGparam * a);
 struct kb_command  {
     const char * cmd_word;         //  points to text e.g. "menu"
@@ -416,10 +388,10 @@
     {"menu", "Lists available commands, same as ls", menucmd},
     {"ls", "Lists available commands, same as menu", menucmd},
     {"stop", "To Stop the Machine !", stopcmd},
-    {"sf", "Spindle Clockwise", sfcmd},
-    {"sr", "Spindle Anticlockwise", srcmd},
     {"f ", "To set Feed Rate mm/min, e.g. f 25", fcmd},
     {"s ", "To set Spindle RPM, e.g. S 1250", scmd},
+    {"m3", "Start Spindle at last 'S'", M3cmd},
+    {"m5", "Stop Spindle", M5cmd},
     {"g0", "Rapid move", g0cmd},
     /*{"m30", "Not Implemented", m30cmd},
     {"m47", "Not Implemented", m47cmd},
@@ -444,10 +416,13 @@
     {"g1", "Linear Interpolation - move straight at current feed rate", g1cmd},
     {"g2", "Helical Interpolation CW (Arc, circle)", g2cmd},
     {"g3", "Helical Interpolation CCW (Arc, circle)", g3cmd},
-    {"liss", "Add Lissajous pattern generator", lisscmd},
+    {"liss", "Run Lissajous pattern generator", lisscmd},
+    {"flags", "Report System Flags", flags_report_cmd},
+    {"inputs", "Report State of Input bits", report_ins_cmd},
+    {"target", "Identify computer device", target_cmd},
 //    {"ttest", "Add a task to prove we can, or not", tasktestcmd},
-    {"dro on", "Turn dro readout on", drooncmd},
-    {"dro off", "Turn dro readout off", drooffcmd}
+//    {"dro on", "Turn dro readout on", drooncmd},
+//    {"dro off", "Turn dro readout off", drooffcmd}
 };
 //const    int numof_menu_items = sizeof(kbc2) / sizeof(kb_command);
 //const    int numof_menu_items_sc = sizeof(input_syntax_check) / sizeof(kb_command);
@@ -468,6 +443,40 @@
     return  false;
 }
 
+void    nudger  (int code)  {
+    //  Using <Ctrl>+ 'F', 'B' for Y, 'L', 'R' for X, 'U', 'D' for Z
+    //                 6    2          12   18         21   4
+//    struct  Gparams dest;
+    struct  pirbufgrain dest;
+    dest.x = last_position.x.dbl;
+    dest.y = last_position.y.dbl;
+    dest.z = last_position.z.dbl;
+    dest.f_rate = feed_rate;
+    switch  (code)  {
+        case    6:  //  'F' move -Y
+        dest.y -= 0.1;
+        break;
+        case    2:  //  'B' move +Y
+        dest.y += 0.1;
+        break;
+        case    12: //  'L' move +X
+        dest.x += 0.1;
+        break;
+        case    18: //  'R' move -X
+        dest.x -= 0.1;
+        break;
+        case    21: //  'U' move +Z
+        dest.z += 0.1;
+        break;
+        case    4:  //  'D' move -Z
+        dest.z -= 0.1;
+        default:
+        break;
+//            pc.printf("Nuffink to do in nudger\r\n");
+    }   //  end of switch
+    move_to_XYZ (dest);
+}
+
 ////class CLI {
 
 /*
@@ -481,7 +490,7 @@
 static  char    cmd_line[MAX_CMD_LEN + 4];
 static  struct  singleGparam   params[MAX_PARAMS + 1];
 static  int     cl_index = 0, lastalpha = 0;
-    pc.printf("Got to cli, Starting cli\r\n");
+//    pc.printf("Got to cli, Starting cli\r\n");
     if  (true)  {
         command_list_ptr = command_execute;
         numof_menu_items = sizeof(command_execute) / sizeof(kb_command);
@@ -498,6 +507,13 @@
                 cl_index = 0;
             }
             ch = tolower(pc.getc());
+            if  (ch == '\r' || ch >= ' ' && ch <= 'z')
+                pc.printf("%c", ch);
+            else    {                   //  Using <Ctrl>+ 'F', 'B' for Y, 'L', 'R' for X, 'U', 'D' for Z
+                cl_index = 0;           //                 6    2          12   18         21   4
+                pc.printf("[%d]", ch);
+                nudger  (ch);
+            }
             if(ch != '\r')  //  was this the 'Enter' key?
                 cmd_line[cl_index++] = ch;  //  added char to command being assembled
             else    {   //  key was CR, may or may not be command to lookup
@@ -587,6 +603,7 @@
                     if(i == numof_menu_items)
                         pc.printf("No Match Found for CMD [%s]\r\n", cmd_line);
                 }           //  End of If have got some chars to lookup
+                pc.printf("\r\n>");
                 cl_index = lastalpha = 0;
             }               // End of else key was CR, may or may not be command to lookup
         }                   //  End of while (pc.readable())