Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 2:b3c668ec43ac, committed 2014-02-20
- Comitter:
- JonFreeman
- Date:
- Thu Feb 20 09:27:18 2014 +0000
- Parent:
- 1:66ee619f206b
- Child:
- 3:7aaf0072cc22
- Commit message:
- As used to produce Lissajous patterns for EiM articles. XYZ axis good, Axis A not implemented, spindle 'S' working. Using MODSERIAL, therefore no longer compatible with KL46Z, good for KL25Z and Mbed LPC1768
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Thu Feb 20 09:27:18 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Sissors/code/MODSERIAL/#f42def64c4ee
--- a/arith.cpp Thu Feb 06 08:45:02 2014 +0000
+++ b/arith.cpp Thu Feb 20 09:27:18 2014 +0000
@@ -4,18 +4,21 @@
const double ball_screw_pitch_mm = 4.0, // KX3 has 4mm ball screws
motor_step_per_rev = 200.0, // KX3 has 200 step per rev steppers
- micro_steps = 20.0, // Arc Eurotrade choice 2,4,5,8,10,16,20,25,32,40,50,64,100,125,128
+ micro_steps = 10.0, // Arc Eurotrade choice 2,4,5,8,10,16,20,25,32,40,50,64,100,125,128
pulses_per_mm = micro_steps * motor_step_per_rev / ball_screw_pitch_mm,
- interrupt_period_us = 24.0, //16 is possible with Mbed LPC1768
+ interrupt_period_us = 32.0,//24.0, //16 is possible with Mbed LPC1768
interrupt_freq_Hz = 1000000.0 / interrupt_period_us, // Serious limit when doing all in software, no real limit with FPGA
- max_pulse_freq_Hz = interrupt_freq_Hz / 4.5, // strictly 4, but allow a good margin
+ max_pulse_freq_Hz = interrupt_freq_Hz / 3.25, // strictly 2.0, but allow a good margin
max_mm_per_min = 60.0 * max_pulse_freq_Hz / pulses_per_mm,
- n_for_onemmpermin = pulses_per_mm * interrupt_period_us * pow(2.0,32) / 60000000.0, // n pir to produce 1mm/min travel
+// n_for_onemmpermin = pulses_per_mm * interrupt_period_us * pow(2.0,32) / 60000000.0, // n pir to produce 1mm/min travel
+ n_for_onemmpermin = pulses_per_mm * interrupt_period_us * pow(2.0,31) / 60000000.0, // n pir to produce 1mm/min travel
+ // note power reduced from 32to 31 as interrupt handler now issued step pulse on both edges
feed_rate_max = max_mm_per_min,
+ spindle_factor = interrupt_period_us * 4280,
spindle_max = 5000.0;
//The output frequency F<sub>out</sub> = 'Kernel Speed (Hz)' * n / (2 to the power of 32)
-
+
struct Gparams last_position;
void grain_clr (struct singleGparam & g) {
g.dbl = 0.0;
--- a/cnc.h Thu Feb 06 08:45:02 2014 +0000
+++ b/cnc.h Thu Feb 20 09:27:18 2014 +0000
@@ -1,3 +1,8 @@
+#define ESTOP 0x100 // bits used in input reading
+#define XLIM 1
+#define YLIM 2
+#define ZLIM 4
+#define UNKN 8
const double TWO_PI = 8.0 * atan(1.0);
const double epsilon = 1e-5;
struct pirbufgrain {
@@ -19,11 +24,6 @@
struct singleGparam x, y, z, i, j, r, a, b, c, d; // After sorting, know where to find any X, Y etc values !
} ;
-struct digital_readouts { // DROs keep count of 'Step' positive edges detected in interrupt handler
- signed long x, y, z; // Could easily expand up to six or more dros
- bool dro_output; // To enabe / disable output to terminal
-} ;
-
-extern const double n_for_onemmpermin, feed_rate_max, feed_rate_min, spindle_min, spindle_max;
+extern const double n_for_onemmpermin, feed_rate_max, feed_rate_min, spindle_min, spindle_max, spindle_factor;
//extern const long pulses_per_mm, max_mm_per_min, interrupt_period_us;
extern const double pulses_per_mm, max_mm_per_min, interrupt_period_us;
--- 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())
--- a/lissajous.cpp Thu Feb 06 08:45:02 2014 +0000
+++ b/lissajous.cpp Thu Feb 20 09:27:18 2014 +0000
@@ -1,8 +1,10 @@
#include "mbed.h"
-#include "rtos.h"
+//#include "rtos.h"
+#include "MODSERIAL.h"
#include "cnc.h"
-extern Serial pc;
-extern void mover (struct pirbufgrain & ins) ;
+extern MODSERIAL pc;
+//extern Serial pc;
+extern void move_to_XYZ (struct pirbufgrain & ins) ;
/*
This file contains one function:
void lissajous () ;
@@ -12,17 +14,16 @@
Thus far we have proved only that both finish at the same point (give or take a few microns)
*/
-bool liss_active = false; // global flag used to prevent running more than once at a time
+//bool liss_active = false; // global flag used to prevent running more than once at a time
-void lissajous (void const * arg_string) {
+void lissajous (double feed_rate) {
const double PI = 4.0 * atan(1.0), //3.142ish but more accurate
Deg2Rad = PI / 180.0, // degrees to radian conversion factor
- MaxX = 6.40, // Plot size X to move +/- MaxX
- MaxY = 6.4, //3.20, // Plot size Y to move +/- MaxY
+ MaxX = 40.0, // Plot size X to move +/- MaxX
+ MaxY = 25.0, // Plot size Y to move +/- MaxY
StartAngDegX = 0.0,
- StartAngDegY = 0.0, //10.0,
- FreqRatio = 1.0, //0.254,
- FeedRate = 500.0; // In mm per minute
+ StartAngDegY = 10.0,
+ FreqRatio = 0.255;
const int StepsPerRevX = 100,
NumofXCycles = 16;
const double AngleStepX = (2.0 * PI / StepsPerRevX),
@@ -33,17 +34,22 @@
double AngleX = StartAngDegX * Deg2Rad,
AngleY = StartAngDegY * Deg2Rad;
- pc.printf("In lissajous func, Loading Lissajous\r\n");
- while (1) {
- while (!liss_active) // Other code to activate
- osThreadYield();
+// pc.printf("In lissajous func, Loading Lissajous\r\n");
+// while (1) {
+// while (!liss_active) // Other code to activate
+// osThreadYield();
// liss_active = true; // this hapens in activating code
pc.printf("In lissajous func, Starting Lissajous, has been activated\r\n");
+ Coords.x = 0.0;
+ Coords.y = 0.0;
+ Coords.z = 12.7;
+ Coords.f_rate = feed_rate;
+ move_to_XYZ (Coords);
Coords.x = MaxX * cos(AngleX); // Coordinates of start position
Coords.y = MaxY * sin(AngleY); // assembled into packet for motion controller
+ move_to_XYZ (Coords);
Coords.z = 0.0;
- Coords.f_rate = FeedRate;
- mover(Coords);
+ move_to_XYZ (Coords);
for (int i = 0; i < NumofXCycles; i++) { // Outer loop 'NumofXCycles' times
for (int j = 0; j < StepsPerRevX; j++) { // Inner loop 'StepsPerRevX' times
@@ -51,16 +57,22 @@
AngleY += AngleStepY;
Coords.x = MaxX * cos(AngleX);
Coords.y = MaxY * sin(AngleY);
- mover(Coords);
- osThreadYield();
+ move_to_XYZ (Coords);
+// osThreadYield();
}
+ pc.printf("liss cyc %d\r\n", i);
}
+ Coords.z = 100.0;
+ move_to_XYZ (Coords);
+ Coords.x = 0.0;
+ Coords.y = 0.0;
+ move_to_XYZ (Coords);
pc.printf("Lissajous finish point X%f, Y%f\r\n", Coords.x, Coords.y);
- liss_active = false;
+// liss_active = false;
pc.printf("Leaving liss\r\n");
- osThreadYield(); // terminate would be better here
- } // end of while(1)
+// osThreadYield(); // terminate would be better here
+// } // end of while(1)
}
/*
--- a/main.cpp Thu Feb 06 08:45:02 2014 +0000
+++ b/main.cpp Thu Feb 20 09:27:18 2014 +0000
@@ -1,22 +1,24 @@
#include "mbed.h"
#include "rtos.h"
+#include "MODSERIAL.h"
#include "cnc.h"
using namespace std;
extern void command_line_interpreter (void const *) ;
-extern void lissajous (void const *) ;
-extern double feed_rate;
+//extern void lissajous (void const *) ;
+extern double feed_rate, spindle_rpm;
extern void more_setup () ;
+extern struct Gparams last_position;
const int BAUD = 38400;
-Serial pc(USBTX, USBRX); // tx, rx to pc
+MODSERIAL pc(USBTX, USBRX); // tx, rx to pc
+//Serial pc(USBTX, USBRX); // tx, rx to pc
Ticker NCO_gen; // Ticker generating interrupts at "Kernel Speed", NCO updating frequency (about 40kHz)
-struct digital_readouts dro; //some signed int
bool running = false, new_run_pending = false, idle = false, move_ended = false;
volatile unsigned long ticks = 0L; // 32 bit count of "interrupt_period_us" interrupts from time t=0
unsigned long tickrun = 0L; // 32 bit effectively stores time in future when current movement to stop
unsigned long ticks_next = 0L; // 32 bit effectively stores time in future when current movement to stop
-unsigned long millisecs = 0L; // 32 bit
+unsigned long millisecs = 0L; // 32 bit
unsigned long pir_a = 0L, // Phase Increment Registers
pir_x = 0L,
pir_y = 0L,
@@ -25,19 +27,20 @@
pir_x_next = 0L, // during a move.
pir_y_next = 0L, // This way, next move can start immediately
pir_z_next = 0L, // on end of current move - minimised jerking
- pir_s = 0L; // Referenced only in command_interpreter as spindle speed setting
+ pir_spin = 0L; // Referenced only in command_interpreter as spindle speed setting
-int spindlefwdrev = 0; // Takes values of 0 or 4 only
#if defined (TARGET_KL25Z)
- DigitalOut intled (PTE1); //J2p20
- DigitalOut charge_pump (PTE0); //J2p18
- DigitalIn D25pin10 (PTD6); //jp217
- DigitalIn D25pin11 (PTE31); //j2p13
- DigitalIn D25pin12 (PTA17); //j2p11
- DigitalIn D25pin13 (PTA16); //j2p9
- DigitalIn D25pin15 (PTC17); //j2p7
+ const char Target[] = "KL25Z";
+ DigitalOut intled (PTE1); //J2p20
+ DigitalOut charge_pumpD25pin1 (PTE0); //J2p18
+// InterruptIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4
+ DigitalIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4
+ DigitalIn D25pin11_XLim (PTE21); //j10p3
+ DigitalIn D25pin12_YLim (PTE22); //j10p5
+ DigitalIn D25pin13_ZLim (PTE23); //j10p7
+ DigitalIn D25pin15_unkn (PTE30); //j10p11
//SPISlave spidevice(PTD3, PTD2, PTD1, PTD0); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
SPISlave spidevice(PTD2, PTD3, PTD1, PTD0); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
// J2p08,J2p10,J2p12, J2p06
@@ -45,45 +48,58 @@
//SPI spidevice(PTD3, PTD2, PTD1); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
//NOTE doubt possibly miso mosi in wrong order here, PTD3 and PTD2
#define STEPPER_PORT PortC
- const int PortBitXSt = 3, // Port bit num X Step J1P05
- PortBitXDi = 4, // Port bit num X Dir J1P07
- PortBitYSt = 5, // Port bit num Y Step J1P09
- PortBitYDi = 6, // Port bit num Y Dir J1P11
- PortBitZSt = 10, // Port bit num Z Step J1P13
- PortBitZDi = 11, // Port bit num Z Dir J1P15
- PortBitASt = 12, // Port bit num A Step J2P01
- PortBitADi = 13; // Port bit num A Dir J2P03
+ const int PortBitXSt = 3, // Port bit num X Step J1P05 D25pin 2
+ PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3
+ PortBitYSt = 5, // Port bit num Y Step J1P09 D25pin 4
+ PortBitYDi = 6, // Port bit num Y Dir J1P11 D25pin 5
+ PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6
+ PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7
+ PortBitASt = 12, // Port bit num A Step J2P01 D25pin 8
+ PortBitADi = 13, // Port bit num A Dir J2P03 D25pin 9
+ PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14
+ PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16
#endif
+
+
+
#if defined (TARGET_KL46Z)
- DigitalOut intled (PTE1); //J2p20
- DigitalOut charge_pump (PTE0); //J2p18
- DigitalIn D25pin10 (PTB9);//d6 on 25 jp217
- DigitalIn D25pin11 (PTA16);//e31 on 25 j2p13
- DigitalIn D25pin12 (PTA15);//a17 on 20 j2p11
- DigitalIn D25pin13 (PTA14);//a16 on 25 j2p9
- DigitalIn D25pin15 (PTA6);//c17 on 25 j2p7
+ const char Target[] = "KL46Z";
+ DigitalOut intled (PTE1); //J2p20 checked
+
+
+ DigitalOut charge_pumpD25pin1 (PTE0); //J2p18 checked
+// InterruptIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10
+ DigitalIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10 checked
+ DigitalIn D25pin11_XLim (PTE21); // j4p3 checked
+ DigitalIn D25pin12_YLim (PTE22); // j4p5 checked
+ DigitalIn D25pin13_ZLim (PTE23); // j4p7 checked
+ DigitalIn D25pin15_unkn (PTE30); // j4p11 checked
SPISlave spidevice(PTA16, PTA17, PTA15, PTA14); // mosi, miso, sclk, ssel (uses p11, p12, p13, p? on mbed LPC)
// J2p13, J2p15, J2p11, J2p09
- // Easy way to allocate port bits for *** N O T CHECKED for 46Z ***
+ // Easy way to allocate port bits for
// output of stepper motor Step and DIR sigs
#define STEPPER_PORT PortC
- const int PortBitXSt = 0, // Port bit num X Step J1P05
- PortBitXDi = 4, // Port bit num X Dir J1P07
- PortBitYSt = 6, // Port bit num Y Step J1P09
- PortBitYDi = 7, // Port bit num Y Dir J1P11
- PortBitZSt = 10, // Port bit num Z Step J1P13
- PortBitZDi = 11, // Port bit num Z Dir J1P15
- PortBitASt = 13, // Port bit num A Step J2P01
- PortBitADi = 16; // Port bit num A Dir J2P03
+ const int PortBitXSt = 0, // Port bit num X Step J1P05 D25pin 2 checked
+ PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3 checked
+ PortBitYSt = 6, // Port bit num Y Step J1P09 D25pin 4 checked
+ PortBitYDi = 7, // Port bit num Y Dir J1P11 D25pin 5 checked
+ PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6 checked
+ PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7 checked
+ PortBitASt = 13, // Port bit num A Step J2P01 D25pin 8 checked
+ PortBitADi = 16, // Port bit num A Dir J2P03 D25pin 9 checked
+ PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14 checked
+ PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16 checked
#endif
#if defined (TARGET_MBED_LPC1768)
+ const char Target[] = "MBED LPC1768";
DigitalOut intled(LED2); // Correct
- DigitalOut charge_pump (PTE0); //J2p18 Following 5 inputs all wrong - TO DO sort which pins
- DigitalIn D25pin10 (PTD6); //jp217
- DigitalIn D25pin11 (PTE31); //j2p13
- DigitalIn D25pin12 (PTA17); //j2p11
- DigitalIn D25pin13 (PTA16); //j2p9
- DigitalIn D25pin15 (PTC17); //j2p7
+ DigitalOut charge_pumpD25pin1 (p25); //J2p18 Following 5 inputs all wrong - TO DO sort which pins
+// InterruptIn D25pin10_EStop (p26); //P2.0
+ DigitalIn D25pin10_EStop (p26); //P2.0
+ DigitalIn D25pin11_XLim (p24); //P2.2
+ DigitalIn D25pin12_YLim (p23); //P2.3
+ DigitalIn D25pin13_ZLim (p19); //P1.30
+ DigitalIn D25pin15_unkn (p20); //P1.31
SPISlave spidevice(p5, p6, p7, p8);
// Easy way to allocate port bits for *** N O T CHECKED for MBED_LPC1768 ***
// output of stepper motor Step and DIR sigs
@@ -91,44 +107,104 @@
/* Port 0 bits routed to DIP pins as follows:-
P0.00 p09 Reserve SDA
P0.01 p10 Reserve SCL
- P0.04 p30 CAN rd - USE X Step
- P0.05 p29 CAN td - USE X Dir
- P0.10 p28 SDA - USE Y Step
- P0.11 p27 SCL - USE Y Dir
- P0.15 p13 Tx - USE Z Step
- P0.16 p14 Rx - USE Z Dir
- P0.17 p12 miso - USE A Step
- P0.18 p11 mosi - Use A Dir
- P0.23 p15 A In
- P0.24 p16 A In
- P0.25 p17 A In
+ P0.04 p30 CAN rd - USE X Step D25pin 2
+ P0.05 p29 CAN td - USE X Dir D25pin 3
+ P0.10 p28 SDA - USE Y Step D25pin 4
+ P0.11 p27 SCL - USE Y Dir D25pin 5
+ P0.15 p13 Tx - USE Z Step D25pin 6
+ P0.16 p14 Rx - USE Z Dir D25pin 7
+ P0.17 p12 miso - USE A Step D25pin 8
+ P0.18 p11 mosi - Use A Dir D25pin 9
+ P0.23 p15 A In - Use S Step D25pin 14
+ P0.24 p16 A In - Use S Dir D25pin 16
+ P0.25 p17 Reserve A In
P0.26 p18 Reserve A Out
*/
- const int PortBitXSt = 4, // Port bit num X Step
- PortBitXDi = 5, // Port bit num X Dir
- PortBitYSt = 10, // Port bit num Y Step
- PortBitYDi = 11, // Port bit num Y Dir
- PortBitZSt = 15, // Port bit num Z Step
- PortBitZDi = 16, // Port bit num Z Dir
- PortBitASt = 17, // Port bit num A Step
- PortBitADi = 18; // Port bit num A Dir
+ const int PortBitXSt = 4, // Port bit num X Step
+ PortBitXDi = 5, // Port bit num X Dir
+ PortBitYSt = 10, // Port bit num Y Step
+ PortBitYDi = 11, // Port bit num Y Dir
+ PortBitZSt = 15, // Port bit num Z Step
+ PortBitZDi = 16, // Port bit num Z Dir
+ PortBitASt = 17, // Port bit num A Step
+ PortBitADi = 18, // Port bit num A Dir
+ PortBitSSt = 23, // Port bit num Spin Step
+ PortBitSDi = 24; // Port bit num Spin Dir
#endif
-const long
- XSt1 = 1 << PortBitXSt, XSt0 = 0,
- XDi1 = 1 << PortBitXDi, XDi0 = 0,
- YSt1 = 1 << PortBitYSt, YSt0 = 0,
- YDi1 = 1 << PortBitYDi, YDi0 = 0,
- ZSt1 = 1 << PortBitZSt, ZSt0 = 0,
- ZDi1 = 1 << PortBitZDi, ZDi0 = 0,
- ASt1 = 1 << PortBitASt, ASt0 = 0,
- ADi1 = 1 << PortBitADi, ADi0 = 0,
+const long // Assemble mask bits from now known port bit positions
+ XSt = 1 << PortBitXSt, // X axis Step signal
+ XDi = 1 << PortBitXDi, // X axis Direction signal
+ YSt = 1 << PortBitYSt, // Y axis Step, etc
+ YDi = 1 << PortBitYDi,
+ ZSt = 1 << PortBitZSt, // Z axis
+ ZDi = 1 << PortBitZDi,
+ ASt = 1 << PortBitASt, // A axis, not implemented in full, for e.g. rotary axis
+ ADi = 1 << PortBitADi,
+ SDi = 1 << PortBitSDi, // Spindle, also driven by Step and Dir signals up to 5kHz
+ SSt = 1 << PortBitSSt, // for 5000 RPM
+
+ SM_MASK = (XSt | XDi | YSt | YDi | ZSt | ZDi | ASt | ADi | SDi | SSt);
- SM_MASK = (XSt1 | XDi1 | YSt1 | YDi1 | ZSt1 | ZDi1 | ASt1 | ADi1);
+ PortOut Steppers (STEPPER_PORT, SM_MASK);
+ const long direction_swappers = XDi | YDi | ZDi | SDi; // include bit to swap direction
+/*
+ long read () {
+ return mysteppers ^ direction_swappers;
+ }
+ void write (long val) {
+ mysteppers = val ^ direction_swappers;
+ }
+ */
+class digital_readout_stuff { // class does not need to be named here
+ private:
+ char * readout (char * txt, long p) // p has running subtotal of all pulses issued to stepper driver
+ {
+ txt[0] = '+'; // constructs string e.g. "+123.456"
+ txt[8] = 0; // null terminated
+ if (p < 0) {
+ txt[0] = '-';
+ p = -p;
+ }
+ p *= 1000;
+ p /= pulses_per_mm;
+ if (p > 999999) {
+ sprintf(txt + 1, "OVRANGE");
+ return txt;
+ }
+ for(int k = 7; k > 0; k--) {
+ if (k == 4)
+ txt[k] = '.';
+ else {
+ txt[k] = '0' + (p % 10);
+ p /= 10;
+ }
+ }
+ return txt; // Returns pointer unaltered for subsequent use by e.g. cout
+ }
+ public:
+ signed long x, y, z, a; // Could easily expand up to six or more dros
+ bool dro_output; // To enabe / disable output to terminal
+ void init () {
+ x = y = z = a = 0; // These dro registers count pulses delivered to stepper motor driver
+ dro_output = true;
+ }
+ void update () {
+ static long t = 300; // Prevent display immediately upon startup
+ if (millisecs < t)
+ return;
+ if(!idle && dro_output) {
+ char txt[12];
+ pc.printf("dros X %s,", readout(txt, x)); // dro.n has running subtotal of all pulses issued to stepper driver.n
+ pc.printf(" Y %s, Z ", readout(txt, y));
+ pc.printf("%s, %s\r\n", readout(txt, z), running ? "R":"idle");
+ if(!running) idle = true; // Purpose of idle flag is to stop dro updates JUST AFTER run completes.
+ t = millisecs + 350; // Schedule next update after this non-blocking delay
+ }
+ }
+} dro_out ;
-PortOut mysteppers(STEPPER_PORT, SM_MASK);
-
-const int PIRBUFFSIZE = 10;
+const int PIRBUFFSIZE = 40; // pirbufgrain are 40 bytes each
class circbuff {
private:
pirbufgrain grain [PIRBUFFSIZE + 1];
@@ -165,7 +241,8 @@
bool readable () {return !buffempty; }
bool writeable () {return !bufffull; }
bool read (pirbufgrain & g) {
- if (buffempty) return false;
+// if (buffempty) return false; // TO DO Fix problem with buffempty flag
+ if (On_Q() == 0) return false;
bufffull = false;
grain_copy (grain[OffPtr++], g);
if (OffPtr >= PIRBUFFSIZE)
@@ -193,17 +270,44 @@
return 0;
}
+const double duration_multiplier = 60000000.0 / interrupt_period_us;
+void move_to_XYZ (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 target_cmd (struct singleGparam * a) {
+ pc.printf("Computer is %s\r\n", Target);
+}
/*
* Interrupt Service Routine
*/
+/* **** UNBROKEN VERSION 6th Feb 2014 ******************
void Numerically_Controlled_Oscillators_ISR () { // services Ticker 'NCO_gen' generated interrupts ***ISR***
static const int millisec_countdown = 1000 / interrupt_period_us;
const long bit_lutx[4] = {XSt0 | XDi0, XSt0 | XDi1, XSt1 | XDi1, XSt1 | XDi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
bit_luty[4] = {YSt0 | YDi0, YSt0 | YDi1, YSt1 | YDi1, YSt1 | YDi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
bit_lutz[4] = {ZSt0 | ZDi0, ZSt0 | ZDi1, ZSt1 | ZDi1, ZSt1 | ZDi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
bit_luta[4] = {ASt0 | ADi0, ASt0 | ADi1, ASt1 | ADi1, ASt1 | ADi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
- bits2shift = (sizeof (long) << 3) - 2;
+ bits2shift = (sizeof (long) << 3) - 2,
static unsigned long
// acc_s = 0L, // For Spindle motor, probably not needed as may be pwm
acc_a = 0L,
@@ -272,20 +376,202 @@
charge_pump = ticks & 0x02;
intled = 0; // LED off
} // end of interrupt handler
-
+*/
/*
* End of Interrupt Service Routine
*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+* Interrupt Service Routine
+*/
+#define STEP_IDLE_HI
+//#define STEP_IDLE_LO
+void Numerically_Controlled_Oscillators_ISR () { // services Ticker 'NCO_gen' generated interrupts ***ISR***
+ static const int millisec_countdown = 1000 / interrupt_period_us;
+ const long step_mask = ASt | XSt | YSt | ZSt, // Added 6th Feb 14 Mask Does NOT include spindle bits
+ dir_mask = ADi | XDi | YDi | ZDi; // Added 6th Feb 14 Mask Does NOT include spindle bits
+ static unsigned long
+ acc_spin = 0L,
+ acc_a = 0L,
+ acc_x = 0L,
+ acc_y = 0L,
+ acc_z = 0L;
+ static long mscount = millisec_countdown;
+ static long dir_bits = 0L, oldSteps = 0L; // Added 6th Feb 14
+ long acts, tmp, newSteps, stbits;
+
+ intled = 1; // LED on for duration of interrupt service - point for scope probing
+ ticks++; // count of interrupts serviced
+ if(!--mscount) { // Maintain global counter of elapsed milli seconds
+ mscount = millisec_countdown;
+ millisecs++;
+ }
+ acc_spin += pir_spin;
+ tmp = Steppers ^ direction_swappers;
+#if defined STEP_IDLE_LO
+ tmp &= ~step_mask; // Step bits prepared for idle lo
+#endif
+#if defined STEP_IDLE_HI
+ tmp |= step_mask; // Step bits prepared for idle hi
+#endif
+ if (acc_spin & 0x80000000) { tmp |= SSt; }
+ else { tmp &= ~SSt; }
+// mysteppers = tmp;
+ if (running) {
+ acc_x += pir_x; // Update phase of signals in accumulators
+ acc_y += pir_y;
+ acc_z += pir_z;
+ acc_a += pir_a; // not yet implemented
+
+ newSteps = 0L; // Added 6th Feb 14
+ if (acc_a & 0x80000000) newSteps |= ASt;// Added 6th Feb 14
+ if (acc_x & 0x80000000) newSteps |= XSt;// Added 6th Feb 14
+ if (acc_y & 0x80000000) newSteps |= YSt;// Added 6th Feb 14
+ if (acc_z & 0x80000000) newSteps |= ZSt;// Added 6th Feb 14
+ stbits = newSteps ^ oldSteps; // Any bit of stbits set to initiate a Step pulse
+ acts = dir_bits | stbits; //
+ oldSteps = newSteps; // Added 6th Feb 14
+// tmp = acts ^ step_mask; // Invert clock - Arc Euro stepp motor driver only goes into half current mode this way
+ tmp ^= stbits;
+ Steppers = tmp ^ direction_swappers; // Output signals to stepper motor drivers, next update dros from 'clocked' bits CLOCK IDLES HIGH
+
+ if(acts & XSt) { // got clk edge for axis X
+ if (acts & XDi)
+ dro_out.x--;
+ else dro_out.x++;
+ }
+ if(acts & YSt) { // got clk edge for axis Y
+ if (acts & YDi)
+ dro_out.y--;
+ else dro_out.y++;
+ }
+ if(acts & ZSt) { // got clk edge for axis Z
+ if (acts & ZDi)
+ dro_out.z--;
+ else dro_out.z++;
+ }
+ if (tickrun <= ticks) { // End of a machine movement detected, start next move here if possible
+ if (new_run_pending) {
+ pir_a = pir_a_next;
+ pir_x = pir_x_next;
+ pir_y = pir_y_next;
+ pir_z = pir_z_next;
+ dir_bits = 0; // Added 6th Feb 14
+ if (pir_a & 0x80000000) dir_bits |= ADi;// Added 6th Feb 14 read sign bits
+ if (pir_x & 0x80000000) dir_bits |= XDi;// Added 6th Feb 14
+ if (pir_y & 0x80000000) dir_bits |= YDi;// Added 6th Feb 14
+ if (pir_z & 0x80000000) dir_bits |= ZDi;// Added 6th Feb 14
+ acts = Steppers ^ direction_swappers; // read output lines
+ acts &= ~dir_mask;
+ acts |= dir_bits;
+ Steppers = acts ^ direction_swappers;
+ tickrun = ticks + ticks_next;
+ running = true; // Start the new run
+ new_run_pending = false; // Clear the flag which initiated this update
+ idle = false;
+ } // End of if (new_run_pending) {
+ else { // End of machine movement AND no new_run_pending
+ running = false;
+ move_ended = true;
+ pir_x = 0L; // stop all stepper motors
+ pir_y = 0L;
+ pir_z = 0L;
+ pir_a = 0L;
+ // ticks = 0L; // Simply to avoid having to think about overflow problems
+ }
+ }
+ }
+ else { // Not running. Grab next data here when or if available
+ Steppers = tmp ^ direction_swappers;
+ if (new_run_pending) { // Pick up on flag set elsewhere
+ pir_a = pir_a_next;
+ pir_x = pir_x_next;
+ pir_y = pir_y_next;
+ pir_z = pir_z_next;
+ dir_bits = 0; // Added 6th Feb 14
+ if (pir_a & 0x80000000) dir_bits |= ADi;// Added 6th Feb 14 read sign bits
+ if (pir_x & 0x80000000) dir_bits |= XDi;// Added 6th Feb 14
+ if (pir_y & 0x80000000) dir_bits |= YDi;// Added 6th Feb 14
+ if (pir_z & 0x80000000) dir_bits |= ZDi;// Added 6th Feb 14
+ acts = Steppers ^ direction_swappers; // read output lines
+ acts &= ~dir_mask;
+ acts |= dir_bits;
+ Steppers = acts ^ direction_swappers;
+ tickrun = ticks + ticks_next;
+ running = true; // Start the new run
+ new_run_pending = false; // Clear the flag which initiated this update
+ idle = false;
+ } // end of if (new_run_pending) { // Pick up on flag set elsewhere
+ } // end of else { // Not running. Grab next data here when or if available
+ charge_pumpD25pin1 = ticks & 0x01; // Can use 0x01 or 0x02 here to alter charge pump freq
+ intled = 0; // LED off
+} // end of interrupt handler
+
+/*
+* End of Interrupt Service Routine
+*/
+bool spindle_running () {
+ return pir_spin;
+}
+void spindle_control (double ss) {
+ long t, p;
+ pir_spin = (signed long) (ss * spindle_factor);
+ t = ticks;
+ while (t == ticks) {} // wait until just after next interrupt
+ p = Steppers ^ direction_swappers;
+ if (pir_spin & 0x80000000)
+ p |= SDi;
+ else
+ p &= ~SDi;
+ Steppers = p ^ direction_swappers;
+ pc.printf("Done setting spindle speed %.0f, delay = %d\r\n", ss, ticks - t);
+}
+
+
+/*
+void scmd (struct singleGparam * a) {
+ long t, p;
+ 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 %.0f Can set Pos or Neg for fwd/rev\r\n", a[1].dbl);
+ 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;
+ pc.printf("Done setting spindle, delay = %d", ticks - t);
+}
+*/
void newpir_updater (void const * name) {
- static long x, y, z, count = 0;
+ static long x, y, z;//, count = 0;
struct pirbufgrain outs;
- pc.printf("Arrived at newpir_updater\r\n");
+// pc.printf("Arrived at newpir_updater\r\n");
while (true) {
- while (!move_ended || !CircBuff.readable()) {
+// while (!move_ended || !CircBuff.readable()) { ** TO DO ** Solve problem with empty flag
+ while (!move_ended || CircBuff.On_Q() == 0) {
osThreadYield();
- }
+ } // Proceed beyond here only when move_ended AND CircBuff.readable() both TRUE
CircBuff.read(outs);
x = (long)(outs.f_rate * outs.x); // These take much CPU time !!
y = (long)(outs.f_rate * outs.y);
@@ -294,55 +580,23 @@
pir_x_next = x;
pir_y_next = y;
pir_z_next = z;
- move_ended = false;
+ move_ended = idle = false;
new_run_pending = true; // cleared and 'running' flag set in interrupt handler
- idle = false;
- count++;
+// idle = false;
+// count++;
// pc.printf("CircB tot %d\r\n", count);
}
}
-class digital_readout_stuff { // class does not need to be named here
- char * readout (char * txt, long p) // p has running subtotal of all pulses issued to stepper driver
- {
- txt[0] = '+'; // constructs string e.g. "+123.456"
- txt[8] = 0; // null terminated
- if (p < 0) {
- txt[0] = '-';
- p = -p;
- }
- p *= 1000;
- p /= pulses_per_mm;
- if (p > 999999) {
- sprintf(txt + 1, "OVRANGE");
- return txt;
- }
- for(int k = 7; k > 0; k--) {
- if (k == 4)
- txt[k] = '.';
- else {
- txt[k] = '0' + (p % 10);
- p /= 10;
- }
- }
- return txt; // Returns pointer unaltered for subsequent use by e.g. cout
- }
- public:
- void update () {
- static long t = 0;
- if (millisecs < t)
- return;
- if(!idle && dro.dro_output) {
- char txt[12];
- pc.printf("dros X %s,", readout(txt, dro.x)); // dro.n has running subtotal of all pulses issued to stepper driver.n
- pc.printf(" Y %s, Z ", readout(txt, dro.y));
- pc.printf("%s, %s\r\n", readout(txt, dro.z), running ? "runn":"idle");
- if(!running) idle = true; // Purpose of idle flag is to stop dro after run completes.
- t = millisecs + 350; // Schedule next update after this non-blocking delay
- }
- }
-} dro_out ;
+void flags_report_cmd (struct singleGparam * a) { // Diagnostic helper function
+ pc.printf("Flags Report\r\nRunning %s\r\n", running ? "T":"F");
+ pc.printf("idle %s\r\n", idle ? "T":"F");
+ pc.printf("new_run_pending %s\r\n", new_run_pending ? "T":"F");
+ pc.printf("move_ended %s\r\n", move_ended ? "T":"F");
+ pc.printf("CircBuff.readable() %s\r\n", CircBuff.readable() ? "T":"F");
+ pc.printf("On CircBuff %d\r\n", CircBuff.On_Q());
+}
/*void taskone (void const * name)
{
@@ -370,39 +624,81 @@
osThreadYield();
}
}*/
+/*
+#define ESTOP 0x100
+#define XLIM 1
+#define YLIM 2
+#define ZLIM 4
+#define UNKN 8
+*/
+class inputsreaderstuff {
+ private:
+ long ins_now;//, ins_old, ins_changed;
+ public:
+ void init () { ins_now = 0L;}//ins_old = ins_changed = 0L; }
+ long read () {
+ ins_now = 0;
+ if (D25pin10_EStop) ins_now |= ESTOP;
+ if (D25pin11_XLim) ins_now |= XLIM;
+ if (D25pin12_YLim) ins_now |= YLIM;
+ if (D25pin13_ZLim) ins_now |= ZLIM;
+ if (D25pin15_unkn) ins_now |= UNKN;
+// ins_changed = ins_now ^ ins_old;
+// ins_old = ins_now;
+ return ins_now;
+ }
+// long changed () { return ins_changed; }
+ } Inputs_From_Machine;
+
+void report_inputs () {
+ long i = Inputs_From_Machine.read();
+ pc.printf("Inputs: EStop %d, XLim %d, YLim %d, ", i & ESTOP ? 1:0, i & XLIM ? 1:0, i & YLIM ? 1:0);
+ pc.printf("ZLim %d, unkn %d\r\n", i & ZLIM ? 1:0, i & UNKN ? 1:0);
+}
+
+//void Emergency_Stop_Interrupt () {
+// pc.printf("Emergency Stop Activated !!\r\n");
+// spindle_control (0.0); // Stop spindle rotation
+//}
int main() {
pc.baud(BAUD); // comms to 'PuTTY' serial terminal via mbed usb
- dro.x = dro.y = dro.z = 0; // These dro registers count pulses delivered to stepper motor driver
- dro.dro_output = true;
+// D25pin11_XLim.mode (PullDown); External resistors now fitted
+// D25pin12_YLim.mode (PullDown);
+// D25pin13_ZLim.mode (PullDown);
+// D25pin15_unkn.mode (PullDown);
+// D25pin10_EStop.mode (PullDown);
+// D25pin10_EStop.rise (& Emergency_Stop_Interrupt);
+// D25pin10_EStop.fall (& Emergency_Stop_Interrupt);
+
more_setup () ; // Zeros one 'pirs' structure 'last_position'
+ dro_out.init();
CircBuff.init ();
+ Inputs_From_Machine.init ();
spidevice.format(8, 0); // 8 bits mode 0, // p11 mosi, p12 miso, p13 sclk ** ONLY 8 BIT **
spidevice.frequency(12000000); // 12MHz bit rate
- pc.printf("\r\n*\n*\n");
-#if defined (TARGET_KL25Z)
- pc.printf ("Found device Freescale KL25Z\r\n");
-#endif
-#if defined (TARGET_KL46Z)
- pc.printf ("Found device Freescale KL46Z\r\n");
-#endif
-#if defined (TARGET_MBED_LPC1768)
- pc.printf ("Found device MBED_LPC1768\r\n");
-#endif
+ pc.printf("\r\n*\n*\nFound Computer %s\r\n", Target);
pc.printf("Welcome to the CNC tester\r\nStep pulses required to move 1.0mm = %9.0f\r\n", pulses_per_mm);
- pc.printf("PIR 'n' for 1mm per min = %9.0f\r\ntop speed = %6.5f mm per min\r\n\n", n_for_onemmpermin, max_mm_per_min);
+ pc.printf("PIR 'n' for 1mm per min = %9.0f\r\ntop speed = %6.1f mm per min\r\n\n", n_for_onemmpermin, max_mm_per_min);
NCO_gen.attach_us(&Numerically_Controlled_Oscillators_ISR, (long)interrupt_period_us);// Have setup timed interrupts, let other code deal
// Thread threadnametaskone (taskone, (void *)"task one stuff");
// Thread t8 (tasktwo, (void *)"task two");
Thread tsr2 (newpir_updater, (void *)"read from CircBuff and move");
// Thread tthree (taskthree, (void *)"task three");
- Thread patterngen (lissajous, (void *)"Loading Lissajous") ;
+// Thread patterngen (lissajous, (void *)"Loading Lissajous") ;
Thread comlin (command_line_interpreter, (void *)"cli"); // Read any instructions arriving via serial port and act upon them
- pc.printf("Added cli thread\r\n");
+ long ins, ins_old, ins_changed = 0;
+ ins = ins_old = Inputs_From_Machine.read ();
move_ended = true; // Needed to kickstart system
while(1) { // Round Robin loop
dro_out.update (); // Update DRO readings if, and as often as needed
+ ins = Inputs_From_Machine.read ();
+ ins_changed = ins ^ ins_old;
+ ins_old = ins;
+ if (ins_changed)
+ pc.printf("Inputs Have Changed 0x%x, read 0x%x\r\n", ins_changed, ins);
+// pc.printf(".");
osThreadYield(); //
} // end of Round Robin loop
} // end of int main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos-marcusbirkin.lib Thu Feb 20 09:27:18 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/marcusbirkin/code/mbed-rtos/#98a14efb7882
--- a/mbed-rtos.lib Thu Feb 06 08:45:02 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed-rtos/#f88660a9bed1