diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index db8d54ec2..c21325c77 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -7,8 +7,8 @@ #define STR(x) STR_HELPER(x) // Firmware version -#define FW_VERSION "3.6.0-RC1" -#define FW_COMMIT_NR 2060 +#define FW_VERSION "3.6.0" +#define FW_COMMIT_NR 2069 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index d9766e96a..68292d90c 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1591,7 +1591,7 @@ void setup() */ manage_heater(); // Update temperatures #ifdef DEBUG_UVLO_AUTOMATIC_RECOVER - printf_P(_N("Power panic detected!\nCurrent bed temp:%d\nSaved bed temp:%d\n"), (int)degBed(), eeprom_read_byte((uint8_t*)EEPROM_UVLO_TARGET_BED)) + printf_P(_N("Power panic detected!\nCurrent bed temp:%d\nSaved bed temp:%d\n"), (int)degBed(), eeprom_read_byte((uint8_t*)EEPROM_UVLO_TARGET_BED)); #endif if ( degBed() > ( (float)eeprom_read_byte((uint8_t*)EEPROM_UVLO_TARGET_BED) - AUTOMATIC_UVLO_BED_TEMP_OFFSET) ){ #ifdef DEBUG_UVLO_AUTOMATIC_RECOVER @@ -4229,8 +4229,8 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) current_position[Z_AXIS] = 5; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder); - current_position[X_AXIS] = pgm_read_float(bed_ref_points); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 1); + current_position[X_AXIS] = BED_X0; + current_position[Y_AXIS] = BED_Y0; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder); st_synchronize(); @@ -4260,8 +4260,8 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) } current_position[Z_AXIS] = 5; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder); - current_position[X_AXIS] = pgm_read_float(bed_ref_points); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 1); + current_position[X_AXIS] = BED_X0; + current_position[Y_AXIS] = BED_Y0; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder); st_synchronize(); find_bed_induction_sensor_point_z(-1.f); @@ -4379,6 +4379,21 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) break; } + uint8_t nMeasPoints = MESH_MEAS_NUM_X_POINTS; + if (code_seen('N')) { + nMeasPoints = code_value_uint8(); + if (nMeasPoints != 7) { + nMeasPoints = 3; + } + } + + uint8_t nProbeRetry = 3; + if (code_seen('R')) { + nProbeRetry = code_value_uint8(); + if (nProbeRetry > 10) { + nProbeRetry = 3; + } + } bool temp_comp_start = true; #ifdef PINDA_THERMISTOR @@ -4407,7 +4422,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) unsigned int custom_message_type_old = custom_message_type; unsigned int custom_message_state_old = custom_message_state; custom_message_type = CUSTOM_MSG_TYPE_MESHBL; - custom_message_state = (MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) + 10; + custom_message_state = (nMeasPoints * nMeasPoints) + 10; lcd_update(1); mbl.reset(); //reset mesh bed leveling @@ -4421,8 +4436,8 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS] / 60, active_extruder); // The move to the first calibration point. - current_position[X_AXIS] = pgm_read_float(bed_ref_points); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 1); + current_position[X_AXIS] = BED_X0; + current_position[Y_AXIS] = BED_Y0; #ifdef SUPPORT_VERBOSITY if (verbosity_level >= 1) @@ -4430,20 +4445,16 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); clamped ? SERIAL_PROTOCOLPGM("First calibration point clamped.\n") : SERIAL_PROTOCOLPGM("No clamping for first calibration point.\n"); } - #endif //SUPPORT_VERBOSITY - // mbl.get_meas_xy(0, 0, current_position[X_AXIS], current_position[Y_AXIS], false); + #endif //SUPPORT_VERBOSITY plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS] / 30, active_extruder); // Wait until the move is finished. st_synchronize(); - int mesh_point = 0; //index number of calibration point - - int ix = 0; - int iy = 0; + uint8_t mesh_point = 0; //index number of calibration point int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20; int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40; - bool has_z = is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point) + bool has_z = (nMeasPoints == 3) && is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point) #ifdef SUPPORT_VERBOSITY if (verbosity_level >= 1) { has_z ? SERIAL_PROTOCOLPGM("Z jitter data from Z cal. valid.\n") : SERIAL_PROTOCOLPGM("Z jitter data from Z cal. not valid.\n"); @@ -4451,13 +4462,13 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) #endif // SUPPORT_VERBOSITY int l_feedmultiply = setup_for_endstop_move(false); //save feedrate and feedmultiply, sets feedmultiply to 100 const char *kill_message = NULL; - while (mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) { + while (mesh_point != nMeasPoints * nMeasPoints) { // Get coords of a measuring point. - ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 - iy = mesh_point / MESH_MEAS_NUM_X_POINTS; - if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag + uint8_t ix = mesh_point % nMeasPoints; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / nMeasPoints; + if (iy & 1) ix = (nMeasPoints - 1) - ix; // Zig zag float z0 = 0.f; - if (has_z && mesh_point > 0) { + if (has_z && (mesh_point > 0)) { uint16_t z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * (ix + iy * 3 - 1))); z0 = mbl.z_values[0][0] + *reinterpret_cast(&z_offset_u) * 0.01; //#if 0 @@ -4480,8 +4491,8 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) st_synchronize(); // Move to XY position of the sensor point. - current_position[X_AXIS] = pgm_read_float(bed_ref_points + 2 * mesh_point); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 2 * mesh_point + 1); + current_position[X_AXIS] = BED_X(ix, nMeasPoints); + current_position[Y_AXIS] = BED_Y(iy, nMeasPoints); @@ -4499,7 +4510,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) // Go down until endstop is hit const float Z_CALIBRATION_THRESHOLD = 1.f; - if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point + if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point kill_message = _T(MSG_BED_LEVELING_FAILED_POINT_LOW); break; } @@ -4552,7 +4563,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) #endif // SUPPORT_VERBOSITY plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], Z_LIFT_FEEDRATE, active_extruder); st_synchronize(); - if (mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) { + if (mesh_point != nMeasPoints * nMeasPoints) { Sound_MakeSound(e_SOUND_TYPE_StandardAlert); bool bState; do { // repeat until Z-leveling o.k. @@ -4630,34 +4641,40 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) float offset = float(correction) * 0.001f; switch (i) { case 0: - for (uint8_t row = 0; row < 3; ++row) { - mbl.z_values[row][1] += 0.5f * offset; - mbl.z_values[row][0] += offset; + for (uint8_t row = 0; row < nMeasPoints; ++row) { + for (uint8_t col = 0; col < nMeasPoints - 1; ++col) { + mbl.z_values[row][col] += offset * (nMeasPoints - 1 - col) / (nMeasPoints - 1); + } } break; case 1: - for (uint8_t row = 0; row < 3; ++row) { - mbl.z_values[row][1] += 0.5f * offset; - mbl.z_values[row][2] += offset; + for (uint8_t row = 0; row < nMeasPoints; ++row) { + for (uint8_t col = 1; col < nMeasPoints; ++col) { + mbl.z_values[row][col] += offset * col / (nMeasPoints - 1); + } } break; case 2: - for (uint8_t col = 0; col < 3; ++col) { - mbl.z_values[1][col] += 0.5f * offset; - mbl.z_values[0][col] += offset; + for (uint8_t col = 0; col < nMeasPoints; ++col) { + for (uint8_t row = 0; row < nMeasPoints; ++row) { + mbl.z_values[row][col] += offset * (nMeasPoints - 1 - row) / (nMeasPoints - 1); + } } break; case 3: - for (uint8_t col = 0; col < 3; ++col) { - mbl.z_values[1][col] += 0.5f * offset; - mbl.z_values[2][col] += offset; + for (uint8_t col = 0; col < nMeasPoints; ++col) { + for (uint8_t row = 1; row < nMeasPoints; ++row) { + mbl.z_values[row][col] += offset * row / (nMeasPoints - 1); + } } break; } } } // SERIAL_ECHOLNPGM("Bed leveling correction finished"); - mbl.upsample_3x3(); //bilinear interpolation from 3x3 to 7x7 points while using the same array z_values[iy][ix] for storing (just coppying measured data to new destination and interpolating between them) + if (nMeasPoints == 3) { + mbl.upsample_3x3(); //bilinear interpolation from 3x3 to 7x7 points while using the same array z_values[iy][ix] for storing (just coppying measured data to new destination and interpolating between them) + } // SERIAL_ECHOLNPGM("Upsample finished"); mbl.active = 1; //activate mesh bed leveling // SERIAL_ECHOLNPGM("Mesh bed leveling activated"); @@ -7481,6 +7498,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s #ifdef FILAMENT_SENSOR if (mmu_enabled == false) { +//-// if (mcode_in_progress != 600) //M600 not in progress if ((mcode_in_progress != 600) && (eFilamentAction != e_FILAMENT_ACTION_autoLoad)) //M600 not in progress, preHeat @ autoLoad menu not active { if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL) && !wizard_active) @@ -7490,7 +7508,8 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s #ifdef PAT9125 fsensor_autoload_check_stop(); #endif //PAT9125 - if (degHotend0() > EXTRUDE_MINTEMP) +//-// if (degHotend0() > EXTRUDE_MINTEMP) +if(0) { if ((eSoundMode == e_SOUND_MODE_LOUD) || (eSoundMode == e_SOUND_MODE_ONCE)) _tone(BEEPER, 1000); @@ -7501,12 +7520,18 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s } else { +/* + lcd_update_enable(false); + show_preheat_nozzle_warning(); + lcd_update_enable(true); +*/ eFilamentAction=e_FILAMENT_ACTION_autoLoad; bFilamentFirstRun=false; if(target_temperature[0]>=EXTRUDE_MINTEMP) { bFilamentPreheatState=true; - mFilamentItem(target_temperature[0],target_temperature_bed); +// mFilamentItem(target_temperature[0],target_temperature_bed); + menu_submenu(mFilamentItemForce); } else { @@ -8402,13 +8427,13 @@ void uvlo_() // Move Z up to the next 0th full step. // Write the file position. eeprom_update_dword((uint32_t*)(EEPROM_FILE_POSITION), sd_position); - // Store the mesh bed leveling offsets. This is 2*9=18 bytes, which takes 18*3.4us=52us in worst case. - for (int8_t mesh_point = 0; mesh_point < 9; ++ mesh_point) { - uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 - uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS; + // Store the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case. + for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) { + uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / MESH_NUM_X_POINTS; // Scale the z value to 1u resolution. - int16_t v = mbl.active ? int16_t(floor(mbl.z_values[iy*3][ix*3] * 1000.f + 0.5f)) : 0; - eeprom_update_word((uint16_t*)(EEPROM_UVLO_MESH_BED_LEVELING+2*mesh_point), *reinterpret_cast(&v)); + int16_t v = mbl.active ? int16_t(floor(mbl.z_values[iy][ix] * 1000.f + 0.5f)) : 0; + eeprom_update_word((uint16_t*)(EEPROM_UVLO_MESH_BED_LEVELING_FULL +2*mesh_point), *reinterpret_cast(&v)); } // Read out the current Z motor microstep counter. This will be later used // for reaching the zero full step before powering off. @@ -8631,20 +8656,18 @@ void recover_machine_state_after_power_panic(bool bTiny) // 2) Initialize the logical to physical coordinate system transformation. world2machine_initialize(); - // 3) Restore the mesh bed leveling offsets. This is 2*9=18 bytes, which takes 18*3.4us=52us in worst case. + // 3) Restore the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case. mbl.active = false; - for (int8_t mesh_point = 0; mesh_point < 9; ++ mesh_point) { - uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 - uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS; + for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) { + uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / MESH_NUM_X_POINTS; // Scale the z value to 10u resolution. int16_t v; - eeprom_read_block(&v, (void*)(EEPROM_UVLO_MESH_BED_LEVELING+2*mesh_point), 2); + eeprom_read_block(&v, (void*)(EEPROM_UVLO_MESH_BED_LEVELING_FULL+2*mesh_point), 2); if (v != 0) mbl.active = true; mbl.z_values[iy][ix] = float(v) * 0.001f; } - if (mbl.active) - mbl.upsample_3x3(); // SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial "); // print_mesh_bed_leveling_table(); diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 16c02ed58..a9274d4a4 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -154,6 +154,8 @@ #define EEPROM_MMU_LOAD_FAIL_TOT (EEPROM_MMU_FAIL - 2) //uint16_t #define EEPROM_MMU_LOAD_FAIL (EEPROM_MMU_LOAD_FAIL_TOT - 1) //uint8_t #define EEPROM_MMU_CUTTER_ENABLED (EEPROM_MMU_LOAD_FAIL - 1) +#define EEPROM_UVLO_MESH_BED_LEVELING_FULL (EEPROM_MMU_CUTTER_ENABLED - 12*12*2) //allow 12 calibration points for future expansion + // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index a3fb4d184..fd11a370d 100644 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -122,7 +122,7 @@ void menu_back_if_clicked_fb(void) void menu_submenu(menu_func_t submenu) { - if (menu_depth <= MENU_DEPTH_MAX) + if (menu_depth < MENU_DEPTH_MAX) { menu_stack[menu_depth].menu = menu_menu; menu_stack[menu_depth++].position = lcd_encoder; @@ -132,7 +132,7 @@ void menu_submenu(menu_func_t submenu) static void menu_submenu_no_reset(menu_func_t submenu) { - if (menu_depth <= MENU_DEPTH_MAX) + if (menu_depth < MENU_DEPTH_MAX) { menu_stack[menu_depth].menu = menu_menu; menu_stack[menu_depth++].position = lcd_encoder; diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index 35798c2e5..0f56d999b 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -23,8 +23,7 @@ float world2machine_shift[2]; #define WEIGHT_FIRST_ROW_Y_HIGH (0.3f) #define WEIGHT_FIRST_ROW_Y_LOW (0.0f) -#define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1 -#define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4.f) // -0.6 + 5 + 4 = 8.4 + // Scaling of the real machine axes against the programmed dimensions in the firmware. // The correction is tiny, here around 0.5mm on 250mm length. @@ -89,19 +88,6 @@ const float bed_ref_points_4[] PROGMEM = { 210.4f - BED_PRINT_ZERO_REF_Y - Y_PROBE_OFFSET_FROM_EXTRUDER - SHEET_PRINT_ZERO_REF_Y }; -const float bed_ref_points[] PROGMEM = { - 13.f - BED_ZERO_REF_X, 10.4f - BED_ZERO_REF_Y, - 115.f - BED_ZERO_REF_X, 10.4f - BED_ZERO_REF_Y, - 216.f - BED_ZERO_REF_X, 10.4f - BED_ZERO_REF_Y, - - 216.f - BED_ZERO_REF_X, 106.4f - BED_ZERO_REF_Y, - 115.f - BED_ZERO_REF_X, 106.4f - BED_ZERO_REF_Y, - 13.f - BED_ZERO_REF_X, 106.4f - BED_ZERO_REF_Y, - - 13.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y, - 115.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y, - 216.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y -}; #else // Positions of the bed reference points in the machine coordinates, referenced to the P.I.N.D.A sensor. @@ -113,22 +99,9 @@ const float bed_ref_points_4[] PROGMEM = { 13.f - BED_ZERO_REF_X, 104.4f - BED_ZERO_REF_Y }; -const float bed_ref_points[] PROGMEM = { - 13.f - BED_ZERO_REF_X, 8.4f - BED_ZERO_REF_Y, - 115.f - BED_ZERO_REF_X, 8.4f - BED_ZERO_REF_Y, - 216.f - BED_ZERO_REF_X, 8.4f - BED_ZERO_REF_Y, - - 216.f - BED_ZERO_REF_X, 104.4f - BED_ZERO_REF_Y, - 115.f - BED_ZERO_REF_X, 104.4f - BED_ZERO_REF_Y, - 13.f - BED_ZERO_REF_X, 104.4f - BED_ZERO_REF_Y, - - 13.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y, - 115.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y, - 216.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y -}; - #endif //not HEATBED_V2 + static inline float sqr(float x) { return x * x; } #ifdef HEATBED_V2 @@ -2428,8 +2401,11 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level refresh_cmd_timeout(); // Go to the measurement point. // Use the coorrected coordinate, which is a result of find_bed_offset_and_skew(). - current_position[X_AXIS] = pgm_read_float(bed_ref_points + mesh_point * 2); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points + mesh_point * 2 + 1); + uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS; + if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; + current_position[X_AXIS] = BED_X(ix, MESH_MEAS_NUM_X_POINTS); + current_position[Y_AXIS] = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS); go_to_current(homing_feedrate[X_AXIS] / 60); delay_keep_alive(3000); } @@ -2806,8 +2782,8 @@ bool sample_mesh_and_store_reference() // The first point defines the reference. current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; go_to_current(homing_feedrate[Z_AXIS]/60); - current_position[X_AXIS] = pgm_read_float(bed_ref_points); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points+1); + current_position[X_AXIS] = BED_X0; + current_position[Y_AXIS] = BED_Y0; world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); go_to_current(homing_feedrate[X_AXIS]/60); memcpy(destination, current_position, sizeof(destination)); @@ -2836,8 +2812,11 @@ bool sample_mesh_and_store_reference() // Print the decrasing ID of the measurement point. current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; go_to_current(homing_feedrate[Z_AXIS]/60); - current_position[X_AXIS] = pgm_read_float(bed_ref_points+2*mesh_point); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points+2*mesh_point+1); + int8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; + int8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS; + if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag + current_position[X_AXIS] = BED_X(ix, MESH_MEAS_NUM_X_POINTS); + current_position[Y_AXIS] = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS); world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); go_to_current(homing_feedrate[X_AXIS]/60); #ifdef MESH_BED_CALIBRATION_SHOW_LCD @@ -2852,9 +2831,7 @@ bool sample_mesh_and_store_reference() return false; } // Get cords of measuring point - int8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; - int8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS; - if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag + mbl.set_z(ix, iy, current_position[Z_AXIS]); } { @@ -2956,8 +2933,13 @@ bool scan_bed_induction_points(int8_t verbosity_level) go_to_current(homing_feedrate[Z_AXIS]/60); // Go to the measurement point. // Use the coorrected coordinate, which is a result of find_bed_offset_and_skew(). - current_position[X_AXIS] = vec_x[0] * pgm_read_float(bed_ref_points+mesh_point*2) + vec_y[0] * pgm_read_float(bed_ref_points+mesh_point*2+1) + cntr[0]; - current_position[Y_AXIS] = vec_x[1] * pgm_read_float(bed_ref_points+mesh_point*2) + vec_y[1] * pgm_read_float(bed_ref_points+mesh_point*2+1) + cntr[1]; + uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS; + if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; + float bedX = BED_X(ix, MESH_MEAS_NUM_X_POINTS); + float bedY = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS); + current_position[X_AXIS] = vec_x[0] * bedX + vec_y[0] * bedY + cntr[0]; + current_position[Y_AXIS] = vec_x[1] * bedX + vec_y[1] * bedY + cntr[1]; // The calibration points are very close to the min Y. if (current_position[Y_AXIS] < Y_MIN_POS_FOR_BED_CALIBRATION) current_position[Y_AXIS] = Y_MIN_POS_FOR_BED_CALIBRATION; diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h index d928f1d11..4990d104b 100644 --- a/Firmware/mesh_bed_calibration.h +++ b/Firmware/mesh_bed_calibration.h @@ -1,10 +1,31 @@ #ifndef MESH_BED_CALIBRATION_H #define MESH_BED_CALIBRATION_H +#define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1 +#define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4.f) // -0.6 + 5 + 4 = 8.4 + +#ifdef HEATBED_V2 + +#define BED_X0 (13.f - BED_ZERO_REF_X) +#define BED_Y0 (10.4f - BED_ZERO_REF_Y) +#define BED_Xn (216.f - BED_ZERO_REF_X) +#define BED_Yn (202.4f - BED_ZERO_REF_Y) + +#else + +#define BED_X0 (13.f - BED_ZERO_REF_X) +#define BED_Y0 (8.4f - BED_ZERO_REF_Y) +#define BED_Xn (216.f - BED_ZERO_REF_X) +#define BED_Yn (202.4f - BED_ZERO_REF_Y) + +#endif //not HEATBED_V2 + +#define BED_X(i, n) ((float)i * (BED_Xn - BED_X0) / (n - 1) + BED_X0) +#define BED_Y(i, n) ((float)i * (BED_Yn - BED_Y0) / (n - 1) + BED_Y0) + // Exact positions of the print head above the bed reference points, in the world coordinates. // The world coordinates match the machine coordinates only in case, when the machine // is built properly, the end stops are at the correct positions and the axes are perpendicular. -extern const float bed_ref_points[] PROGMEM; extern const float bed_ref_points_4[] PROGMEM; extern const float bed_skew_angle_mild; diff --git a/Firmware/mesh_bed_leveling.cpp b/Firmware/mesh_bed_leveling.cpp index 746458aea..344d41e3f 100644 --- a/Firmware/mesh_bed_leveling.cpp +++ b/Firmware/mesh_bed_leveling.cpp @@ -21,78 +21,6 @@ static inline bool vec_undef(const float v[2]) return vx[0] == 0x0FFFFFFFF || vx[1] == 0x0FFFFFFFF; } -void mesh_bed_leveling::get_meas_xy(int ix, int iy, float &x, float &y, bool /*use_default*/) -{ -#if 0 - float cntr[2] = { - eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+0)), - eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+4)) - }; - float vec_x[2] = { - eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +0)), - eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +4)) - }; - float vec_y[2] = { - eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +0)), - eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +4)) - }; - - if (use_default || vec_undef(cntr) || vec_undef(vec_x) || vec_undef(vec_y)) { - // Default, uncorrected positions of the calibration points. Works well for correctly built printers. - x = float(MESH_MIN_X) + float(MEAS_NUM_X_DIST) * float(ix) - X_PROBE_OFFSET_FROM_EXTRUDER; - //FIXME - //x -= 5.f; - y = float(MESH_MIN_Y) + float(MEAS_NUM_Y_DIST) * float(iy) - Y_PROBE_OFFSET_FROM_EXTRUDER; - } else { -#if 0 - SERIAL_ECHO("Running bed leveling. Calibration data: "); - SERIAL_ECHO(cntr[0]); - SERIAL_ECHO(","); - SERIAL_ECHO(cntr[1]); - SERIAL_ECHO(", x: "); - SERIAL_ECHO(vec_x[0]); - SERIAL_ECHO(","); - SERIAL_ECHO(vec_x[1]); - SERIAL_ECHO(", y: "); - SERIAL_ECHO(vec_y[0]); - SERIAL_ECHO(","); - SERIAL_ECHO(vec_y[1]); - SERIAL_ECHOLN(""); -#endif - - x = cntr[0]; - y = cntr[1]; - if (ix < 1) { - x -= vec_x[0]; - y -= vec_x[1]; - } else if (ix > 1) { - x += vec_x[0]; - y += vec_x[1]; - } - if (iy < 1) { - x -= vec_y[0]; - y -= vec_y[1]; - } else if (iy > 1) { - x += vec_y[0]; - y += vec_y[1]; - } - -#if 0 - SERIAL_ECHO("Calibration point position: "); - SERIAL_ECHO(x); - SERIAL_ECHO(","); - SERIAL_ECHO(y); - SERIAL_ECHOLN(""); -#endif - } -#else - // Default, uncorrected positions of the calibration points. - // This coordinate will be corrected by the planner. - x = pgm_read_float(bed_ref_points + 2 * (iy * 3 + ix)); - y = pgm_read_float(bed_ref_points + 2 * (iy * 3 + ix) + 1); -#endif -} - #if MESH_NUM_X_POINTS>=5 && MESH_NUM_Y_POINTS>=5 && (MESH_NUM_X_POINTS&1)==1 && (MESH_NUM_Y_POINTS&1)==1 // Works for an odd number of MESH_NUM_X_POINTS and MESH_NUM_Y_POINTS diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index cdd85e9bb..2e3fca914 100644 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -1052,6 +1052,16 @@ else { } } +//-// +void extr_unload_view() +{ +lcd_clear(); +lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_UNLOADING_FILAMENT)); +lcd_print(" "); +if (mmu_extruder == MMU_FILAMENT_UNKNOWN) lcd_print(" "); +else lcd_print(mmu_extruder + 1); +} + void extr_unload() { //unload just current filament for multimaterial printers #ifdef SNMM @@ -1066,12 +1076,15 @@ void extr_unload() st_synchronize(); //show which filament is currently unloaded - lcd_update_enable(false); +//-// lcd_update_enable(false); +menu_submenu(extr_unload_view); +/* lcd_clear(); lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_UNLOADING_FILAMENT)); lcd_print(" "); if (mmu_extruder == MMU_FILAMENT_UNKNOWN) lcd_print(" "); else lcd_print(mmu_extruder + 1); +*/ mmu_filament_ramming(); @@ -1079,7 +1092,8 @@ void extr_unload() // get response manage_response(false, true, MMU_UNLOAD_MOVE); - lcd_update_enable(true); +//-// lcd_update_enable(true); +menu_back(); #else //SNMM lcd_clear(); @@ -1380,9 +1394,7 @@ bFilamentAction=false; // NOT in "mmu_fil_eject_menu( LcdUpdateDisabler disableLcdUpdate; lcd_clear(); lcd_set_cursor(0, 1); lcd_puts_P(_i("Ejecting filament")); - current_position[E_AXIS] -= 80; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder); - st_synchronize(); + mmu_filament_ramming(); mmu_command(MmuCmd::E0 + filament); manage_response(false, false, MMU_UNLOAD_MOVE); if (recover) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index f6ad87615..4ce13bd60 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -55,7 +55,8 @@ int current_temperature_raw[EXTRUDERS] = { 0 }; float current_temperature[EXTRUDERS] = { 0.0 }; #ifdef PINDA_THERMISTOR -int current_temperature_raw_pinda = 0 ; +uint16_t current_temperature_raw_pinda = 0 ; //value with more averaging applied +uint16_t current_temperature_raw_pinda_fast = 0; //value read from adc float current_temperature_pinda = 0.0; #endif //PINDA_THERMISTOR @@ -1029,6 +1030,7 @@ static void updateTemperaturesFromRawValues() } #ifdef PINDA_THERMISTOR + current_temperature_raw_pinda = (uint16_t)((uint32_t)current_temperature_raw_pinda * 3 + current_temperature_raw_pinda_fast) >> 2; current_temperature_pinda = analog2tempBed(current_temperature_raw_pinda); #endif @@ -1594,7 +1596,7 @@ extern "C" { void adc_ready(void) //callback from adc when sampling finished { current_temperature_raw[0] = adc_values[ADC_PIN_IDX(TEMP_0_PIN)]; //heater - current_temperature_raw_pinda = adc_values[ADC_PIN_IDX(TEMP_PINDA_PIN)]; + current_temperature_raw_pinda_fast = adc_values[ADC_PIN_IDX(TEMP_PINDA_PIN)]; current_temperature_bed_raw = adc_values[ADC_PIN_IDX(TEMP_BED_PIN)]; #ifdef VOLT_PWR_PIN current_voltage_raw_pwr = adc_values[ADC_PIN_IDX(VOLT_PWR_PIN)]; diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index f8cbd6b2c..2f0cb7852 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2319,6 +2319,7 @@ eFILAMENT_ACTION eFilamentAction=e_FILAMENT_ACTION_none; // must be initialized bool bFilamentFirstRun; bool bFilamentPreheatState; bool bFilamentAction=false; +bool bFilamentWaitingFlag=false; static void mFilamentPrompt() { @@ -2350,14 +2351,14 @@ if(lcd_clicked()) if(!bFilamentPreheatState) { nLevel++; -// setTargetHotend0(0.0); // uncoment if return to base state is required +// setTargetHotend0(0.0); // uncoment if return to base-state is required } menu_back(nLevel); switch(eFilamentAction) { case e_FILAMENT_ACTION_Load: case e_FILAMENT_ACTION_autoLoad: - loading_flag = true; + loading_flag=true; enquecommand_P(PSTR("M701")); // load filament break; case e_FILAMENT_ACTION_unLoad: @@ -2390,7 +2391,8 @@ if(lcd_clicked()) } } -void mFilamentItem(uint16_t nTemp,uint16_t nTempBed) +/* +void _mFilamentItem(uint16_t nTemp,uint16_t nTempBed) { static int nTargetOld,nTargetBedOld; uint8_t nLevel; @@ -2491,6 +2493,106 @@ else { else bBeep=true; } } +*/ + +void mFilamentItem(uint16_t nTemp,uint16_t nTempBed) +{ +static int nTargetOld,nTargetBedOld; +uint8_t nLevel; + +//if(bPreheatState) // not necessary + nTargetOld=target_temperature[0]; + nTargetBedOld=target_temperature_bed; +setTargetHotend0((float)nTemp); +setTargetBed((float)nTempBed); +lcd_timeoutToStatus.stop(); +if(current_temperature[0]>(target_temperature[0]*0.95)) + { + switch(eFilamentAction) + { + case e_FILAMENT_ACTION_Load: + case e_FILAMENT_ACTION_autoLoad: + case e_FILAMENT_ACTION_unLoad: + if(bFilamentWaitingFlag) + menu_submenu(mFilamentPrompt); + else { + nLevel=bFilamentPreheatState?1:2; + menu_back(nLevel); + if((eFilamentAction==e_FILAMENT_ACTION_Load)||(eFilamentAction==e_FILAMENT_ACTION_autoLoad)) + { + loading_flag=true; + enquecommand_P(PSTR("M701")); // load filament + if(eFilamentAction==e_FILAMENT_ACTION_autoLoad) + eFilamentAction=e_FILAMENT_ACTION_none; // i.e. non-autoLoad + } + if(eFilamentAction==e_FILAMENT_ACTION_unLoad) + enquecommand_P(PSTR("M702")); // unload filament + } + break; + case e_FILAMENT_ACTION_mmuLoad: + nLevel=bFilamentPreheatState?1:2; + bFilamentAction=true; + menu_back(nLevel); + menu_submenu(mmu_load_to_nozzle_menu); + break; + case e_FILAMENT_ACTION_mmuUnLoad: + nLevel=bFilamentPreheatState?1:2; + bFilamentAction=true; + menu_back(nLevel); + extr_unload(); + break; + case e_FILAMENT_ACTION_mmuEject: + nLevel=bFilamentPreheatState?1:2; + bFilamentAction=true; + menu_back(nLevel); + menu_submenu(mmu_fil_eject_menu); + break; + } + if(bFilamentWaitingFlag) + Sound_MakeSound(e_SOUND_TYPE_StandardPrompt); + bFilamentWaitingFlag=false; + } +else { + bFilamentWaitingFlag=true; + lcd_set_cursor(0,0); + lcdui_print_temp(LCD_STR_THERMOMETER[0],(int)degHotend(0),(int)degTargetHotend(0)); + lcd_set_cursor(0,1); + switch(eFilamentAction) + { + case e_FILAMENT_ACTION_Load: + case e_FILAMENT_ACTION_autoLoad: + case e_FILAMENT_ACTION_mmuLoad: + lcd_puts_P(_i("Preheating to load")); ////MSG_ c=20 r=1 + break; + case e_FILAMENT_ACTION_unLoad: + case e_FILAMENT_ACTION_mmuUnLoad: + lcd_puts_P(_i("Preheating to unload")); ////MSG_ c=20 r=1 + break; + case e_FILAMENT_ACTION_mmuEject: + lcd_puts_P(_i("Preheating to eject")); ////MSG_ c=20 r=1 + break; + } + lcd_set_cursor(0,3); + lcd_puts_P(_i(">Cancel")); ////MSG_ c=20 r=1 + if(lcd_clicked()) + { + bFilamentWaitingFlag=false; + if(!bFilamentPreheatState) + { + setTargetHotend0(0.0); + setTargetBed(0.0); + menu_back(); + } + else { + setTargetHotend0((float)nTargetOld); + setTargetBed((float)nTargetBedOld); + } + menu_back(); + if(eFilamentAction==e_FILAMENT_ACTION_autoLoad) + eFilamentAction=e_FILAMENT_ACTION_none; // i.e. non-autoLoad + } + } +} static void mFilamentItem_PLA() { @@ -2549,6 +2651,11 @@ MENU_ITEM_SUBMENU_P(PSTR("FLEX - " STRINGIFY(FLEX_PREHEAT_HOTEND_TEMP) "/" STRI MENU_END(); } +void mFilamentItemForce() +{ +mFilamentItem(target_temperature[0],target_temperature_bed); +} + void lcd_unLoadFilament() { diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index c947a346d..ca45d7636 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -149,6 +149,7 @@ extern bool bFilamentFirstRun; extern bool bFilamentPreheatState; extern bool bFilamentAction; void mFilamentItem(uint16_t nTemp,uint16_t nTempBed); +void mFilamentItemForce(); void mFilamentMenu(); void unload_filament();