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
command_interpreter.cpp@0:5d0f270bfc87, 2014-01-31 (annotated)
- Committer:
- JonFreeman
- Date:
- Fri Jan 31 11:16:21 2014 +0000
- Revision:
- 0:5d0f270bfc87
- Child:
- 1:66ee619f206b
First wip, tested on KL25 and KL46
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JonFreeman | 0:5d0f270bfc87 | 1 | #include "mbed.h" |
JonFreeman | 0:5d0f270bfc87 | 2 | #include "cnc.h" |
JonFreeman | 0:5d0f270bfc87 | 3 | using namespace std; |
JonFreeman | 0:5d0f270bfc87 | 4 | |
JonFreeman | 0:5d0f270bfc87 | 5 | extern Serial pc; |
JonFreeman | 0:5d0f270bfc87 | 6 | extern void pir_updater (struct axis_speeds_element * p) ; // Uses pointer as we may wish to rapid update from circular buffer |
JonFreeman | 0:5d0f270bfc87 | 7 | |
JonFreeman | 0:5d0f270bfc87 | 8 | double feed_rate = 1.0; // global scope, mm per minute |
JonFreeman | 0:5d0f270bfc87 | 9 | |
JonFreeman | 0:5d0f270bfc87 | 10 | bool isdigit (int a) |
JonFreeman | 0:5d0f270bfc87 | 11 | { |
JonFreeman | 0:5d0f270bfc87 | 12 | if(a > ('0' - 1) && a < ('9' + 1)) |
JonFreeman | 0:5d0f270bfc87 | 13 | return true; |
JonFreeman | 0:5d0f270bfc87 | 14 | return false; |
JonFreeman | 0:5d0f270bfc87 | 15 | } |
JonFreeman | 0:5d0f270bfc87 | 16 | |
JonFreeman | 0:5d0f270bfc87 | 17 | bool isupper (int a) |
JonFreeman | 0:5d0f270bfc87 | 18 | { |
JonFreeman | 0:5d0f270bfc87 | 19 | if ((a >= 'A') && (a <= 'Z')) return true; |
JonFreeman | 0:5d0f270bfc87 | 20 | return false; |
JonFreeman | 0:5d0f270bfc87 | 21 | } |
JonFreeman | 0:5d0f270bfc87 | 22 | |
JonFreeman | 0:5d0f270bfc87 | 23 | int tolower (int a) |
JonFreeman | 0:5d0f270bfc87 | 24 | { |
JonFreeman | 0:5d0f270bfc87 | 25 | if (isupper(a)) |
JonFreeman | 0:5d0f270bfc87 | 26 | a += 'a' - 'A'; |
JonFreeman | 0:5d0f270bfc87 | 27 | return a; |
JonFreeman | 0:5d0f270bfc87 | 28 | } |
JonFreeman | 0:5d0f270bfc87 | 29 | |
JonFreeman | 0:5d0f270bfc87 | 30 | extern double find_distance (struct Gparams & from, struct Gparams & to, struct Gparams & distance); |
JonFreeman | 0:5d0f270bfc87 | 31 | extern long find_traverse_ticks(double dist, double feed_rate); |
JonFreeman | 0:5d0f270bfc87 | 32 | extern struct Gparams last_position; |
JonFreeman | 0:5d0f270bfc87 | 33 | |
JonFreeman | 0:5d0f270bfc87 | 34 | const int goodcodes[] = {0,'a','b','c','i','j','l','r','x','y','z'}; // possible G Code options |
JonFreeman | 0:5d0f270bfc87 | 35 | const int const_numofcodes = sizeof(goodcodes) / sizeof(int); |
JonFreeman | 0:5d0f270bfc87 | 36 | |
JonFreeman | 0:5d0f270bfc87 | 37 | int find_char_in_goodcodes (int target) // Returns position of char in goodcodes[], 0 if not found. |
JonFreeman | 0:5d0f270bfc87 | 38 | { |
JonFreeman | 0:5d0f270bfc87 | 39 | for (int i = 1; i < const_numofcodes; i++) |
JonFreeman | 0:5d0f270bfc87 | 40 | if (goodcodes[i] == target) |
JonFreeman | 0:5d0f270bfc87 | 41 | return i; |
JonFreeman | 0:5d0f270bfc87 | 42 | return 0; |
JonFreeman | 0:5d0f270bfc87 | 43 | } |
JonFreeman | 0:5d0f270bfc87 | 44 | |
JonFreeman | 0:5d0f270bfc87 | 45 | /* |
JonFreeman | 0:5d0f270bfc87 | 46 | void get_codepositions (struct singleGparam * a, struct Gparams & p) |
JonFreeman | 0:5d0f270bfc87 | 47 | Only call from "void g0g1cmdcore (struct singleGparam * a, double f_rate)" |
JonFreeman | 0:5d0f270bfc87 | 48 | Purpose: |
JonFreeman | 0:5d0f270bfc87 | 49 | G code line may have any number of valid axes or parameters entered in any order or position. |
JonFreeman | 0:5d0f270bfc87 | 50 | This function detects any X,Y,Z,A,I,J,R entries in 'p' if present and copies values into their |
JonFreeman | 0:5d0f270bfc87 | 51 | respective positions within singleGparam 'a', setting the 'changed' flag for each to true if found, |
JonFreeman | 0:5d0f270bfc87 | 52 | false if not found |
JonFreeman | 0:5d0f270bfc87 | 53 | struct Gparams { // Where possibly messy G code line gets ordered and sorted into |
JonFreeman | 0:5d0f270bfc87 | 54 | struct singleGparam x, y, z, i, j, r, a, b, c, d; // After sorting, know where to find any X, Y etc values ! |
JonFreeman | 0:5d0f270bfc87 | 55 | } ; |
JonFreeman | 0:5d0f270bfc87 | 56 | */ |
JonFreeman | 0:5d0f270bfc87 | 57 | void get_codepositions (struct singleGparam * source_array, struct Gparams & dest) |
JonFreeman | 0:5d0f270bfc87 | 58 | { |
JonFreeman | 0:5d0f270bfc87 | 59 | //const int goodcodes[] = {0,'a','b','c','i','j','l','r','x','y','z'}; // possible G Code options |
JonFreeman | 0:5d0f270bfc87 | 60 | //const int const_numofcodes = sizeof(goodcodes) / sizeof(int); |
JonFreeman | 0:5d0f270bfc87 | 61 | int codecnt[const_numofcodes +1]; |
JonFreeman | 0:5d0f270bfc87 | 62 | int codepos[const_numofcodes +1]; |
JonFreeman | 0:5d0f270bfc87 | 63 | int j; |
JonFreeman | 0:5d0f270bfc87 | 64 | for (j = 0; j < const_numofcodes; j++) |
JonFreeman | 0:5d0f270bfc87 | 65 | codecnt[j] = codepos[j] = 0; // Zero all results |
JonFreeman | 0:5d0f270bfc87 | 66 | for (int i = 1; i <= source_array[0].i; i++) { // for number of parameters passed to us here |
JonFreeman | 0:5d0f270bfc87 | 67 | for(j = 0; j < const_numofcodes; j++) { // for a, for b, ... for x, then y, then z |
JonFreeman | 0:5d0f270bfc87 | 68 | if (source_array[i].c == goodcodes[j]) { |
JonFreeman | 0:5d0f270bfc87 | 69 | codecnt[j]++; // Count of number of 'a's, 'b's ... 'x's, 'y's, 'z's. All should be 0 or 1 but could be more |
JonFreeman | 0:5d0f270bfc87 | 70 | codepos[j] = i; // Identifies the a[?] containing last incidence of goodcodes[j] |
JonFreeman | 0:5d0f270bfc87 | 71 | } |
JonFreeman | 0:5d0f270bfc87 | 72 | } |
JonFreeman | 0:5d0f270bfc87 | 73 | } |
JonFreeman | 0:5d0f270bfc87 | 74 | dest.x.changed = dest.y.changed = dest.z.changed = dest.a.changed = false; |
JonFreeman | 0:5d0f270bfc87 | 75 | dest.i.changed = dest.j.changed = dest.r.changed = false; |
JonFreeman | 0:5d0f270bfc87 | 76 | dest.x.dbl = last_position.x.dbl; // copy previous coordinates in case not re-specified |
JonFreeman | 0:5d0f270bfc87 | 77 | dest.y.dbl = last_position.y.dbl; dest.z.dbl = last_position.z.dbl; |
JonFreeman | 0:5d0f270bfc87 | 78 | dest.a.dbl = last_position.a.dbl; dest.i.dbl = last_position.i.dbl; |
JonFreeman | 0:5d0f270bfc87 | 79 | dest.j.dbl = last_position.j.dbl; dest.r.dbl = last_position.r.dbl; |
JonFreeman | 0:5d0f270bfc87 | 80 | j = codepos[find_char_in_goodcodes('a')]; |
JonFreeman | 0:5d0f270bfc87 | 81 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 82 | dest.a.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 83 | dest.a.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 84 | } |
JonFreeman | 0:5d0f270bfc87 | 85 | j = codepos[find_char_in_goodcodes('x')]; |
JonFreeman | 0:5d0f270bfc87 | 86 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 87 | dest.x.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 88 | dest.x.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 89 | } |
JonFreeman | 0:5d0f270bfc87 | 90 | j = codepos[find_char_in_goodcodes('y')]; |
JonFreeman | 0:5d0f270bfc87 | 91 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 92 | dest.y.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 93 | dest.y.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 94 | } |
JonFreeman | 0:5d0f270bfc87 | 95 | j = codepos[find_char_in_goodcodes('z')]; |
JonFreeman | 0:5d0f270bfc87 | 96 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 97 | dest.z.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 98 | dest.z.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 99 | } |
JonFreeman | 0:5d0f270bfc87 | 100 | j = codepos[find_char_in_goodcodes('i')]; |
JonFreeman | 0:5d0f270bfc87 | 101 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 102 | dest.i.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 103 | dest.i.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 104 | } |
JonFreeman | 0:5d0f270bfc87 | 105 | j = codepos[find_char_in_goodcodes('j')]; |
JonFreeman | 0:5d0f270bfc87 | 106 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 107 | dest.j.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 108 | dest.j.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 109 | } |
JonFreeman | 0:5d0f270bfc87 | 110 | j = codepos[find_char_in_goodcodes('r')]; |
JonFreeman | 0:5d0f270bfc87 | 111 | if (j) { |
JonFreeman | 0:5d0f270bfc87 | 112 | dest.r.changed = true; |
JonFreeman | 0:5d0f270bfc87 | 113 | dest.r.dbl = source_array[j].dbl; |
JonFreeman | 0:5d0f270bfc87 | 114 | } |
JonFreeman | 0:5d0f270bfc87 | 115 | } |
JonFreeman | 0:5d0f270bfc87 | 116 | |
JonFreeman | 0:5d0f270bfc87 | 117 | |
JonFreeman | 0:5d0f270bfc87 | 118 | void g0g1cmdcore (struct singleGparam * source_array, double f_rate) // Updates any / all of x, y, z NCOs |
JonFreeman | 0:5d0f270bfc87 | 119 | { |
JonFreeman | 0:5d0f270bfc87 | 120 | struct Gparams pxyz, distance; |
JonFreeman | 0:5d0f270bfc87 | 121 | struct axis_speeds_element q; |
JonFreeman | 0:5d0f270bfc87 | 122 | get_codepositions (source_array, pxyz); // will overwrite with new where entered |
JonFreeman | 0:5d0f270bfc87 | 123 | pc.printf("g0"); |
JonFreeman | 0:5d0f270bfc87 | 124 | if (pxyz.x.changed) {pc.printf(" X %f", pxyz.x.dbl);} |
JonFreeman | 0:5d0f270bfc87 | 125 | if (pxyz.y.changed) {pc.printf(" Y %f", pxyz.y.dbl);} |
JonFreeman | 0:5d0f270bfc87 | 126 | if (pxyz.z.changed) {pc.printf(" Z %f", pxyz.z.dbl);} |
JonFreeman | 0:5d0f270bfc87 | 127 | pc.printf("\r\n"); |
JonFreeman | 0:5d0f270bfc87 | 128 | // for (int j = 1; j < const_numofcodes; j++) { |
JonFreeman | 0:5d0f270bfc87 | 129 | // pc.printf ("Count of %c is %d, last position %d, last value %f\r\n", goodcodes[j], codecnt[j], codepos[j], a[codepos[j]].d); |
JonFreeman | 0:5d0f270bfc87 | 130 | // } |
JonFreeman | 0:5d0f270bfc87 | 131 | double distT = find_distance (last_position, pxyz, distance); // also fills in distance x y z |
JonFreeman | 0:5d0f270bfc87 | 132 | double temp = n_for_onemmpermin * f_rate / distT; |
JonFreeman | 0:5d0f270bfc87 | 133 | q.duration_ticks = find_traverse_ticks(distT, f_rate); |
JonFreeman | 0:5d0f270bfc87 | 134 | last_position.x.dbl = pxyz.x.dbl; // Update global last_position record |
JonFreeman | 0:5d0f270bfc87 | 135 | last_position.y.dbl = pxyz.y.dbl; |
JonFreeman | 0:5d0f270bfc87 | 136 | last_position.z.dbl = pxyz.z.dbl; |
JonFreeman | 0:5d0f270bfc87 | 137 | q.x = (signed long)(temp * distance.x.dbl); |
JonFreeman | 0:5d0f270bfc87 | 138 | q.y = (signed long)(temp * distance.y.dbl); |
JonFreeman | 0:5d0f270bfc87 | 139 | q.z = (signed long)(temp * distance.z.dbl); |
JonFreeman | 0:5d0f270bfc87 | 140 | q.a = 0; |
JonFreeman | 0:5d0f270bfc87 | 141 | pir_updater (&q); // pir_updater (struct Gparams & p); // To arrive here with wanted 'mm per min' values in x, y and z |
JonFreeman | 0:5d0f270bfc87 | 142 | } |
JonFreeman | 0:5d0f270bfc87 | 143 | |
JonFreeman | 0:5d0f270bfc87 | 144 | void g0cmd (struct singleGparam * a) // Updates any / all of x, y, z NCOs |
JonFreeman | 0:5d0f270bfc87 | 145 | { |
JonFreeman | 0:5d0f270bfc87 | 146 | g0g1cmdcore (a, feed_rate_max); // Defined parameter in code |
JonFreeman | 0:5d0f270bfc87 | 147 | } |
JonFreeman | 0:5d0f270bfc87 | 148 | |
JonFreeman | 0:5d0f270bfc87 | 149 | void g1cmd (struct singleGparam * a) // Updates any / all of x, y, z NCOs |
JonFreeman | 0:5d0f270bfc87 | 150 | { |
JonFreeman | 0:5d0f270bfc87 | 151 | g0g1cmdcore (a, feed_rate); // Settable feed_rate |
JonFreeman | 0:5d0f270bfc87 | 152 | } |
JonFreeman | 0:5d0f270bfc87 | 153 | |
JonFreeman | 0:5d0f270bfc87 | 154 | void fcmd (struct singleGparam * a) { |
JonFreeman | 0:5d0f270bfc87 | 155 | if (a[1].dbl < feed_rate_min || a[1].dbl > feed_rate_max) { |
JonFreeman | 0:5d0f270bfc87 | 156 | pc.printf ("Errror setting feed rate, can't set to %f, ignoring request\r\n", a[1].dbl); |
JonFreeman | 0:5d0f270bfc87 | 157 | return; |
JonFreeman | 0:5d0f270bfc87 | 158 | } |
JonFreeman | 0:5d0f270bfc87 | 159 | pc.printf ("Setting feed_rate to %f\r\n", a[1].dbl); |
JonFreeman | 0:5d0f270bfc87 | 160 | feed_rate = a[1].dbl; |
JonFreeman | 0:5d0f270bfc87 | 161 | } |
JonFreeman | 0:5d0f270bfc87 | 162 | |
JonFreeman | 0:5d0f270bfc87 | 163 | extern unsigned long pir_s; |
JonFreeman | 0:5d0f270bfc87 | 164 | extern int spindlefwdrev; |
JonFreeman | 0:5d0f270bfc87 | 165 | |
JonFreeman | 0:5d0f270bfc87 | 166 | void sfcmd (struct singleGparam * a) {pc.printf("Spindle Fwd\r\n"); spindlefwdrev = 0;} |
JonFreeman | 0:5d0f270bfc87 | 167 | void srcmd (struct singleGparam * a) {pc.printf("Spindle Rev\r\n"); spindlefwdrev = 4;} |
JonFreeman | 0:5d0f270bfc87 | 168 | void stopcmd (struct singleGparam * a) {pc.printf("Stop ! er, not working yet\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 169 | |
JonFreeman | 0:5d0f270bfc87 | 170 | void scmd (struct singleGparam * a) { |
JonFreeman | 0:5d0f270bfc87 | 171 | pc.printf("pir_s=0x%x\r\n", pir_s); |
JonFreeman | 0:5d0f270bfc87 | 172 | if (a[1].dbl < spindle_min || a[1].dbl > spindle_max) { |
JonFreeman | 0:5d0f270bfc87 | 173 | pc.printf ("Errror setting spindle RPM, can't set to %f, ignoring request\r\n", a[1].dbl); |
JonFreeman | 0:5d0f270bfc87 | 174 | // return; |
JonFreeman | 0:5d0f270bfc87 | 175 | } |
JonFreeman | 0:5d0f270bfc87 | 176 | pc.printf ("Setting spindle RPM to %f\r\n", a[1].dbl); |
JonFreeman | 0:5d0f270bfc87 | 177 | // feed_rate = a[1].d; // ****TO DO**** |
JonFreeman | 0:5d0f270bfc87 | 178 | pir_s = (unsigned long) (a[1].dbl * 4096); |
JonFreeman | 0:5d0f270bfc87 | 179 | pc.printf("pir_s=0x%x\r\n", pir_s); |
JonFreeman | 0:5d0f270bfc87 | 180 | } |
JonFreeman | 0:5d0f270bfc87 | 181 | |
JonFreeman | 0:5d0f270bfc87 | 182 | //void stopcmd (struct grain * a) {pc.printf("Stop !\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 183 | void m1cmd (struct singleGparam * a) {pc.printf("m1 Optional Programme Stop\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 184 | void m3cmd (struct singleGparam * a) {pc.printf("m3 Rotate Spindle Clockwise\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 185 | void m4cmd (struct singleGparam * a) {pc.printf("m4 Rotate Spindle Counter Clockwise\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 186 | void m5cmd (struct singleGparam * a) {pc.printf("m5 Stop Spindle\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 187 | /*void m30cmd (struct singleGparam * a) {pc.printf("m30 Programme End and Rewind\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 188 | void m47cmd (struct singleGparam * a) {pc.printf("m47 Repeat Prog from First Line\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 189 | void m48cmd (struct singleGparam * a) {pc.printf("m48 Enable Speed and Feed Override\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 190 | void m49cmd (struct singleGparam * a) {pc.printf("m49 Disable Speed and Feed Override\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 191 | void m98cmd (struct singleGparam * a) {pc.printf("m98 Call Subroutine\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 192 | void m99cmd (struct singleGparam * a) {pc.printf("m99 Return from Subroutine\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 193 | void g10cmd (struct singleGparam * a) {pc.printf("g10 Coord System Origin Set\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 194 | void g17cmd (struct singleGparam * a) {pc.printf("g17 XY Plane Select\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 195 | void g20cmd (struct singleGparam * a) {pc.printf("g20 Inch\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 196 | void g21cmd (struct singleGparam * a) {pc.printf("g21 mm\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 197 | |
JonFreeman | 0:5d0f270bfc87 | 198 | void g40cmd (struct singleGparam * a) {pc.printf("g40 Cutter Compensation Off\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 199 | void g50cmd (struct singleGparam * a) {pc.printf("g50 Reset Scale Factors\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 200 | void g53cmd (struct singleGparam * a) {pc.printf("g53 Move in Absolute Coordinates\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 201 | void g90cmd (struct singleGparam * a) {pc.printf("g90 Absolute Distance Mode\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 202 | */ |
JonFreeman | 0:5d0f270bfc87 | 203 | void g2cmd (struct singleGparam * a) {pc.printf("g2 Clockwise Arc\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 204 | void g3cmd (struct singleGparam * a) {pc.printf("g3 CounterClockwise Arc\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 205 | void g4cmd (struct singleGparam * a) {pc.printf("g4 Dwell\r\n");} |
JonFreeman | 0:5d0f270bfc87 | 206 | void g91p1cmd (struct singleGparam * a) {pc.printf("g91.1 \r\n");} |
JonFreeman | 0:5d0f270bfc87 | 207 | |
JonFreeman | 0:5d0f270bfc87 | 208 | extern struct digital_readouts dro; // |
JonFreeman | 0:5d0f270bfc87 | 209 | void drooncmd (struct singleGparam * a) |
JonFreeman | 0:5d0f270bfc87 | 210 | { |
JonFreeman | 0:5d0f270bfc87 | 211 | dro.dro_output = true; // Enable continuous dro display update |
JonFreeman | 0:5d0f270bfc87 | 212 | } |
JonFreeman | 0:5d0f270bfc87 | 213 | void drooffcmd (struct singleGparam * a) |
JonFreeman | 0:5d0f270bfc87 | 214 | { |
JonFreeman | 0:5d0f270bfc87 | 215 | dro.dro_output = false; // Disable continuous dro display update |
JonFreeman | 0:5d0f270bfc87 | 216 | } |
JonFreeman | 0:5d0f270bfc87 | 217 | |
JonFreeman | 0:5d0f270bfc87 | 218 | //extern void craptest () ; |
JonFreeman | 0:5d0f270bfc87 | 219 | //void g1cmd (struct singleGparam * a) { |
JonFreeman | 0:5d0f270bfc87 | 220 | // craptest (); |
JonFreeman | 0:5d0f270bfc87 | 221 | //} |
JonFreeman | 0:5d0f270bfc87 | 222 | |
JonFreeman | 0:5d0f270bfc87 | 223 | void g90p1cmd (struct singleGparam * a) |
JonFreeman | 0:5d0f270bfc87 | 224 | { |
JonFreeman | 0:5d0f270bfc87 | 225 | pc.printf ("Arrived at function fredcmd with %d parameters\r\n", a[0].i); |
JonFreeman | 0:5d0f270bfc87 | 226 | for (int i = 1; i <= a[0].i; i++) { |
JonFreeman | 0:5d0f270bfc87 | 227 | pc.printf ("*%c* ", a[i].c); |
JonFreeman | 0:5d0f270bfc87 | 228 | pc.printf ("%d, ", a[i].i); |
JonFreeman | 0:5d0f270bfc87 | 229 | pc.printf ("%f\r\n", a[i].dbl); |
JonFreeman | 0:5d0f270bfc87 | 230 | } |
JonFreeman | 0:5d0f270bfc87 | 231 | pc.printf (" endof param list\r\n"); |
JonFreeman | 0:5d0f270bfc87 | 232 | } |
JonFreeman | 0:5d0f270bfc87 | 233 | |
JonFreeman | 0:5d0f270bfc87 | 234 | void menucmd (struct singleGparam * a); |
JonFreeman | 0:5d0f270bfc87 | 235 | struct kb_command { |
JonFreeman | 0:5d0f270bfc87 | 236 | const char * cmd_word; // points to text e.g. "menu" |
JonFreeman | 0:5d0f270bfc87 | 237 | const char * explan; |
JonFreeman | 0:5d0f270bfc87 | 238 | void (*f)(struct singleGparam *); // points to function |
JonFreeman | 0:5d0f270bfc87 | 239 | } kbc[] = { |
JonFreeman | 0:5d0f270bfc87 | 240 | {(char const *)"menu", "Lists available commands, same as ls", menucmd}, |
JonFreeman | 0:5d0f270bfc87 | 241 | {(char const *)"ls", "Lists available commands, same as menu", menucmd}, |
JonFreeman | 0:5d0f270bfc87 | 242 | {"stop", "To Stop the Machine !", stopcmd}, |
JonFreeman | 0:5d0f270bfc87 | 243 | {"sf", "Spindle Clockwise", sfcmd}, |
JonFreeman | 0:5d0f270bfc87 | 244 | {"sr", "Spindle Anticlockwise", srcmd}, |
JonFreeman | 0:5d0f270bfc87 | 245 | {"f ", "To set Feed Rate mm/min, e.g. f 25", fcmd}, |
JonFreeman | 0:5d0f270bfc87 | 246 | {"s ", "To set Spindle RPM, e.g. S 1250", scmd}, |
JonFreeman | 0:5d0f270bfc87 | 247 | {"g0", "Not Implemented", g0cmd}, |
JonFreeman | 0:5d0f270bfc87 | 248 | /*{"m30", "Not Implemented", m30cmd}, |
JonFreeman | 0:5d0f270bfc87 | 249 | {"m47", "Not Implemented", m47cmd}, |
JonFreeman | 0:5d0f270bfc87 | 250 | {"m48", "Not Implemented", m48cmd}, |
JonFreeman | 0:5d0f270bfc87 | 251 | {"m49", "Not Implemented", m49cmd}, |
JonFreeman | 0:5d0f270bfc87 | 252 | {"m98", "Not Implemented", m98cmd}, |
JonFreeman | 0:5d0f270bfc87 | 253 | {"m99", "Not Implemented", m99cmd}, |
JonFreeman | 0:5d0f270bfc87 | 254 | {"m1", "Not Implemented", m1cmd}, |
JonFreeman | 0:5d0f270bfc87 | 255 | {"m3", "Not Implemented", m3cmd}, |
JonFreeman | 0:5d0f270bfc87 | 256 | {"m4", "Not Implemented", m4cmd}, |
JonFreeman | 0:5d0f270bfc87 | 257 | {"m5", "Not Implemented", m5cmd}, |
JonFreeman | 0:5d0f270bfc87 | 258 | {"g10", "Not Implemented", g10cmd}, |
JonFreeman | 0:5d0f270bfc87 | 259 | {"g17", "Not Implemented", g17cmd}, |
JonFreeman | 0:5d0f270bfc87 | 260 | {"g20", "Not Implemented", g20cmd}, |
JonFreeman | 0:5d0f270bfc87 | 261 | {"g21", "Not Implemented", g21cmd}, |
JonFreeman | 0:5d0f270bfc87 | 262 | {"g40", "Not Implemented", g40cmd}, |
JonFreeman | 0:5d0f270bfc87 | 263 | {"g50", "Not Implemented", g50cmd}, |
JonFreeman | 0:5d0f270bfc87 | 264 | {"g90.1", "Not Implemented", g90p1cmd}, |
JonFreeman | 0:5d0f270bfc87 | 265 | {"g91.1", "Not Implemented", g91p1cmd}, |
JonFreeman | 0:5d0f270bfc87 | 266 | {"g90", "Not Implemented", g90cmd}, |
JonFreeman | 0:5d0f270bfc87 | 267 | */ |
JonFreeman | 0:5d0f270bfc87 | 268 | {"g1", "", g1cmd}, |
JonFreeman | 0:5d0f270bfc87 | 269 | {"g2", "", g2cmd}, |
JonFreeman | 0:5d0f270bfc87 | 270 | {"g3", "", g3cmd}, |
JonFreeman | 0:5d0f270bfc87 | 271 | {"g4", "", g4cmd}, |
JonFreeman | 0:5d0f270bfc87 | 272 | {"dro on", "Turn dro readout on", drooncmd}, |
JonFreeman | 0:5d0f270bfc87 | 273 | {"dro off", "Turn dro readout off", drooffcmd} |
JonFreeman | 0:5d0f270bfc87 | 274 | }; |
JonFreeman | 0:5d0f270bfc87 | 275 | const int numof_menu_items = sizeof(kbc) / sizeof(kb_command); |
JonFreeman | 0:5d0f270bfc87 | 276 | |
JonFreeman | 0:5d0f270bfc87 | 277 | void menucmd (struct singleGparam * a) |
JonFreeman | 0:5d0f270bfc87 | 278 | { |
JonFreeman | 0:5d0f270bfc87 | 279 | pc.printf("At menucmd function - listing commands:-\r\n"); |
JonFreeman | 0:5d0f270bfc87 | 280 | for(int i = 0; i < numof_menu_items; i++) |
JonFreeman | 0:5d0f270bfc87 | 281 | pc.printf("[%s]\t\t%s\r\n", kbc[i].cmd_word, kbc[i].explan); |
JonFreeman | 0:5d0f270bfc87 | 282 | pc.printf("End of List of Commands\r\n"); |
JonFreeman | 0:5d0f270bfc87 | 283 | } |
JonFreeman | 0:5d0f270bfc87 | 284 | |
JonFreeman | 0:5d0f270bfc87 | 285 | bool isalpha (int c) |
JonFreeman | 0:5d0f270bfc87 | 286 | { |
JonFreeman | 0:5d0f270bfc87 | 287 | if ((c >= 'a') && (c <= 'z')) return true; |
JonFreeman | 0:5d0f270bfc87 | 288 | if ((c >= 'A') && (c <= 'Z')) return true; |
JonFreeman | 0:5d0f270bfc87 | 289 | return false; |
JonFreeman | 0:5d0f270bfc87 | 290 | } |
JonFreeman | 0:5d0f270bfc87 | 291 | |
JonFreeman | 0:5d0f270bfc87 | 292 | char * readout (char * txt, int p) // p has running subtotal of all pulses issued to stepper driver |
JonFreeman | 0:5d0f270bfc87 | 293 | { |
JonFreeman | 0:5d0f270bfc87 | 294 | txt[0] = '+'; // constructs string e.g. "+123.456" |
JonFreeman | 0:5d0f270bfc87 | 295 | txt[8] = 0; // null terminated |
JonFreeman | 0:5d0f270bfc87 | 296 | if (p < 0) { |
JonFreeman | 0:5d0f270bfc87 | 297 | txt[0] = '-'; |
JonFreeman | 0:5d0f270bfc87 | 298 | p = -p; |
JonFreeman | 0:5d0f270bfc87 | 299 | } |
JonFreeman | 0:5d0f270bfc87 | 300 | p *= 1000; |
JonFreeman | 0:5d0f270bfc87 | 301 | p /= pulses_per_mm; |
JonFreeman | 0:5d0f270bfc87 | 302 | for(int k = 7; k > 0; k--) { |
JonFreeman | 0:5d0f270bfc87 | 303 | if (k == 4) |
JonFreeman | 0:5d0f270bfc87 | 304 | txt[k] = '.'; |
JonFreeman | 0:5d0f270bfc87 | 305 | else { |
JonFreeman | 0:5d0f270bfc87 | 306 | txt[k] = '0' + (p % 10); |
JonFreeman | 0:5d0f270bfc87 | 307 | p /= 10; |
JonFreeman | 0:5d0f270bfc87 | 308 | } |
JonFreeman | 0:5d0f270bfc87 | 309 | } |
JonFreeman | 0:5d0f270bfc87 | 310 | return txt; // Returns pointer unaltered for subsequent use by e.g. cout |
JonFreeman | 0:5d0f270bfc87 | 311 | } |
JonFreeman | 0:5d0f270bfc87 | 312 | |
JonFreeman | 0:5d0f270bfc87 | 313 | ////class CLI { |
JonFreeman | 0:5d0f270bfc87 | 314 | |
JonFreeman | 0:5d0f270bfc87 | 315 | const int MAX_PARAMS = 20, MAX_CMD_LEN = 120; |
JonFreeman | 0:5d0f270bfc87 | 316 | char cmd_line[MAX_CMD_LEN + 4]; |
JonFreeman | 0:5d0f270bfc87 | 317 | struct singleGparam params[MAX_PARAMS + 1]; |
JonFreeman | 0:5d0f270bfc87 | 318 | int cl_index = 0, ch, lastalpha = 0; |
JonFreeman | 0:5d0f270bfc87 | 319 | double fracmul; |
JonFreeman | 0:5d0f270bfc87 | 320 | /* |
JonFreeman | 0:5d0f270bfc87 | 321 | void command_line_interpreter () |
JonFreeman | 0:5d0f270bfc87 | 322 | Purpose: |
JonFreeman | 0:5d0f270bfc87 | 323 | |
JonFreeman | 0:5d0f270bfc87 | 324 | */ |
JonFreeman | 0:5d0f270bfc87 | 325 | void command_line_interpreter () |
JonFreeman | 0:5d0f270bfc87 | 326 | { |
JonFreeman | 0:5d0f270bfc87 | 327 | while (pc.readable()) { |
JonFreeman | 0:5d0f270bfc87 | 328 | if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines |
JonFreeman | 0:5d0f270bfc87 | 329 | pc.printf ("Keyboard Error!! Killing stupidly long command line"); |
JonFreeman | 0:5d0f270bfc87 | 330 | cl_index = 0; |
JonFreeman | 0:5d0f270bfc87 | 331 | } |
JonFreeman | 0:5d0f270bfc87 | 332 | ch = tolower(pc.getc()); |
JonFreeman | 0:5d0f270bfc87 | 333 | if(ch != '\r') // was this the 'Enter' key? |
JonFreeman | 0:5d0f270bfc87 | 334 | cmd_line[cl_index++] = ch; // added char to command being assembled |
JonFreeman | 0:5d0f270bfc87 | 335 | else { // key was CR, may or may not be command to lookup |
JonFreeman | 0:5d0f270bfc87 | 336 | cmd_line[cl_index] = 0; // null terminate command string |
JonFreeman | 0:5d0f270bfc87 | 337 | if(cl_index) { // If have got some chars to lookup |
JonFreeman | 0:5d0f270bfc87 | 338 | int i, wrdlen; |
JonFreeman | 0:5d0f270bfc87 | 339 | for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list |
JonFreeman | 0:5d0f270bfc87 | 340 | wrdlen = strlen(kbc[i].cmd_word); |
JonFreeman | 0:5d0f270bfc87 | 341 | if(strncmp(kbc[i].cmd_word, cmd_line, wrdlen) == 0) { // If match found |
JonFreeman | 0:5d0f270bfc87 | 342 | bool negflag = false; |
JonFreeman | 0:5d0f270bfc87 | 343 | int state = 0, paramindex; |
JonFreeman | 0:5d0f270bfc87 | 344 | // pc.printf("Found match for word [%s]\r\n", kbc[i].wrd); |
JonFreeman | 0:5d0f270bfc87 | 345 | for(paramindex = 0; paramindex < MAX_PARAMS; paramindex++) { |
JonFreeman | 0:5d0f270bfc87 | 346 | // Clear out whole set of old parameters ready for anything new on this line |
JonFreeman | 0:5d0f270bfc87 | 347 | params[paramindex].i = 0; // for integer parameters |
JonFreeman | 0:5d0f270bfc87 | 348 | params[paramindex].c = 0; // for last alpha char, helps tie 'X' to '-23.5' etc |
JonFreeman | 0:5d0f270bfc87 | 349 | params[paramindex].dbl = 0.0; // for floating point parameters |
JonFreeman | 0:5d0f270bfc87 | 350 | params[paramindex].ul = 0; |
JonFreeman | 0:5d0f270bfc87 | 351 | params[paramindex].changed = false; |
JonFreeman | 0:5d0f270bfc87 | 352 | } |
JonFreeman | 0:5d0f270bfc87 | 353 | paramindex = 0; |
JonFreeman | 0:5d0f270bfc87 | 354 | // read any parameters from command line here |
JonFreeman | 0:5d0f270bfc87 | 355 | // Using parameters[0] as count of parameters to follow |
JonFreeman | 0:5d0f270bfc87 | 356 | while (wrdlen <= cl_index) { |
JonFreeman | 0:5d0f270bfc87 | 357 | ch = cmd_line[wrdlen++]; |
JonFreeman | 0:5d0f270bfc87 | 358 | if(isalpha(ch)) lastalpha = ch; |
JonFreeman | 0:5d0f270bfc87 | 359 | if(ch == '-') negflag = true; |
JonFreeman | 0:5d0f270bfc87 | 360 | if(ch == '+') negflag = false; |
JonFreeman | 0:5d0f270bfc87 | 361 | switch (state) { |
JonFreeman | 0:5d0f270bfc87 | 362 | case 0: // looking for start of a number string |
JonFreeman | 0:5d0f270bfc87 | 363 | if(isdigit(ch)) { // found first digit of a number string |
JonFreeman | 0:5d0f270bfc87 | 364 | paramindex++; |
JonFreeman | 0:5d0f270bfc87 | 365 | if(paramindex > MAX_PARAMS) { |
JonFreeman | 0:5d0f270bfc87 | 366 | wrdlen = cl_index; // exit condition |
JonFreeman | 0:5d0f270bfc87 | 367 | pc.printf("WARNING - too many parameters, ignoring extra\r\n"); |
JonFreeman | 0:5d0f270bfc87 | 368 | } else { |
JonFreeman | 0:5d0f270bfc87 | 369 | params[paramindex].i = ch - '0'; |
JonFreeman | 0:5d0f270bfc87 | 370 | params[paramindex].c = lastalpha; |
JonFreeman | 0:5d0f270bfc87 | 371 | state = 1; // Found first digit char of number string |
JonFreeman | 0:5d0f270bfc87 | 372 | } |
JonFreeman | 0:5d0f270bfc87 | 373 | } |
JonFreeman | 0:5d0f270bfc87 | 374 | break; |
JonFreeman | 0:5d0f270bfc87 | 375 | case 1: // looking for end of a number string |
JonFreeman | 0:5d0f270bfc87 | 376 | if(isdigit(ch)) { // accumulating integer from string |
JonFreeman | 0:5d0f270bfc87 | 377 | params[paramindex].i *= 10; |
JonFreeman | 0:5d0f270bfc87 | 378 | params[paramindex].i += ch - '0'; |
JonFreeman | 0:5d0f270bfc87 | 379 | } else { // found non-digit terminating number |
JonFreeman | 0:5d0f270bfc87 | 380 | if (ch == '.') { |
JonFreeman | 0:5d0f270bfc87 | 381 | state = 2; |
JonFreeman | 0:5d0f270bfc87 | 382 | fracmul = 0.1; |
JonFreeman | 0:5d0f270bfc87 | 383 | params[paramindex].dbl = (double)params[paramindex].i; |
JonFreeman | 0:5d0f270bfc87 | 384 | } else { |
JonFreeman | 0:5d0f270bfc87 | 385 | params[0].i++; // count of validated parameters |
JonFreeman | 0:5d0f270bfc87 | 386 | state = 0; // Have read past last digit of number string |
JonFreeman | 0:5d0f270bfc87 | 387 | if(negflag) { |
JonFreeman | 0:5d0f270bfc87 | 388 | params[paramindex].i = -params[paramindex].i; |
JonFreeman | 0:5d0f270bfc87 | 389 | negflag = false; |
JonFreeman | 0:5d0f270bfc87 | 390 | } |
JonFreeman | 0:5d0f270bfc87 | 391 | params[paramindex].dbl = (double)params[paramindex].i; |
JonFreeman | 0:5d0f270bfc87 | 392 | } |
JonFreeman | 0:5d0f270bfc87 | 393 | } |
JonFreeman | 0:5d0f270bfc87 | 394 | break; |
JonFreeman | 0:5d0f270bfc87 | 395 | case 2: // looking for fractional part of double |
JonFreeman | 0:5d0f270bfc87 | 396 | if(isdigit(ch)) { // accumulating fractional part from string |
JonFreeman | 0:5d0f270bfc87 | 397 | params[paramindex].dbl += (double)((ch - '0') * fracmul); |
JonFreeman | 0:5d0f270bfc87 | 398 | fracmul /= 10.0; |
JonFreeman | 0:5d0f270bfc87 | 399 | } else { // found non-digit terminating double precision number |
JonFreeman | 0:5d0f270bfc87 | 400 | params[0].i++; // count of validated parameters |
JonFreeman | 0:5d0f270bfc87 | 401 | state = 0; // Have read past last digit of number string |
JonFreeman | 0:5d0f270bfc87 | 402 | if(negflag) { |
JonFreeman | 0:5d0f270bfc87 | 403 | params[paramindex].i = -params[paramindex].i; |
JonFreeman | 0:5d0f270bfc87 | 404 | params[paramindex].dbl = -params[paramindex].dbl; |
JonFreeman | 0:5d0f270bfc87 | 405 | negflag = false; |
JonFreeman | 0:5d0f270bfc87 | 406 | } |
JonFreeman | 0:5d0f270bfc87 | 407 | } |
JonFreeman | 0:5d0f270bfc87 | 408 | break; |
JonFreeman | 0:5d0f270bfc87 | 409 | default: |
JonFreeman | 0:5d0f270bfc87 | 410 | break; |
JonFreeman | 0:5d0f270bfc87 | 411 | } // end of switch state |
JonFreeman | 0:5d0f270bfc87 | 412 | } // end of while wrdlen < cl_index |
JonFreeman | 0:5d0f270bfc87 | 413 | // pc.printf("Found match to [%s] with %d parameters\r\n", kbc[i].wrd, paramindex); |
JonFreeman | 0:5d0f270bfc87 | 414 | kbc[i].f(params); // execute command |
JonFreeman | 0:5d0f270bfc87 | 415 | i = numof_menu_items + 1; // to exit for loop |
JonFreeman | 0:5d0f270bfc87 | 416 | } |
JonFreeman | 0:5d0f270bfc87 | 417 | } // End of for numof_menu_items |
JonFreeman | 0:5d0f270bfc87 | 418 | if(i == numof_menu_items) |
JonFreeman | 0:5d0f270bfc87 | 419 | pc.printf("No Match Found for CMD [%s]\r\n", cmd_line); |
JonFreeman | 0:5d0f270bfc87 | 420 | } // End of If have got some chars to lookup |
JonFreeman | 0:5d0f270bfc87 | 421 | cl_index = lastalpha = 0; |
JonFreeman | 0:5d0f270bfc87 | 422 | } // End of else key was CR, may or may not be command to lookup |
JonFreeman | 0:5d0f270bfc87 | 423 | } // End of while (pc.readable()) |
JonFreeman | 0:5d0f270bfc87 | 424 | // osThreadYield(); // Not using RTOS on this project |
JonFreeman | 0:5d0f270bfc87 | 425 | } |
JonFreeman | 0:5d0f270bfc87 | 426 | |
JonFreeman | 0:5d0f270bfc87 | 427 | ////} cli; |
JonFreeman | 0:5d0f270bfc87 | 428 |