DIY heated bed for a Cetus 3D printer

Last year I purchased a Cetus 3D printer which I have now been using off and on for 8 months. So far I have been very happy with the results.

Quick review of the printer


  • ~10 min assembly time.
  • Extremely high print quality due to the use of linear rails and small nozzle sizes.
  • Simple user interface.
  • Can be modded for other uses such as a laser engraver.
  • Can print in Pet-G and ABS without a heated bed if you use a glue stick prior to the first layer.


  • Included software has limited slicing options. It does support 3rd party g-code but when doing so you no longer have a print time estimating.
  • If no heated bed is used then you are limited to PLA or using large rafts.
  • If you do purchase with a heated bed it is apparently quite slow to warm up and will only reach about 50C if your ambient temperature is low.

Overall I would highly recommend this printer to anyone needing a cheap high quality 3D printer in a small form factor.

After seeing this video by Marco Reps I have decided to upgrade my printer to include a heated bed. You can purchase an official heated bed for this printer but I want to roll my own more powerful version

DIY heated bed

Design objectives:

  • Ability to monitor and set the print bed temperature
  • Use a separate power supply to that  used by the 3D printer so as to not overload it.
  • Over-temperature protection independent of the temperature monitoring.

Parts list

Both the power supply and the switching MOSFET are overkill for this application but they are what I had on hand. On the upside having over rated parts also means they will be more heat tolerant if I build a heated changer enclosure down the road and have them located inside the chamber.

Modifying the heated bed

The power resistors were attached with two part epoxy as I did not have any thermal adhesive on hand. After many dozens of hours of printing this method appears to be working just fine. The resistors were wired up in a 4S-2P configuration so that the current draw from the power supply was around 4.2A for a total of 100W output.

In series with the input to the heated bed was placed the bi-metal switch so that in the even that it becomes stuck on full power it should still stay within a safe temperature range. Note that you can use a bi-metal switch as a method of temperature control on its own but that they tend to become stuck after a few thousand cycles. The MOSFET board was connected directly to the power-supply and switched with the relay output of the temperature controller. Note that the MOSFET board requires 12V to turn on and so I used a simple voltage divider to drop the 24V down to 12V.

The wires and the thermocouple were attached with capton tape. After remounting the bed I was pleased to see that it all just fits without needing to make any further changes.


Building the enclosure

Naturally, I wanted to print the enclosure on the Cetus and so I put something together in F360 which can be found here. It just fits the power supply, temperature controller and the MOSFET board. Plenty of veneration was also included. The CAD models for all the Omron parts were supplied by Omron on their website.

The temperature controller can be powered of mains AC or 24V DC. I decided to seperate the high voltage mains from the low voltage components via a deciding wall and power the temperature controller off 24V.


This design is made so that the whole Cetus 3D printer can safely sit on top of the enclosure which keeps the foot print nice and small.


Ever square mm of the printing area was used to print the enclosure, something that could not have been done without a heated bed.

Note that I initially printed the red lid first using the default Cetus print settings (and then ran out of filament) and the final result was pretty bad. After looking around on the cetus forums it looks like there is a problem with the included slicer when printing without a raft. To solve this I switched over to the excellent Simplify 3D slicer. After a few hours of adjusting the settings I managed to get great results. If your interested you can find a copy of my final settings here.

And finally the end result.


It takes around 4 minutes to reach 70C in an ambient temperature of 14C (it was cold in my garage where I timed it) which is a great improvement over the reported times of the stock heated bed.

If I was to repeat this whole exercise it would probably be a good idea to squeeze in a mains fuse some where just in case there was a fault with the power supply that its own internal protection didn’t catch. Also printing the enclosure in all one colour and including a cable drag chain would improve the overall look. Otherwise I’m quite happy with the end result

Posted in 3d printing | Tagged , , , , , , , | Leave a comment

How to sketch equation curves in Fusion 360

The ability to sketch an equation curve is available in Autodesk’s more professional (and expensive) CAD product, Autodesk Inventor, but is missing from Fusion360’s. This tutorial details how you can get similar functionality using the Fusion 360 API.

The Fusion 360 API (Application Programming Interface) allows you to control the functionality of Fusion 360 by wiring code rather than directly through the graphical interface. This is a powerful tool which is useful for automating repetitive tasks and writing add-ins like those you will find on the Autodesk app-store.

In this tutorial we will be using the API in Fusion 360 to sketch a curve using an equation in both 2D and 3D. This is useful when you need to produce a specific, mathematically correct curve that can not be formed easily from primitive geometric shapes. For example, how would you sketch a line along the following equation


which when plotted over range 0 to 6.3 (2pi) (spreadsheet here) looks like the following:


To do so we can follow a few simple steps:

  1. Get acquainted with the basics of how to use the API by watching the following short video from the Autodesk Design Academy channel.

2. Refer to the following example python script to suit your need which can be found here.

import adsk.core, adsk.fusion,, traceback, math

def run(context):

ui = None


app = adsk.core.Application.get()

ui = app.userInterface

design = app.activeProduct

# Get the root component of the active design.

rootComp = design.rootComponent

# Create a new sketch on the xy plane.

sketches = rootComp.sketches

xyPlane = rootComp.xYConstructionPlane

sketch = sketches.add(xyPlane)

points = adsk.core.ObjectCollection.create() # Create an object collection for the points.

# Enter variables here. E.g. E = 50

startRange = 0 # Start of range to be evaluated.

endRange = 2*math.pi # End of range to be evaluated.

splinePoints = 100 # Number of points that splines are generated.

# WARMING: Using more than a few hundred points may cause your system to hang.

i = 0

while i <= splinePoints:

t = startRange + ((endRange – startRange)/splinePoints)*i

xCoord = (math.sin(2*t))

yCoord = (math.sin(3*t))


i = i + 1

#Generates the spline curve


# Error handeling


if ui:


3. Either hit run from Anaconda (The python compiler installed by Fusion 360) or save the script and run it in Fusion 360 directly using the ‘Add-ins’ dialog box. The above script generates the following curve.


To extrude the shape you can select the curve and use the ‘Open/Close Spline Curve’ function to form a closed sketch.


Increasing the ‘splinePoints’ variable will increase the number of spline points generated and in-turn will produce a curve that more accurately fits the equation used. Below is a the same curve with 500 spline points.


However, using a large number of spline points (approx. >500) may cause a considerable delay in generating your sketch or may even crash Fusion 360 completely.

Also note that the API exclusively works in the units of cm for length, radians for angles (radians = degrees * pi/180) and kg for mass. If you prefer to work in different units see this section of the Fusion 360 API manual.

To extend this concept into 3D space we only need to add another coordinate Z and include that in the points object.

while i <= splinePoints:

t = startRange + ((endRange – startRange)/splinePoints)*i

xCoord = (math.sin(2*t))

yCoord = (math.sin(3*t))

zCoord = 2**t


i = i + 1

#Generates the spline curve


Below is how this sketch looks when viewed face on and at an angle.

2018-07-02 21-38-53.gif

That’s it for this post. For a more in-depth understanding of the API be sure to take a look at the Fusion 360 API User manual, sample scripts and the API training series playlist on YouTube.

Big thanks to Macaba on the Odrive discord channel for showing me his cycloidal script  which I modified to use as the example in this post.

Posted in 3D Design | Tagged , , , , | Leave a comment

CAD design of a DIY Strain Wave (harmonic drive) Reduction in Fusion 360

Strain wave gearing is known for its near zero backlash, compact design and axial construction. However it is not known for being cheap. This is why Simon Merrett created waves (pun fully intended) with his DIY 3D printed strain wave gear reduction first shown on hackaday in 2017.

In this post I show how to recreate this design in Fusion 360 along with a few improvements like the use of a proper flex spline cup. Such a design could be idea for robotics applications or things like a 4th axis on a milling machine.

The belt I have chosen for the flex spline is a 50T HTD 5M (5mm pitch) belt turned inside out. As discussed in a previous post this belt has the following parameters:

  • Thickness of 3.81 mm
  • Tooth height of 2.08 mm
  • 5mm pitch
  • 3.05 mm radius on the teeth and 1.49 mm radius on the base of the teeth.

The pitch diameter of a belt is the diameter of the belt as measured at the reinforcing steel wire. To estimate the pitch diameter of this belt you just calculate the circumference (50 teeth * 5 mm pitch = 250 mm) and divide by pi (250mm / pi = 79.58 mm). When we turn the belt inside out (invert it) this length should remain the same due to the steel wire. The rest of the belt however will become compressed/stretched to accommodate the new shape. Thanks to this this handy timing pulley diameter calculator created by droftarts on his parametric pulley page we can see that the pitch line offset for a HTD 5M belt is 0.5715 mm. That is the distance from the pitch diameter to the base of the tooth. This distance will be the same when the belt is inverted and so we now know the distance to the base of the tooth will be:

Diameter for base of tooth for an inverted belt = pitch diameter + 2 * pitch offset

Diameter for base of tooth for an inverted belt = 79.58 + 2 * 0.5715 = 80.723 mm

With that piece of key information we can now model the inverted belt in the same way as you would a normal pulley


One assumption that I made with this belt is that the majority of the flex occurs in the valleys rather than the teeth and so I have modelled the belt accordingly. This involved generating 3.05 mm teeth diameter spaced 7.2 degrees apart with the valley distance increased to make up the gap. For comparison the image below is of a the same belt but not inverted. Notice that the valleys are slightly different in size.

With the inverse belt design its time to move onto the circular spline. The construction of the circular spline is exactly the same as the inverse belt discussed above with the exception that the grooves are concave and facing inwards. For the circular spline I have selected 54 grooves for a gear ration of 12.5:1 (50 / (54 – 50) = 12.5 : 1).


Its clear from the image above that the inner inverted belt (flexible spline) and the outer ring (circular spline) are not touching. This is because the flexible spline has not been deformed by a wave generator.

To determine the correct shape of the wave generator and thus the scaling of our flex spline in two dimensions we can consult this ellipse calculator. I used the base of the teeth for reference of the starting circle and the matching base in the outer ring for the widest diameter after deforming. The spreadsheet just estimates the minor axis of an ellipse that maintains the same area as the starting circle and displays the required scaling for the flexible spline. Once applied to the flexible spline it now meshes with the circular spline.


Moving on to the flex spline cup. This component will need to be attached to the flex spline belt by some means, possibly a flexible glue. The flex spline cup acts to hold the flex spline belt in place and stop it from rotating and thereby allowing it to do usable work to the circular spline. This cup was generated by creating a circle a desired distance below the deformed flex spline belt and then using the loft feature to generate the geometry. Note that you will need to loft a solid body first then create an offset top and bottom to loft cut out the middle.

This cup would be the trickiest thing to make for a DIY construction. If possible, an off the shelf cup (a literal drinking cup) made of stainless steel or similar could work well. Shout-out to the Dexter guys for that idea which they use on their robot arm.

Finally we come to the wave generator. The is the component that is connected to your motor and that deforms the flex spline. Rather than bearings in a cage like the commercial design I have oped for for the easier to construct ball bearing approach.

686ZZ Bearings are attached to a plate by M6 bolts and lock nuts. These bearings are arranged so that they maintain the correct ellipse shape of the spline. The position of the bearings was estimated by just offsetting the inner section of the ellipse by the diameter of the bearings plus the thickness of the flex spline cup wall.

Lastly we need a bearing surface with pre-load to hold the output circular spline. Large 6820 sized bearings could work well that regards but I have yet to include them in the model.


More to come.

Posted in 3D Design | Tagged , , , , , , , , , , | Leave a comment

Full guide to creating a HTD timing pulley in CAD (Fusion 360)

After having some trouble finding a clear guide on how to create the correct tooth profile for a HTD 5M timing pulley  I have decided to create my own. This method will also work for a HTD 3M or 8M pulley, just change the pitch accordingly.


Note: If you want a pulley with a standard number of teeth it is often easier to just modify a CAD file provided by online retailers (ie. Misumi) rather than trying to roll your own.


First a few notes about the HTD tooth profile. The correct profile courtesy of SDP-SI is shown below

HTD 5M Pulley specs

The belt has a 5mm pitch (peak to peak), a tooth height of 2.08 mm, a total belt thickness of 3.81 mm, a the tooth width is 3.05 mm, a radius of 1.49 mm and a valley radius of 0.43 mm. Note that the image below is one of many you will find online that shows an incorrect tooth profile! If you use the dimensions shown below to make the pulley in CAD it looks like that shown by SDP-SI with a flat valley.

A photo of a HTD 5M belt for comparison is shown below.


We now most of the information we need to construct the pulley.

To construct the pulley do the following:

  1. Select the number of grooves for your pulley. In this example we will choose 50 grooves.
  2. Refer to this handy timing pulley diameter calculator created by droftarts on his parametric pulley page on Thingiverse  and find the outside diameter for your selected number of teeth. In this example for 50 teeth thats 78.43 mm. This will be the diameter of the pulley if you were to measure it with a caliper.HTD OD.jpg
  3. In your cad software sketch a circle of this diameter1
  4. Calculate the diameter of your pulley if you were to measure it with a caliper valley to valley by subtracting two times the tooth height of 2.06 mm. For example: 78.43 – 2 * 2.06 = 74.31 mm. Sketch this second circle diameter of 74.31 mm.2.jpg
  5. Using a ‘2-point circle tool’ sketch a 3.05 mm circle at the top of your 74.31 mm diameter circle and fix it in place. This will form the valley of your tooth profile.346
  6. Now for the tooth valley. Create a circle with a radius 0.43 mm (0.86 mm diameter) and using the tangent tool attach its tangent to the outer 78.43 mm circle and the 3.05 mm diameter circle you just created as shown below. This will form your valley radius.5.jpg7.jpg
  7. Zooming back out we now need to sketch the tooth pitch. For our 50 groove pulley we will have a tooth every 7.2 degrees (360 degrees / 50 grooves = 7.2 degrees). Sketch a construction line 7.2 degrees away from your first circle with the origin as your point of rotation. In the example below the angle is measured from the horizontal and so becomes 90 – 7.2 = 82.8 degrees.8.jpg
  8. On this new line repeat steps 5 and 6 so that you have a full tooth profile as shown below.9.jpg
  9. In this second last step we use the centre point arc tool to sketch the inner circles of the pulley profile and finish it off with a single straight line segment be tween the two 0.86 mm dia circles. Note that in order to get the lines to meet exactly you may need to turn off grid snapping using the icon on the bottom of the window.12.jpg10.jpg11.jpg13With this done our pulley profile is now complete.
  10. In our final step we just need to repeat this profile 50 times to form our pulley. Select the lines as shown in the previous image, choose the ‘circular pattern’ tool from the sketch menu (not the create menu!), choose the origin as your point of rotation and set the quantity to your number of grooves which in this case is 50.



And thats it, your done! Now you can go create your own custom pulleys for all sorts of applications such as making custom 3D printed strain wave gears.

You may have noticed that the diameter of pulley valley is 3.05 mm and not the 2.98mm dia specified for the belt. This is ok since there must be some play between the tooth for it to engage properly.

An example of the end result after 3D printing with a 0.4mm nozzle is shown below.


You can find a copy of the CAD file on grabcad here.

Posted in 3D Design | Tagged , , , , , , , , , | 5 Comments

1kW Yaskawa servopack teardown and tuning process

This is a quick tear down of a Yaskawa servopack.

Model: SGDV-120A01A 200V 1kW (2012 Model)

Link to the datasheet here.

You can find the full album of images here.

This model of servopack can be configured either using the built in onscreen display or by using their free software over USB. Below is a screen cap of the configuration process for a 750W servopack.

If anyone happens to stumble  upon this post and your trying to get your motor to rotate make sure to check that the three phase leads to the motor are in the correct configuration. Big thanks to user Tecfacet for that one! This system does not self test at startup like an RC controller and so you must have the phases in the correct order or else the motor will shudder violently and throw a ‘current detection error’. To find the correct order just mark each of the there cables and the the 9 possible configurations or use the following:

U -> Red
V -> White
W -> Black

The motor shown in the video is a SGMJV-08ADC6S 200V 750W 2.39N.m rated. It also came paired with a 7:1 planetary reduction as shown in the video below. With this gearbox you can achieve a staggering 58.5 N.m momentary peak output!

This motor uses a 20 bit encoder giving 1048576 discrete ‘steps’. Below is a photo of the encoder with its dust cover removed.

_1190248.jpgThis level of positional accuracy is hard to fathom so here is some perspective: If you attach a mirror to the rotor and bounce a laser off it onto a wall some 20m away then a 5/1048576 positional change is still only just visible to the human eye at a calculated deviation of 0.12mm. Incredible!JPEG_20180210_174709.jpg

Even more impressive is that this level positional accuracy can be maintained even when I try and disturb the rotor by hand. The image below is from the free Yaskawa software. It is plotting in real time the encoder position. Notice that I am only able to move the rotor a few encoder counts (again, 1048576 per rotation) of its desired position.


Overall I am very impressed with the Yaskawa SGDV servopack series. Yes they are expensive but if you get a good deal second hand they are well worth the money for the right project.

Side note: If you are looking for an opensource motor controller that you can assemble yourself to drive an industrial servo motor like the one shown above then, I highly recommend you take a look at stmbl which is actively developed by Rene Hopf (rene-dev) and Nico Stute (crinq).



Posted in Electric Motors | Tagged , , , , , , | Leave a comment

Stepper motors or a BLDC servo motors? Which is better and when to use them.

Nema23 Stepper motor

Clearpath servo motors

Which is better, a stepper motor or a brushless DC (BLDC) servo motor like these from Teknic (Clearpath)?

The short answer: It depends on your application.

If you only need open-loop position control (no shaft position feedback), are on a tight budget, don’t require high shaft speeds (~600 RPM Max) and can get away with somewhat heavy and bulky motors then stepper motors are for you.

However, if you find you need closed-loop control (shaft position feedback), have more money to spend or need lots of torque in a small light weight package that can also operate at higher speeds then a BLDC servo motor is the way to go.

The slightly longer answer:

Generally speaking, anything you can do with a stepper motor you can also do with servo motor, only better. However this is not true the other way around. So why would you ever use a stepper motor?

  1. Stepper motors are super cheap.

Incredibly, you can now buy a four motor microcontroller+stepper driver kit and four stepper motors for less than $40 USD. The price for a single Clearpath motor starts at $254 and a Mechaduino servo (more later on these) comes in at $63 USD each.

  2. Open-loop stepper motors are much easier to control than a servo motor.

Simply tell a stepper motor how many steps to move and in what direction. Easy. Depending on the control electronics, a servo motors may also be used in a simple step/direction setup. However, to really make use of its performance careful tuning of its PID parameters under both static and dynamic conditions is needed. Granted, good control firmware can just about take care of this for you these days but it is still definitely something to consider if you are changing the loading which the motors are placed under on a regular basis (ie: different sized parts on an an XY table moving at high speeds) or if you ever decided to roll your own electronics and firmware.

3. High precision and high torque can achieved by stepper motors through gearing

Need 0.0375 degree per step output with 2.4 Nm of torque? Simply use x16 micro-stepping on a long body Nema 23 stepper motor with a 3:1 gear GT2 timing belt gear reduction. Even though this setup is more complicated than a single large servo, it is also much much cheaper.

4. Stepper motors can be converted to a servo motor but adding a rotary encoder.

Projects like Mechaduino have made it possible to turn a stepper motor into a servo motor in that you can have positional, velocity and torque control with sub 0.1 degree pointing capability. By knowing the shaft position it is then also possible to run a stepper motor at considerably higher speeds than would otherwise be possible.

So when should you use a dedicated servo motor?

When I say ‘dedicated servo motor’ I mean a servo motor that is designed from the ground up to be a servo motor, and not a modified stepper motor. The key difference being that a dedicated servo motor will generally not have pole plates with teeth (with each tooth acting like its own pole pair) and will generally have a lower winding inductance than a stepper motor of equal size.

You should use a dedicated servo motor when you require a high power density motor with closed loop control.

If you need a powerful motor in a small, lightweight frame that you can also precisely control then a servo motor is really your only option. For example, servo motors are almost exclusively used to drive industrial robotic arms as the amount of power (torque x angular speed = power) you can produce for a given motor size is considerably larger than an equivalent stepper motor.

Lets compare a Nema23 stepper motor from Pololu with a Hudson-series M-2310 Clearpath servo motor. Both motors have roughly the same frame size and yet the stepper is nearly twice the weight of the servo at 1.05 kg vs 0.63 kg while producing around 30 % less holding torque at 1.9 and 2.7 Nm respectively. However the real difference comes from the peak power produced by each type of motor. By using the torque torque curves from the stepper motor data sheet and assuming a simple linear reduction in torque for the servo motor to around 6000 RPM, 2000 RPM higher than its listed maximum speed of 4000 RPM  (I could not find a torque curve for Clearpath motors) we can compare the peak power produced by each motor.

Now we see that the output power of the servo is around three times that of the stepper motor with a maximum of ~350 W vs  the stepper motors ~120 W. The difference is even greater still when you consider that the open-loop stepper motors are rarely run at speeds greater than a few hundred RPM.

ServoVsStepper output poweV2r.jpg

This difference in output power is  due to the high number of poles (200 for 1.8 degree per step) found in a stepper motor that are needed o achieve its fine position control. This high number of pole pairs comes at the expense of maximum rotational speed and torque, greatly limiting the available power the motor can produce. Servo motors on the other hand are fundamentally no different to a BLDC motor.

The next step: Converting cheap and extremely powerful ‘hobby’ BLDC motors into servo motors with Odrive

Up until this point I have only discussed the Clearpath range of servo motors. However, they may soon be a considerably cheaper and yet more powerful alternative available thanks to Oskar Weigl‘s and his alpha release of a BLDC motor controller called  Odrive.

Odrive Robotics BLDC Servo Controller


The ODrive motor controller (currently in alpha) is a motor controller designed from the ground up to turn cheap BLDC motors used by RC hobbyists into powerful servo motors by coupling them with equally cheap (~8USD) rotary encoders.

Each ODrive controller board is capable of controlling two motors which are often smaller and lighter than a nema23 stepper motor but can be capable of producing many time the power and torque of even a clearpath servo motors. This is possible because these motors have been designed to be as powerful as possible at the expense of durability and efficiency. So while these motors are not suitable for industrial environments they could be of real interest to the DIY community.

The Odrive controller also has some interesting features such as the ability for regenerative-breaking. This is incredibly useful even outside of transportation applications as it makes it easy to safely remove unwanted power from your system during rapid deceleration without running it backwards through your power-supply, potentially damaging it. The Odrive is also designed to be powered in tandem with a hobby-grade Lithium polymer battery. This is also very important in order to achieve the full capabilities of these BLDC motors, which can have peak power draws in the multi-kW range. By using a high discharge Lipoly batter as a temporary energy store it becomes possible to draw the full 2 kW needed during rapid accelerations while still powering the whole system off a modest power supply.

However there are also drawbacks to adopting Odrive for your projects at this time (July 2017). Namely:

  • Features like step/direction commands are still in active development and so this system can not currently be used as a drop in replacement for your existing CNC controller like you can potentially do with Clearpath’s motors.
  • Intermittent, small volume production runs of the alpha boards translates to a high unit cost of around $100 USD for a board that can control two motors.
  • Limited documentation and discussion of how to get started makes this a project more suited to those users with prior experience in tinkering with firmware development.
  • A relatively small development community with Oskar himself doing, as far as I can tell, nearly all of the hardware and software development simultaneously means a slow release schedule is to be expected.

Still, if Odrive can successfully mature into an easy to use drop in replacement for stepper motors then there may finally be an affordable servomotor available for hobbyists that is also many time more powerful than a Clearpath servo.

I have obtained an alpha Odrive board and a few different BLDC motors to try with it and will be posting about my  findings in the next post.

Posted in Mendel Build | Tagged , , , , , , | 1 Comment

Modifying Marlin Firmware to work with a TandemB

In previous posts I built a prototype ‘TandemB’  which can be thought of as a 2D Delta printer in terms of its x and y-axis movement. This prototype could be moved about under its own power but that had no compatible firmware to drive it. In this post I cover the firmware modifications required to make the Tandem move using normal g-code commands. You can find a copy of this modified firmware here.

Modifying Marlin

Note: If you are considering doing any major modifications to firmware beyond just editing the config files I highly recommend exploring options other than the standard arduino code editor. I have been using the free community edition Visual Studio 2013 to view, modify and upload the firmware and it is a big improvement. Visual studio actively monitors the #define statements and then greys out any code that is not defined. ie: definitions that have been commented out. This makes skimming through the code much quicker as around 80% of what’s there is not in use for any one setup and so is greyed out. The tabs are also much easier to view, search and organise and I find the the compiling errors are simpler to find and diagnose. If you would like to use VS then you will also need VisualMicro for arduino support.

Marlin firmware was modified to work with my Tandem setup due to its compartmentalised nature and the fact that Craig Bossard had already started to make the very changes I needed. Craig would like to use scavenged flatbed scanner parts to build a 3D printer in the same manner as the Tandem and so had already been modifying Marlin to this end before I even started working on the Tandem idea. So thanks Craig for sending me a copy of you modified Marlin as it gave me a great starting point!

Craig’s idea was that rather than  re-writing a lot of code it would be far simpler to modify the existing Delta reverse kinematics. The required changes all take place in marlin.main.cpp.

The original Delta kinematic equations from marlin.main are shown below:

void recalc_delta_settings(float radius, float diagonal_rod)
delta_tower1_x= -SIN_60*radius; // front left tower
delta_tower1_y= -COS_60*radius;
delta_tower2_x= SIN_60*radius; // front right tower
delta_tower2_y= -COS_60*radius;
delta_tower3_x= 0.0; // back middle tower
delta_tower3_y= radius;
delta_diagonal_rod_2= sq(diagonal_rod);

void calculate_delta(float cartesian[3])
delta[X_AXIS] = sqrt(delta_diagonal_rod_2
– sq(delta_tower1_x-cartesian[X_AXIS])
– sq(delta_tower1_y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS];
delta[Y_AXIS] = sqrt(delta_diagonal_rod_2
– sq(delta_tower2_x-cartesian[X_AXIS])
– sq(delta_tower2_y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS];
delta[Z_AXIS] = sqrt(delta_diagonal_rod_2
– sq(delta_tower3_x-cartesian[X_AXIS])
– sq(delta_tower3_y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS];

This code works off the delta tower definitions which is also located in marlin.main.cpp and is shown below:

#ifdef DELTA
float delta[3] = { 0, 0, 0 };
#define SIN_60 0.8660254037844386
#define COS_60 0.5
// these are the default values, can be overriden with M665
float delta_radius = DELTA_RADIUS;
float delta_tower1_x = -SIN_60 * delta_radius; // front left tower
float delta_tower1_y = -COS_60 * delta_radius;
float delta_tower2_x = SIN_60 * delta_radius; // front right tower
float delta_tower2_y = -COS_60 * delta_radius;
float delta_tower3_x = 0; // back middle tower
float delta_tower3_y = delta_radius;
float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;

Using the code above as a basis I constructed an excel spreadsheet that modeled the delta kinematics (copy here) so as to allow me to make changes to the equations and see the results in real time. Note that excel does not allow you to plot an xyz three dimensional scatter plot and so if you want to visualise the results you will need to use a third party program such as Origin Pro.

By removing one tower completely, and then redefining the z-axis to behave as the y-axis the changes were complete. A spreadsheet that models the tandem kinematics and plots the required carriage position can be found here.

The new kinematic equations in marlin for the tandem setup are shown below:

void recalc_delta_settings(float radius, float diagonal_rod)
delta_tower1_x = -radius; // front left tower
delta_tower2_x = radius; // front right tower
delta_diagonal_rod_2 = sq(diagonal_rod);

void calculate_delta(float cartesian[2])
delta[X_AXIS] = (sqrt(delta_diagonal_rod_2 – sq(delta_tower1_x – cartesian[X_AXIS])) + cartesian[Y_AXIS]);
delta[Y_AXIS] = sqrt(delta_diagonal_rod_2 – sq(delta_tower2_x – cartesian[X_AXIS])) + cartesian[Y_AXIS];
delta[Z_AXIS] = cartesian[Z_AXIS];

and the new tower definitions:

#ifdef DELTA
float delta[3] = { 0, 0, 0 };
#define SIN_60 0.8660254037844386
#define COS_60 0.5
// these are the default values, can be overriden with M665
float delta_radius = DELTA_RADIUS;
float delta_tower1_x = -delta_radius; // front left tower
float delta_tower2_x = delta_radius; // front right tower
float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;

For now I have left the homing code unchanged as it seems to be working fine. The only other changes were to configuration.h. Here the normal delta definitions are as follows:

// Center-to-center distance of the holes in the diagonal push rods.
#define DELTA_DIAGONAL_ROD 175.0 // mm

// Horizontal offset from middle of printer to smooth rod center. Adjust this to calibrate x-axis distance for tandem setup.
#define DELTA_SMOOTH_ROD_OFFSET 118.0 // mm

// Horizontal offset of the universal joints on the end effector.
#define DELTA_EFFECTOR_OFFSET 0.0 // mm

// Horizontal offset of the universal joints on the carriages.
#define DELTA_CARRIAGE_OFFSET 0.0 // mm

As there is no effector or carriage offset both of these values were set to zero. The DELTA_DIAGONAL_ROD distance was set to the length of the arms (175.0mm) and the DELTA_SMOOTH_ROD_OFFSET was originally set to half half the distance separating the smooth rods, just as you would in a normal delta. The result of these setting is shown below where an upscaled 40mm cube print is being dry run with a pen acting as a pen plotter.


Its clear that the cube outline is neither symmetrical or square.

In a norma Delta configuration each carriage has two parallel arms connecting it to the end effector in such a way that the resulting  parallelogram prevents the tool head from moving in any direction other than parallel to the print surface. For the TandemB setup only two arms in total are used and therefore no such parallelogram exists. It is because of this, and the fact the tool head is not directly positioned where the centre pivot is located, that we are seeing this curvature. The solution turned out to be as simple as adjusting the DELTA_SMOOTH_ROD_OFFSET from 118.0 down to 89.5 which was determined by trial and error but is something that should also be derivable mathematically. After this adjustment I can now trace cubes that are almost square.


Hopefully some fine tuning of the carriage homing positions and the tool head location is all thats now needed to make it perfect.

In the video below you can again see an upscaled ’40mm’ cube that has been stretched so as to fill the available build area and had the first layers removed so that the infill is now being drawn first.

Its far from perfect, but its a good start.

As expected, there is quite a lot of play in the z-axis (vertical) direction during rapid direction changes. This is not a problem when using a pen, as the pen acts to support itself as it pushes against the surface its drawing on. However, it will be a massive problem for a 3d printer and so needs to be addressed. I have a few ideas of how to solve this problem without reverting to the potentially much slower ‘TandemC’ design shown here and these ideas may even remove the need for any smooth rods in the whole design. More to come soon.

Posted in Tandem | Tagged , , , , , , , , , | 4 Comments