From f178ba835c314443622021e396a1de2854de8a89 Mon Sep 17 00:00:00 2001 From: Matt Long Date: Sat, 23 Nov 2019 08:20:35 -0500 Subject: [PATCH 1/3] First pass at laser control including dynamic power control --- g2core/canonical_machine.cpp | 7 +++++++ g2core/canonical_machine.h | 2 ++ g2core/plan_exec.cpp | 4 ++++ g2core/spindle.cpp | 27 +++++++++++++++++++++++++-- g2core/spindle.h | 1 + 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ab26d1b80..6415218ed 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1370,6 +1370,13 @@ stat_t cm_change_tool(const uint8_t tool_change) return (STAT_OK); } +bool cm_is_laser_tool(void) +{ + // Tool 32 is always a laser. Later we can use a different qualified. + return (32 == cm->gm.tool_select); +} + + /**************************************************************************************** **** Miscellaneous Functions (4.3.9) *************************************************** ****************************************************************************************/ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index d37579eb0..0e56b5b06 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -463,6 +463,8 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // G stat_t cm_select_tool(const uint8_t tool); // T parameter stat_t cm_change_tool(const uint8_t tool); // M6 +bool cm_is_laser_tool(void); // True if tool is a laser + // Miscellaneous Functions (4.3.9) // see coolant.h for coolant functions - which would go right here diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 9e78ac854..5aaa495d3 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -917,6 +917,10 @@ static stat_t _exec_aline_segment() } } + if (cm_is_laser_tool() && spindle.direction == SPINDLE_CCW) { + spindle_update_laser_override(mr->segment_velocity); + } + // Convert target position to steps // Bucket-brigade the old target down the chain before getting the new target from kinematics // diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 2880a0caa..f740b26df 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -215,7 +215,7 @@ static void _exec_spindle_control(float *value, bool *flag) } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); - if (spinup_delay) { + if (spinup_delay && !cm_is_laser_tool()) { mp_request_out_of_band_dwell(spindle.spinup_delay); } } @@ -261,7 +261,7 @@ static void _exec_spindle_speed(float *value, bool *flag) spindle.speed = value[0]; pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); - if (fp_ZERO(previous_speed)) { + if (fp_ZERO(previous_speed) && !cm_is_laser_tool()) { mp_request_out_of_band_dwell(spindle.spinup_delay); } } @@ -318,6 +318,12 @@ static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm) } // normalize speed to [0..1] float speed = (_spindle.speed - speed_lo) / (speed_hi - speed_lo); + if (cm_is_laser_tool() && spindle.direction == SPINDLE_CCW) { + // We are in dynamic laser mode (M4) + Laser tool. Adjust + // speed based on override_factor which is updated based on + // current velocity. + speed *= spindle.override_factor; + } return ((speed * (phase_hi - phase_lo)) + phase_lo); } else { return (_pwm.c[PWM_1].phase_off); @@ -369,6 +375,23 @@ void spindle_end_override(const float ramp_time) return; } +// Called in ISR so be careful and fast +void spindle_update_laser_override(float current_velocity) { + float spindle_override = 0.0; + float feed_rate = cm_get_feed_rate(ACTIVE_MODEL); + + if (feed_rate > 0.0) { + spindle_override = current_velocity / feed_rate; + if (spindle_override > 1.0) spindle_override = 1.0; + else if (spindle_override < 0.0) spindle_override = 0.0; + } +// if (fabs(spindle_override - spindle.override_factor) >= 0.01) { + // Only update if the change is worth while (at least 1%) + spindle.override_factor = spindle_override; + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); +// } +} + /**************************** * END OF SPINDLE FUNCTIONS * ****************************/ diff --git a/g2core/spindle.h b/g2core/spindle.h index 2b6f21ed6..d0d37cd17 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -120,6 +120,7 @@ stat_t spindle_speed_sync(float speed); // S parameter 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); void spindle_end_override(const float ramp_time); +void spindle_update_laser_override(float current_velocity); stat_t sp_get_spmo(nvObj_t *nv); stat_t sp_set_spmo(nvObj_t *nv); From cf53039297891ded5cf438d4c756d4859fcd7d3d Mon Sep 17 00:00:00 2001 From: Matt Long Date: Sat, 23 Nov 2019 16:53:09 -0500 Subject: [PATCH 2/3] Addressing review comments to remove / update comments. --- g2core/canonical_machine.cpp | 3 ++- g2core/spindle.cpp | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 6415218ed..61f630851 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1372,7 +1372,8 @@ stat_t cm_change_tool(const uint8_t tool_change) bool cm_is_laser_tool(void) { - // Tool 32 is always a laser. Later we can use a different qualified. + // Tool 32 is always a laser. Later we can use a different qualifier, + // possibly a new field in the tool db which indicates tool type. return (32 == cm->gm.tool_select); } diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index f740b26df..e71b35d91 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -385,11 +385,8 @@ void spindle_update_laser_override(float current_velocity) { if (spindle_override > 1.0) spindle_override = 1.0; else if (spindle_override < 0.0) spindle_override = 0.0; } -// if (fabs(spindle_override - spindle.override_factor) >= 0.01) { - // Only update if the change is worth while (at least 1%) - spindle.override_factor = spindle_override; - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); -// } + spindle.override_factor = spindle_override; + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); } /**************************** From 7b350c11e839fe9869b2cb51170b58696ec9b649 Mon Sep 17 00:00:00 2001 From: Matt Long Date: Sun, 24 Nov 2019 10:38:47 -0500 Subject: [PATCH 3/3] Initialized spindle override when entering dynamic laser mode. --- g2core/spindle.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index e71b35d91..4e5912804 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -180,6 +180,11 @@ static void _exec_spindle_control(float *value, bool *flag) spindle.direction = control; spindle.state = control; spinup_delay = true; + if (cm_is_laser_tool() && spindle.direction == SPINDLE_CCW) { + // Since dynamic laser mode relies on spindle override to scale + // the power, ensure it is initialize when transitioning into this state. + spindle.override_factor = 0.0; + } break; } case SPINDLE_PAUSE : {