From 2b07f865c6417324b4187d9cb58422ffbf767b51 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 16:09:13 -0500 Subject: [PATCH] Changed base spindle control and speed functions --- g2core/alarm.cpp | 2 +- g2core/canonical_machine.cpp | 2 +- g2core/cycle_probing.cpp | 6 +- g2core/gcode_parser.cpp | 8 +- g2core/spindle.cpp | 214 ++++++++++++++++++----------------- g2core/spindle.h | 67 +++++------ 6 files changed, 155 insertions(+), 144 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 9516d98e..e5e23334 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -123,7 +123,7 @@ stat_t cm_is_alarmed() void cm_halt_all(void) { cm_halt_motion(); - spindle_off_immediate(); + spindle_control_immediate(SPINDLE_OFF, false); cm_coolant_off_immediate(); } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index fbbe3c84..974a6235 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1555,7 +1555,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_select_plane(cm->default_select_plane); // reset to default arc plane cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default - spindle_off_immediate(); // M5 + spindle_control_immediate(SPINDLE_OFF, false); // M5 cm_coolant_off_immediate(); // M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index ff254fda..68751fa7 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -251,8 +251,8 @@ static uint8_t _probing_init() { gpio_set_probing_mode(pb.probe_input, true); // turn off spindle and start the move - spindle_optional_pause(true); // pause the spindle if it's on - return (_set_pb_func(_probing_start)); // start the probe move + spindle_pause(); // pause the spindle if it's on + return (_set_pb_func(_probing_start)); // start the probe move } /* @@ -391,7 +391,7 @@ static void _probe_restore_settings() { cm_set_distance_mode(pb.saved_distance_mode); // restart spindle if it was paused - spindle_resume(spindle.dwell_seconds); + spindle_resume(); // cancel the feed modes used during probing cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index b51f6699..ba840539 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -733,14 +733,18 @@ static stat_t _execute_gcode_block(char *active_comment) cm_set_model_linenum(gv.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, F_word); // F - EXEC_FUNC(spindle_queue_speed, S_word); // S + EXEC_FUNC(spindle_speed_sync, S_word); // S + if (gf.sso_control) { // spindle speed override ritorno(spindle_override_control(gv.P_word, gf.P_word)); } EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written EXEC_FUNC(cm_change_tool, tool_change); // M6 - EXEC_FUNC(spindle_queue_control, spindle_control); // spindle CW, CCW, OFF + + if (gf.spindle_control) { // spindle OFF, CW, CCW + ritorno(spindle_control_sync(gv.spindle_control, false)); + } EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 0e5dcca6..750174c5 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -39,13 +39,13 @@ /**** Allocate structures ****/ -cmSpindleton_t spindle; +spSpindle_t spindle; /**** Static functions ****/ static void _exec_spindle_speed(float *value, bool *flag); static void _exec_spindle_control(float *value, bool *flag); -static float _get_spindle_pwm (spState state, spDir direction); +static float _get_spindle_pwm (spState state, spControl direction); /*********************************************************************************** * spindle_init() @@ -65,95 +65,55 @@ void spindle_reset() float value[AXES] = { 0,0,0,0,0,0 }; // set spindle speed to zero bool flags[] = { 1,0,0,0,0,0 }; _exec_spindle_speed(value, flags); - spindle_off_immediate(); // turn spindle off + spindle_control_immediate(SPINDLE_CONTROL_OFF, false); // turn spindle off } /*********************************************************************************** - * spindle_off_immediate() - turn on/off spindle w/o planning - * spindle_optional_pause() - pause spindle immediately if option is true - * spindle_resume() - restart a paused spindle with an optional dwell + * spindle_pause() - pause spindle immediately if option is true + * spindle_resume() - restart a paused spindle with an optional dwell + * spindle_control_immediate() - execute spindle control immediately + * spindle_control_sync() - queue a spindle control to the planner buffer + * _exec_spindle_control() - actually execute the spindle command */ -void spindle_off_immediate() +void spindle_pause() +{ + if (spindle.state == SPINDLE_ON) { + spindle_control_sync(SPINDLE_CONTROL_OFF, true); + } +} + +void spindle_resume() +{ + if (spindle.state == SPINDLE_PAUSE) { + spindle_control_sync(SPINDLE_CONTROL_CW, false); + } +} + +stat_t spindle_control_immediate(uint8_t control, bool pause) { - spindle.state = SPINDLE_OFF; float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; + bool flags[] = { 1,0, pause, 0,0,0 }; + + if (control != SPINDLE_CONTROL_OFF) { + value[0] = SPINDLE_ON; + value[1] = control; + flags[1] = true; + } _exec_spindle_control(value, flags); + return(STAT_OK); } -void spindle_optional_pause(bool option) +stat_t spindle_control_sync(uint8_t control, bool pause) // uses spControl arg: OFF, CW, CCW { - if (option && spindle.state == SPINDLE_ON) { - spindle_off_immediate(); - spindle.state = SPINDLE_PAUSE; + float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; + bool flags[] = { 1,0, pause, 0,0,0 }; + + if (control != SPINDLE_CONTROL_OFF) { + value[0] = SPINDLE_ON; + value[1] = control; + flags[1] = true; } -} - -void spindle_resume(float dwell_seconds) -{ - if(spindle.state == SPINDLE_PAUSE) { - spindle.state = SPINDLE_ON; - mp_request_out_of_band_dwell(dwell_seconds); - float value[] = { (float)SPINDLE_ON, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_control(value, flags); - } -} - -/*********************************************************************************** - * spindle_queue_speed() - queue the S parameter to the planner buffer - * _exec_spindle_speed() - spindle speed callback from planner queue - */ - -stat_t spindle_queue_speed(float speed) -{ - if (speed < spindle.speed_min) { - return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); - } - if (speed > spindle.speed_max) { - return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); - } - - float value[AXES] = { speed, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_spindle_speed, value, flags); - return (STAT_OK); -} - -static void _exec_spindle_speed(float *value, bool *flag) -{ - if (flag[0]) { - spindle.speed = value[0]; - } - - if (flag[1]) { - spindle.direction = (spDir)value[1]; - } - - // update spindle speed if we're running - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); -} - -/*********************************************************************************** - * spindle_queue_control() - queue the spindle command to the planner buffer. Observe PAUSE - * _exec_spindle_control() - actually execute the spindle command - */ - -stat_t spindle_queue_control(uint8_t control) // requires SPINDLE_CONTROL_xxx style args -{ - if (control == SPINDLE_CONTROL_OFF) { - spindle.state = SPINDLE_OFF; - } else { - spindle.state = SPINDLE_ON; - if (control == SPINDLE_CONTROL_CW) { - spindle.direction = SPINDLE_CW; - } else { - spindle.direction = SPINDLE_CCW; - } - } - float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; mp_queue_command(_exec_spindle_control, value, flags); return(STAT_OK); } @@ -165,27 +125,70 @@ stat_t spindle_queue_control(uint8_t control) // requires SPINDLE_CONTROL_xxx s static void _exec_spindle_control(float *value, bool *flag) { - // set the direction first - if (flag[1]) - { - spindle.direction = (spDir)value[1]; // record spindle direction in the struct - if (spindle.direction ^ spindle.dir_polarity) { + if (flag[1]) { // set the direction first + spindle.direction = (spControl)value[1]; // record spindle direction in the struct + if ((spindle.direction-1) ^ spindle.dir_polarity) { // take CW/CCW down to 0 or 1 _set_spindle_direction_bit_hi(); } else { _set_spindle_direction_bit_lo(); } } - - if (flag[0]) - { - // set on/off. Mask out PAUSE and consider it OFF - spindle.state = (spState)value[0]; // record spindle state in the struct - if ((spindle.state & 0x01) ^ spindle.enable_polarity) { + if (flag[0]) { // set on/off + spindle.state = (spState)value[0]; // record spindle state in the struct + if ((spindle.state & 0x01) ^ spindle.enable_polarity) { // mask out PAUSE bit and consider it to be OFF _set_spindle_enable_bit_lo(); } else { _set_spindle_enable_bit_hi(); } } + if (flag[2]) { // set pause + spindle.state = SPINDLE_PAUSE; + } + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); +} + +/*********************************************************************************** + * spindle_queue_speed() - queue the S parameter to the planner buffer + * _exec_spindle_speed() - spindle speed callback from planner queue + */ + +stat_t spindle_speed_immediate(float speed) +{ + if (speed < spindle.speed_min) { + return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); + } + if (speed > spindle.speed_max) { + return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); + } + float value[AXES] = { speed, 0,0,0,0,0 }; +// bool flags[] = { 1,0,0,0,0,0 }; + _exec_spindle_speed(value, nullptr); + return (STAT_OK); +} + +stat_t spindle_speed_sync(float speed) +{ + if (speed < spindle.speed_min) { + return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); + } + if (speed > spindle.speed_max) { + return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); + } + float value[AXES] = { speed, 0,0,0,0,0 }; +// bool flags[] = { 1,0,0,0,0,0 }; + mp_queue_command(_exec_spindle_speed, value, nullptr); + return (STAT_OK); +} + +static void _exec_spindle_speed(float *value, bool *flag) +{ + spindle.speed = value[0]; +/* + if (flag[1]) { + spindle.direction = (spDir)value[1]; + } +*/ + // update spindle speed if we're running pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } @@ -193,15 +196,15 @@ static void _exec_spindle_control(float *value, bool *flag) * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ -static float _get_spindle_pwm (spState state, spDir direction) +static float _get_spindle_pwm (spState state, spControl direction) { float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; - if (direction == SPINDLE_CW ) { + if (direction == SPINDLE_CONTROL_CW ) { speed_lo = pwm.c[PWM_1].cw_speed_lo; speed_hi = pwm.c[PWM_1].cw_speed_hi; phase_lo = pwm.c[PWM_1].cw_phase_lo; phase_hi = pwm.c[PWM_1].cw_phase_hi; - } else { // if (direction == SPINDLE_CCW ) { + } else { // if (direction == SPINDLE_CONTROL_CCW ) { speed_lo = pwm.c[PWM_1].ccw_speed_lo; speed_hi = pwm.c[PWM_1].ccw_speed_hi; phase_lo = pwm.c[PWM_1].ccw_phase_lo; @@ -226,20 +229,10 @@ static float _get_spindle_pwm (spState state, spDir direction) /*********************************************************************************** * spindle_override_control() - * spindle_sp_start_spindle_override() - * sp_end_spindle_override() + * spindle_start_override() + * spindle_end_override() */ -void spindle_start_override(const float ramp_time, const float override_factor) -{ - return; -} - -void spindle_end_override(const float ramp_time) -{ - return; -} - stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 { bool new_enable = true; @@ -269,6 +262,17 @@ stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 return (STAT_OK); } +void spindle_start_override(const float ramp_time, const float override_factor) +{ + return; +} + +void spindle_end_override(const float ramp_time) +{ + return; +} + + /**************************** * END OF SPINDLE FUNCTIONS * ****************************/ diff --git a/g2core/spindle.h b/g2core/spindle.h index f2446155..9258f2f3 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -28,22 +28,6 @@ #ifndef SPINDLE_H_ONCE #define SPINDLE_H_ONCE -typedef enum { // how spindle controls are presented by the Gcode parser - SPINDLE_CONTROL_OFF = 0, // M5 - SPINDLE_CONTROL_CW, // M3 - SPINDLE_CONTROL_CCW // M4 -} spControl; - -typedef enum { // spindle direction state - SPINDLE_CW = 0, - SPINDLE_CCW -} spDir; - - -// *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h -// These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 -// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types - typedef enum { SPINDLE_DISABLED = 0, // spindle will not operate SPINDLE_PLAN_TO_STOP, // spindle operating, plans to stop @@ -51,19 +35,32 @@ typedef enum { } spMode; #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS +// Note on spControl: +// This enum is used to both request the spindle operation (ON, CW, CCW), +// and to record spindle direction (1=CW, 2=CCW) in spindle.direction +typedef enum { // how spindle controls are presented by the Gcode parser + SPINDLE_CONTROL_OFF = 0, // M5 + SPINDLE_CONTROL_CW = 1, // M3 + SPINDLE_CONTROL_CCW = 2 // M4 +} spControl; + +// *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h +// These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 +// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types + typedef enum { // Note: These values agree with SPINDLE_ACTIVE_LOW = 0, // Will set output to 0 to enable the spindle or CW direction SPINDLE_ACTIVE_HIGH = 1, // Will set output to 1 to enable the spindle or CW direction } spPolarity; -typedef enum { // basic spindle state machine +typedef enum { // basic spindle state machine. Do not change this enum SPINDLE_OFF = 0, - SPINDLE_ON, // spindle on and at speed - SPINDLE_PAUSE, // meaning it was on and now it's off - SPINDLE_WAITING // spindle not at speed yet + SPINDLE_ON = 1, // spindle on and at speed + SPINDLE_PAUSE = 2, // meaning it was on and now it's off + SPINDLE_WAITING = 3 // spindle not at speed yet } spState; -typedef enum { +typedef enum { // electronic speed controller for some spindles ESC_ONLINE = 0, ESC_OFFLINE, ESC_LOCKOUT, @@ -73,22 +70,22 @@ typedef enum { #define SPINDLE_OVERRIDE_ENABLE false #define SPINDLE_OVERRIDE_FACTOR 1.00 -#define SPINDLE_OVERRIDE_MIN 0.05 // 5% -#define SPINDLE_OVERRIDE_MAX 2.00 // 200% +#define SPINDLE_OVERRIDE_MIN 0.05 // 5% +#define SPINDLE_OVERRIDE_MAX 2.00 // 200% #define SPINDLE_OVERRIDE_RAMP_TIME 1 // change sped in seconds /* * Spindle control structure */ -typedef struct cmSpindleSingleton { +typedef struct spSpindle { // Public and settable spMode mode; // spondle operating mode float speed; // S in RPM float speed_min; // minimum settable spindle speed float speed_max; // maximum settable spindle speed - spDir direction; // CW, CCW + spControl direction; // 1=CW, 2=CCW spPolarity enable_polarity; // 0=active low, 1=active high spPolarity dir_polarity; // 0=clockwise low, 1=clockwise high float dwell_seconds; // dwell on spindle resume @@ -104,8 +101,8 @@ typedef struct cmSpindleSingleton { uint32_t esc_boot_timer; // When the ESC last booted up uint32_t esc_lockout_timer; // When the ESC lockout last triggered -} cmSpindleton_t; -extern cmSpindleton_t spindle; +} spSpindle_t; +extern spSpindle_t spindle; /* * Global Scope Functions @@ -113,11 +110,17 @@ extern cmSpindleton_t spindle; void spindle_init(); void spindle_reset(); -stat_t spindle_queue_speed(float speed); // S parameter -stat_t spindle_queue_control(uint8_t control); // M3, M4, M5 integrated spindle control -void spindle_off_immediate(void); -void spindle_optional_pause(bool option); // stop spindle based on system options selected -void spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state + +void spindle_pause(void); +void spindle_resume(void); +stat_t spindle_control_immediate(uint8_t control, bool pause); +stat_t spindle_control_sync(uint8_t control, bool pause); +stat_t spindle_speed_immediate(float speed); // S parameter +stat_t spindle_speed_sync(float speed); // S parameter + +//void spindle_off_immediate(void); +//void spindle_optional_pause(bool option); // stop spindle based on system options selected +//void spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state stat_t spindle_override_control(const float P_word, const bool P_flag); // M51 void spindle_start_override(const float ramp_time, const float override_factor);