(Near) Perfect Dualstrusions with the FlashForge Creator Pro and PrusaSlicer

dualstrusion-postproc.pl v1.1

This post-processing script allows to make high-quality dual extrusion prints on the type of 3D printers that have two extruders on a single carriage, like the FlashForge Creator Pro which is based on the Replicator Dual. The script takes regular PrusaSlicer dual extrusion G-code as input, and transforms it such as to produce prints free of ooze and gaps. The downside is that printing time and waste material will be greatly increased, but this is inevitable with the single-carriage-dual-extruder system.

Why would you want to use this? The single-carriage-dual-extruder design was a first naïve attempt at offering dual extrusion and it was not well thought out. If you have such model of 3D printer and attempted a dual extrusion, most likely you noticed the inactive extruder contaminating the rest of the object, and perhaps you also noticed under-extrusion after each tool change. A specific strategy is required to avoid these problems, this post-processing script offers such strategy.

If you are planning to buy this kind of printer with 2 nozzles on a single carriage specifically to do a lot of dual material prints: don't. The design is inherently poor, and this script is to be considered a duct tape solution for some of its shortcomings. There are better multi-material approaches, like IDEX (independent extruders) or a single nozzle that swaps filaments (also not ideal because wasteful, but results are excellent).

Note: recent versions of PrusaSlicer also contain multi-material printing improvements. However, those are specific to the Prusa i3 multi-material setup which is very different from printers like the FFCP. It is unlikely that the strategy I've implemented in this post-processing script will be incorporated into PrusaSlicer anytime soon, therefore the script presented here will probably remain your best bet for making good-looking dual extrusion prints on an FFCP or similar printer if you are using PrusaSlicer.

Frog
2-color tree frog by nervoussystem (this print is from the more Slic3r-friendly ‘repaired’ version by LordThrash).

Motivations

Before I made this script, I shied away from doing dual extrusion prints using Slic3r with my FlashForge Creator Pro because the few times I tried, the results were pretty awful. There are two main problems:

  1. the unused extruder keeps oozing filament, polluting the print;
  2. due to all this oozing and unpredictable retraction states, there is considerable lag when the nozzle is (re)activated and nothing comes out the first few seconds, causing gaps in the model.

The only provisions Slic3r offered to combat oozing at that time, were adding a skirt as tall as the object, and an experimental feature to lower the temperature of the unused nozzle. The skirt is ineffective for larger objects because the other nozzle will be inside the skirt and pass over the model anyway, oozing all over it. The skirt was also printed always with the same nozzle, making it useless to prime both nozzles. The temperature feature is useless because it has bugs that cause the wrong nozzle to heat up at the wrong times with the wrong temperature, and moreover it does not wait for the other nozzle to cool down, therefore it oozes anyway. Some of these things have improved in the latest PrusaSlicer, some haven't.

An ideal tool change should:

  1. move the toolheads away from the print before doing the tool change,
  2. let the deactivated nozzle cool down to a temperature where it stops oozing,
  3. heat up the activated nozzle to normal printing temperature,
  4. prime the activated nozzle by printing a sacrificial structure,
  5. wipe any ooze from the deactivated nozzle on that sacrificial structure.

As you can see, a whole procedure expensive both in time and material, therefore it is essential to bring the number of tool changes for any print down to the absolute minimum. Only the Prusa3D fork of Slic3r starting from version 1.35.1 tries to optimize tool changes, but it still is not always optimal.

Because I saw no evidence of anything like the above strategy being implemented in Slic3r, I did it myself. I wrote a script that prints a hollow priming tower behind the actual object. It varies the position at which the wipe occurs, to reduce the risk that a wipe operation will bump into a solidified blob from a previous wipe. The script does not actively wait for the inactive nozzle to cool down, only for the active nozzle to heat up. The main reason for this is that it is better not to wait until the nozzle has cooled down completely when wiping it.

If you want to do dual extrusion prints on a regular basis, a better dual extruder design with separate carriages like the BCN3D Sigma may be a good investment. Another option is the Prusa i3 with multi-material upgrade, which can combine 4 materials. (It still requires purging and priming the extruder at each material change however.) For the occasional dualstrusion with the less-than-optimal design of the FFCP though, the approach presented here is adequate if you have a bit of patience.

Post-processing script

The script pulls the input G-code file apart and then reassembles it in an order that minimises the number of tool changes, and replaces the simple tool changes by the above procedure. If there was no tool change in a layer, it will ‘top up’ the priming tower to maintain it unless there are no more tool changes in the rest of the print. Since v1.0, the script will also replace the start G-code according to what extruder is deemed the best one to start with.

Make sure to update your PrusaSlicer configs if you are upgrading this script from a version older than 0.6. The configs and start G-code were switched to relative E coordinates between version 0.5 and 0.6. The script will refuse to work with the old G-code.
Just as with my config bundle, this script only supports PrusaSlicer, although it is likely to work with the regular Slic3r as well, but there are no guarantees whatsoever and I offer no support for it.

The script is hosted as a GitHub project ‘DualstrusionPostproc’. The main reason why I put this on GitHub is to make it easier for anyone with programming skills to contribute to it. For instance it would be nice to make the script compatible with other slicing programs. I know, it is written in Perl and not some fancy new hipster language, but if you look in the source code you'll see that I believe it is possible to write readable and maintainable Perl code.

Installing

Go to the Releases on GitHub to download the latest version deemed usable. The README.md file contains concise instructions, here are somewhat more elaborate ones.

Place the script from the src directory in a path of your choice inside your Linux or Mac OS environment and make sure the file is executable. In a terminal, cd to where the script resides, and execute:
chmod +x dualstrusion-postproc.pl

Make sure your version of GPX is higher than 2.0-alpha. I don't know what the lowest good version is, but that one will definitely cause problems. Safest is to use the very latest one, which at the time of this writing is 2.5.3 when installing from the latest source.

If you are already using my PrusaSlicer config bundle and the included make_fcp_x3g.pl wrapper script, all you need to do next is open the script's config text file in an editor of your choice, and update the line specifying DUALSTRUDE_SCRIPT according to the comments in the script, such that this line points to where you have placed the dualstrusion-postproc.pl script. Make sure you have the latest version of make_fcp_x3g.pl to ensure compatibility.

You need a Perl interpreter, which is present by default in Linux or Mac OS X. For Windows you need to have something installed like CygWin or the WSL environment offered since recent editions of Windows 10. If you have already set up my config bundle and post-processing script in Windows, you shouldn't need to do anything extra.

If instead you want to use this script with your own custom configs, mind that it cannot be directly configured as a post-processing script inside PrusaSlicer because the converted G-code is sent to standard output. You either need to manually run the script and redirect the output to a file, or use a wrapper script. Also be aware that the script only works if ‘Use relative E distances’ is enabled in the printer settings.
The script looks for certain markers that occur in my G-code snippets. You can either update the MARK variables in the script to match your own markers, or simply add my markers to your G-code.

Using

First and foremost: do not attempt to use any of PrusaSlicer's own multi-material provisions except what is mentioned below. Also do not try to use the “ramping lift” feature because it might interfere with the post-processing script (not tested).

In PrusaSlicer, first select a dual extrusion printer profile (if you are using my configs: one of the ‘LR’ profiles). Simplest is then to load both STL files for both materials at the same time. PrusaSlicer will ask whether you are importing multiple parts of a single object, answer ‘Yes.’ Alternatively, you can load one part, then right-click it in the parts list, and use ‘Add Part’ → ‘Load…’

PrusaSlicer setup

Select the correct filaments: the topmost one is the right extruder (1), the other one is left (2). Then assign the desired extruder to each of the parts in the parts list. (The colours in the preview might not always reflect the chosen materials due to a bug in PrusaSlicer.)

You should enable a tall skirt for maximum print quality. This helps to catch ooze that may fail to be wiped, or that exits the active nozzle during its travel towards the print. This skirt must reach the highest layer where a tool change occurs. One loop in the skirt is enough, but to ensure it is well anchored, you should fiddle with the ‘Minimum extrusion length’ until the first layer of the skirt has at least 2 loops for small objects, or 3 to 4 for larger ones. (Mind that PrusaSlicer will only show the correct shape of the skirt after slicing is complete.)

PrusaSlicer preview
This object has dual materials across its entire height, therefore I configured the skirt to reach up to the final layer.

Make sure there is enough space behind the object to print the priming tower. It needs 22 mm behind the highest Y coordinate that occurs in the print, skirt included. I plan to implement a smarter placement of the priming tower and automatic shifting of the entire print when necessary, but for the time being you'll have to do this yourself.

The default values configured in the script should be OK. You may want to tweak the temperatureDrop value depending on your filament. A smaller drop will speed up the tool change, but increase the risk of ooze.

Note that although PrusaSlicer's predictions for total print time are usually pretty good, they will be extremely optimistic when using this script because PrusaSlicer is unaware of the added operations and the time it takes to cool down and heat up the nozzles.

Example of a print
What a typical (small) print looks like. The tower is especially messy in this one because most of it exists of top-up layers, but as you can see the mess is entirely contained within the tower.

Hints

Before starting a print, make sure your nozzles do not have remains of filament sticking to them. Clean nozzles will reduce the risk that strands of ooze stick to them and manage to get past the wipe tower and into the print. As a matter of fact it is best if your nozzles are slightly greasy as opposed to impeccably clean. Rubbing a tiny amount of heat-resistant silicone oil or grease onto the nozzles might help to avoid filament sticking to them. (Need I mention that trying to rub oil on heated nozzles using your fingers is a bad idea?)

Bed temperature is set according to the material in the right extruder unless there is only left extruder material in the first layer. What this means is that if your first layer has 2 materials that have different optimal bed temperatures, load the material that occurs most in the first layer into the right extruder.

For things with inlays, like typical coasters or poker chips, you should enable the ‘Lift Z’ feature in the Printer Settings, not necessarily for the entire print, but certainly for the topmost layers. (Do not enable ramping lift!)
I recommend a lift distance of 0.2 mm. This avoids that the second colour printed in a layer smears the first one during travel moves. Due to the inherently poor design of the dual nozzle configuration, smearing is difficult to avoid and especially visible when combining black filament with a lighter colour. To get the best results, use nozzles that are as pointy as possible.

If the two materials are not perfectly aligned, you will need to adjust your toolhead offsets. This can be caused by your extruder carriage not being perfectly parallel to the X axis. You can of course try to loosen the screws and wiggle it, but it is better to measure the deviation and compensate for it. Do a small test print (I recommend the minimalAlign model from here) and make a guess at how far the extruders are misaligned. Go to Toolhead Offsets in the printer Settings LCD menu. Typically you only need to modify the Y offset and leave the X offset untouched, although it is possible that your nozzles are not at the ideal 34 mm distance either. Repeat your small test print after adjusting the offsets (no need to reboot the printer).
Unfortunately there seems to be a discrepancy between firmware versions when it comes to the direction in which the offsets need to be adjusted. In the most recent Sailfish build, I need to decrease the Y offset if the left extruder prints too much towards the rear edge of the bed. As for the X axis, if the left extruder prints too much to the right, reduce the X offset. Try it this way and if it moves the extruder in the wrong direction, just adjust it in the opposite direction.

If the object you're printing has small intricate details and small perimeters, you should avoid large differences in extrusion rate, otherwise you risk over- or under-extrusion problems. If you are using my profiles, the ‘mediumStrong’ print settings are a good starting point but they will still print the skirt at a much higher speed than the rest. To remedy this, reduce the ‘support material’ speed to be closer to the perimeters speed. You can also try increasing the small perimeters speed a bit. Next to this, it helps a lot if all parts in the model can be printed with at least 2 perimeters because this gives the extruders more time to equalise their pressure before printing the outer walls of your object. If you cannot edit the model to make small parts thicker, it might still be possible to increase the thickness of small details by using the ‘XY size compensation’ in the advanced settings.

Limitations

This approach is not suitable for printing two materials that should not be printed on top of each other like ABS and PLA, because there is only one priming tower that piles everyting together. If the materials really don't stick to each other, you will end up with a terrible mess. I might update the script to allow two separate priming towers. It should be OK for soluble support materials because those are supposed to be stackable.

This has only been tested for objects that weren't very tall (the tallest thing I have printed with this script was about 40 mm. Objects that still have two materials high up could be problematic because the wipe tower risks being knocked over. (On my perhaps-TODO-sometimes list is making the tower wider at the base for tall prints.)

Support

If you appreciate the effort that went into this script, you may consider leaving a tip :) You can also tip me through my Thingiverse profile.

Version History

  • 0.2 (2017/03/04): first public release
  • 0.3 (2017/03/10): fixed bug that could skip all layers after the last tool change
  • 0.4 (2017/03/17): allow variable layer height; fix incorrect first layer temperatures for priming tower
  • 0.5 (2017/08/06): add support for Lift Z, and read feed rates from file instead of overriding them
  • 0.6 (2017/12/29): now uses relative E distances; optional extra vertical line in maintaining layers of the tower; less aggressive tool change speed; heat T1 to true standby temperature while T0 starts; correct position of priming tower; support wipe on retract (untested though).
  • 0.7 (2018/06/20): handle variable fan speed commands M106/M107 for compatibility with the MightyVariableFan system; correctly preserve fan state; better logging with program identifier; abort with fatal error if the print doesn't start with the right extruder.
  • 1.0 (2019/07/07): prints can now have any single material in the first layer; override start G-code with our own (‘Start-dual-extruders-postproc’ is now obsolete); fix bug that could cause incorrect unretractions; improved fan speed management; ensure correct travel feedrates.

License

This script is released under the Creative Commons Attribution 4.0 International license. In short, you can do pretty much anything with it, at the condition that you give appropriate credit to the author. You can use my real name ‘Alexander Thomas’ or my pseudonym ‘DrLex’, and you should preferably link to this website.

Use at your own risk. The author is not responsible for damage to your printer or other accidents due to the use of this script.

©2017/03-2024/01 Alexander Thomas