// Probe pin initialization routine. void probe_init() { // PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins // #ifdef DISABLE_PROBE_PIN_PULL_UP // PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down. // #else // PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. // #endif set_as_input(PROBE); probe_configure_invert_mask(false); // Initialize invert mask. Re-updated during use. }
void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t is_probe_away, uint8_t is_no_error) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. if (sys.state == STATE_CHECK_MODE) { return; } // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); // Initialize probing control variables sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle. probe_configure_invert_mask(is_probe_away); // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); protocol_execute_realtime(); } if (sys.abort) { return; } // Return if system reset has been issued. // Setup and queue probing motion. Auto cycle-start should not start the cycle. #ifdef USE_LINE_NUMBERS mc_line(target, feed_rate, invert_feed_rate, line_number); #else mc_line(target, feed_rate, invert_feed_rate); #endif // Activate the probing state monitor in the stepper module. sys_probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); do { protocol_execute_realtime(); if (sys.abort) { return; } // Check for system abort } while (sys.state != STATE_IDLE); // Probing cycle complete! // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys_probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); } else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } sys_probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. protocol_execute_realtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort // Reset the stepper and planner buffers to remove the remainder of the probe motion. st_reset(); // Reest step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. // TODO: Update the g-code parser code to not require this target calculation but uses a gc_sync_position() call. // NOTE: The target[] variable updated here will be sent back and synced with the g-code parser. system_convert_array_steps_to_mpos(target, sys.position); #ifdef MESSAGE_PROBE_COORDINATES // All done! Output the probe position as message. report_probe_parameters(); #endif }
// Perform tool length probe cycle. Requires probe switch. // NOTE: Upon probe failure, the program will be stopped and placed into ALARM state. uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags) { // TODO: Need to update this cycle so it obeys a non-auto cycle start. if (sys.state == STATE_CHECK_MODE) { return(GC_PROBE_CHECK_MODE); } // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); if (sys.abort) { return(GC_PROBE_ABORT); } // Return if system reset has been issued. // Initialize probing control variables uint8_t is_probe_away = bit_istrue(parser_flags,GC_PARSER_PROBE_IS_AWAY); uint8_t is_no_error = bit_istrue(parser_flags,GC_PARSER_PROBE_IS_NO_ERROR); sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle. probe_configure_invert_mask(is_probe_away); // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_INITIAL); protocol_execute_realtime(); probe_configure_invert_mask(false); // Re-initialize invert mask before returning. return(GC_PROBE_FAIL_INIT); // Nothing else to do but bail. } // Setup and queue probing motion. Auto cycle-start should not start the cycle. mc_line(target, pl_data); // Activate the probing state monitor in the stepper module. sys_probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. system_set_exec_state_flag(EXEC_CYCLE_START); do { protocol_execute_realtime(); if (sys.abort) { return(GC_PROBE_ABORT); } // Check for system abort } while (sys.state != STATE_IDLE); // Probing cycle complete! // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys_probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys_probe_position, sys_position, sizeof(sys_position)); } else { system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_CONTACT); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } sys_probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. probe_configure_invert_mask(false); // Re-initialize invert mask. protocol_execute_realtime(); // Check and execute run-time commands // Reset the stepper and planner buffers to remove the remainder of the probe motion. st_reset(); // Reset step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. #ifdef MESSAGE_PROBE_COORDINATES // All done! Output the probe position as message. report_probe_parameters(); #endif if (sys.probe_succeeded) { return(GC_PROBE_FOUND); } // Successful probe cycle. else { return(GC_PROBE_FAIL_END); } // Failed to trigger probe within travel. With or without error. }
// A helper method to set settings from command line uint8_t settings_store_global_setting(uint8_t parameter, float value) { if (value < 0.0) { return(STATUS_NEGATIVE_VALUE); } if (parameter >= AXIS_SETTINGS_START_VAL) { // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines. // NOTE: Ensure the setting index corresponds to the report.c settings printout. parameter -= AXIS_SETTINGS_START_VAL; uint8_t set_idx = 0; while (set_idx < AXIS_N_SETTINGS) { if (parameter < N_AXIS) { // Valid axis setting found. switch (set_idx) { case 0: #ifdef MAX_STEP_RATE_HZ if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } #endif settings.steps_per_mm[parameter] = value; break; case 1: #ifdef MAX_STEP_RATE_HZ if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } #endif settings.max_rate[parameter] = value; break; case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use. } break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call. } else { set_idx++; // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out. if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); } parameter -= AXIS_SETTINGS_INCREMENT; } } } else { // Store non-axis Grbl settings uint8_t int_value = trunc(value); switch(parameter) { case 0: if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); } settings.pulse_microseconds = int_value; break; case 1: settings.stepper_idle_lock_time = int_value; break; case 2: settings.step_invert_mask = int_value; st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. break; case 3: settings.dir_invert_mask = int_value; st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. break; case 4: // Reset to ensure change. Immediate re-init may cause problems. if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; } break; case 5: // Reset to ensure change. Immediate re-init may cause problems. if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; } break; case 6: // Reset to ensure change. Immediate re-init may cause problems. if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; } else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; } probe_configure_invert_mask(false); break; case 10: settings.status_report_mask = int_value; break; case 11: settings.junction_deviation = value; break; case 12: settings.arc_tolerance = value; break; case 13: if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; } else { settings.flags &= ~BITFLAG_REPORT_INCHES; } system_flag_wco_change(); // Make sure WCO is immediately updated. break; case 20: if (int_value) { if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); } settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; } break; case 21: if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; } limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later. break; case 22: if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; } else { settings.flags &= ~BITFLAG_HOMING_ENABLE; settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits. } break; case 23: settings.homing_dir_mask = int_value; break; case 24: settings.homing_feed_rate = value; break; 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 = value; spindle_init(); break; // Re-initialize spindle rpm calibration case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration case 32: #ifdef VARIABLE_SPINDLE if (int_value) { settings.flags |= BITFLAG_LASER_MODE; } else { settings.flags &= ~BITFLAG_LASER_MODE; } #else return(STATUS_SETTING_DISABLED_LASER); #endif break; default: return(STATUS_INVALID_STATEMENT); } } write_global_settings(); return(STATUS_OK); }