diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index a0be20276..ac41d7b65 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -25,6 +25,7 @@ * mesh_num_x * mesh_num_y * z_values[][] + * zprobe_zoffset * * DELTA: * endstop_adj (x3) @@ -39,7 +40,6 @@ * absPreheatHotendTemp * absPreheatHPBTemp * absPreheatFanSpeed - * zprobe_zoffset * * PIDTEMP: * Kp[0], Ki[0], Kd[0], Kc[0] @@ -118,7 +118,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) { // wrong data being written to the variables. // ALSO: always make sure the variables in the Store and retrieve sections are in the same order. -#define EEPROM_VERSION "V17" +#define EEPROM_VERSION "V18" #ifdef EEPROM_SETTINGS @@ -143,7 +143,7 @@ void Config_StoreSettings() { uint8_t mesh_num_x = 3; uint8_t mesh_num_y = 3; - #if defined(MESH_BED_LEVELING) + #ifdef MESH_BED_LEVELING // Compile time test that sizeof(mbl.z_values) is as expected typedef char c_assert[(sizeof(mbl.z_values) == MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS*sizeof(dummy)) ? 1 : -1]; mesh_num_x = MESH_NUM_X_POINTS; @@ -161,7 +161,12 @@ void Config_StoreSettings() { for (int q=0; q 1 @@ -1162,6 +1162,7 @@ static void run_z_probe() { zPosition += home_retract_mm(Z_AXIS); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder); st_synchronize(); + endstops_hit_on_purpose(); // move back down slowly to find bed @@ -1179,6 +1180,7 @@ static void run_z_probe() { zPosition -= home_retract_mm(Z_AXIS) * 2; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder); st_synchronize(); + endstops_hit_on_purpose(); current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); // make sure the planner knows where we are as it may be a bit different than we last said to move to @@ -1383,11 +1385,11 @@ static float probe_pt(float x, float y, float z_before, ProbeAction retract_acti if (verbose_level > 2) { SERIAL_PROTOCOLPGM(MSG_BED); SERIAL_PROTOCOLPGM(" X: "); - SERIAL_PROTOCOL(x + 0.0001); + SERIAL_PROTOCOL_F(x, 3); SERIAL_PROTOCOLPGM(" Y: "); - SERIAL_PROTOCOL(y + 0.0001); + SERIAL_PROTOCOL_F(y, 3); SERIAL_PROTOCOLPGM(" Z: "); - SERIAL_PROTOCOL(measured_z + 0.0001); + SERIAL_PROTOCOL_F(measured_z, 3); SERIAL_EOL; } return measured_z; @@ -2108,6 +2110,10 @@ inline void gcode_G28() { * * S Set the XY travel speed between probe points (in mm/min) * + * D Dry-Run mode. Just evaluate the bed Topology - Don't apply + * or clean the rotation Matrix. Useful to check the topology + * after a first run of G29. + * * V Set the verbose level (0-4). Example: "G29 V3" * * T Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report. @@ -2149,6 +2155,7 @@ inline void gcode_G28() { } } + bool dryrun = code_seen('D') || code_seen('d'); bool enhanced_g29 = code_seen('E') || code_seen('e'); #ifdef AUTO_BED_LEVELING_GRID @@ -2158,7 +2165,10 @@ inline void gcode_G28() { #endif if (verbose_level > 0) + { SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n"); + if (dryrun) SERIAL_ECHOLN("Running in DRY-RUN mode"); + } int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS; #ifndef DELTA @@ -2215,21 +2225,26 @@ inline void gcode_G28() { st_synchronize(); - #ifdef DELTA - reset_bed_level(); - #else //!DELTA - // make sure the bed_level_rotation_matrix is identity or the planner will get it wrong - //vector_3 corrected_position = plan_get_position_mm(); - //corrected_position.debug("position before G29"); - plan_bed_level_matrix.set_to_identity(); - vector_3 uncorrected_position = plan_get_position(); - //uncorrected_position.debug("position during G29"); - current_position[X_AXIS] = uncorrected_position.x; - current_position[Y_AXIS] = uncorrected_position.y; - current_position[Z_AXIS] = uncorrected_position.z; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - #endif //!DELTA + if (!dryrun) + { + #ifdef DELTA + reset_bed_level(); + #else //!DELTA + // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly + //vector_3 corrected_position = plan_get_position_mm(); + //corrected_position.debug("position before G29"); + plan_bed_level_matrix.set_to_identity(); + vector_3 uncorrected_position = plan_get_position(); + //uncorrected_position.debug("position during G29"); + current_position[X_AXIS] = uncorrected_position.x; + current_position[Y_AXIS] = uncorrected_position.y; + current_position[Z_AXIS] = uncorrected_position.z; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + + #endif + } + setup_for_endstop_move(); feedrate = homing_feedrate[Z_AXIS]; @@ -2330,9 +2345,12 @@ inline void gcode_G28() { clean_up_after_endstop_move(); #ifdef DELTA - extrapolate_unprobed_bed_level(); + + if (!dryrun) extrapolate_unprobed_bed_level(); print_bed_level(); + #else // !DELTA + // solve lsq problem double *plane_equation_coefficients = qr_solve(abl2, 3, eqnAMatrix, eqnBVector); @@ -2380,10 +2398,10 @@ inline void gcode_G28() { } //do_topography_map - set_bed_level_equation_lsq(plane_equation_coefficients); + if (!dryrun) set_bed_level_equation_lsq(plane_equation_coefficients); free(plane_equation_coefficients); - #endif // !DELTA + #endif //!DELTA #else // !AUTO_BED_LEVELING_GRID @@ -2402,7 +2420,7 @@ inline void gcode_G28() { z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, ProbeEngageAndRetract, verbose_level); } clean_up_after_endstop_move(); - set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3); + if (!dryrun) set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3); #endif // !AUTO_BED_LEVELING_GRID @@ -2413,15 +2431,18 @@ inline void gcode_G28() { // Correct the Z height difference from z-probe position and hotend tip position. // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend. // When the bed is uneven, this height must be corrected. - real_z = float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS]; //get the real Z (since the auto bed leveling is already correcting the plane) - x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER; - y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER; - z_tmp = current_position[Z_AXIS]; + if (!dryrun) + { + real_z = float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS]; //get the real Z (since the auto bed leveling is already correcting the plane) + x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER; + y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER; + z_tmp = current_position[Z_AXIS]; - apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); //Apply the correction sending the probe offset - current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS]; //The difference is added to current position and sent to planner. - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - #endif + apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); //Apply the correction sending the probe offset + current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS]; //The difference is added to current position and sent to planner. + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + } + #endif // !DELTA #ifdef Z_PROBE_SLED dock_sled(true, -SLED_DOCKING_OFFSET); // dock the probe, correcting for over-travel diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 713d0312f..ef75ae439 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -576,6 +576,12 @@ void manage_heater() { updateTemperaturesFromRawValues(); + #ifdef HEATER_0_USES_MAX6675 + float ct = current_temperature[0]; + if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0); + if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0); + #endif //HEATER_0_USES_MAX6675 + unsigned long ms = millis(); // Loop through all extruders @@ -607,7 +613,7 @@ void manage_heater() { #ifdef TEMP_SENSOR_1_AS_REDUNDANT if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) { disable_heater(); - _temp_error(-1, MSG_EXTRUDER_SWITCHED_OFF, MSG_ERR_REDUNDANT_TEMP); + _temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP)); } #endif //TEMP_SENSOR_1_AS_REDUNDANT @@ -1162,20 +1168,40 @@ enum TempState { StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle }; +#ifdef TEMP_SENSOR_1_AS_REDUNDANT + #define TEMP_SENSOR_COUNT 2 +#else + #define TEMP_SENSOR_COUNT EXTRUDERS +#endif + +static unsigned long raw_temp_value[TEMP_SENSOR_COUNT] = { 0 }; +static unsigned long raw_temp_bed_value = 0; + +static void set_current_temp_raw() { + #ifndef HEATER_0_USES_MAX6675 + current_temperature_raw[0] = raw_temp_value[0]; + #endif + #if EXTRUDERS > 1 + current_temperature_raw[1] = raw_temp_value[1]; + #if EXTRUDERS > 2 + current_temperature_raw[2] = raw_temp_value[2]; + #if EXTRUDERS > 3 + current_temperature_raw[3] = raw_temp_value[3]; + #endif + #endif + #endif + #ifdef TEMP_SENSOR_1_AS_REDUNDANT + redundant_temperature_raw = raw_temp_value[1]; + #endif + current_temperature_bed_raw = raw_temp_bed_value; +} + // // Timer 0 is shared with millies // ISR(TIMER0_COMPB_vect) { - #ifdef TEMP_SENSOR_1_AS_REDUNDANT - #define TEMP_SENSOR_COUNT 2 - #else - #define TEMP_SENSOR_COUNT EXTRUDERS - #endif - //these variables are only accesible from the ISR, but static, so they don't lose their value static unsigned char temp_count = 0; - static unsigned long raw_temp_value[TEMP_SENSOR_COUNT] = { 0 }; - static unsigned long raw_temp_bed_value = 0; static TempState temp_state = StartupDelay; static unsigned char pwm_count = BIT(SOFT_PWM_SCALE); @@ -1478,22 +1504,7 @@ ISR(TIMER0_COMPB_vect) { if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms. if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading. - #ifndef HEATER_0_USES_MAX6675 - current_temperature_raw[0] = raw_temp_value[0]; - #endif - #if EXTRUDERS > 1 - current_temperature_raw[1] = raw_temp_value[1]; - #if EXTRUDERS > 2 - current_temperature_raw[2] = raw_temp_value[2]; - #if EXTRUDERS > 3 - current_temperature_raw[3] = raw_temp_value[3]; - #endif - #endif - #endif - #ifdef TEMP_SENSOR_1_AS_REDUNDANT - redundant_temperature_raw = raw_temp_value[1]; - #endif - current_temperature_bed_raw = raw_temp_bed_value; + set_current_temp_raw(); } //!temp_meas_ready // Filament Sensor - can be read any time since IIR filtering is used @@ -1506,11 +1517,7 @@ ISR(TIMER0_COMPB_vect) { for (int i = 0; i < TEMP_SENSOR_COUNT; i++) raw_temp_value[i] = 0; raw_temp_bed_value = 0; - #ifdef HEATER_0_USES_MAX6675 - float ct = current_temperature[0]; - if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0); - if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0); - #else + #ifndef HEATER_0_USES_MAX6675 #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP #define GE0 <= #else diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 0c27e7d50..f6af156d5 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -204,7 +204,7 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) #endif //!ENCODER_RATE_MULTIPLIER #define END_MENU() \ - if (encoderLine >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\ + if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; }\ if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \ } } while(0)