Skip to content

Commit

Permalink
Added auto leveling to mesh (only for me)
Browse files Browse the repository at this point in the history
  • Loading branch information
epatel committed Nov 8, 2015
1 parent 7633215 commit 7613a15
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 11 deletions.
1 change: 1 addition & 0 deletions Marlin/Conditionals.h
Expand Up @@ -220,6 +220,7 @@
#define BEEPER_PIN -1 // Turn beeper off
#define BTN_EN1 33 // Swap encoder direction
#define BTN_EN2 31
#define Z_MIN_PROBE_PIN 19

#ifndef USBCON
#define HardwareSerial_h // trick to disable the standard HWserial
Expand Down
4 changes: 3 additions & 1 deletion Marlin/Configuration.h
Expand Up @@ -342,7 +342,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of
const bool X_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
const bool Y_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
#define DISABLE_MAX_ENDSTOPS
//#define DISABLE_MIN_ENDSTOPS

Expand Down Expand Up @@ -444,6 +444,8 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define MESH_HOME_SEARCH_Z 4 // Z after Home, bed somewhere below but above 0.0.
#endif // MESH_BED_LEVELING

#define Z_MIN_PROBE_ENDSTOP

//===========================================================================
//============================ Bed Auto Leveling ============================
//===========================================================================
Expand Down
56 changes: 52 additions & 4 deletions Marlin/Marlin_main.cpp
Expand Up @@ -2251,7 +2251,9 @@ inline void gcode_G28() {

#if ENABLED(MESH_BED_LEVELING)

enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset };
enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset, MeshProbeStart, MeshProbePoints };

bool mesh_is_leveling = false;

/**
* G29: Mesh-based Z probe, probes a grid and produces a
Expand All @@ -2260,10 +2262,12 @@ enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffse
* Parameters With MESH_BED_LEVELING:
*
* S0 Produce a mesh report
* S1 Start probing mesh points
* S1 Start probing mesh points manually
* S2 Probe the next mesh point
* S3 Xn Yn Zn.nn Manually modify a single point
* S4 Zn.nn Set z offset. Positive away from bed, negative closer to bed.
* S5 Start probing mesh points automatically
* S6 Probe mesh points
*
* The S0 report the points as below
*
Expand All @@ -2276,8 +2280,8 @@ enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffse
inline void gcode_G29() {
static int probe_point = -1;
MeshLevelingState state = code_seen('S') ? (MeshLevelingState)code_value_short() : MeshReport;
if (state < 0 || state > 4) {
SERIAL_PROTOCOLLNPGM("S out of range (0-4).");
if (state < 0 || state > 6) {
SERIAL_PROTOCOLLNPGM("S out of range (0-6).");
return;
}
int ix, iy;
Expand Down Expand Up @@ -2382,6 +2386,50 @@ inline void gcode_G29() {
return;
}
mbl.z_offset = z;
break;
case MeshProbeStart:
mesh_is_leveling = true;
mbl.reset();
enqueuecommands_P(PSTR("G28\nG1 Z4\nG29 S6"));
break;
case MeshProbePoints: {
enable_endstops(true);
st_synchronize();

int ix, iy;
float zLevel = current_position[Z_AXIS];

for (int probe_point=0; probe_point<MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS; probe_point++) {
ix = probe_point % MESH_NUM_X_POINTS;
iy = probe_point / MESH_NUM_X_POINTS;
if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // zig-zag
current_position[X_AXIS] = mbl.get_x(ix);
current_position[Y_AXIS] = mbl.get_y(iy);
current_position[Z_AXIS] = zLevel;
feedrate = homing_feedrate[X_AXIS]*2.0;
line_to_current_position();
st_synchronize();
feedrate = homing_feedrate[Z_AXIS]/2.0;
line_to_z(-(Z_MAX_LENGTH + 10));
st_synchronize();
endstops_hit_on_purpose();
current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
mbl.set_z(ix, iy, current_position[Z_AXIS] + MESH_HOME_SEARCH_Z);
sync_plan_position();
line_to_z(zLevel);
st_synchronize();
}

current_position[X_AXIS] = mbl.get_x(0);
current_position[Y_AXIS] = mbl.get_y(0);
current_position[Z_AXIS] = zLevel;
feedrate = homing_feedrate[X_AXIS];
line_to_current_position();
st_synchronize();

mbl.active = 1;
mesh_is_leveling = false;
}
} // switch(state)
}

Expand Down
9 changes: 9 additions & 0 deletions Marlin/language_en.h
Expand Up @@ -108,6 +108,15 @@
#ifndef MSG_LEVEL_BED
#define MSG_LEVEL_BED "Level bed"
#endif
#ifndef MSG_LEVEL_BED_MANUAL
#define MSG_LEVEL_BED_MANUAL "Level bed manual"
#endif
#ifndef MSG_LEVEL_BED_AUTO
#define MSG_LEVEL_BED_AUTO "Level bed auto"
#endif
#ifndef MSG_LEVEL_BED_OFFSET
#define MSG_LEVEL_BED_OFFSET "Level bed offset"
#endif
#ifndef MSG_MOVE_X
#define MSG_MOVE_X "Move X"
#endif
Expand Down
88 changes: 82 additions & 6 deletions Marlin/ultralcd.cpp
Expand Up @@ -72,7 +72,10 @@ static void lcd_control_volumetric_menu();
#include "mesh_bed_leveling.h"
static void _lcd_level_bed();
static void _lcd_level_bed_homing();
static void lcd_level_bed();
static void lcd_level_bed_menu();
static void lcd_level_bed_manual();
static void lcd_level_bed_auto();
static void lcd_level_bed_offset();
#endif

/* Different types of actions that can be used in menu items. */
Expand Down Expand Up @@ -472,7 +475,7 @@ static void lcd_tune_menu() {
//
// Bed Z:
//
MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1);
MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -3, 3);
#endif
//
// Nozzle:
Expand Down Expand Up @@ -685,7 +688,7 @@ static void lcd_prepare_menu() {
if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS])
MENU_ITEM(gcode, MSG_LEVEL_BED, PSTR("G29"));
#elif ENABLED(MANUAL_BED_LEVELING)
MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed);
MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed_menu);
#endif
//
// Move Axis
Expand Down Expand Up @@ -1106,7 +1109,7 @@ static void lcd_control_motion_menu() {
MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX);
#endif
#if ENABLED(MANUAL_BED_LEVELING)
MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1);
MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -3, 3);
#endif
MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 10, 99000);
MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &max_xy_jerk, 1, 990);
Expand Down Expand Up @@ -2019,6 +2022,7 @@ char* ftostr52(const float& x) {

#if ENABLED(MANUAL_BED_LEVELING)

extern bool mesh_is_leveling;
static int _lcd_level_bed_position;

/**
Expand Down Expand Up @@ -2069,6 +2073,28 @@ static void _lcd_level_bed() {
debounce_click = false;
}

static void _lcd_level_bed_offset() {
if (encoderPosition != 0) {
refresh_cmd_timeout();
mbl.z_offset += float((int)encoderPosition) * MBL_Z_STEP;
if (min_software_endstops && current_position[Z_AXIS] < Z_MIN_POS) current_position[Z_AXIS] = Z_MIN_POS;
if (max_software_endstops && current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
encoderPosition = 0;
line_to_current(Z_AXIS);
lcdDrawUpdate = 2;
}
if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("Z"), ftostr43(mbl.z_offset));
static bool debounce_click = false;
if (LCD_CLICKED) {
if (!debounce_click) {
debounce_click = true;
enqueuecommands_P(PSTR("G28"));
lcd_return_to_status();
}
} else
debounce_click = false;
}

/**
* MBL Move to mesh starting point
*/
Expand All @@ -2086,17 +2112,67 @@ static void _lcd_level_bed_homing() {
lcdDrawUpdate = 2;
}

static void _lcd_level_bed_homing_offset() {
if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("XYZ"), "Homing");
if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS]) {
current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
current_position[X_AXIS] = MESH_MIN_X;
current_position[Y_AXIS] = MESH_MIN_Y;
line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS);
lcd_goto_menu(_lcd_level_bed_offset);
}
lcdDrawUpdate = 2;
}

/**
* MBL Move to mesh starting point
*/
static void _lcd_level_bed_probing() {
if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("XYZ"), "Probing");
if (!mesh_is_leveling) {
axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
enqueuecommands_P(PSTR("G28"));
lcd_return_to_status();
}
lcdDrawUpdate = 2;
}

/**
* MBL entry-point
* MBL entry-points
*/
static void lcd_level_bed() {
static void lcd_level_bed_menu() {
START_MENU();
MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu);
MENU_ITEM(submenu, MSG_LEVEL_BED_AUTO, lcd_level_bed_auto);
MENU_ITEM(submenu, MSG_LEVEL_BED_OFFSET, lcd_level_bed_offset);
MENU_ITEM(submenu, MSG_LEVEL_BED_MANUAL, lcd_level_bed_manual);
END_MENU();
}

static void lcd_level_bed_manual() {
axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
mbl.reset();
enqueuecommands_P(PSTR("G28"));
lcdDrawUpdate = 2;
lcd_goto_menu(_lcd_level_bed_homing);
}

static void lcd_level_bed_auto() {
mesh_is_leveling = true;
enqueuecommands_P(PSTR("G29 S5"));
lcdDrawUpdate = 2;
lcd_goto_menu(_lcd_level_bed_probing);
}

static void lcd_level_bed_offset() {
axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
mbl.z_offset = 0;
enqueuecommands_P(PSTR("G28"));
lcdDrawUpdate = 2;
lcd_goto_menu(_lcd_level_bed_homing_offset);
}

#endif // MANUAL_BED_LEVELING

#endif // ULTRA_LCD

0 comments on commit 7613a15

Please sign in to comment.