Complete guide to make the auto-levelling of G2S operational
Posted: Tue Jul 25, 2017 3:46 pm
I think a lot of people just give up the auto-levelling feature of the G2S because it just does not work straight from the box. But as I thought it would be interesting to change the bed plate easily I made some (easy) Hardware and software change to make it reliable.
First a list of identified problems :
Hardware problems
• the holes on the spider to fix the probe mount are not correctly aligned making the probe getting stuck when going too low.
• the screw in the lock ring is of poor quality making difficult to put the spring under tension.
• the microswitch used to detect the levelling of the z-probe is reliable when used to detect the closing of the circuit (ie for end-stop), but not when used to detect the opening.
• to close the microswitch the spring around the z-probe should have enough tension to be stronger than the internal spring of the microswitch. To be sure that each time the z-probe goes down the microswitch will close, you have to put the external spring under a big tension, meaning big risks of spider tilt when pushing the probe.
Software problems (on the official version of the marlin software : 1.0.3 dev )
• If you launch a G29 command without a closed z-probe circuit (ie the z-probe down) the behavior is not predictable, the spider is likely to go one way without stopping on end-stop but forcing the mechanical stop until you stop the power (I broke ball bearings that way).
• normally for the initial adjustment you should modify the z-probe height by the M851 gcode. Unfortunately it does not do anything with the official marlin version. So you have to recompile for each try.
• The auto-levelling is not compatible with multi extruders in this version of marlin (at each extruder change the spider will go up a little)
there is no command to put in a script to wait until the z-probe is up or down.
What to do to repair that ?
Hardware change :
first point : change the grub screw of the probe lock ring. To detect a reliable level, the tension of the spring should be constant, the grub screw is too difficult to tighten!.I used a remaining #15 screw but you may use any M3 screw (see photo). Be careful the the head of the crew does not touch anything that could block the probe. Second point : Tighten the lock ring to put enough spring tension so that the probe come at its lowest level. Verify that the probe won’t get stuck in the probe mount due to hole misalignment. I had to file down the slot of the probe mount to avoid that.
Third point : Change the microswitch. it is impossible to use the provided switch for auto levelling. But luckily it is very easy to find better ones. I bought mine in a local electronic shop (see photo), it is almost the same, it has the same form factor, it cost twice the price of the original (but just a few bucks) and its lever has a hinge, so it needs much less force to switch and is considerably more reliable. Then you should adjust the tension of the sprint to be sure that every time the spider mounts, the circuit will close (it is much easier with my new switch) but not too much (there is a risk of spider tilt) . You may verify with the M119 command.
At this point your Auto-leveling should work. But to make it really usable I made some software change. I use Marlin 1.0.3 of the RKMB_GT2560_G2S package provided by GEEETECH so all the following modification are for this version only.
first software change : Block the use of auto-levelling if probe is not down to prevent erratic behaviour.
in marlin_main.cpp file in function gcode_G29() at line 2568 after the line :
st_synchronize();
add the following code :
#define MSG_PROBE_NOT_DEPLOYED "G29 probe not deployed"
if (!deploy_probe_for_each_reading) { // if the probe is not to deploy for each point,
// it should be deploy at this point.
// otherwise return in error
boolean probestate=true;
#if HAS_Z_MIN
probestate=READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING;
#endif
#ifdef Z_PROBE_ENDSTOP
probestate=READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING;
#endif
if (probestate){ // test the probe state state
LCD_MESSAGEPGM(MSG_PROBE_NOT_DEPLOYED);
SERIAL_ECHO_START;
SERIAL_ECHOLN(MSG_PROBE_NOT_DEPLOYED);
return;
}
}
second software change : Correct gcode_T() function to use two extruders and auto-levelling.
in marlin_main.cpp file in function gcode_T() at line 5128 after the line :
// Offset extruder (only by XY)
change the following code :
for (int i=X_AXIS; i<=Y_AXIS; i++)
current_position += extruder_offset[tmp_extruder] - extruder_offset[active_extruder];
// Set the new active extruder and position
active_extruder = tmp_extruder;
#endif // !DUAL_X_CARRIAGE
#ifdef DELTA
sync_plan_position_delta();
#else
sync_plan_position();
#endif
// Move to the old position if 'F' was in the parameters
if (make_move && IsRunning()) prepare_move();
by this one :
if (extruder_offset[X_AXIS][tmp_extruder]==0 && extruder_offset[Y_AXIS][tmp_extruder]==0 &&
extruder_offset[X_AXIS][active_extruder]==0 && extruder_offset[Y_AXIS][active_extruder]==0){
active_extruder = tmp_extruder;
} else {
for (int i=X_AXIS; i<=Y_AXIS; i++)
current_position += extruder_offset[tmp_extruder] - extruder_offset[active_extruder];
// Set the new active extruder and position
active_extruder = tmp_extruder;
#endif // !DUAL_X_CARRIAGE
SERIAL_ECHO_START;
SERIAL_ECHOLN(" send plan position");
#ifdef DELTA
sync_plan_position_delta();
#else
sync_plan_position();
#endif
// Move to the old position if 'F' was in the parameters
if (make_move && IsRunning()) prepare_move();
}
Third software change : Enable the use of M851 for probe level setting.
in marlin_main.cpp file in function gcode_G29() at line 2600 after the line :
delta_grid_spacing[1] = yGridSpacing;
change the line
float z_offset = Z_PROBE_OFFSET_FROM_EXTRUDER;
by
float z_offset = -zprobe_zoffset ; // do not use Z_PROBE_OFFSET_FROM_EXTRUDER;
in marlin_main.cpp file in function clamp_to_software_endstops() at line 5748 after the line :
#ifdef ENABLE_AUTO_BED_LEVELING
change the line :
if (Z_PROBE_OFFSET_FROM_EXTRUDER < 0) negative_z_offset += Z_PROBE_OFFSET_FROM_EXTRUDER;
by
if (zprobe_zoffset > 0) negative_z_offset -= zprobe_zoffset;
Fourth software change : Modify M401 (raise z-probe) and M402 (stow z-probe) function to be blocking until the z-probe has been raised or stowed.
in marlin_main.cpp file at line 4569 after the line :
inline void gcode_M400() { st_synchronize(); }
change the line :
#if defined(ENABLE_AUTO_BED_LEVELING) && !defined(Z_PROBE_SLED) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY))
by
#if defined(ENABLE_AUTO_BED_LEVELING)
in marlin_main.cpp file in function gcode_M401() at line 4587 after the line :
deploy_z_probe();
Add the lines :
// and block if probe is not deployed
#define MSG_WAIT_PROBE_DEPLOYED "Wait probe deployment"
boolean probestate=true,probe_msg=true;
while(probestate){
#if HAS_Z_MIN
probestate=READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING;
#endif
#ifdef Z_PROBE_ENDSTOP
probestate=READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING;
#endif
if (probestate && probe_msg){ // send waiting message once
LCD_MESSAGEPGM(MSG_WAIT_PROBE_DEPLOYED);
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_WAIT_PROBE_DEPLOYED);
probe_msg=false;
}
idle();
}
SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT);
LCD_MESSAGEPGM(MSG_ZPROBE_OUT);
in marlin_main.cpp file in functionn gcode_M402() at line 45ç7 after the line :
stow_z_probe(false);
Add the lines :
// and block if probe is not stowed
#define MSG_WAIT_PROBE_DEPLOYED "Wait probe stowed"
boolean probestate=false,probe_msg=true;
while( ! probestate){
#if HAS_Z_MIN
probestate=READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING;
#endif
#ifdef Z_PROBE_ENDSTOP
probestate=READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING;
#endif
if (! probestate && probe_msg){ // send waiting message once
LCD_MESSAGEPGM(MSG_WAIT_PROBE_DEPLOYED);
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_WAIT_PROBE_DEPLOYED);
probe_msg=false;
}
idle();
}
// add a waiting tiile to secure the probe
if (! probe_msg){
millis_t codenum = 3500;
codenum += millis(); // keep track of when we started waiting
while (millis() < codenum) idle();
;
}
SERIAL_ECHOLNPGM(WELCOME_MSG);
LCD_MESSAGEPGM(WELCOME_MSG);
in marlin_main.cpp file at line 5598 after the lines :
gcode_M400();
break;
change the line :
#if defined(ENABLE_AUTO_BED_LEVELING) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY)) && !defined(Z_PROBE_SLED)
by
#if defined(ENABLE_AUTO_BED_LEVELING)|| (defined(Z_PROBE_ALLEN_KEY) && !defined(Z_PROBE_SLED))
With all that you should have a perfectly functional auto-levelling function. You may add a glass bed or change it with an other one of difeerent height whithout any recallibration ..
I had the following code in my gcode scripts :
M401; lower probe or wait for it
G29 ; auto-levelling
G1 Z10 F5000 ; lift nozzle
M402; stow probe or wait for it
Here is the auto-level function working:
www.youtube.com/watch?v=H3ro2tZpl1g
Attachments:
[attachment=0]20170725154321.png[/attachment]
First a list of identified problems :
Hardware problems
• the holes on the spider to fix the probe mount are not correctly aligned making the probe getting stuck when going too low.
• the screw in the lock ring is of poor quality making difficult to put the spring under tension.
• the microswitch used to detect the levelling of the z-probe is reliable when used to detect the closing of the circuit (ie for end-stop), but not when used to detect the opening.
• to close the microswitch the spring around the z-probe should have enough tension to be stronger than the internal spring of the microswitch. To be sure that each time the z-probe goes down the microswitch will close, you have to put the external spring under a big tension, meaning big risks of spider tilt when pushing the probe.
Software problems (on the official version of the marlin software : 1.0.3 dev )
• If you launch a G29 command without a closed z-probe circuit (ie the z-probe down) the behavior is not predictable, the spider is likely to go one way without stopping on end-stop but forcing the mechanical stop until you stop the power (I broke ball bearings that way).
• normally for the initial adjustment you should modify the z-probe height by the M851 gcode. Unfortunately it does not do anything with the official marlin version. So you have to recompile for each try.
• The auto-levelling is not compatible with multi extruders in this version of marlin (at each extruder change the spider will go up a little)
there is no command to put in a script to wait until the z-probe is up or down.
What to do to repair that ?
Hardware change :
first point : change the grub screw of the probe lock ring. To detect a reliable level, the tension of the spring should be constant, the grub screw is too difficult to tighten!.I used a remaining #15 screw but you may use any M3 screw (see photo). Be careful the the head of the crew does not touch anything that could block the probe. Second point : Tighten the lock ring to put enough spring tension so that the probe come at its lowest level. Verify that the probe won’t get stuck in the probe mount due to hole misalignment. I had to file down the slot of the probe mount to avoid that.
Third point : Change the microswitch. it is impossible to use the provided switch for auto levelling. But luckily it is very easy to find better ones. I bought mine in a local electronic shop (see photo), it is almost the same, it has the same form factor, it cost twice the price of the original (but just a few bucks) and its lever has a hinge, so it needs much less force to switch and is considerably more reliable. Then you should adjust the tension of the sprint to be sure that every time the spider mounts, the circuit will close (it is much easier with my new switch) but not too much (there is a risk of spider tilt) . You may verify with the M119 command.
At this point your Auto-leveling should work. But to make it really usable I made some software change. I use Marlin 1.0.3 of the RKMB_GT2560_G2S package provided by GEEETECH so all the following modification are for this version only.
first software change : Block the use of auto-levelling if probe is not down to prevent erratic behaviour.
in marlin_main.cpp file in function gcode_G29() at line 2568 after the line :
st_synchronize();
add the following code :
#define MSG_PROBE_NOT_DEPLOYED "G29 probe not deployed"
if (!deploy_probe_for_each_reading) { // if the probe is not to deploy for each point,
// it should be deploy at this point.
// otherwise return in error
boolean probestate=true;
#if HAS_Z_MIN
probestate=READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING;
#endif
#ifdef Z_PROBE_ENDSTOP
probestate=READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING;
#endif
if (probestate){ // test the probe state state
LCD_MESSAGEPGM(MSG_PROBE_NOT_DEPLOYED);
SERIAL_ECHO_START;
SERIAL_ECHOLN(MSG_PROBE_NOT_DEPLOYED);
return;
}
}
second software change : Correct gcode_T() function to use two extruders and auto-levelling.
in marlin_main.cpp file in function gcode_T() at line 5128 after the line :
// Offset extruder (only by XY)
change the following code :
for (int i=X_AXIS; i<=Y_AXIS; i++)
current_position += extruder_offset[tmp_extruder] - extruder_offset[active_extruder];
// Set the new active extruder and position
active_extruder = tmp_extruder;
#endif // !DUAL_X_CARRIAGE
#ifdef DELTA
sync_plan_position_delta();
#else
sync_plan_position();
#endif
// Move to the old position if 'F' was in the parameters
if (make_move && IsRunning()) prepare_move();
by this one :
if (extruder_offset[X_AXIS][tmp_extruder]==0 && extruder_offset[Y_AXIS][tmp_extruder]==0 &&
extruder_offset[X_AXIS][active_extruder]==0 && extruder_offset[Y_AXIS][active_extruder]==0){
active_extruder = tmp_extruder;
} else {
for (int i=X_AXIS; i<=Y_AXIS; i++)
current_position += extruder_offset[tmp_extruder] - extruder_offset[active_extruder];
// Set the new active extruder and position
active_extruder = tmp_extruder;
#endif // !DUAL_X_CARRIAGE
SERIAL_ECHO_START;
SERIAL_ECHOLN(" send plan position");
#ifdef DELTA
sync_plan_position_delta();
#else
sync_plan_position();
#endif
// Move to the old position if 'F' was in the parameters
if (make_move && IsRunning()) prepare_move();
}
Third software change : Enable the use of M851 for probe level setting.
in marlin_main.cpp file in function gcode_G29() at line 2600 after the line :
delta_grid_spacing[1] = yGridSpacing;
change the line
float z_offset = Z_PROBE_OFFSET_FROM_EXTRUDER;
by
float z_offset = -zprobe_zoffset ; // do not use Z_PROBE_OFFSET_FROM_EXTRUDER;
in marlin_main.cpp file in function clamp_to_software_endstops() at line 5748 after the line :
#ifdef ENABLE_AUTO_BED_LEVELING
change the line :
if (Z_PROBE_OFFSET_FROM_EXTRUDER < 0) negative_z_offset += Z_PROBE_OFFSET_FROM_EXTRUDER;
by
if (zprobe_zoffset > 0) negative_z_offset -= zprobe_zoffset;
Fourth software change : Modify M401 (raise z-probe) and M402 (stow z-probe) function to be blocking until the z-probe has been raised or stowed.
in marlin_main.cpp file at line 4569 after the line :
inline void gcode_M400() { st_synchronize(); }
change the line :
#if defined(ENABLE_AUTO_BED_LEVELING) && !defined(Z_PROBE_SLED) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY))
by
#if defined(ENABLE_AUTO_BED_LEVELING)
in marlin_main.cpp file in function gcode_M401() at line 4587 after the line :
deploy_z_probe();
Add the lines :
// and block if probe is not deployed
#define MSG_WAIT_PROBE_DEPLOYED "Wait probe deployment"
boolean probestate=true,probe_msg=true;
while(probestate){
#if HAS_Z_MIN
probestate=READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING;
#endif
#ifdef Z_PROBE_ENDSTOP
probestate=READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING;
#endif
if (probestate && probe_msg){ // send waiting message once
LCD_MESSAGEPGM(MSG_WAIT_PROBE_DEPLOYED);
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_WAIT_PROBE_DEPLOYED);
probe_msg=false;
}
idle();
}
SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT);
LCD_MESSAGEPGM(MSG_ZPROBE_OUT);
in marlin_main.cpp file in functionn gcode_M402() at line 45ç7 after the line :
stow_z_probe(false);
Add the lines :
// and block if probe is not stowed
#define MSG_WAIT_PROBE_DEPLOYED "Wait probe stowed"
boolean probestate=false,probe_msg=true;
while( ! probestate){
#if HAS_Z_MIN
probestate=READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING;
#endif
#ifdef Z_PROBE_ENDSTOP
probestate=READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING;
#endif
if (! probestate && probe_msg){ // send waiting message once
LCD_MESSAGEPGM(MSG_WAIT_PROBE_DEPLOYED);
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_WAIT_PROBE_DEPLOYED);
probe_msg=false;
}
idle();
}
// add a waiting tiile to secure the probe
if (! probe_msg){
millis_t codenum = 3500;
codenum += millis(); // keep track of when we started waiting
while (millis() < codenum) idle();
;
}
SERIAL_ECHOLNPGM(WELCOME_MSG);
LCD_MESSAGEPGM(WELCOME_MSG);
in marlin_main.cpp file at line 5598 after the lines :
gcode_M400();
break;
change the line :
#if defined(ENABLE_AUTO_BED_LEVELING) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY)) && !defined(Z_PROBE_SLED)
by
#if defined(ENABLE_AUTO_BED_LEVELING)|| (defined(Z_PROBE_ALLEN_KEY) && !defined(Z_PROBE_SLED))
With all that you should have a perfectly functional auto-levelling function. You may add a glass bed or change it with an other one of difeerent height whithout any recallibration ..
I had the following code in my gcode scripts :
M401; lower probe or wait for it
G29 ; auto-levelling
G1 Z10 F5000 ; lift nozzle
M402; stow probe or wait for it
Here is the auto-level function working:
www.youtube.com/watch?v=H3ro2tZpl1g
Attachments:
[attachment=0]20170725154321.png[/attachment]