If you build your own 3D printer design, one of the confusing things about configuring its firmware is the limit switches on each axis, homing the printer, and setting up the printer description in slicing software.
One of the first things you need to do when you finish building your printer is measure its limits of motion. Move each axis as far as it can go and physically measure how far it went. Write down the numbers.
Three main considerations for homing and slicing:
- The printer's origin and limits
- The bed's dimensions
- The bed's origin
Note: if your printer is a coreXY type, I wrote a separate blog post on setting up its origin and endstops, here.
The Printer's Origin:
First principle: the home position - i.e. the place the extruder ends up when you (or the gcode) issues a home-all-axes command - is not necessarily the printer's origin. If you read through the material below this will make sense.
Simplifying assumptions:
- CAD software and slicing software use right-hand-rule coordinate space. Your printer should, too, or your prints will come out mirrored. For FDM printers, that means that the printer's origin, the (0,0,0) point, must be located at the left-front or right-rear corner of the printer with the extruder nozzle at bed level.
- The Z axis limit switch is almost always placed at the Z=0 position at the bottom of the Z axis if the extruder moves up, like in a Prusa i3, or at the top of the Z axis if the bed moves down. For the discussion below I'll assume that the Z axis switch is located at Z=0 and we'll simply ignore the Z axis.
Right hand rule says origin must be at left-front or right-rear corner of printer. Note- they are equivalent- one is just a rotation of the other. |
Slicer's and host software have default views of the print bed that they present to the user. Slic3r, Cura, and Pronterface all default to show the printer's origin at the left-front corner of the bed. If you set your printer up that way, the view presented in the slicer and host will match what you see when you look at your printer. If the printer's origin is at the right-rear of the printer, the slicer view will show the view of the bed from the back of the printer.
Setting up the printer's origin involves multiple settings in the controller's firmware. You can control the motor rotation direction for each axis, whether the motor is to move toward maximum or minimum when executing a home instruction, and finally, the ordinate value to set for each axis after a home instruction has been executed.
Setting up the printer's origin involves multiple settings in the controller's firmware. You can control the motor rotation direction for each axis, whether the motor is to move toward maximum or minimum when executing a home instruction, and finally, the ordinate value to set for each axis after a home instruction has been executed.
3D printers typically have one limit switch on each of the 3 axes, though you can have two on each, one for minimum and one for maximum. The Z axis limit switch is almost always set at Z=0, so we'll ignore it for now. Everything that applies to the X and Y axes also applies to the Z axis. For simplicity, we'll assume there's one limit switch for each axis.
Basic rules and sequence for establishing printer origin in the controller's firmware:
Basic rules and sequence for establishing printer origin in the controller's firmware:
- Mount your limit switches at whichever end of each axis is most convenient
- Set the motor rotation direction to drive the mechanism toward the limit switches when a home command is executed.
- Set home to min or max depending on where you put the switches and where you want the printer's origin to be (see the table)
- Assign the ordinate values for X and Y after a homing instruction depending on where you want the printer's origin to be.
- Make sure you plug the limit switches into the appropriate inputs on the controller board.
When the printer is ordered to home the extruder via the gcode or via a command from a host computer, the motors should drive the mechanism toward the limit switches in each axis. If the mechanism moves away from the switches in any axis, you have to reverse that motor's direction of rotation either by changing a firmware definition or by powering down the printer and physically reversing the connector on the motor or the controller board.
Once the motors are all turning in the right directions, you can assign ordinate values. Assuming the most common configuration in which there is one limit switch per axis, you may put the switches at either end of each axis, depending on where it is most convenient. You might want to keep cables short, or have other specific reasons for placing switches at one end or the other. It doesn't matter. The Z axis limit switch is normally put at the Z=0 position and we'll assume that for the examples, below.
Here are a few examples of different set-ups to illustrate how to configure the firmware. In all examples, we'll assume that the printer's limits of motion are 310 mm x 248 mm x 215 mm measured by jogging or manually pushing the extruder carriage, Y, and Z axis as far as they will go and measuring the distances traveled.
Consult your firmware documentation for the exact syntax required to set motor rotation direction, home to min/max, and ordinate values.
Example: bed moves in Y, origin is at left-front of printer
If you put a limit switch at the left end of the X axis, you must plug the limit switch into the Xmin limit switch input, set the motor to move the extruder carriage toward the switch, and specify that the X axis homes to minimum in the firmware configuration, and assign an ordinate value of 0 to X after homing.
If you put a limit switch at the right end of the X axis, you must plug the switch into the Xmax limit switch input, tell the firmware to rotate the motor in the right direction- i.e. the extruder carriage should move toward the switch, and tell it to "home to max" in X, then once it has done so, assign an ordinate value of 310 mm to X.
If you put a limit switch at the right end of the X axis, you must plug the switch into the Xmax limit switch input, tell the firmware to rotate the motor in the right direction- i.e. the extruder carriage should move toward the switch, and tell it to "home to max" in X, then once it has done so, assign an ordinate value of 310 mm to X.
If you put the Y axis limit switch at the back of the printer, you plug the limit switch into the Ymin input, tell the firmware to spin the motor to move the bed toward the switch, and set the Y axis as "home to min" in the configuration file, (because the switch will be activated when the extruder is near the front edge of the bed), and set Y=0 when the bed bumps the limit switch.
Example 2: bed moves in Z (extruder moves in X and Y), origin is at left-front of printer
Using the same limits of motion for the printer, and the left-front of the printer as the origin, placing the switches at the left end of the X axis and at the back of the machine for Y, will require setting firmware to "home to min" in X and "home to max" in Y, then assign ordinate values of 0 for X and 248 for Y. The limit switches will plug into the Xmin and Ymax inputs on the controller board.
Example 3: bed moves in Z, origin is at right-rear of printer
Placing the X axis limit switch on the left side of the X axis and the Y limit switch at the front of the printer will require that both axes "home to max" and you'll assign ordinate values of 310 to X and 248 to Y. You will plug the switches into the Xmax and Y max inputs on the controller board.
This table summarizes all the possibilities for FDM printers (using the 310 x 248 mm limits from the examples, above):
Bed | Homing | Switch | Controller | |||
Motion | Printer’s | Switch | Location | Home | Ordinate | Limit Switch |
Axis | Origin | Axis | on Axis | to: | Value | Input |
Y | Left-Front | X | Left | min | 0 | Xmin |
Y | Left-Front | X | Right | max | 310 | Xmax |
Y | Left-Front | Y | Front | max | 248 | Ymax |
Y | Left-Front | Y | Rear | min | 0 | Ymin |
Y | Right-Rear | X | Left | max | 310 | Xmax |
Y | Right-Rear | X | Right | min | 0 | Xmin |
Y | Right-Rear | Y | Front | min | 0 | Ymin |
Y | Right-Rear | Y | Rear | max | 248 | Ymax |
Z | Left-Front | X | Left | min | 0 | Xmin |
Z | Left-Front | X | Right | max | 310 | Xmax |
Z | Left-Front | Y | Front | min | 0 | Ymin |
Z | Left-Front | Y | Rear | max | 248 | Ymax |
Z | Right-Rear | X | Left | max | 310 | Xmax |
Z | Right-Rear | X | Right | min | 0 | Xmin |
Z | Right-Rear | Y | Front | max | 248 | Ymax |
Z | Right-Rear | Y | Rear | min | 0 | Ymin |
Slicer setup - the print bed's dimensions
Your printer's bed is all that matters to the slicer. It doesn't know or care about the limits of the printer's motion, except as they may limit the printable area of the bed. The slicer needs to know two things: the printable size of the bed and the bed's offset from the printer's origin.
In the examples below, we'll use the X and Y travel limits above (310 x 248 mm) with a bed plate that is 200 x 200 mm and is shown with the printer in the home position.
Example A is the most common situation where the entire bed surface is within the printer's limits of motion. In this example, you would tell the slicer that the bed size is 200 x 200 mm.
Example B would only be printable over 180 x 175 mm, so those are the dimensions you set in the slicer.
Example C is printable over 165 x 170 mm, so those are the dimensions you set in the slicer.
Example D is printable over 200 x 180 mm, so those are the dimensions you set in the slicer.
If the bed is larger than the printer's limits of motion, you simply tell the slicer the bed dimensions are the same as the printer's limits.
Slicer setup - the print bed's origin
Slicers default to dropping the your print at the center of the print bed. This is a good thing for several reasons. Even if you have an unflat, unlevel, unevenly heated bed, the center is where prints are most likely to stick. If you're printing multiple parts that are going to use a large portion of the printer's bed, having them centered makes it less likely that any of them are going to end up outside the printable area.
The slicer uses XY coordinates on the bed, and the bed's origin is normally the closest point on the bed to the printer's origin. The bed occupies the first quadrant of the coordinate space, so the printer's origin is in the 3rd quadrant of the bed's coordinate space and the offsets are 0 or negative. So when you enter the offset in the slicer, the values entered are normally zero or negative.
In example A, above, the printer's origin is at bed coordinates (-50, -30), so that's the offset you enter in the slicer.
Example B shows a situation with no offset, so you enter (0,0).
Example C shows an offset of (-145,-78).
Example D shows an offset in only the X axis, so the offset is (-50,0).
If you are trying to use the center of the bed for the origin, just use the appropriate offsets, and be sure to tell the slicer that the origin is at the center of the bed. Of course, you want to specify the center of the printable area, which may not be the same as the dimensions of the bed plate.
Cura is a little different. It assumes that the home position puts the nozzle on the bed. If that isn't true in your printer you have to play some tricks with custom gcode when you set up the printer in Cura.
When you set up the custom printer description in Cura, you tell it the size of the printable area of the bed. In my printer, UMMD, I tell Cura that the bed is 298 x 300 x 695 mm. The machine homes to max in both X and Y, landing at extruder nozzle at coordinates (300,330,0) as set by the controller's firmware. The bed's origin is at (2, -27, 0). I get Cura to place prints on the center of the bed by using custom gcode. After homing the printer, which takes it to (300, 330, 0), I drop the bed 15 mm, then use a G92 command to set the coordinates at (300,330,15), then send the extruder to (2,27,15), then use the G92 command to reset the printer's coordinate system to (0,0,15) at that point. Now the print will be placed in the same position that Cura set it when it was sliced. The first G92 command ensures that the printer coordinates are correct if I run a second print after the first without resetting the controller.
Here's the start gcode for UMMD:
The slicer uses XY coordinates on the bed, and the bed's origin is normally the closest point on the bed to the printer's origin. The bed occupies the first quadrant of the coordinate space, so the printer's origin is in the 3rd quadrant of the bed's coordinate space and the offsets are 0 or negative. So when you enter the offset in the slicer, the values entered are normally zero or negative.
The slicer's view of the bed's origin. The origin is left-front, but it could just as well be right-rear. |
In example A, above, the printer's origin is at bed coordinates (-50, -30), so that's the offset you enter in the slicer.
Example B shows a situation with no offset, so you enter (0,0).
Example C shows an offset of (-145,-78).
Example D shows an offset in only the X axis, so the offset is (-50,0).
If you are trying to use the center of the bed for the origin, just use the appropriate offsets, and be sure to tell the slicer that the origin is at the center of the bed. Of course, you want to specify the center of the printable area, which may not be the same as the dimensions of the bed plate.
What about Cura?
Cura is a little different. It assumes that the home position puts the nozzle on the bed. If that isn't true in your printer you have to play some tricks with custom gcode when you set up the printer in Cura.
When you set up the custom printer description in Cura, you tell it the size of the printable area of the bed. In my printer, UMMD, I tell Cura that the bed is 298 x 300 x 695 mm. The machine homes to max in both X and Y, landing at extruder nozzle at coordinates (300,330,0) as set by the controller's firmware. The bed's origin is at (2, -27, 0). I get Cura to place prints on the center of the bed by using custom gcode. After homing the printer, which takes it to (300, 330, 0), I drop the bed 15 mm, then use a G92 command to set the coordinates at (300,330,15), then send the extruder to (2,27,15), then use the G92 command to reset the printer's coordinate system to (0,0,15) at that point. Now the print will be placed in the same position that Cura set it when it was sliced. The first G92 command ensures that the printer coordinates are correct if I run a second print after the first without resetting the controller.
Here's the start gcode for UMMD:
G28 ;Home
G0 Z15 F1200 ; drop bed 15 mm
G92 X300 Y330 Z15 ; set printer's coordinates to (300, 330, 15)
G0 X2 Y27 F12000; go to left-front corner of bed
G92 X0 Y0 Z15 ; set printer's coordinates to (0,0,15)
G92 E0 ; set extruder to 0
Summary
- The home position is not necessarily the printer's origin.
- Limit switches can be placed at either end of the X and Y axes.
- The firmware needs to turn the motors to move the mechanism toward the limit switch in each axis.
- The firmware needs to know where the origin of the printer is (left-front or right-rear corner).
- The firmware needs to know the machine's limits of motion in each axis.
- The slicer needs to know the printable dimensions of the bed, which are not necessarily the physical dimensions of the bed plate.
- The slicer needs to know the offset of the printer's origin from the bed plate's origin.
- With proper setup, the slicer will arrange prints around the center of the printable area of the bed plate.
I've just found this blog. Amazing writeup. Thank you for taking the time to share this.
ReplyDeleteKeep up the good work.
Martin
Thanks, and I'll try to respond to comments sooner, too!
DeleteYou've chosen to put the origin of the coordinate system at one corner of the bed; but I prefer to put it at the centre of the printable area. This is standard on delta printers anyway. It means that in the slicer, the print is always centred on X=0 Y=0. This in turn means after slicimg a file, I can run it on all 3 of my printers (one SCARA, one Delta and one Cartesian). There are a few commercial Cartesian printers that put origin at the centre of the bed too.
ReplyDeleteYes, I have since "seen the light" and switched to center of the bed origin when I replaced the Smoothieboard with a Duet controller. There's another blog post on it here: https://drmrehorst.blogspot.com/2018/07/ummd-better-way-to-set-up-origin-and.html
DeleteProbably a bit too late to ask this, but are the principles exactly the same for CNC machines? I'm trying to figure out (if I need to) what the differences would be between the bed moving as opposed to the spindle being moved. This is the best description I've seen, though. Thank you.
ReplyDeleteIn some 3D printers the bed moves up and down and in some the entire X axis, including the extruder moves up and down. In either case the coordinate system is always referenced from the point of view of the print, and the nozzle touches the bed at Z=0. In CNC machines that subtract material, they may use the top of the part as the Z=0 reference, so the Z direction may be reversed compared to a 3D printer.
DeleteIn either case, home is where the endstops are...
i diy a corexy printer, the print come out mirrored, bed print volumn is 110x110.
ReplyDeletex endstop = x max = 110
y endstop = y max = 110
home position at back-right conner
0,0 at front left, everything seem setup right but print alway come out mirrored can you help me
It sounds like your hardware and mental concept are set up correctly for right hand rule coordinates, but it's possible there's some configuration problem that's creating left hand coordinates. It may also be that you have misdefined the bed and origin in the slicer.
DeleteI wrote an update to this post that you may want to look at- it explains how to set up the origin of the printer at the center of the bed and why you might want to do that. see: https://drmrehorst.blogspot.com/2018/07/ummd-better-way-to-set-up-origin-and.html