diff --git a/Grbl_Esp32/Grbl_Esp32.ino b/Grbl_Esp32/Grbl_Esp32.ino index 13762b6b..943c2c52 100644 --- a/Grbl_Esp32/Grbl_Esp32.ino +++ b/Grbl_Esp32/Grbl_Esp32.ino @@ -36,7 +36,8 @@ volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bit volatile uint8_t sys_rt_exec_debug; #endif -NullSpindle my_spindle; +Spindle *my_spindle; + void setup() { @@ -116,7 +117,8 @@ void loop() { // Reset Grbl primary systems. serial_reset_read_buffer(CLIENT_ALL); // Clear serial read buffer gc_init(); // Set g-code parser to default state - my_spindle.init(); + // my_spindle.init(); + spindle_select(SPINDLE_TYPE_PWM); coolant_init(); limits_init(); probe_init(); diff --git a/Grbl_Esp32/gcode.cpp b/Grbl_Esp32/gcode.cpp index 5ab0eb33..369f2b96 100644 --- a/Grbl_Esp32/gcode.cpp +++ b/Grbl_Esp32/gcode.cpp @@ -1091,12 +1091,12 @@ uint8_t gc_execute_line(char* line, uint8_t client) { #ifdef VARIABLE_SPINDLE if (bit_isfalse(gc_parser_flags, GC_PARSER_LASER_ISMOTION)) { if (bit_istrue(gc_parser_flags, GC_PARSER_LASER_DISABLE)) - my_spindle.set_state(gc_state.modal.spindle, 0.0); + my_spindle->set_state(gc_state.modal.spindle, 0.0); else - my_spindle.set_state(gc_state.modal.spindle, gc_block.values.s); + my_spindle->set_state(gc_state.modal.spindle, gc_block.values.s); } #else - my_spindle.set_state(gc_state.modal.spindle, 0.0); + my_spindle->set_state(gc_state.modal.spindle, 0.0); #endif } gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state. @@ -1118,7 +1118,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) { // Update spindle control and apply spindle speed when enabling it in this block. // NOTE: All spindle state changes are synced, even in laser mode. Also, pl_data, // rather than gc_state, is used to manage laser state for non-laser motions. - my_spindle.set_state(gc_block.modal.spindle, pl_data->spindle_speed); + my_spindle->set_state(gc_block.modal.spindle, pl_data->spindle_speed); gc_state.modal.spindle = gc_block.modal.spindle; } pl_data->condition |= gc_state.modal.spindle; // Set condition flag for planner use. @@ -1294,7 +1294,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) { if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) FAIL(STATUS_SETTING_READ_FAIL); system_flag_wco_change(); // Set to refresh immediately just in case something altered. - my_spindle.set_state(SPINDLE_DISABLE, 0.0); + my_spindle->set_state(SPINDLE_DISABLE, 0.0); coolant_set_state(COOLANT_DISABLE); } report_feedback_message(MESSAGE_PROGRAM_END); diff --git a/Grbl_Esp32/motion_control.cpp b/Grbl_Esp32/motion_control.cpp index c7ea8df5..d8afdf08 100644 --- a/Grbl_Esp32/motion_control.cpp +++ b/Grbl_Esp32/motion_control.cpp @@ -424,7 +424,7 @@ void mc_reset() { if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) { system_set_exec_state_flag(EXEC_RESET); // Kill spindle and coolant. - my_spindle.stop(); + my_spindle->stop(); coolant_stop(); // turn off all digital I/O sys_io_control(0xFF, false); diff --git a/Grbl_Esp32/protocol.cpp b/Grbl_Esp32/protocol.cpp index 0668e70c..2f3b825f 100644 --- a/Grbl_Esp32/protocol.cpp +++ b/Grbl_Esp32/protocol.cpp @@ -564,7 +564,7 @@ static void protocol_exec_rt_suspend() { // Ensure any prior spindle stop override is disabled at start of safety door routine. sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; #ifndef PARKING_ENABLE - my_spindle.set_state(SPINDLE_DISABLE, 0.0); // De-energize + my_spindle->set_state(SPINDLE_DISABLE, 0.0); // De-energize coolant_set_state(COOLANT_DISABLE); // De-energize #else // Get current position and store restore location and spindle retract waypoint. @@ -599,7 +599,7 @@ static void protocol_exec_rt_suspend() { // NOTE: Clear accessory state after retract and after an aborted restore motion. pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION | PL_COND_FLAG_NO_FEED_OVERRIDE); pl_data->spindle_speed = 0.0; - my_spindle.set_state((SPINDLE_DISABLE, 0.0); // De-energize + my_spindle->set_state((SPINDLE_DISABLE, 0.0); // De-energize coolant_set_state(COOLANT_DISABLE); // De-energize // Execute fast parking retract motion to parking target location. if (parking_target[PARKING_AXIS] < PARKING_TARGET) { @@ -610,7 +610,7 @@ static void protocol_exec_rt_suspend() { } else { // Parking motion not possible. Just disable the spindle and coolant. // NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately. - my_spindle.set_state((SPINDLE_DISABLE, 0.0); // De-energize + ->set_state((SPINDLE_DISABLE, 0.0); // De-energize coolant_set_state(COOLANT_DISABLE); // De-energize } #endif @@ -620,7 +620,7 @@ static void protocol_exec_rt_suspend() { if (sys.state == STATE_SLEEP) { report_feedback_message(MESSAGE_SLEEP_MODE); // Spindle and coolant should already be stopped, but do it again just to be sure. - my_spindle.set_state(SPINDLE_DISABLE, 0.0); // De-energize + my_spindle->set_state(SPINDLE_DISABLE, 0.0); // De-energize coolant_set_state(COOLANT_DISABLE); // De-energize st_go_idle(); // Disable steppers while (!(sys.abort)) protocol_exec_rt_system(); // Do nothing until reset. @@ -659,7 +659,7 @@ static void protocol_exec_rt_suspend() { // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_RPM); } else { - my_spindle.set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + my_spindle->set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); delay_sec(SAFETY_DOOR_SPINDLE_DELAY, DELAY_MODE_SYS_SUSPEND); } } @@ -705,7 +705,7 @@ static void protocol_exec_rt_suspend() { // Handles beginning of spindle stop if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_INITIATE) { if (gc_state.modal.spindle != SPINDLE_DISABLE) { - my_spindle.set_state(SPINDLE_DISABLE, 0.0); // De-energize + my_spindle->set_state(SPINDLE_DISABLE, 0.0); // De-energize sys.spindle_stop_ovr = SPINDLE_STOP_OVR_ENABLED; // Set stop override state to enabled, if de-energized. } else { sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state @@ -718,7 +718,7 @@ static void protocol_exec_rt_suspend() { // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_RPM); } else - my_spindle.set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + my_spindle->set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); } if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_RESTORE_CYCLE) { system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. @@ -729,7 +729,7 @@ static void protocol_exec_rt_suspend() { // Handles spindle state during hold. NOTE: Spindle speed overrides may be altered during hold state. // NOTE: STEP_CONTROL_UPDATE_SPINDLE_RPM is automatically reset upon resume in step generator. if (bit_istrue(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_RPM)) { - my_spindle.set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + my_spindle->set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); bit_false(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_RPM); } } diff --git a/Grbl_Esp32/report.cpp b/Grbl_Esp32/report.cpp index c882f4ec..96505e81 100644 --- a/Grbl_Esp32/report.cpp +++ b/Grbl_Esp32/report.cpp @@ -744,7 +744,7 @@ void report_realtime_status(uint8_t client) { } else sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT - 1); sprintf(temp, "|Ov:%d,%d,%d", sys.f_override, sys.r_override, sys.spindle_speed_ovr); strcat(status, temp); - uint8_t sp_state = my_spindle.get_state(); + uint8_t sp_state = my_spindle->get_state(); uint8_t cl_state = coolant_get_state(); if (sp_state || cl_state) { strcat(status, "|A:"); diff --git a/Grbl_Esp32/settings.cpp b/Grbl_Esp32/settings.cpp index 82a5df0d..a919f43b 100644 --- a/Grbl_Esp32/settings.cpp +++ b/Grbl_Esp32/settings.cpp @@ -366,19 +366,19 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) { case 25: settings.homing_seek_rate = value; break; case 26: settings.homing_debounce_delay = int_value; break; case 27: settings.homing_pulloff = value; break; - case 30: settings.rpm_max = std::max(value, 1.0f); my_spindle.init(); break; // Re-initialize spindle rpm calibration (min of 1) - case 31: settings.rpm_min = value; my_spindle.init(); break; // Re-initialize spindle rpm calibration + case 30: settings.rpm_max = std::max(value, 1.0f); my_spindle->init(); break; // Re-initialize spindle rpm calibration (min of 1) + case 31: settings.rpm_min = value; my_spindle->init(); break; // Re-initialize spindle rpm calibration case 32: if (int_value) settings.flags |= BITFLAG_LASER_MODE; else settings.flags &= ~BITFLAG_LASER_MODE; - my_spindle.init(); // update the spindle class + my_spindle->init(); // update the spindle class break; - case 33: settings.spindle_pwm_freq = value; my_spindle.init(); break; // Re-initialize spindle pwm calibration - case 34: settings.spindle_pwm_off_value = value; my_spindle.init(); break; // Re-initialize spindle pwm calibration - case 35: settings.spindle_pwm_min_value = value; my_spindle.init(); break; // Re-initialize spindle pwm calibration - case 36: settings.spindle_pwm_max_value = value; my_spindle.init(); break; // Re-initialize spindle pwm calibration + case 33: settings.spindle_pwm_freq = value; my_spindle->init(); break; // Re-initialize spindle pwm calibration + case 34: settings.spindle_pwm_off_value = value; my_spindle->init(); break; // Re-initialize spindle pwm calibration + case 35: settings.spindle_pwm_min_value = value; my_spindle->init(); break; // Re-initialize spindle pwm calibration + case 36: settings.spindle_pwm_max_value = value; my_spindle->init(); break; // Re-initialize spindle pwm calibration case 80: case 81: case 82: diff --git a/Grbl_Esp32/stepper.cpp b/Grbl_Esp32/stepper.cpp index 775a5904..ea560b9c 100644 --- a/Grbl_Esp32/stepper.cpp +++ b/Grbl_Esp32/stepper.cpp @@ -284,7 +284,7 @@ void IRAM_ATTR onStepperDriverTimer(void* para) { // ISR It is time to take a st // Set real-time spindle output as segment is loaded, just prior to the first step. //spindle_set_speed(st.exec_segment->spindle_rpm); //grbl_send(CLIENT_SERIAL, "A_"); - my_spindle.set_rpm(prep.current_spindle_rpm); + my_spindle->set_rpm(prep.current_spindle_rpm); } else { @@ -296,7 +296,7 @@ void IRAM_ATTR onStepperDriverTimer(void* para) { // ISR It is time to take a st if (st.exec_block->is_pwm_rate_adjusted) { //spindle_set_speed(spindle_pwm_off_value); //grbl_send(CLIENT_SERIAL, "B_"); - my_spindle.set_rpm(0.0); + my_spindle->set_rpm(0.0); } } @@ -990,8 +990,8 @@ void st_prep_buffer() { } else prep.current_speed = sqrt(pl_block->entry_speed_sqr); - //st_prep_block->is_pwm_rate_adjusted = my_spindle.isRateAdjusted(); - if (my_spindle.isRateAdjusted() ){ // settings.flags & BITFLAG_LASER_MODE) { + + if (my_spindle->isRateAdjusted() ){ // settings.flags & BITFLAG_LASER_MODE) { if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) { // Pre-compute inverse programmed rate to speed up PWM updating per step segment. prep.inv_rate = 1.0 / pl_block->programmed_rate; @@ -1205,7 +1205,7 @@ void st_prep_buffer() { } // If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE) // but this would be instantaneous only and during a motion. May not matter at all. - //prep.current_spindle_rpm = my_spindle.set_rpm(rpm); + prep.current_spindle_rpm = rpm; } else { sys.spindle_speed = 0.0; diff --git a/Grbl_Esp32/tools/SpindleClass.cpp b/Grbl_Esp32/tools/SpindleClass.cpp index 34db4de7..0ea289d5 100644 --- a/Grbl_Esp32/tools/SpindleClass.cpp +++ b/Grbl_Esp32/tools/SpindleClass.cpp @@ -41,6 +41,35 @@ #include "RelaySpindle.cpp" #include "Laser.cpp" +NullSpindle null_spindle; +PWMSpindle pwm_spindle; +RelaySpindle relay_spindle; +Laser laser; +DacSpindle dac_spindle; + +void spindle_select(uint8_t spindle_type) { + + switch (spindle_type) { + case SPINDLE_TYPE_PWM: + my_spindle = &pwm_spindle; + break; + case SPINDLE_TYPE_RELAY: + my_spindle = &relay_spindle; + break; + case SPINDLE_TYPE_LASER: + my_spindle = &laser; + break; + case SPINDLE_TYPE_DAC: + my_spindle = &dac_spindle; + break; + case SPINDLE_TYPE_NONE: + default: + my_spindle = &null_spindle; + break; + } + my_spindle->init(); +} + bool Spindle::isRateAdjusted() { return false; // default for basic spindles is false } diff --git a/Grbl_Esp32/tools/SpindleClass.h b/Grbl_Esp32/tools/SpindleClass.h index 3cc76959..5620cc19 100644 --- a/Grbl_Esp32/tools/SpindleClass.h +++ b/Grbl_Esp32/tools/SpindleClass.h @@ -26,6 +26,12 @@ #define SPINDLE_STATE_CW bit(0) #define SPINDLE_STATE_CCW bit(1) +#define SPINDLE_TYPE_NONE 0 +#define SPINDLE_TYPE_PWM 1 +#define SPINDLE_TYPE_RELAY 2 +#define SPINDLE_TYPE_LASER 4 +#define SPINDLE_TYPE_DAC 5 + #ifndef SPINDLE_CLASS_H #define SPINDLE_CLASS_H @@ -120,7 +126,15 @@ class DacSpindle : public PWMSpindle { void set_pwm(uint32_t duty); // sets DAC instead of PWM }; -extern NullSpindle my_spindle; +extern Spindle *my_spindle; + +extern NullSpindle null_spindle; +extern PWMSpindle pwm_spindle; +extern RelaySpindle relay_spindle; +extern Laser laser; +extern DacSpindle dac_spindle; + +void spindle_select(uint8_t spindle_type); #endif