Saturday, December 19, 2015

Tribed: a fully automatic bed leveling and tool height adjustment, with FSR and 3 Z screws

This post is the continuation of my preliminary analysis regarding bed tramming and automatic tool height adjustment. So far I never made the step to redo my bed, even though it was on my wish list for years. Now it is a reality :)

Early testing of the complete setup : starting with a properly calibrated bed,
corrupting it manually, and letting the system auto-calibrate it again.
A faster / realistic movement is here, since speed was not a concern above.

So why now? A few months ago, someone came and talked to me about his wish to design a new, open source, user-friendly printer for the prosumer market. Please check this as your opinion counts!

All in all, it was an excellent reason to realize my idea of a fully automatic bed leveling. And since the new printer will also be opensource, here is the work, design and my analysis. How nice: not only I was given the possibility, but I was asked to do so!

As said, this improvement is part of a longer effort towards a user-friendly printer, for more reliability and less manual tweaking. My Ultimaker itself may eventually be ditched one day. Huh. No, I am joking. Well.. unless the new one is really is obviously better... Damn, that's exactly what it is all about :/


Automatic bed leveling and tool height compensation

Specifically, the idea is to combine bed leveling (aka tramming), and tool Z offset (automatic calibration of the tool height). The latter is important as we plan to offer multiple heads and an automatic tool changer (my next work). Nobody wants to deal with the corresponding offsets that needs to be set to less than a tenth of millimeter to avoid havoc. You can read my preliminary analysis there, but here are the main goals for the combined bed leveling + tool height calibration system:

  • automatic bed tramming - bed should be level after calibration, with no user interaction
  • automatic Z offset calibration - i.e. according to the mounted tool (various length)
  • repeatability - two successive calibrations should give the same result.
  • real accuracy - vs. software compensation of imperfect bed calibration
  • simplicity - reduce mechanical risks due to wear or backlash
  • compatibility with heated bed and 3D printer designs whenever possible

Secondary, but nonetheless important items are:
  • small weight - less inertia for better speeds and overall print quality
  • small footprint - reduce impact on the printable volume and surface
  • minimal cabling - mostly, tools should not carry duplicated sensors
  • steadiness of the bed - no bed vibration including at high speed (springs?)
  • low impact on the firmware
Given prior analysis, I settled on a fully revised heated platform, with 3 embedded FSR force sensitive sensors, 3 independent Z screws, and some modified software.

Interesting (temporary?) options left out

The tiny low cost 15mm linear actuators
I'd use if I had to tram a cantilever bed.
Using a regular cantilever bed with 2 small-range actuators could do the job. But I tend to dislike such "hanging beds" as they eventually wear out and leave room for vertical free play. Well, unless the whole thing is supersized (which, in this case is not really over-engineering, but just pricey).


For example, the bed of my old Ultimaker could be shaken vertically by a few millimeters at the end, and I was never able to fix that with the existing design. For some time I thought about adding a second slave Z screw on the front side just to prevent this sloppiness. Better add another one and fully control the 3 "corners" of the bed.



Rediscovering what is done already: FSR groove mount by edlep.
I would try to use a load cell instead, for a sturdier mechanical
attachment (but heavy and more complex to interface).
For some time I thought about putting the pressure sensors on the tool holder itself. The head itself would then know when it hits the bed.

Three-point bed attachments would still be required for the actual tramming, and a cable to be run from the tool holder to the firmware.
This idea is not yet fully out of my mind because it is elegant, and it may be even more reliable than embedded sensors in the bed. And I found someone who did it, so it may not be stupid ;)




Still, I first want to check my current solution. I suspect that the mechanical joint at the head may then be somehow fragile with FSR that cannot be squeezed too much (some floating must be left, necessarily). It may create vibrations during high speed printing or milling for example. In this regard, a metallic load cell could be a better choice than FSR, but it is sensibly heavier also and more complex to interface due to its wheatstone bridge.

Now for regular single head printers, I really like the idea: it is both simple and probably efficient, so go with it and tell me ;)

Hardware choices and requirements

Overall the improvement required significant additional hardware:
  • of course, three FSR sensors and a new bed gantry...

    An FSR sensor on the bottom plate of the bed (the tail goes below the bed).
    The corresponding nut is linked to the plate with a 3D printed join,
    aluminum tube towards the other links (in a triangular setup),
    and glued to the bottom of the bed with high temperature silicone.
  • due to the two additional steppers, I added a 3 axis CNC shield slave (running a firmware of my own, not GRBL). There are now 3 of them for Z in place of a single one one.
  • so... 3 Z screws instead of one. By laziness, I bought Nema17 steppers pre-equipped with Z screws (just to test initially). At least there is no more Z elasticity as with those common aluminum couplers (oldham are better but not cheap), and the screws were still straight enough for no noticeable wobble. I used the worst one for the background center "free" screw.
    Basic all-in one stepper motors with lead screw (surprisingly good)
    At least I avoid low quality aluminum flex shaft couplers!
  • a few easily designed and 3D-printed holders for the top front roller bearings, and two for the bottom steppers. I should relocate them under the bottom plate of the printer as done the third stepper (I re-used the existing holes of my Ultimaker original). The top of the screw of this stepper is left "free" so as to to over-constrain the 3 Z screws (this is a common error when people want to constrain everything. The front two screws are already doing the job nicely).

Bottom and top 3D-printed parts. Both are temporary, since the stepper should
eventually be relocated under the wooden bottom (like the regular Ultimaker Z),
and the top part should not protrude like this. No printable area is lost,
as my banana block is already hitting the end stop in this configuration.
  • you may have noticed the small arduino pro mini on the bottom of the printer. It is dedicated to the FSR filtering, so that they behave as regular hardware end stops for the CNC slave. Initially I wanted to make sure they acted reliably and independently of the main controllers, but timings seem to indicate it could be computed by the slave or even the main board for less hardware.

Tricky points

Time will tell but I know that both guiding and driving with a lead screw is somehow "impolite" to most engineers -- but I am pragmatic: it seems to work quite well with only three Z screws that do both jobs. The bed does not move at all. Milling may add lateral wear to the nuts though, but we have here very cheap Chinese stuff so they can be improved also.

Wear. This is yet to test... For this reason, part of this post may then get updated without much notice, and as usual, any feedback is welcome, so feel free to criticize!

A major trouble came with how to insert and fix the 3 pressure sensors to the bed, without impacting the surface area, without exposing them directly to heat (the bed shall be able to go up to 150°C), and more importantly.

These show how sensitive the FSR force-senstive-resistors can be, after heavy filtering.
I did not keep this seemingly fine setting though, as it generates too many "false positive" signals.
So I had to ask for more pressure before they trigger. Some room for improvement is left !

More importantly even, I had troube figuring out how not to overload the sensors because of the bed weight (PCB heater + aluminum plate + glass plate). Resting the bed directly on the FSR transmitted also all kind of vibrations which triggered them too easily unless I asked for excessive/risky pressure (the nozzle could break the glass, no good).

My best idea was to use neoprene, that protrude largely around the FSR sensors. This way the bed is well maintained laterally, it will not transmit its heat to the FSR, its weight is well supported, but it still transmits very well the slightest pressures. And neoprene does not melt like thermoplastics (I would not recommend to print these parts!).

Neoprene is just excellent as a heat-resistant spacer, as a shock absorber,
and as a weight relief. It filters most of the mechanical noise, but it transmits
nicely the pressure from the nozzle on the top plate to the FSR.
Electrically, using the convenient internal 10K pull-ups of the Pro mini was not wise, as it sent the signals in a tiny dynamic range, which was prone to trigger false positive. I had to use external resistors (not difficult but it means specific electronics...). False positives are when the sensor triggers abusively (e.g. when the bed brakes hardly while it goes down, due to interia). They just ruins the very first idea of user-friendliness!

Also, the CNC slave is used to drive 3 stepper drivers. All in all we have 1 X, 1 Y, 3 Z screws and 1 for each extruder. With our minimum of two heads by default, it means 7 steppers and most 3D printer boards cannot handle so many motors. As long as we do not design our own electronics, which we may better do in the end, we had to use a slave controller, and this sucks. The good news is that it only controls the Z during calibration (see below my trick with "transparent mode").

Software requirements

There were also some software modifications:
  • I modified Marlin to activate the third Arduino Mega serial port 3 (soldered a connector on the board). It links to the CNC shield slave (on an arduino Uno). I wrote a small protocol to control the slave from Marlin, and I added corresponding custom menus in the LCD too.
  • I wrote a basic but fully custom stepper driver for the CNC shield, named "bunchosteps". It should not have been compulsory as GRBL is a very nice piece of software and does its job. The problem is that it was made with "only" CNC control in mind, notably with the "fatal" endstops and asynchronous operations and look ahead (block-based segmentation of the commands). It took me too much time to tailor it to my needs so I rewrote my own simpler version. It is also low-level (non-Arduino) code, based on fast interrupts so as to achieve fully controllable smooth Z movements with acceleration and brake (you'll see the effet in the introductory video), but it also handle direct interrupts, common 3Z movement, and most of the calibration (complex interaction with the pseudo-endstops), thanks to a pseudo g-code interpreter fed via the serial link. For me it was much simpler to write one from scratch and deal with it overall.
The sources are posted on my github account, but they are mostly proofs of concepts, still in evolution. So better ask me before you clone or you fork them, and use with care! I need to polish the FSR filtering, but I see Johann Roscholl already has posted such source code also (check the page! I realize a lot work was done there already).

I should at least post the low-level Serial3 support for Marlin as it may help others. I still am unsure whether I rewrote something existing, but I really was not able to active it in the existing state of Marlin.

How it works

Bed leveling

Tramming is triggered by a specific "tribed" menu.

The bed components.
It is a mix of XY moves (done by the master), and Z1,2,3 and combined Z (done by the slave). The procedure is simple : lower the bed (to avoid crashing in it), do a regular XY calibration (find origin), move back to center, home the entire bed (to have an average point of reference). Lower again slightly (assuming the bed is not skewed more than this value), then move sequentially over each of the FSR sensors, raise the entire bed until it triggers the sensor. Lower the bed again, but only by a few millimeters, then raise only the corresponding Z to "home" the axis (this is where the calibration really occurs). Rinse and repeat.

The origin of the first axis is not changed, as it is used a the unique reference. Only the second and third axes are modified to that eventually the zero matches expectation.

As usual any homing is done in two passes: a fast seek up, slight lowering, and a second, slower seek up. The deal is never to move too fast to crash the head on the bed. The first homing is faster and less precise, the second moves a shorter distance but is much more precise (just because it is easier to stop at once when breaking due to a lower inertia).

This is just how it is done on existing printers and CNC machines: it is also why there is this weird "bounce" when homing.


Homing and post calibration: transparent mode!

Once calibration is done (moving the 3 Z axes independently with the slave), all the remaining operations can be done by the master.

The nice little trick I found is to switch the slave to "transparent mode", where it acts as a multiplexer to the stepper signal emitted by the main controller board: I literally redirected into the slave hardware interrupts the "step" and "direction" signals that I took from the empty Z pololu socket on the main board!

So the slave gets the pulse quickly from the master and passes them as soon as possible (a few nanoseconds), unchanged, to its own 3 stepper drivers.

The benefit is great: I can drive my Z just like before, as if I had only one Z screw. But I can also set them separately by switching the slave in calibration mode first!

My goal here is to ditch the obsolete RAMPS + Marlin and easily switch to a more powerful and promising board like the Smoothieboard or the Replicape. I plan to do in a near future, so the less I have to tweak the main firmare, the better. Seriously, I spend already too much time just on enabling the third serial port in Marlin for my Ultimaker RAMPS... The old AVR is at its end of life for driving fast 3D printers, and even more when it comes to additional sensors and hacking. Times are for ARM32 boards.

Flashing the slave

As a final trick, I added a menu entry in my "tribed" section so that I can shut off the serial link between the RAMPS and the slave. This way I can flash or talk to the slave directly without conflicts. This was a huge time saver. In between, I have tweaked Marlin g-code interpreter so that orders are sent to the slave when I prefix them with S3 (this stands for Serial3). So "S3 g120" will ask the slave to do a homing. Yes, this is no g-code, sorry ;)

Notes and conclusion

The overall is pretty clean imho: the bed is much thinner, so I also maximize the printing volume.
The two vertical Z screws in the front lost no horizontal printing area - Full win :)
(OK, the short cable and the arduino mini should be fixed, and the two steppers
in the front should go to the underside, just as the one in the background is)

Achievements


  • this 3Z-bed works well, as intended, even though there are still rare few false positive to fix during calibration. I can print straight out of a badly configured bed without having to tune anything
  • this setup accepts any bed thickness and any tool height. I can change my nozzle and even the entire printer head and simply run another calibration, the new tool length is taken into account automatically. Even if a complete bed tramming is slow, it is not required often, unless I change the bed components and it ends not perfectly level for some reason.
  • we really have a hardware calibration, not software compensation of the hardware defaults
  • not really expensive (it costs less than the high-quality hardware that would be required to avoid the need for any calibration in my opinion)
  • it is compatible with heated bed (the sensors are safe, not exposed to external accidents)
  • it looks cool! My ultimaker looks empty :)

Improvements? Of course!

Optimization and testing is not only possible, but compulsory.
  • tramming requires more than one pass, because the distance between the FSR sensors and the Z nuts is not null. It creates a pivotal point, and fixing one Z impacts all other settings, so a subsequent pass is usually necessary
  • in the video above, 3 passes were required to go below significant changes. Actually by simply moving the calibration offsets as close as possible to their respective Z nuts, only two passes are now required. A third one fixes nothing visible, so it makes the whole faster.
  • may be I could also scan first to get the offsets, solve the equation and fix in second pass
  • better, with some trigonometry, I think should be able to reduce it to one single pass.
  • I should also simply stop the calibration as soon as no more "fix" is required. This is useful because once the bed is properly calibrated, it should stay so unless major events happens
  • once stable, I could also increase the Z speed. The thing is to make sure not to trigger the FSR when the bed brakes, which I should be able to do as no detection is expected when the bed moves down! Still, some vibration may be transmitted to the FSR when moving fast (it was just so frustrating before I used neoprene spacers as shock absorbers).
And finally, more importantly for our project and in order to reduce the total cost of the machine, I think I should move to hardware multiplexing of the Z, so as to avoid the need for an overly complex CNC slave. But this requires a specific hardware board, which I should take into account (honesty, I think it will be beneficial).

Oh, and of course, a lot of real world testing to verify the options were sound and efficient.

And now, I can switch to something else: designing an automatic tool changer!

Addendum: the reprap way -- making it cheaper

Motors and drivers

Since there are 3 motors to drive the Z, and since it does not need to move fast (unless may be for Z-hopping), I think it may be possible to trade the NEMA 17 and CNC shield for 3 of these little $5 stepper motors found on ebay.
5$ stepper driver with UNL2003 driver. Could three of them drive the bed?

Alternate force-sensitive sensors

A very cheap pressure sensor!
Unsurprisingly, there also a few ways to replace the efficient, robust, but $10 intersil FSR sensors.

I am not telling here about on/off contacts as they are trivial to make but they are harder to tune. The deluxe version would be to use more durable conductive rubber, as used in gamepads or TV remote controller. The cheaper would be bare cables criss-crossed on top of each other with a tiny air gap made by "just enough" foam spacers. Probably not very reliable.

More interestingly, you can make your own basic pressure sensitive sensor using antistatic/conductive foam (static dissipative foam), like the one often used to protect the pins of electronic chips (well, when your seller is serious - or you can buy some very cheap on ebay). There are tons of howtos on the web (ex. this or that). The deal is just to insert two wires in it, or here, put a slice of conductive foam between two conductive plate: here, the bottom may be the common steel plate, and the top made of cooking aluminium foil, or bare wire in zig-zag. The resistance depends on the distance between the two, it may just have to be calibrated.

Another idea would be to use (ideally partially) conductive textiles. Even though it is harder to find R.F shielding textiles nowadays to recycle, it can be found online. Not sure how expensive it would be though... I would make a sandwich with a very thin or porous non-conductive intermediate layer, like coarsely woven non-conductive fabric. This way, the the two conductive layers would not tough by default and, when you use partially conductive textile, the more you press the lower the resistance. This makes life easier to set triggering thresholds. Oh -- just found someone who made it into an interesting touch-sensitive matrix.

You could also sew your own "conductive textile" by using nichrome wire, an interesting material to use in many projects. For some time it was used to make heated beds, before PCBs and silicone heaters became common online -- an option I forgot to talk about about in my obsolete heated bed (... failures).





Note: this work was partly sponsored, as part as a former attempt to create an opensource printer. Please do comment and give your opinion! Since the printer will be fully open, the community could benefit from the result reciprocally, if it is worth -- and we share the thing as with this post. It would be a pity that I do something stupid and miss an interesting point or feature.

Note2: tribed, tri-bed or tridibed... I did not spend enough time on chosing a good name, but since hackaday linked to this page and its title before I had a chance to change it, let me keep it now ;)

1 comment:

  1. Update 20191002!

    To be frank, I would probably no more recommend the burden to implement this solution unless you like to tinker of course.

    If you design a new printer from scratch, better go with a super sturdy frame that will not distort with time or stress, e.g. by using super thick smooth Z rods, and very long linear bearings for the bed. It is still possible to link 3 Z axes (e.g. by means of a belt underside, or 3 steppers). Modern software compensation with head-mounted sensors is pretty reliable nowadays. They do not produce visible artifacts, if (and only if) the sensor and printing surface are well matched (which is not always the case).

    E.g. modern 3D printers like the UM3 (I have one as well) are workhorses that "just work". After not trusting it fully, I admit I ended up leaving the "autolevel" on and I have yet to see a problem. It does this by detecting the sudden flattening of the capacitive sensor signal when the nozzle ends up hitting the bed and stays at a constant distance while the bed is kept moving up a bit further -- something that could easily be duplicated in another setup, and that probably was somehwere else (not worth a patent imho).

    The main advantages left with a 3-point bed leveling system IMO is to prevent any freeplay in the bed at all because it brings 2 additional Z axes by definition... It also helps to make ultra-light heads, while improving visibility/printable surface (by not having such sensors on the head).

    My main complaint about reliable printers like the UM3 (beyond the outrageous price!) is that it is incredibly slow. They have such a massive head to move around, with the additional burden that one just cannot see what it is printing (=it is impossible to fine tune the flow in real time). It also waste a really significant surface because of the dual head setup (nothing to do with the sensor actually here). In this respect, I would better buy an E3D tool-changer nowadays, or even a BCN3D: no need to drag an unused head everywhere, for the few jobs that require dual extrusions in my case. Both of them have very sturdy frames and rails, and once finely tuned, bed leveling is probably something to forget about.

    ReplyDelete