From 65eeab7ac7c78dad9cb4c536c4597197d433c4ad Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 14 Jan 2017 11:49:23 -0500 Subject: [PATCH] Testing and tweaks --- g2core/canonical_machine.cpp | 4 +- g2core/canonical_machine.h | 2 +- g2core/config.cpp | 4 +- g2core/config_app.cpp | 43 +++---- g2core/gcode_parser.cpp | 2 +- g2core/spindle.cpp | 227 ++++++++++++++--------------------- g2core/spindle.h | 102 +++++++--------- 7 files changed, 160 insertions(+), 224 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ab85fa20..c1083edb 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1353,8 +1353,8 @@ static void _exec_feed_override(const bool m48_enable, const bool m50_enable, co * cm_m48_enable() - M48, M49 * * M48 is the master enable for manual feedrate override and spindle override - * If M48 is asserted M50 (mfo), M50.1 (mto) and M51 (sso) settings are in effect - * If M49 is asserted M50 (mfo), M501. (mto) and M51 (sso) settings are in ignored + * If M48 is asserted M50 (mfo), M50.1 (mto) and M51 (spo) settings are in effect + * If M49 is asserted M50 (mfo), M501. (mto) and M51 (spo) settings are in ignored * * See http://linuxcnc.org/docs/html/gcode/m-code.html#sec:M48,-M49-Speed-and-Feed-Override-Control */ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 821bb900..23386d38 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -432,7 +432,7 @@ void cm_reset_overrides(void); stat_t cm_m48_enable(uint8_t enable); // M48, M49 stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50 stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1 -// See spindle.cpp for cm_sso_control() // M51 +// See spindle.cpp for cm_spo_control() // M51 // Program Functions (4.3.10) void cm_cycle_start(void); // (no Gcode) diff --git a/g2core/config.cpp b/g2core/config.cpp index 4ef94f40..2e380328 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -532,13 +532,13 @@ void nv_get_nvObj(nvObj_t *nv) // special processing for system groups and stripping tokens for groups if (nv->group[0] != NUL) { - if (GET_TABLE_BYTE(flags) & F_NOSTRIP) { + if (cfgArray[nv->index].flags & F_NOSTRIP) { nv->group[0] = NUL; } else { strcpy(nv->token, &nv->token[strlen(nv->group)]); // strip group from the token } } - ((fptrCmd)GET_TABLE_WORD(get))(nv); // populate the value + ((fptrCmd)cfgArray[nv->index].get)(nv); // populate the value } nvObj_t *nv_reset_nv(nvObj_t *nv) // clear a single nvObj structure diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 0dd3b4eb..a615368f 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -835,6 +835,28 @@ const cfgItem_t cfgArray[] = { { "jid","jidc",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, + // Spindle functions + { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, + { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, + { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spinup delay +// { "sp","spds", _fip, 2, sp_print_spds, sp_get_spds, sp_set_spds, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spindown delay +// { "sp","spdr", _fip, 2, sp_print_spdr, sp_get_spdr, sp_set_spdr, (float *)&cs.null, SPINDLE_DWELL_TIME }, // direction reversal delay + { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, + { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, + { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, + { "sp","spdp", _fip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, + { "sp","spoe", _fip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, + { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, + { "sp","spc", _f0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state + { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed + + // Coolant functions + { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, + { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, + { "sys","coph",_fipn,0, cm_print_coph,get_ui8, set_01, (float *)&coolant.pause_on_hold, COOLANT_PAUSE_ON_HOLD }, + { "", "com", _fiz, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable + { "", "cof", _fiz, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable + // General system parameters { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, @@ -851,27 +873,6 @@ const cfgItem_t cfgArray[] = { { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors - // Spindle functions - { "sp","spmo",_fipn, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, - { "sp","spep",_fipn, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, - { "sp","spdp",_fipn, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, - { "sp","spph",_fipn, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, - { "sp","spdw",_fipn, 2, sp_print_spdw, sp_get_spdw, sp_set_spdw, (float *)&cs.null, SPINDLE_DWELL_TIME }, - { "sp","spsn",_fipn, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, - { "sp","spsm",_fipn, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, - { "sp","ssoe",_fipn, 0, sp_print_ssoe, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, - { "sp","sso", _fipn, 3, sp_print_sso, sp_get_sso, sp_set_sso, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, - { "", "sps", _fiz, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // get spindle speed - { "", "spe", _fiz, 0, sp_print_spe, sp_get_spe, set_nul, (float *)&cs.null, 0 }, // get spindle enable state - { "", "spd", _fiz, 0, sp_print_spd, sp_get_spd, sp_set_spd, (float *)&cs.null, 0 }, // get spindle direction - - // Coolant functions - { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, - { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, - { "sys","coph",_fipn,0, cm_print_coph,get_ui8, set_01, (float *)&coolant.pause_on_hold, COOLANT_PAUSE_ON_HOLD }, - { "", "com", _fiz, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable - { "", "cof", _fiz, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable - // Communications and reporting parameters #ifdef __TEXT_MODE { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 5faef621..b834198b 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -743,7 +743,7 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_change_tool, tool_change); // M6 if (gf.spindle_control) { // spindle OFF, CW, CCW - ritorno(spindle_control_sync((spState)gv.spindle_control)); + ritorno(spindle_control_sync((spControl)gv.spindle_control)); } EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 61b69d19..63f32e50 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -45,7 +45,7 @@ spSpindle_t spindle; 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, spState direction); +static float _get_spindle_pwm (spControl state, spControl direction); /*********************************************************************************** * spindle_init() @@ -87,36 +87,45 @@ void spindle_reset() * In this case spindle.state is SPINDLE_WAIT until move is "played", and dwell completes. * spindle_control_immediate() has no dwell behavior. * - * - SPINDLE_PAUSE, when in CW or CCW state, turns spindle OFF and preserves PAUSE in spindle.state. - * If PAUSE is received when not in CW or CCW state it is ignored. + * - SPINDLE_PAUSE is only applicable to CW and CCW states. It forces the spindle OFF and + * sets spindle.state to PAUSE. If PAUSE is received when not in CW or CCW state it is ignored. * * - SPINDLE_RESUME, if in a PAUSE state, reverts to previous SPINDLE_CW or SPINDLE_CCW. - * If RESUME is received from spindle_control_sync() the same dwell and WAIT behavior occurs. - * If RESUME is received when not in a PAUSED state it is ignored. + * The SPEED is not changed, and if it were changed in the interim the "new" speed is used. + * If RESUME is received from spindle_control_sync() the usual dwell and WAIT behavior occurs. + * If RESUME is received when not in a PAUSED state it is ignored. This recognizes that the main + * reason an immediate command would be issued - either manually by the user or by an alarm or + * some other program function - is to stop a spindle. So the Resume should be ignored for safety. + * + * Notes: + * - Changes to polarities and other setup parameters take effect on the next spindle action. + * There is no reason to make these occur instantly. + * + * - Since it's possible to queue a sync'd control, then set any control value with an + * immediate() before the queued command is reached, _exec_spindle_control() must gracefully + * handle any arbitrary state transition (not just the "legal" ones) + * + * - Do we need a spin-down for direction reversal? + * - Should the JSON be able to pause and resume? */ -#define _set_spindle_enable_bit_hi() spindle_enable_pin.set() -#define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() -#define _set_spindle_direction_bit_hi() spindle_dir_pin.set() -#define _set_spindle_direction_bit_lo() spindle_dir_pin.clear() - static void _exec_spindle_control(float *value, bool *flag) { - spState control = (spState)value[0]; - if (control > SPINDLE_RESUME) { + spControl control = (spControl)value[0]; + if (control >= SPINDLE_ACTION_MAX) { return; } - - uint8_t on_bit = SPINDLE_OFF; - int8_t dir_bit = -1; // use this value to skip setting the direction - - spindle.state = control; // record spindle state + if ((control == SPINDLE_RESUME) && (spindle.state != SPINDLE_PAUSE)) { + return; + } + spindle.state = control; // record new spindle state + uint8_t on_bit = SPINDLE_OFF; // default to off + int8_t dir_bit = -1; // -1 will skip setting the direction if ((control == SPINDLE_CW) || (control == SPINDLE_CCW)) { on_bit = 1; // use 1 (not true) to indicate this is a bitmask dir_bit = control-1; // adjust direction so it can be used as a bitmask spindle.direction = control; -// spindle.state = control; } else if (control == SPINDLE_RESUME) { on_bit = 1; @@ -127,97 +136,46 @@ static void _exec_spindle_control(float *value, bool *flag) // set the direction first if (dir_bit >= 0) { if (dir_bit ^ spindle.dir_polarity) { - _set_spindle_direction_bit_hi(); + spindle_dir_pin.set(); // drive pin HI } else { - _set_spindle_direction_bit_lo(); + spindle_dir_pin.clear(); // drive pin LO } } // set on/off if (on_bit ^ spindle.enable_polarity) { - _set_spindle_enable_bit_lo(); + spindle_enable_pin.clear(); // drive pin LO } else { - _set_spindle_enable_bit_hi(); + spindle_enable_pin.set(); // drive pin HI } - -// if (flag[2]) { // set pause -// spindle.state = SPINDLE_PAUSE; -// } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } -stat_t spindle_control_immediate(spState control) +stat_t spindle_control_immediate(spControl control) { -// bool pause = (control == SPINDLE_PAUSE) ? true : false; - -// float value[] = { (float)control, 0,0,0,0,0 }; float value[] = { (float)control }; -// 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, nullptr); return(STAT_OK); } -stat_t spindle_control_sync(spState control) // uses spControl arg: OFF, CW, CCW +stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, CCW { -/* - bool pause = (control == SPINDLE_PAUSE) ? true : false; - 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; - } -*/ - float value[] = { (float)control, 0,0,0,0,0 }; +// float value[] = { (float)control, 0,0,0,0,0 }; + float value[] = { (float)control }; mp_queue_command(_exec_spindle_control, value, nullptr); - if (fp_NOT_ZERO(spindle.dwell_seconds)) { + if (fp_NOT_ZERO(spindle.spinup_delay)) { // mp_queue_command(dwell); } return(STAT_OK); } /*********************************************************************************** - * spindle_queue_speed() - queue the S parameter to the planner buffer - * _exec_spindle_speed() - spindle speed callback from planner queue + * spindle_speed_immediate() - execute spindle speed change immediately + * spindle_speed_sync() - queue a spindle speed change to the planner buffer + * _exec_spindle_speed() - actually execute the spindle speed command */ -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]; @@ -230,6 +188,29 @@ static void _exec_spindle_speed(float *value, bool *flag) pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } +static stat_t _casey_jones(float speed) +{ + if (speed < spindle.speed_min) { return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); } + if (speed > spindle.speed_max) { return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); } + return (STAT_OK); +} + +stat_t spindle_speed_immediate(float speed) +{ + ritorno(_casey_jones(speed)); + float value[] = { speed }; + _exec_spindle_speed(value, nullptr); + return (STAT_OK); +} + +stat_t spindle_speed_sync(float speed) +{ + ritorno(_casey_jones(speed)); + float value[] = { speed }; + mp_queue_command(_exec_spindle_speed, value, nullptr); + return (STAT_OK); +} + /*********************************************************************************** * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ @@ -266,7 +247,7 @@ static float _get_spindle_pwm (spSpindle_t *sp, pwmControl_t *pwm) } */ -static float _get_spindle_pwm (spState state, spState direction) +static float _get_spindle_pwm (spControl state, spControl direction) { float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; if (direction == SPINDLE_CW ) { @@ -317,18 +298,18 @@ stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 if (P_word > SPINDLE_OVERRIDE_MAX) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - spindle.sso_factor = P_word; // P word is valid, store it. + spindle.override_factor = P_word; // P word is valid, store it. new_override = true; } } if (cm->gmx.m48_enable) { // if master enable is ON - if (new_enable && (new_override || !spindle.sso_enable)) { // 3 cases to start a ramp - spindle_start_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.sso_factor); - } else if (spindle.sso_enable && !new_enable) { // case to turn off the ramp + if (new_enable && (new_override || !spindle.override_enable)) { // 3 cases to start a ramp + spindle_start_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.override_factor); + } else if (spindle.override_enable && !new_enable) { // case to turn off the ramp spindle_end_override(SPINDLE_OVERRIDE_RAMP_TIME); } } - spindle.sso_enable = new_enable; // always update the enable state + spindle.override_enable = new_enable; // always update the enable state return (STAT_OK); } @@ -366,53 +347,23 @@ stat_t sp_set_spdp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_pola stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1)); } -stat_t sp_get_spdw(nvObj_t *nv) { return(get_float(nv, spindle.dwell_seconds)); } -stat_t sp_set_spdw(nvObj_t *nv) { return(set_float_range(nv, spindle.dwell_seconds, 0, SPINDLE_DWELL_MAX)); } +stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } +stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } stat_t sp_get_spsm(nvObj_t *nv) { return(get_float(nv, spindle.speed_max)); } stat_t sp_set_spsm(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_max, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } -stat_t sp_get_ssoe(nvObj_t *nv) { return(get_int(nv, spindle.sso_enable)); } -stat_t sp_set_ssoe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.sso_enable, 0, 1)); } -stat_t sp_get_sso(nvObj_t *nv) { return(get_float(nv, spindle.sso_factor)); } -stat_t sp_set_sso(nvObj_t *nv) { return(set_float_range(nv, spindle.sso_factor, SPINDLE_OVERRIDE_MIN, SPINDLE_OVERRIDE_MAX)); } - -/* These are provided as a way to set and clear spindle states without using M commands - * SPD is useful because disabling a spindle (M5) does not change the direction, only the enable. - */ +stat_t sp_get_spoe(nvObj_t *nv) { return(get_int(nv, spindle.override_enable)); } +stat_t sp_set_spoe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.override_enable, 0, 1)); } +stat_t sp_get_spo(nvObj_t *nv) { return(get_float(nv, spindle.override_factor)); } +stat_t sp_set_spo(nvObj_t *nv) { return(set_float_range(nv, spindle.override_factor, SPINDLE_OVERRIDE_MIN, SPINDLE_OVERRIDE_MAX)); } +// These are provided as a way to view and control spindles without using M commands +stat_t sp_get_spc(nvObj_t *nv) { return(get_int(nv, spindle.state)); } +stat_t sp_set_spc(nvObj_t *nv) { return(spindle_control_immediate((spControl)nv->value)); } stat_t sp_get_sps(nvObj_t *nv) { return(get_float(nv, spindle.speed)); } -stat_t sp_set_sps(nvObj_t *nv) -{ - set_float_range(nv, spindle.speed, spindle.speed_min, spindle.speed_max); - float value[] = { spindle.speed, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_speed(value, flags); - return (STAT_OK); -} - -stat_t sp_get_spe(nvObj_t *nv) { return(get_int(nv, spindle.state)); } -/* -stat_t sp_set_spe(nvObj_t *nv) -{ -// set_int(nv, (uint8_t &)spindle.state, 0, 1); - float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; - _exec_spindle_control(value, flags); - return (STAT_OK); -} -*/ - -stat_t sp_get_spd(nvObj_t *nv) { return(get_int(nv, spindle.direction)); } -stat_t sp_set_spd(nvObj_t *nv) -{ - set_int(nv, (uint8_t &)spindle.direction, 0, 1); - float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; - _exec_spindle_control(value, flags); - return (STAT_OK); -} +stat_t sp_set_sps(nvObj_t *nv) { return(spindle_speed_immediate(nv->value)); } /*********************************************************************************** * TEXT MODE SUPPORT @@ -421,30 +372,28 @@ stat_t sp_set_spd(nvObj_t *nv) #ifdef __TEXT_MODE +const char fmt_spc[] = "[spc] spindle control:%12d [0=OFF,1=CW,2=CCW]\n"; +const char fmt_sps[] = "[sps] spindle speed:%14.0f rpm\n"; const char fmt_spmo[] = "[spmo] spindle mode%16d [0=disabled,1=plan-to-stop,2=continuous]\n"; const char fmt_spep[] = "[spep] spindle enable polarity%5d [0=active_low,1=active_high]\n"; const char fmt_spdp[] = "[spdp] spindle direction polarity%2d [0=CW_low,1=CW_high]\n"; const char fmt_spph[] = "[spph] spindle pause on hold%7d [0=no,1=pause_on_hold]\n"; -const char fmt_spdw[] = "[spdw] spindle dwell time%12.1f seconds\n"; +const char fmt_spde[] = "[spde] spindle spinup delay%10.1f seconds\n"; const char fmt_spsn[] = "[spsn] spindle speed min%14.2f rpm\n"; const char fmt_spsm[] = "[spsm] spindle speed max%14.2f rpm\n"; -const char fmt_ssoe[] = "[ssoe] spindle speed override ena%2d [0=disable,1=enable]\n"; -const char fmt_sso[] = "[sso] spindle speed override%10.3f [0.050 < sso < 2.000]\n"; -const char fmt_sps[] = "Spindle Speed: %7.0f rpm\n"; -const char fmt_spe[] = "Spindle Enable:%7d [0=OFF,1=ON,2=PAUSE]\n"; -const char fmt_spd[] = "Spindle Direction:%4d [0=CW,1=CCW]\n"; +const char fmt_spoe[] = "[spoe] spindle speed override ena%2d [0=disable,1=enable]\n"; +const char fmt_spo[] = "[spo] spindle speed override%10.3f [0.050 < spo < 2.000]\n"; +void sp_print_spc(nvObj_t *nv) { text_print(nv, fmt_spc);} // TYPE_INT +void sp_print_sps(nvObj_t *nv) { text_print(nv, fmt_sps);} // TYPE_FLOAT void sp_print_spmo(nvObj_t *nv) { text_print(nv, fmt_spmo);} // TYPE_INT void sp_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT void sp_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT void sp_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT -void sp_print_spdw(nvObj_t *nv) { text_print(nv, fmt_spdw);} // TYPE_FLOAT +void sp_print_spde(nvObj_t *nv) { text_print(nv, fmt_spde);} // TYPE_FLOAT void sp_print_spsn(nvObj_t *nv) { text_print(nv, fmt_spsn);} // TYPE_FLOAT void sp_print_spsm(nvObj_t *nv) { text_print(nv, fmt_spsm);} // TYPE_FLOAT -void sp_print_ssoe(nvObj_t *nv) { text_print(nv, fmt_ssoe);} // TYPE INT -void sp_print_sso(nvObj_t *nv) { text_print(nv, fmt_sso);} // TYPE FLOAT -void sp_print_spe(nvObj_t *nv) { text_print(nv, fmt_spe);} // TYPE_INT -void sp_print_spd(nvObj_t *nv) { text_print(nv, fmt_spd);} // TYPE_INT -void sp_print_sps(nvObj_t *nv) { text_print(nv, fmt_sps);} // TYPE_FLOAT +void sp_print_spoe(nvObj_t *nv) { text_print(nv, fmt_spoe);} // TYPE INT +void sp_print_spo(nvObj_t *nv) { text_print(nv, fmt_spo);} // TYPE FLOAT #endif // __TEXT_MODE diff --git a/g2core/spindle.h b/g2core/spindle.h index 56dac343..42a0b1a4 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -28,6 +28,12 @@ #ifndef SPINDLE_H_ONCE #define SPINDLE_H_ONCE +#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_RAMP_TIME 1 // change sped in seconds + typedef enum { SPINDLE_DISABLED = 0, // spindle will not operate SPINDLE_PLAN_TO_STOP, // spindle operating, plans to stop @@ -35,22 +41,19 @@ typedef enum { } spMode; #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS -// spState is used for multiple purposes: -// - request the spindle operation (OFF, CW, CCW) -// - request PAUSE and RESUME +// spControl is used for multiple purposes: +// - request a spindle operation (OFF, CW, CCW, PAUSE, RESUME) // - run the spindle state machine for spindle wait states -// - store current direction (1=CW, 2=CCW) in spindle.direction +// - CW and CCW values are stored as current direction in spindle.direction typedef enum { // how spindle controls are presented by the Gcode parser SPINDLE_OFF = 0, // M5 SPINDLE_CW = 1, // M3 and store CW to spindle.direction SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW - SPINDLE_WAIT // handle transient WAIT states -} spState; - -// SPINDLE_ON is either of SPINDLE_CW or SPINDLE_CCW -//#define SPINDLE_ON(s) ((s == SPINDLE_CW) || (s == SPINDLE__CCW)) + SPINDLE_WAIT // handle transient WAIT states (not an action state) +} spControl; +#define SPINDLE_ACTION_MAX SPINDLE_RESUME // *** 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 @@ -61,15 +64,6 @@ typedef enum { // Note: These values agree with SPINDLE_ACTIVE_HIGH = 1, // Will set output to 1 to enable the spindle or CW direction } spPolarity; -/* -typedef enum { // basic spindle state machine. Do not change this enum - SPINDLE_OFF = 0, - 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 { // electronic speed controller for some spindles ESC_ONLINE = 0, ESC_OFFLINE, @@ -78,33 +72,29 @@ typedef enum { // electronic speed controller for some spindles ESC_LOCKOUT_AND_REBOOTING, } ESCState; -#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_RAMP_TIME 1 // change sped in seconds - /* * Spindle control structure */ typedef struct spSpindle { - spMode mode; // spindle operating mode - spState state; // OFF, ON, PAUSE, RESUME, WAIT - spState direction; // 1=CW, 2=CCW (subset of above state) + spMode mode; // {spm:} spindle operating mode + spControl state; // {spc:} OFF, ON, PAUSE, RESUME, WAIT + spControl direction; // 1=CW, 2=CCW (subset of above state) - float speed; // S in RPM - float speed_min; // minimum settable spindle speed - float speed_max; // maximum settable spindle speed + float speed; // {sps:} S in RPM + float speed_min; // {spsn:} minimum settable spindle speed + float speed_max; // {spsm:} maximum settable spindle speed - 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 - bool pause_on_hold; // pause on feedhold + spPolarity enable_polarity; // {spep:} 0=active low, 1=active high + spPolarity dir_polarity; // {spdp:} 0=clockwise low, 1=clockwise high + bool pause_on_hold; // {spph:} pause on feedhold + float spinup_delay; // {spde:} optional delay on spindle start (set to 0 to disable) + float spindown_delay; // {spds:} optional delay on spindle stop (set to 0 to disable) + float reversal_delay; // {spdr:} optional delay on direction reversal (set to 0 to disable) - bool sso_enable; // TRUE = spindle speed override enabled (see also m48_enable in canonical machine) - float sso_factor; // 1.0000 x S spindle speed. Go up or down from there + bool override_enable; // {spoe:} TRUE = spindle speed override enabled (see also m48_enable in canonical machine) + float override_factor; // {spo:} 1.0000 x S spindle speed. Go up or down from there // Spindle speed controller variables ESCState esc_state; // state management for ESC controller @@ -121,8 +111,8 @@ extern spSpindle_t spindle; void spindle_init(); void spindle_reset(); -stat_t spindle_control_immediate(spState control); -stat_t spindle_control_sync(spState control); +stat_t spindle_control_immediate(spControl control); +stat_t spindle_control_sync(spControl control); stat_t spindle_speed_immediate(float speed); // S parameter stat_t spindle_speed_sync(float speed); // S parameter @@ -143,24 +133,22 @@ stat_t sp_set_spdp(nvObj_t *nv); stat_t sp_get_spph(nvObj_t *nv); stat_t sp_set_spph(nvObj_t *nv); -stat_t sp_get_spdw(nvObj_t *nv); -stat_t sp_set_spdw(nvObj_t *nv); +stat_t sp_get_spde(nvObj_t *nv); +stat_t sp_set_spde(nvObj_t *nv); stat_t sp_get_spsn(nvObj_t *nv); stat_t sp_set_spsn(nvObj_t *nv); stat_t sp_get_spsm(nvObj_t *nv); stat_t sp_set_spsm(nvObj_t *nv); -stat_t sp_get_ssoe(nvObj_t* nv); -stat_t sp_set_ssoe(nvObj_t* nv); -stat_t sp_get_sso(nvObj_t* nv); -stat_t sp_set_sso(nvObj_t* nv); +stat_t sp_get_spoe(nvObj_t* nv); +stat_t sp_set_spoe(nvObj_t* nv); +stat_t sp_get_spo(nvObj_t* nv); +stat_t sp_set_spo(nvObj_t* nv); +stat_t sp_get_spc(nvObj_t* nv); +stat_t sp_set_spc(nvObj_t* nv); stat_t sp_get_sps(nvObj_t* nv); stat_t sp_set_sps(nvObj_t* nv); -stat_t sp_get_spe(nvObj_t* nv); -stat_t sp_set_spe(nvObj_t* nv); -stat_t sp_get_spd(nvObj_t* nv); -stat_t sp_set_spd(nvObj_t* nv); /*--- text_mode support functions ---*/ @@ -170,14 +158,13 @@ stat_t sp_set_spd(nvObj_t* nv); void sp_print_spep(nvObj_t* nv); void sp_print_spdp(nvObj_t* nv); void sp_print_spph(nvObj_t* nv); - void sp_print_spdw(nvObj_t* nv); + void sp_print_spde(nvObj_t* nv); void sp_print_spsn(nvObj_t* nv); void sp_print_spsm(nvObj_t* nv); - void sp_print_ssoe(nvObj_t* nv); - void sp_print_sso(nvObj_t* nv); + void sp_print_spoe(nvObj_t* nv); + void sp_print_spo(nvObj_t* nv); + void sp_print_spc(nvObj_t* nv); void sp_print_sps(nvObj_t* nv); - void sp_print_spe(nvObj_t* nv); - void sp_print_spd(nvObj_t* nv); #else @@ -185,14 +172,13 @@ stat_t sp_set_spd(nvObj_t* nv); #define sp_print_spep tx_print_stub #define sp_print_spdp tx_print_stub #define sp_print_spph tx_print_stub - #define sp_print_spdw tx_print_stub + #define sp_print_spde tx_print_stub #define sp_print_spsn tx_print_stub #define sp_print_spsm tx_print_stub - #define sp_print_ssoe tx_print_stub - #define sp_print_spe tx_print_stub + #define sp_print_spoe tx_print_stub + #define sp_print_spo tx_print_stub + #define sp_print_spc tx_print_stub #define sp_print_sps tx_print_stub - #define sp_print_sso tx_print_stub - #define sp_print_spd tx_print_stub #endif // __TEXT_MODE