Maslow Home Maslow Community Garden

Chain Length Calculations


The following information is based upon an old message from @rjon17469. I’ve interpretted what he described and believe I have it accurate. Please, if there are mistakes/errors, edit it or post a comment regardinging it.

Components that Make Up the Chain Length Calculation

Maslow has only one mechanism to move the sled to where it needs to go and that is by extending or shortening the chain length between the sled and the two motors. Everything reduces down to determining how long each chain needs to be to perform a certain operation. The current software (as of 8/21/18) currently performs the following to determine the chain length:

  1. Calculate the straight distance between the center of the motor and the center of the router bit based upon the coordinates of the motor and the target coordinates (Motor1Distance)
  2. Calculate the amount of chain, starting from the 12 o’clock position, that wraps around the sprocket based upon the coordinates of the motor and the the target coordinates (Chain1AroundSprocket)
  3. Calculate the straight chain length from the point the chain leaves the sprocket to the center of the router bit (Chain1Straight)
  4. Increase the straight chain length to account for chain sag.
  5. Sum the straight chain length and amount of chain wrapped around sprocket and subtract the rotational radius of the ring/linkage kit (Chain1)

Note 1: The above and below generally references only the left chain (Chain1). So where you see Motor1Distance, that’s the distance from the left motor to the center of the router bit. Unsurprisingly, Motor2Distance is the distance from the right motor to the center of the router bit, etc. Got it? Good.

Note 2: The below is based upon a chain-over-top feed configuration where the chain slack drops vertically toward the floor (original design). The chain-off-bottom feed configuration, where the chain slack runs horizontal along the top beam, is only different in calculation of the amount of chain that wraps around the sprocket… the formulas are very similar between the two. Chain-off-bottom feed might get detailed at some time in the future.



The software knows (based upon calibration and other values) the x,y location of the center of the motor sprocket and, from the gcode for the desired move, the x,y location of the target. With this, Motor1Distance is easily calculated:

float Motor1Distance = sqrt(pow((-1*_xCordOfMotor - xTarget),2)+pow((_yCordOfMotor - yTarget),2));


To calculate the amount of chain that wraps around the sprocket, two individual steps are taken.

a = the angle from the target to the center of the motor sprocket.
b = the additional angle based upon the radius of the sprocket

These two angles are shown in the diagram above and are calculated as follows:

a = asin((_yCordOfMotor - yTarget)/Motor1Distance)
b = asin((RleftChainTolerance/Motor1Distance)

Currently (8/21/18), the software calculates RleftChainTolerance (“r” in the diagram) as the chain pitch * number of teeth / (2*pi) and then adjusts it to account for chain wear compensation factors. It is believed that ‘r’ should be the true pitch diameter of the sprocket and should be chain pitch / sin(180/number of teeth). Because the chain is meshed with the sprocket, there should be no adjustment made for chain wear. A proposed change to the code is forthcoming.

Once a and b are calculated, the amount of chain that wraps around the sprocket is calculated as:

Chain1Angle = a + b
Chain1AroundSprocket = RleftChainTolerance * (Chain1Angle)

As above, RleftChainTolerance is subject to a forthcoming code revision.


Knowing the the chain comes off the sprocket at a right angle, it is easy to calculate the length of chain from where it comes off the sprocket to the center of the router bit using Pythagorean’s Theorem:

Chain1Straight = sqrt ( pow(Motor1Distance,2) - pow(RleftChainTolerance,2) )

As mentioned earlier, RleftChainTolerance is subject to a forthcoming code revision

Increase Chain1Straight to Account for Chain Sag

I have no idea how this formula works, but the chainSagCorrection value that is calculated during calibration is multiplied by some glob of sines and cosines to figure out how much to increase Chain1Straight. If someone understands this math, feel free to edit the post:

Chain1Straight *= (1 + ((sysSettings.chainSagCorrection / 1000000000000) * pow(cos(Chain1Angle),2) * pow(Chain1Straight,2) * pow((tan(Chain2Angle) * cos(Chain1Angle)) + sin(Chain1Angle),2)));


So, at the end, Chain1 is calculated simply as the sum of Chain1Straight and Chain1AroundSprocket and then , because the sorftware has calculated all of this to the center of the router bit, the rotational radius (distance from center of router bit to the end of the chain) is subtracted out to arrive at the target chain length:

Chain1 = Chain1AroundSprocket + Chain1Straight;
Chain1 = Chain1 - rotationalDiskRadius;

Chain-Over-Top vs. Chain-Off_Bottom

The following is a comparison of the formulas used between the two. Need a diagram to explain better:


Chain1Angle = asin((_yCordOfMotor-yTarget)/Motor1Distance)+asin(RleftChainTolerance/Motor1Distance)
Chain1AroundSprocket = RleftChainTolerance * Chain1Angle;


Chain1Angle = asin((_yCordOfMotor-yTarget)/Motor1Distance)-asin(RleftChainTolerance/Motor1Distance)
Chain1AroundSprocket = RleftChainTolerance * (3.14159 - Chain1Angle);

Thoughts on the Software
Discussion Regarding Triangular Calibration
Table of Contents


Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque congue elementum dui, porttitor iaculis risus vestibulum sed. Aenean viverra finibus turpis in luctus. Morbi elementum nulla at dui ultricies blandit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi tincidunt lacinia augue. Integer a augue pretium, tristique dolor nec, dapibus leo. Donec enim enim, volutpat at malesuada quis, pharetra dignissim neque. Vestibulum tristique lobortis nunc. Morbi id magna vel metus dignissim egestas. Duis in arcu sed dui aliquet dignissim. Ut convallis justo sit amet dignissim finibus. Curabitur sagittis aliquet felis. Proin non ex lorem.



Vestibulum sollicitudin odio sed odio sagittis consectetur. Proin maximus magna id ex rhoncus aliquam vitae id ante. Donec odio libero, consequat a ipsum vel, dignissim aliquam ex. Phasellus viverra auctor augue et porttitor. Proin cursus tristique odio vel bibendum. Vivamus sollicitudin massa ac pellentesque euismod. Suspendisse luctus dolor leo, et semper dui facilisis vel.



Aliquam erat volutpat. Ut sapien est, lobortis ac aliquam id, vehicula dignissim magna. Etiam lectus nisl, malesuada eu pulvinar in, malesuada non metus. Cras luctus dolor sit amet enim vehicula pellentesque. Integer odio ligula, eleifend ut egestas sit amet, faucibus id elit. Suspendisse lobortis sapien augue, nec rutrum dui facilisis id. Phasellus pharetra, sem nec sodales condimentum, diam sapien porta turpis, vel ullamcorper metus lacus non nulla. Phasellus consequat mi nec imperdiet tempor.



Fusce nunc lectus, vestibulum id interdum at, mattis id erat. Sed gravida suscipit facilisis. Sed diam sem, fermentum eget ex ac, cursus placerat tellus. Cras rhoncus mauris ligula, nec blandit est pellentesque in. Cras non nulla eu magna viverra mollis et ut enim. Etiam a magna et nunc mollis consequat. Donec pretium, ante at gravida elementum, nibh ipsum faucibus est, id lacinia lectus tellus ac dui. Integer fringilla libero ut mauris fermentum sollicitudin.



Donec arcu nulla, viverra ut sagittis pellentesque, imperdiet sed ipsum. Etiam sed auctor nulla. Curabitur vel dictum ex, quis consectetur lacus. Aliquam congue felis at justo consectetur maximus. Donec dapibus nisl eros, id auctor eros posuere ac. Vestibulum sagittis consequat facilisis. Vestibulum eu odio nulla. Vivamus euismod tristique tempus. Aliquam ex mauris, vulputate sed tempor id, faucibus sed nulla. Nullam non scelerisque ligula. Morbi maximus risus pretium dui malesuada viverra.


Fantastic explanation. Does it take into account the different over and under chain mount methods.

Thanks, Ed


The explanation doesn’t take it into account, but the code does… It’s just a couple different steps. It was enough of a pain enough to wrap my head around over top so I wanted to just get through that. I’ll put a disclaimer in the post.

Accuracy Issues and Calibration Overview

I’m pretty sure this is wrong. Everywhere else, the angles are in radians, while this calculation is based on them being in degrees.

There is another issue that you don’t get at here (that I believe is buried in the forumulas somewhere), is that it’s not only the chain length that shifts, but it’s also the x,y point at which the chain leaves the sprocket and becomes a ‘straight’ line. IIRC (from when I looked at this over a year ago), there was some trickery based on how radians are defined


I’m confused… both python and c++ calculates sin, cos and tan from radian and that’s the only functions that uses the angles.


What I presented is the code that’s used for the calculations. If some calculation is missing, then it was either never there or was removed by someone. I’m just trying to document what’s there now.