Merge pull request #1024 from oliasmage/Marlin_v1

Adding Z Probe via sled mounted endstop
This commit is contained in:
Erik van der Zalm 2014-08-28 16:15:54 +02:00
commit 68dd5e635e
3 changed files with 155 additions and 49 deletions

View file

@ -437,6 +437,8 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
#define Z_RAISE_BEFORE_PROBING 15 //How much the extruder will be raised before traveling to the first probing point.
#define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when traveling from between next probing points
//#define Z_PROBE_SLED // turn on if you have a z-probe mounted on a sled like those designed by Charles Bell
//#define SLED_DOCKING_OFFSET 5 // the extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like.
//If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk
//The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it.

View file

@ -78,6 +78,8 @@
// G28 - Home all Axis
// G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet.
// G30 - Single Z Probe, probes bed at current XY location.
// G31 - Dock sled (Z_PROBE_SLED only)
// G32 - Undock sled (Z_PROBE_SLED only)
// G90 - Use Absolute Coordinates
// G91 - Use Relative Coordinates
// G92 - Set current position to coordinates given
@ -548,6 +550,10 @@ void setup()
#ifdef DIGIPOT_I2C
digipot_i2c_init();
#endif
#ifdef Z_PROBE_SLED
pinMode(SERVO0_PIN, OUTPUT);
digitalWrite(SERVO0_PIN, LOW); // turn it off
#endif // Z_PROBE_SLED
}
@ -1035,10 +1041,14 @@ static float probe_pt(float x, float y, float z_before) {
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
#ifndef Z_PROBE_SLED
engage_z_probe(); // Engage Z Servo endstop if available
#endif // Z_PROBE_SLED
run_z_probe();
float measured_z = current_position[Z_AXIS];
#ifndef Z_PROBE_SLED
retract_z_probe();
#endif // Z_PROBE_SLED
SERIAL_PROTOCOLPGM(MSG_BED);
SERIAL_PROTOCOLPGM(" x: ");
@ -1071,6 +1081,7 @@ static void homeaxis(int axis) {
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
#ifndef Z_PROBE_SLED
// Engage Servo endstop if enabled
#ifdef SERVO_ENDSTOPS
#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
@ -1083,7 +1094,7 @@ static void homeaxis(int axis) {
servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
}
#endif
#endif // Z_PROBE_SLED
destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
feedrate = homing_feedrate[axis];
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
@ -1125,7 +1136,7 @@ static void homeaxis(int axis) {
}
#endif
#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
if (axis==Z_AXIS) retract_z_probe();
// if (axis==Z_AXIS) retract_z_probe();
#endif
}
@ -1180,6 +1191,42 @@ void refresh_cmd_timeout(void)
} //retract
#endif //FWRETRACT
#ifdef ENABLE_AUTO_BED_LEVELING
//
// Method to dock/undock a sled designed by Charles Bell.
//
// dock[in] If true, move to MAX_X and engage the electromagnet
// offset[in] The additional distance to move to adjust docking location
//
static void dock_sled(bool dock, int offset=0) {
int z_loc;
if (!((axis_known_position[X_AXIS]) && (axis_known_position[Y_AXIS]))) {
LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
return;
}
if (dock) {
do_blocking_move_to(X_MAX_POS + SLED_DOCKING_OFFSET + offset,
current_position[Y_AXIS],
current_position[Z_AXIS]);
// turn off magnet
digitalWrite(SERVO0_PIN, LOW);
} else {
if (current_position[Z_AXIS] < (Z_RAISE_BEFORE_PROBING + 5))
z_loc = Z_RAISE_BEFORE_PROBING;
else
z_loc = current_position[Z_AXIS];
do_blocking_move_to(X_MAX_POS + SLED_DOCKING_OFFSET + offset,
Y_PROBE_OFFSET_FROM_EXTRUDER, z_loc);
// turn on magnet
digitalWrite(SERVO0_PIN, HIGH);
}
}
#endif
void process_commands()
{
unsigned long codenum; //throw away variable
@ -1490,6 +1537,9 @@ void process_commands()
break; // abort G29, since we don't know where we are
}
#ifdef Z_PROBE_SLED
dock_sled(false);
#endif // Z_PROBE_SLED
st_synchronize();
// make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
//vector_3 corrected_position = plan_get_position_mm();
@ -1615,13 +1665,15 @@ void process_commands()
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]);
#ifdef Z_PROBE_SLED
dock_sled(true, -SLED_DOCKING_OFFSET); // correct for over travel.
#endif // Z_PROBE_SLED
}
break;
#ifndef Z_PROBE_SLED
case 30: // G30 Single Z Probe
{
engage_z_probe(); // Engage Z Servo endstop if available
st_synchronize();
// TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
setup_for_endstop_move();
@ -1639,10 +1691,17 @@ void process_commands()
SERIAL_PROTOCOLPGM("\n");
clean_up_after_endstop_move();
retract_z_probe(); // Retract Z Servo endstop if available
}
break;
#else
case 31: // dock the sled
dock_sled(true);
break;
case 32: // undock the sled
dock_sled(false);
break;
#endif // Z_PROBE_SLED
#endif // ENABLE_AUTO_BED_LEVELING
case 90: // G90
relative_mode = false;
@ -2256,7 +2315,7 @@ Sigma_Exit:
/* See if we are heating up or cooling down */
target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling
cancel_heatup = false;
#ifdef TEMP_RESIDENCY_TIME
@ -3032,7 +3091,7 @@ Sigma_Exit:
st_synchronize();
}
break;
#if defined(ENABLE_AUTO_BED_LEVELING) && defined(SERVO_ENDSTOPS)
#if defined(ENABLE_AUTO_BED_LEVELING) && defined(SERVO_ENDSTOPS) && not defined(Z_PROBE_SLED)
case 401:
{
engage_z_probe(); // Engage Z Servo endstop if available

129
README.md
View file

@ -1,8 +1,8 @@
==========================
Marlin 3D Printer Firmware
==========================
[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224)
Marlin has a GPL license because I believe in open development.
Please do not use this code in products (3D printers, CNC etc) that are closed source or are crippled by a patent.
@ -159,6 +159,8 @@ Implemented G Codes:
* G28 - Home all Axis
* G29 - Detailed Z-Probe, probes the bed at 3 points. You must de at the home position for this to work correctly.
* G30 - Single Z Probe, probes bed at current XY location.
* G31 - Dock Z Probe sled (if enabled)
* G32 - Undock Z Probe sled (if enabled)
* G90 - Use Absolute Coordinates
* G91 - Use Relative Coordinates
* G92 - Set current position to cordinates given
@ -207,15 +209,15 @@ M Codes
* M140 - Set bed target temp
* M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating
* Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
* M200 D<millimeters>- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).
* M200 D<millimeters>- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).
* M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
* M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
* M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
* M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate
* M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk
* M206 - set additional homeing offset
* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting
* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min]
* M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting
* M208 - set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/min]
* M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
* M218 - set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y>
* M220 S<factor in percent>- set speed factor override percentage
@ -272,50 +274,21 @@ That's ok. Enjoy Silky Smooth Printing.
===============================================
Instructions for configuring Bed Auto Leveling
===============================================
Uncomment the "ENABLE_AUTO_BED_LEVELING" define (commented by default)
There are two options for this feature. You may choose to use a servo mounted on the X carriage or you may use a sled that mounts on the X axis and can be docked when not in use.
See the section for each option below for specifics about installation and configuration. Also included are instructions that apply to both options.
You will probably need a swivel Z-MIN endstop in the extruder. A rc servo do a great job.
Check the system working here: http://www.youtube.com/watch?v=3IKMeOYz-1Q (Enable English subtitles)
Teasing ;-) video: http://www.youtube.com/watch?v=x8eqSQNAyro
In order to get the servo working, you need to enable:
* \#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command
* \#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1
* \#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 165,60} // X,Y,Z Axis Extend and Retract angles
The first define tells firmware how many servos you have.
The second tells what axis this servo will be attached to. In the example above, we have a servo in Z axis.
The third one tells the angle in 2 situations: Probing (165º) and resting (60º). Check this with command M280 P0 S{angle} (example: M280 P0 S60 moves the servo to 60º)
For RAMPS users:
----------------
Note for RAMPS users:
---------------------
By default, RAMPS have no power on servo bus (if you happen to have a multimeter, check the voltage on servo power pins).
In order to get the servo working, you need to supply 5V to 5V pin.. You can do it using your power supply (if it has a 5V output) or jumping the "Vcc" from Arduino to the 5V RAMPS rail.
These 2 pins are located just between the Reset Button and the yellow fuses... There are marks in the board showing 5V and VCC.. just connect them..
If jumping the arduino Vcc do RAMPS 5V rail, take care to not use a power hungry servo, otherwise you will cause a blackout in the arduino board ;-)
Instructions for Both Options
-----------------------------
Next you need to define the Z endstop (probe) offset from hotend.
My preferred method:
* a) Make a small mark in the bed with a marker/felt-tip pen.
* b) Place the hotend tip as *exactly* as possible on the mark, touching the bed. Raise the hotend 0.1mm (a regular paper thickness) and zero all axis (G92 X0 Y0 Z0);
* d) Raise the hotend 10mm (or more) for probe clearance, lower the Z probe (Z-Endstop) with M401 and place it just on that mark by moving X, Y and Z;
* e) Lower the Z in 0.1mm steps, with the probe always touching the mark (it may be necessary to adjust X and Y as well) until you hear the "click" meaning the mechanical endstop was trigged. You can confirm with M119;
* f) Now you have the probe in the same place as your hotend tip was before. Perform a M114 and write down the values, for example: X:24.3 Y:-31.4 Z:5.1;
* g) You can raise the z probe with M402 command;
* h) Fill the defines bellow multiplying the values by "-1" (just change the signal)
* \#define X_PROBE_OFFSET_FROM_EXTRUDER -24.3
* \#define Y_PROBE_OFFSET_FROM_EXTRUDER 31.4
* \#define Z_PROBE_OFFSET_FROM_EXTRUDER -5.1
Uncomment the "ENABLE_AUTO_BED_LEVELING" define (commented by default)
The following options define the probing positions. These are good starting values.
I recommend to keep a better clearance from borders in the first run and then make the probes as close as possible to borders:
@ -337,7 +310,79 @@ Bear in mind that really fast moves may render step skipping. 6000 mm/min (100mm
The Z axis is lifted when traveling to the first probe point by Z_RAISE_BEFORE_PROBING value
and then lifted when traveling from first to second and second to third point by Z_RAISE_BETWEEN_PROBINGS.
All values are in mm as usual.
All values are in mm as usual.
Servo Option Notes
------------------
You will probably need a swivel Z-MIN endstop in the extruder. A rc servo do a great job.
Check the system working here: http://www.youtube.com/watch?v=3IKMeOYz-1Q (Enable English subtitles)
Teasing ;-) video: http://www.youtube.com/watch?v=x8eqSQNAyro
In order to get the servo working, you need to enable:
* \#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command
* \#define SERVO_ENDSTOPS {-1, -1, 0} // Servo index for X, Y, Z. Disable with -1
* \#define SERVO_ENDSTOP_ANGLES {0,0, 0,0, 165,60} // X,Y,Z Axis Extend and Retract angles
The first define tells firmware how many servos you have.
The second tells what axis this servo will be attached to. In the example above, we have a servo in Z axis.
The third one tells the angle in 2 situations: Probing (165º) and resting (60º). Check this with command M280 P0 S{angle} (example: M280 P0 S60 moves the servo to 60º)
Next you need to define the Z endstop (probe) offset from hotend.
My preferred method:
* a) Make a small mark in the bed with a marker/felt-tip pen.
* b) Place the hotend tip as *exactly* as possible on the mark, touching the bed. Raise the hotend 0.1mm (a regular paper thickness) and zero all axis (G92 X0 Y0 Z0);
* d) Raise the hotend 10mm (or more) for probe clearance, lower the Z probe (Z-Endstop) with M401 and place it just on that mark by moving X, Y and Z;
* e) Lower the Z in 0.1mm steps, with the probe always touching the mark (it may be necessary to adjust X and Y as well) until you hear the "click" meaning the mechanical endstop was trigged. You can confirm with M119;
* f) Now you have the probe in the same place as your hotend tip was before. Perform a M114 and write down the values, for example: X:24.3 Y:-31.4 Z:5.1;
* g) You can raise the z probe with M402 command;
* h) Fill the defines bellow multiplying the values by "-1" (just change the signal)
* \#define X_PROBE_OFFSET_FROM_EXTRUDER -24.3
* \#define Y_PROBE_OFFSET_FROM_EXTRUDER 31.4
* \#define Z_PROBE_OFFSET_FROM_EXTRUDER -5.1
Sled Option Notes
-----------------
The sled option uses an electromagnet to attach and detach to/from the X carriage. See http://www.thingiverse.com/thing:396692 for more details on how to print and install this feature. It uses the same connections as the servo option.
To use the sled option, you must define two additional things in Configuration.h:
* \#define Z_PROBE_SLED
* \#define SLED_DOCKING_OFFSET 5
Uncomment the Z_PROBE_SLED to define to enable the sled (commented out by default).
Uncomment the SLED_DOCKING_OFFSET to set the extra distance the X axis must travel to dock the sled. This value can be found by moving the X axis to its maximum position then measure the distance to the right X end and subtract the width of the sled (23mm if you printed the sled from Thingiverse).
Next you need to define the Z endstop (probe) offset from hotend.
My preferred method:
* a) Home the X and Y axes.
* b) Move the X axis to about the center of the print bed. Make a mark on the print bed.
* c) Move the Y axis to the maximum position. Make another mark.
* d) Home the X axis and use a straight edge to make a line between the two points.
* e) Repeat (b)-(d) reversing the X and Y. When you are done you will have two lines on the print bed. We will use these to measure the offset for the Z probe endstop.
* f) Move the nozzle so that it is positioned on the center point of the two lines. You can use fine movement of 0.1mm to get it as close as possible. Note the position of X and Y.
* g) Zero the Z axis with the G92 Z0 command.
* h) Raise the Z axis about 20mmm.
* i) Use the G32 command to retrieve the sled.
* j) Now more the X and Y axis to the position recorded in (f).
* k) Lower the Z axis in 0.1mm steps until you hear the "click" meaning the mechanical endstop was trigged. You can confirm with the M119 command. Note the position of the Z axis.
* l) Make a mark on the print bed where the endstop lever has touched the print bed. Raise the Z-axis about 30mm to give yourself some room.
* m) Now measure the distance from the center point to the endstop impact site along the X and Y axis using the lines drawn previously.
* n) Fill in the values below. If the endstop mark is in front of the line running left-to-right, use positive values. If it is behind, use negative values. For the Z axis use the value from (k) and subtract 0.1mm.
For example, suppose you measured the endstop position and it was 20mm to the right of the line running front-to-back, 10mm toward the front of the line running left-to-right, and the value from (k) was 2.85. The values for the defines would be:
* \#define X_PROBE_OFFSET_FROM_EXTRUDER 20
* \#define Y_PROBE_OFFSET_FROM_EXTRUDER 10
* \#define Z_PROBE_OFFSET_FROM_EXTRUDER 2.75
That's it.. enjoy never having to calibrate your Z endstop neither leveling your bed by hand anymore ;-)