Musings and Experiments on the Art and Science of 3D Printing



FSR Auto Calibration Setup for Duet Controller

By SublimeLayers Sunday, January 24, 2016
A lot of folks have pinged me for information about setting up FSRs for auto calibration using the Duet controller and dc42 branch of the RepRapFirmware. So I'll document what I've done here. Please feel free to post questions in the comments section so everyone can learn from them.

By far the easiest way to interface FSRs is with the JohnSL board. Several vendors sell them singly or in a kit with the FSRs and wiring harness. I like the UltiBot FSR Kit as it is competitively priced, the FSRs are the short variety with PRE-ATTACHED connectors (a significant feature), the JohnSL board and the wiring harness. Oh, and there are silicone pads for properly distributing the force on the FSR surface. I've equipped 12 printers with FSRs now and this is by far the easiest route.

I'll leave mounting the FSRs for another post as each printer has it's own requirements. To date, I've created printable mounts for Rostock Max, Mini Kossel, Kossel 250 and TAZ 4 and 5 printers. These can probably be adapted to any other delta or Cartesian printer. If you need them before I add them here, let me know. I also have a little JohnSL board holder to attach the board securely to the printer.

Wiring Up

On to the Duet and wiring...
Here's a photo of a Duet 0.8.5 on a Kossel 250. The Duet 0.8.5 has a dedicated connector for Z probes (upper right corner next to the PanelDue connector in the photo) but the folks at Think3DPrint3D recommended using the extruder end stop connector (labeled P above) for this type of probe (which actually makes the FSR output look like a standard mechanical endstop switch to the controller).

The wiring harness that comes with the UltiBot kit to connect the JohnSL to the Duet needs to be modified as the Duet has a different pin ordering than Arduino-based controllers. Take a look at the grey-red-black wires in the photo above. Grey is the Signal, red is 3v3 and black is ground. You can use a needle or thin wire to press the little tab in the connector housing slot to remove and rearrange the pins.
The JohnSL board is connected to the other end of this 3 wire harness. The photo above shows the wire order. The JohnSL also has jumpers to set the sensitivity - but leave those alone for now. There is also a jumper to set the switch behavior NC or NO. The jumper MUST BE installed to make the JohnSL behave like a NC switch. That is documented along with the sensitivity jumpers at the bottom of this page. The three FSR wiring harnesses attach to the two pin connectors at the bottom of the photo - the wire color order does not make a difference. It is good practice to twist the two wires to minimize signal noise.

Configuring Firmware

With the FSRs connected to JohnSL and the JohnSL connected to Duet, you can give your sensors a dry run test. First, edit your config.g file to let Duet know about the "Z probe". It is located near the bottom of the file. (TIP: with the Duet Web Control 1.08 you can edit this file right from the Web UI). Look for the section:

; Z probe and compensation definition
;*** If you have an IR zprobe instead of a switch, change P4 to P1 in the following M558 command
M558 P4 X0 Y0 Z0         ; Z probe is a switch and is not used for homing any axes
G31 X0 Y0 Z-.08 P500     ; Set the zprobe height and threshold (put your own values here)

The above is configured correctly for the FSR probe. Note the G31 line "Z" parameter. We'll come back to that later but for now set it to Z0.

While you are editing config.g, also set the primary delta parameters. Look for the M665 line:

;*** The homed height is deliberately set too high in the following - you will adjust it during calibration
M665 R97.336 L217.71 B85 H210 X0.33 Y-0.11 Z0.00   ; set delta radius, diagonal rod length, printable radius and homed height
M666 X-0.31 Y1.32 Z-1.01    ; put your endstop adjustments here, or let auto calibration find them

Set the delta radius R to a reasonably close value wither by measuring or using the manufacturer's recommendation. Set diagonal rod length L either by measuring your rods or using the lengths from the manufacturer, set the printable radius B, and set the homed height H to the distance from your nozzle tip when homed to the bed surface - 10mm to give a little clearance for calibration later.

Now power up your Duet. Press a finger tip on each of the FSRs one at a time. You should see the corresponding LED on the JohnSL light up and you should also see the LED above the extruder endstop connector on the Duet turn off (it is normally lit up with an NC switch). Once you've verified everything is working correctly, you can mount your FSRs and button up the installation.

In addition to the config.g edits above, you also need to edit your bed.g file. bed.g contains all the auto calibration configuration, mine looks like this (for a Kossel 250):

; Auto calibration routine for delta printers
; Before running this, you should have set up your zprobe Z offset to suit your build, in the G31 command in config.g.

; About the G30 S parameter
; Used to specify what calibration computation to perform.
; S=-1 Don't adjust anything, just print the height error at each probe point
; S=0 Equivalent to S=
; S=3 Adjust homing switch corrections only
; S=4 Adjust homing switch corrections and delta radius
; S=6 Adjust homing switch corrections, delta radius, and X and Y tower position offsets
; S=7 Adjust homing switch corrections, delta radius, X and Y tower position offsets, and diagonal rod length

M561    ; clear any bed transform, otherwise homing may be at the wrong height
G31 X0 Y0    ; don't want any probe offset for this
G28    ; home the printer

;*** Remove the following line if your Z probe does not need to be deployed
;M98 Pdeployprobe.g    ; deploy the mechanical Z probe

; The first time the mechanical probe is used after deployment, it gives slightly different results.
; So do an extra dummy probe here. The value stored gets overwritten later. You can remove this if you use an IR probe.

;G30 P0 X0 Y0 Z-99999

; Probe the bed and do 6- or 7-factor auto calibration
G30 P0 X-69.28 Y-40.00 Z-99999 H0.0   ; X tower
G30 P1 X0.00 Y-80.00 Z-99999 H0.0   ; between X-Y towers
G30 P2 X69.28 Y-40.00 Z-99999 H0.0   ; Y tower
G30 P3 X69.28 Y40.00 Z-99999 H0.0   ; between Y-Z towers
G30 P4 X0.00 Y80.00 Z-99999 H0.0   ; Z tower
G30 P5 X-69.28 Y40.00 Z-99999 H0.0 ; between Z-X towers
G30 P6 X-34.64 Y-20.00 Z-99999 H0.0   ; X tower
G30 P7 X0.00 Y-40.00 Z-99999 H0.0   ; between X-Y towers
G30 P8 X34.64 Y-20.00 Z-99999 H0.0   ; Y tower
G30 P9 X34.64 Y20.00 Z-99999 H0.0   ; between Y-Z towers
G30 P10 X0.00 Y40.00 Z-99999 H0.0   ; Z tower
G30 P11 X-34.64 Y20.00 Z-99999 H0.0   ; between Z-X towers
G30 P12 X0 Y0 Z-99999 H0.0 S6   ; center and auto-calibrate 6 factors

;*** Remove the following line if your Z probe does not need to be retracted
;M98 Pretractprobe.g   ; retract the mechanical Z probe

G1 X0 Y0 Z150 F10000   ; get the head out of the way of the bed
There are a couple of important things here. Firstly, read my comments on the S value at the top. I always do S=6 calibration. I don't want auto calibration messing around with my delta arm length as that can affect the part X-Y scaling and is easy enough to figure out and set independently. You can do an S=3 or S=4 once you have the machine calibrated, but since it only takes 30 seconds to do a full S=6 I just use that all the time.

Also note the commented out M98 lines. FSRs do not retract! I left them here commented out as a reminder since the default has them uncommented.

Next, you need to set the bed probe points. David has a nice web-based bed.g file generator here to sett all of this up. I use 13 point, 6 factor with a probing radius = 100 for my calibration above. TIP: it is best to start with a smaller probe radius than your bed actually supports to make sure your hot end, arms, carriages or wiring interferes. You can then sneak up on the maximum probe radius.

Make the edits to bed.g and upload or copy it to the CF card on Duet into the /sys folder.


Everything is ready to go, now what? Now it's time to test and make sure everything is working properly. I recommend doing a dry run with the hot end and bed cold. Once you have things working correctly, you always want to calibrate with the hot end and bed up to printing temperatures.

Power up your printer and Home it. Verify that the FSRs are working properly by tapping gently on the bed - you should see the LEDs blink on the JohnSL board and the endstop LED on Duet blink off-on. Test all three FSRs by tapping directly over them. With everything ready to go, enter G32 into the Web interface G-Code console or press the Auto Cal button on the PanelDue. Be ready to turn off the printer quickly in the event of a problem. The printer should home then descend to about 10mm above the bed. Then it moves out and probes each of your probe points, ending with a probe at 0,0. Finally, the nozzle raises 150 mm off the bed (that's the last line in the bed.g file that says G1 X0 Y0 Z150 F15000. You can change that to anything you'd like.

Presumably the probing worked. You can check the results easily. If you ran from PanelDue, click the Console tab and the auto calibration results will be printed. The deviation value tells you the least means square deviation for the calibration. You'd like to keep this below 0.05 for the best results. If you auto calibrated from the web interface, the output will be in the G-Code Console log output. Here's an example:
Calibrated 6 factors using 12 points, deviation before 0.208 after 0.045
If you issue an M665 command, you'll get the calculated delta radius, homed height, and tower position offsets.
Diagonal 215.53, delta radius 96.64, homed height 208.92, bed radius 85.0, X 1.59°, Y 1.31°, Z 0.00°
M666 shows the end stop adjustments.
Endstop adjustments X0.21 Y1.41 Z-1.63
Once you have calibration tested and working, bring the hot end and bed up to temperature and run calibration (G32) again. If your deviation is too high, run auto calibration again. Sometimes 2-3 runs will improve things. If after 3 runs it is still too high, I recommend checking your printer carefully for mechanical issues. In particular, check that the FSRs are triggering reliably with little force.

After you have a good calibration, you can transfer the M665 and M666 values to your config.g file so the next time you start your printer, you are ready to go. I find calibration so quick to perform that I just run G32 everytime I startup my printer. In fact, you can add a shortcut to the Duet Web Control menu for it. Click the Settings menu and the List Items tab. In the Add new G-Code box enter G32 for G-code and Auto Calibrate for the description. Click Add G-Code and Apply Settings. Now you can run Auto Calibrate from the pull-down menu at the top left of the Web Control screen.

Post Script

Once you have FSR based auto calibration working you may find that it needs a little tweaking to set Z=0 properly. FSRs require force to trigger. Depending on how rigid your bed and FSR mounting system is, you may get a little flex before the FSR triggers. This can result in the nozzle being too low - the nozzle will drag on the bed on the first layer or the layer height will be too thin. The G31 line in the config.g file can offset this. I have a very rigid bed and mounting system and find I need -0.05 mm compensation using the Z parameter for Z probe height.

G31 X0 Y0 Z-.05 P500 ; Set the zprobe height and threshold (put your own values here)

In the dc42 firmware, David has built-in some very flexible probe height offset with the G30 H parameter. Basically, this allows you to correct for any offset differences at the probing points. Here's how you go about doing that:
  1. Above each probe point (from the bed.g file) lower the nozzle using the paper grip test.
  2. Send a G92 Z0.
  3. Raise the nozzle 5mm.
  4. Send G30 S-1 and write that down.
  5. Read the trigger height (if you did the above from the web interface, read it there, otherwise read from the PanelDue console).
  6. Repat 3 - 5 several times and average the results. I like to do 3 probes.
  7. Repeat 1 - 6 for each probe point from the bed.g file.
  8. Edit the G31 Z parameter in config.g to the trigger height you measured at the bed center: X = Y = 0.
  9. In bed.g set the H parameter for for each of the probe points like this:
H = (trigger height measured at the point) - (trigger height at the bed center)

I'd like to thank David Crocker (dc42) for his great firmware and guidance in understanding his probing and configuration.

29 comments to ''FSR Auto Calibration Setup for Duet Controller"

  1. Michael -

    Great writeup. I was able to get the Duet installed, commissioned, calibrated, and printing in a few hours on our K250VS-BSE Delta. Thanks for the link to UltiBots and support of our FSR kits.


  2. Glad it helped Brad. I corrected the spelling to "UltiBot", sorry about that. Good products and companies deserve to be called out.

  3. Any chance you could upload the mounts for the Rostock Max V2 to thingiverse. That would be v. helpful.
    Thanks for your guidance it has been super helpful.

  4. Yes, I'll do that when I get home later this week and put a link here.

  5. Ok, I've published the mounts on Thingiverse here:

  6. "In bed.g set the H parameter for for each of the probe points like this:
    H = (trigger height measured at the point) - (trigger height at the bed center)"

    little confused, I don't see H parameter in the bed.g sample file you have posted. Where do I enter that parameter?

  7. I didn't have the H parameter in my bed.g for simplicity but I've edited the example in the text above to include H0.0 that can be replaced. Basically, you insert H in the G30 line like this:

    G30 P0 X-69.28 Y-40.00 Z-99999 H0.0

  8. Did not know about the jumper for setting the JohnSL board to NC, thanks for the tip. Thought it was causing homing problems (and it might have been), though appearently I had swapped my X and Z motors.

    Question though, when I run the AutoCal, the nozzle drops to the bed and pushes /drags on it through out the entire probing process. In Rich Cattel's Marlin calibration, it would probe the bed from 5mm or so before moving to the next point.

    1. Nevermind. In the default gcode, I thought it said to overestimate the bed height which was contrary to what you wrote...bed height minus ten.

      You were right, my bed height is roughly 160 and entering 150 in the config.g file worked perfectly. Overestimating (165) was causing the dragging during the probe.

      Thanks again, glad I found your blog.

  9. AH, it sounds like you have your initial M665 "H" value set to high. Do this:

    home the printer and measure the distance from the nozzle to the bed. Subtract 5mm and then enter M665 HNNN where NNN is your height. Here is the comment in David's config.g file:

    ;*** The homed height is deliberately set too high in the following - you will adjust it during calibration
    M665 R105.6 L215.0 B85 H240 ; set delta radius, diagonal rod length, printable radius and homed height

    The behavior should be that the nozzle comes down to within a few mm of the bed, travels to your first probe point, probes, next probe point, probe, etc.

  10. Hi,

    Thank you for the writeup!
    I'd like to point out that link to David's web-based bed.g generator is broken. Your "http://for%20my%20calibration%20above/" should be ""


  11. Thanks Mait, I'll fix the link in the text. Cheers!

  12. Could you add tags to this to make it easier to find? This page was the missing puzzle piece, in conjunction with "converting the rostock to Duet Wifi" and "new FSR bed system". Thanks!

  13. Done! Sorry about that, I do try to tag things but this one got away from me.

  14. Hi Michael - I've been following your work in my quest to get my Rostock Max V3 into service and have completed the Duet Wifi/JohnSL FSR/E3DV6 upgrades, but can't seem to get my machine to level correctly. I always get high spots on the order of 1-2 mm in the sections of the bed between the towers. This seems to be an issue with the delta radius calibration, but no matter how many times I run the calibration routine nothing helps. I did go through the process of adjusting the H values in the bed.g file, which helped a little. Right now the delta radius the Autocal settles on is around 144.2mm. Any idea what could be going on? Thank You!

  15. Tyson, the first thing you need to do is determine if there is variability in probes from run to run. To do this, open bed.g in DWC and copy it. Then make a new Macro and call it Probe Test. Copy the contents of Bed.g into it. Then find the last G30 line in the file and change the S6 to S-1. Here's what mine looks like:

    G30 P12 X0 Y0 Z-99999 S-1 ; center and auto-calibrate 6 factors

    Save and then run this macro. It will probe and report it's results on the console without changing the calibration. Run it 3-5 times and then compare each of the probes points across all runs. They should all be remarkably close, if not, you have an issue with probe triggering. If you used my printed FSR mounts, there could be slight binding in one or more.

    The other thing to be aware of is a lot of people are observing what we call the "taco effect" on V3s. Basically the probes near a tower are low and opposite are high, so you get a wavy set of probe points for both the outer and inner radii in the probe set. If you have H values in the G30s in your macro, remove them first (only from the macro for now).

    1. Hi Michael

      Thanks for the reply! When I did the H value calibration, I did notice the "taco effect" to some degree. Here are my current H values:

      G30 P0 X0.00 Y135.00 Z-99999 H.004
      G30 P1 X116.91 Y67.50 Z-99999 H.029
      G30 P2 X116.91 Y-67.50 Z-99999 H.104
      G30 P3 X0.00 Y-135.00 Z-99999 H-.026
      G30 P4 X-116.91 Y-67.50 Z-99999 H.055
      G30 P5 X-116.91 Y67.50 Z-99999 H.079
      G30 P6 X0.00 Y67.50 Z-99999 H.001
      G30 P7 X58.46 Y33.75 Z-99999 H-.004
      G30 P8 X58.46 Y-33.75 Z-99999 H.126
      G30 P9 X0.00 Y-67.50 Z-99999 H.075
      G30 P10 X-58.46 Y-33.75 Z-99999 H.115
      G30 P11 X-58.46 Y33.75 Z-99999 H.061
      G30 P12 X0 Y0 Z-99999 S6

      I ran the test you suggested using S-1 and verified these findings. I'm using your bed design from trick laser. The FSRs are stuck to the Rostock V3 top plate, with one rubber pad stuck on top of each. Right now the melamine bed is just sitting on top of the rubber pads. The Onx PCB is stuck to the melamine using the recommended tape and a glass palte sits on top of that, which is currently stuck in place with Kapton tape along the edges. I'm intending to make swivel clips for the glass plate as soon as I can print something reliably. Thanks for any suggestions you might have!

  16. Hey Michael,

    I've been following your blog/forum posts for guidance as I upgrade my Rostock Max v3 to Duet Wifi and FSRs for probing. So far, it's been going great. However, as I was running the autocal G32 I couldn't seem to get a deviation value of less than around 0.15~, which is not really close to the 0.05 you recommended, even after multiple autocals (all consistent around 0.15). There does not seem to be any obvious mechanical issues with my FSRs (using your new plate, LEDs trigger on very light taps across the entire bed). Do you think perhaps my glass bed or buildTak on top of that may have inconsistencies, or perhaps it is another issue?


  17. Hi Leon. Large deviations like you are seeing can be due to a number of things. You've done the first thing, which is make sure the FSRs are not binding or restricted. The plate really helps eliminate that issue, but how are you attaching the plate to the printer and FSRs? I simply dab silicone on top of the FSR pad and press the plate in and let cure.

    Next up, make a copy of your bed.g file and save it called probetest.g as a macro. Change the last probe line from S6 to S-1 which tells RRF to run through the probing and report the individual probe positions and the calculation results but does not change the calibration settings. Do this 3 times and look for variability across each probe location. Feel free to email or message me on the forum and I'll take a look - or you could become a patron and I'm on my Slack channel ;)

    1. Hi Michael,

      Sorry for posting here again. I followed your instructions to create that probe macro, and generally the probes have been pretty consistent, but I'm noticing a trend that probe points in-between the towers seem to be lower than at the towers themselves (probe test results in positive-negative-positive-negative... output, using points from your bed.g file for the Rostock-Duet conversion). My setup has the Onyx floating on your plate on the silicon pads on the FSRs mounted to the Rostock panel. For some reason getting rid of the double sided tape I had attaching your plate to the silicon pads seemed to drop my deviation to around 0.12-0.13 (odd?). Any ideas on what could be causing the problem? I feel like I should try to converse with you in a more convenient method, such as email.

      Thanks again

    2. Feel free to email me

      However, the issue you are experiencing is due to the Rostock MAX's geometry as best we can tell. The way I deal with it is to reduce the outer probe radius by 10mm or so. The further in from the towers you probe, the better the deviations will be. I can describe why in an email.

  18. Meant to add, I doubt there's an issue with the plate or buildtak but the above test will shed some light on that.

  19. Hey Michael

    I just wanted to say thank you again for your help! I was finally able to get a decently flat first layer by reducing my 13 point calibration circle to 85MM in diameter. I can now print out to almost the entire bed diameter. The last issue I'm still having is inconsistent overall Z height due to some filament oozing out of the nozzle during the startup calibration (which I'm now doing before every print). Right now I have to watch as the first layer starts and manually adjust the "Z Baby Stepping" offset up or down to get the layer just right. Do you have any suggestions for getting consistent initial calibrations?

  20. Michael,

    Is there a way to wire the "peek" fan similar to the RAMBo where it is on when the hot end is on and then shuts off below 50C?


    1. Yes, absolutely. You use one of the PWM fan ports and use M106 to enable thermostatic control. This is what's in my config.g file:

      M106 P1 T50 S255 H1 ; Set hotend heatsink FAN1 thermostatic control at 50°C

  21. So I've dialed my height back to avoid crashing into the bed. I'm trying to do auto calibration and have ran into two issues. I get the following error message on all probes. "Z probe already triggered at start of probing move". Also on one of the points the stepper motor slaps the z tower. I'm using a titan aero mount.

  22. Thank you so much for this guide, I now have my Rostock fully converted to a Duet Wifi + FSR system

    I also wanted to give back a little bit by sharing the spring tension bed clip I thought of, printed, and have successfully utilized.

    When I had the FSR plate cut from melamine, I noticed that the hole locations for a bed clip system might split the melamine I chose with a screw, and it made me think:
    Maybe I dont want to keep tightening or untightening a screw in this wood if I have to remove the glass.

    So I put a spring on a wood screw, and designed a bed clip that restrains the glass with the spring in mind. I'd like to send you that file and a picture of the setup if I could, if others would find it useful that is.

  23. I wanted to thank you for this excellent read!! I definitely loved every little bit of it. I have you bookmarked your site to check out the new stuff you post. doosan parts

  24. Just checking in to say thanks, and that I did this. It worked. I like the FSR's, my first layer was perfect.