Wednesday, July 4, 2018

UMMD: A Better Way to Set Up the Origin and RepRapFirmware Manual Bed Leveling Assist

Setting Up the Printer's Origin

In a previous post I explained how to set up the endstops and origin of a 3D printer.  In the method I outlined, slic3r is easy to set up, but Cura required some custom gcode to get prints dropped on the center of the bed.  It turn out that it's easier to set up the slicers to drop prints on the center of the bed if the printer's origin is at the printable center of the bed.

This post describes how I put UMMD's origin at the printable center of the bed with the new Duet Ethernet controller board, and how you can do the same for your printer.

First, you have to know the dimensions of the printable area of your printer's bed.  It may sound strange, but some machines can't print on the entire bed surface.  So, move your printer through it's motion limits and watch the nozzle relative to the bed.  If it is unable to print on part of the bed, mark a line (or lines) on the bed where the nozzle can't go any further.  Now mark the center point of the printable area of the bed (you can find the center by drawing diagonals between opposite corners of the printable area).

Next, move the extruder to the "home" position (where the X and Y end stop switches are both triggered). Use a ruler to measure the distance from the printable center of the bed to the nozzle in X and Y and write the numbers down.  Now move the extruder carriage to the diagonally opposite corner of the motion limits and measure again, and write down the numbers.

Make a sketch of the top view of the printer, showing the limits of nozzle travel and the outline of the printable area within those limits, like this one that I made for UMMD:
Top view of UMMD's XY stage.  The outer rectangle represents the limits of XY motion of the extruder nozzle.  The  printable area of the bed is a 300x300 mm square that fits within those limits.  The leveling screws are shown for reference (we'll use those later).  The home position is in the right rear corner of the machine because that's where the end stop switches are located.

The origin is set to the dead center of the bed's printable area.  Notice that the bed is not centered within the range of motion.  That's OK.

In the Duet config.g file, the following statements define the origin as the center of the bed's printable area:

M208 X-151 Y-185 Z0 S1 ;  sets the minimum values for all axes
M208 X150 Y153 Z680 S0  ; sets the maximum values for all axes

With the Duet (RepRapFirmware), the fact that the upper right corner is the home position is a function of where the endstop switches are positioned on the X and Y axes and the motor rotation directions.  In SmoothieWare, there are explicit statements that the X and Y axis home to max or min, and then the ordinate values to assign to each.

Now mark the coordinates of the corners of the printable area of the bed:
When you set up Cura you tell it the dimensions of the printable area of the bed (in this case, 300x300 mm), and check the "origin at center" box:

Cura custom machine setup.  There's no need to make changes to the start gcode to position the origin.
Plater view in Cura, origin at center of bed.

When you set up Slic3r, you enter the dimensions of the printable area of the bed and then enter offsets that put the origin at the center:

Slic3r bed set-up.  You enter dimensions of the printable bed area and offset values that put the origin at the center of that printable area.

And this is what you see in the Plater view- origin at center- it matches the diagram perfectly.

Why is this better?  Besides the easier setup in the slicers, it makes the gcode a little more portable between different printers, assuming they use origin at center.  Of course, you still need other things to be right for gcode to be moved from one machine to another.  You won't be able to use gcode for a 300x400x200mm print in a machine with print capacity that's 200x200x200, for example.

Manual Bed Leveling Assistant

The Duet has been working fine for a few weeks now and I am still exploring some of the options in the firmware.  One of the really great ones for people with printers like UMMD that have flat, stable beds that don't require frequent releveling, is called the "manual bed leveling assistant".  The assistant "probes" (actually, you do the "probing" with a piece of paper placed under the extruder nozzle) the bed at a few locations then does a least-squares fit and tells you how much to adjust each leveling screw up or down to minimize leveling error .  It's a quick process that works extremely well.  In order to use it, you'll need to add the coordinates and pitch of the leveling screws in a config file statement, so start by adding the coordinates to the diagram we drew above by measuring the distance from the bed center to each of the screws:

Leveling screw coordinates added.  These coordinates will be used in the M671 statement in the config.g file.

There's going to be some gcode presented below.  You can find definitions of all the gcode supported by RepRapFirmware at this site.

You'll also need to select probing points, at least one for each leveling screw.  If you have 3 leveling screws, you might choose to use just 3 probing points.  You must use at least as many probing points as there are leveling screws, so if you have 4 screws, you need at least 4 probing points.  I chose to use five points, one near each corner of the bed and one at the center:
Probing point coordinates added.  P0-P4 designators are used in G30 statements in the bed.g file.

The config.g file has to contain a few specific lines to enable use of the manual bed leveling assistant.  First, there's and M667 statement that tells the firmware the architecture of the printer you're setting up (coreXY, delta, etc.).  Then you need a couple statements that set up the origin of the printer because everything to come will depend on the coordinates.  You need an M558 statement to tell the assistant how the probing is to be done, and an M671 statement to tell the assistant where the leveling screws are located.  In the M671 statement, list the screw coordinates reference first, then pitch, then roll.  UMMD's config.g file will contain:

M667  S1  ;  set coreXY architecture
M208 X-151 Y-185 Z0 S1 ;  set minimum travel limits (front left corner) for X, Y, and Z
M208 X150 Y153 Z680 S0;  set maximum travel limits for X, Y, and Z
M558 P0 F180 H5 T6000  ; no probe, probe at 180mm/min, start 5 mm above the bed, travel between probing points at 6000 mm/min
M671 X-161:161:0 Y0:0:-161 P0.7  ; defines leveling screw locations and thread pitch

Finally, you need to have a bed.g file that specifies the coordinates of the probing points.:

bed.g file:

G28 ;  home
G30 P0 X-140 Y-140 Z-99999  ; first probe point coordinates
G30 P1 X140 Y-140 Z-99999  ; second probe point coordinates
G30 P2 X140 Y140 Z-99999  ; third probe point coordinates
G30 P3 X-140 Y140 Z-99999  ; fourth probe point coordinates
G30 P4 X0 Y0 Z-99999 S3  ; fifth probe point coordinates, 3 leveling screws

Once all this stuff is in place, you can start the manual bed leveling assistant from the Panel Due by first preheating the bed and nozzle to print temperatures, homing all the axes, then touching the wavy looking icon under "P0" on the right side of the control screen.

Heat up the bed and nozzle, home all axes, then touch the sine wave looking icon on the right side to start the manual bed leveling assistant. Note: I did not heat the bed and nozzle for this photo...
Then you'll see a screen like this for each of the probing points:

The manual leveling assistant at work.  The nozzle will start at the height set by the H parameter in the M558 statement in the config.g file, in UMMD, that will be 5 mm above the bed.
Put a piece of paper between the bed and the nozzle and lower the nozzle using the buttons on the screen until the nozzle just grabs the paper.  After the last point has been probed, the assistant stops. and you go back to the ordinary control screen.  What happened?!!

Fear not!  Switch to the console screen and you will see a message telling you how far off the leveling is at each leveling screw, and how much to rotate it to correct the error:

The message at the bottom tells you the result of the manual leveling assist process.  The first leveling screw is considered the reference and the error and correction are always zero there.  
The example above shows that there is no error or adjustment required at the reference screw (it will always show that, and that's why you put the reference screw coordinates first in the M671 statement on config.g), the bed is low by 20 um at the pitch adjust screw, and the bed is low by 60 um at the roll adjust screw.  Since I told it the pitch of the screws are 0.7mm (the P parameter in the M671 statement in config.g), the bed Pitch adjust screw needs to be turned 0.03 of one rotation (that's not much!) in the direction that raises the bed to correct the leveling error, and the bed Roll adjust screw needs to be turned 0.08 of one turn in the direction that raises the bed to correct the leveling error.

You twist the leveling screws by the stated amounts to bring the bed into "level" (true meaning is parallel to the XY plane of the printer defined by the X and Y guide rails).  If you are full-on OCD or just borderline like me, you repeat the process as many times as it takes to satisfy you that the bed is as level as it can possibly be.

Finally, it's a good idea to readjust the Z=0 position after you're satisfied that the bed is level.

You can find info on using the manual bed leveling assistant here, and definitions of all the gcode that RepRapFirmware supports here.


  1. Thanks for writing this up. Always enjoy your posts.
    One thing that keeps me from setting the 0 position to be bed centre is that now all my absolute coordinates in macros would need to be updated, because what was once x10 y10 has now become x-60 y-60 or there abouts. Or am I completely wrong about that?

    1. Thanks! Yes, you'd have to recalculate and replace any absolute (x,Y) coordinates in your macros. I only had a couple macros that I needed to tweak, so it was really easy for me to make the change. I suspect that having the bed center at (0,0) will make writing new macros easier.

  2. Hi Mark

    Thanks for sharing this with us. Are you sure the G-code is M208? According to the Marlin site :M208 - Firmware Recover"
    Should it not be: "M206 - Set Home Offsets"?


    1. M208 is the correct command for RepRap Firmware that runs on Duet controllers. See:

      Different firmwares use different gcodes to accomplish the same tasks. If you're trying to set up a machine that runs Marlin, you'll have to figure the appropriate codes to use by reviewing the Marlin gocde definitions.


Leave comments or a questions here and I'll try to post a response as soon as I can.