Skip to content

Commit

Permalink
Add inline belt calculator (#393)
Browse files Browse the repository at this point in the history
  • Loading branch information
abidingabi authored Sep 18, 2023
1 parent cc9ec6a commit 95dd484
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 25 deletions.
29 changes: 29 additions & 0 deletions source/_static/calculator-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function prettifyFloat(float) {
return float.toFixed(2);
}

function writeText(id, content) {
if (isNaN(content)) {
content = "Invalid!";
}

document.getElementById(id).innerText = content;
}

function getValue(id) {
const value = parseFloat(document.getElementById(id).value);

if (isNaN(value)) {
throw new Error("Value must be a number!");
}

if (value <= 0) {
throw new Error("Value must be positive!");
}

if (value >= 1e6) {
throw new Error("Value must be reasonably small! (Less than 1e6.)");
}

return value;
}
148 changes: 148 additions & 0 deletions source/docs/common-mechanisms/power-transmission/belt-calculator.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<!--UI-->
<label for="belt-pitch">Belt Pitch:</label>
<select onchange="updateBeltCalculator()" name="belt-pitch" id="belt-pitch">
<option value="5" selected>5 mm (HTD)</option>
<option value="3">3 mm (HTD)</option>
<option value="3">3 mm (GT2)</option>
<option value="2">2 mm (GT2)</option>
<option value="6.35">1/4" (RT25)</option>
</select>
<hr>

<label for="pulley-a">Pulley A Teeth:</label>
<input oninput="updateBeltCalculator()" type="number" id="pulley-a" name="pulley-a" min=1 max=1000 value=48>
<br>
Pulley A Pitch Diameter (mm): <span id="pulley-a-pd"></span>
<hr>

<label for="pulley-b">Pulley B Teeth:</label>
<input oninput="updateBeltCalculator()" type="number" id="pulley-b" name="pulley-b" min=1 max=1000 value=24>
<br>
Pulley B Pitch Diameter (mm): <span id="pulley-b-pd"></span>
<hr>

<label for="c2c">Desired Center Distance (mm):</label>
<input oninput="updateBeltCalculator()" type="number" id="c2c" name="pulley-a" min=1 max=10000 value=100>
<br>
Ratio: <span id="ratio"></span>
<hr>

<label for="belt-options">Belt Options:</label>
<table id="belt-options">
<tr>
<th>Tooth Count</th>
<th>C2C (mm)</th>
<th>Length (mm)</th>
</tr>
</table>

<template id="belt-option">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
<!--End UI-->

<style>
#belt-options {
table-layout: fixed;
width: 100%;
text-align: center;
}

.closest-belt {
font-weight: bold;
}

table, th, td {
border: 1px solid black;
border-collapse: collapse;
}

/* Remove arrows for numeric inputs. */
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
</style>

<script src="../../../_static/calculator-utils.js"></script>
<script>
function pitchDiameter(teeth, pitch) {
return teeth*pitch/Math.PI;
}

// https://www.sdp-si.com/Belt-Drive/Designing-a-miniature-belt-drive.pdf
// Engineering Formulas Table 1, No. 1
function centerDistance(pitchDiameterA, pitchDiameterB, pitch, toothCount) {
const pl = toothCount * pitch;
const D = Math.max(pitchDiameterA, pitchDiameterB);
const d = Math.min(pitchDiameterA, pitchDiameterB);

const b = 2 * pl - (Math.PI * (D + d));
return (b + Math.sqrt(Math.pow(b, 2)-(8*Math.pow(D-d, 2)))) / 8;
}

// Engineering Formulas Table 1, No. 3
function beltPitchLength(pitchDiameterA, pitchDiameterB, pitch, c2c) {
const D = Math.max(pitchDiameterA, pitchDiameterB);
const d = Math.min(pitchDiameterA, pitchDiameterB);

return 2 * c2c + Math.PI / 2 * (D+d) + Math.pow(D-d, 2)/(4*c2c);
}

function updateBeltCalculator() {
const pitch = getValue("belt-pitch");
const teethA = getValue("pulley-a");
const teethB = getValue("pulley-b");
const c2c = getValue("c2c");

const pdA = pitchDiameter(teethA, pitch);
const pdB = pitchDiameter(teethB, pitch);

const idealBeltTeeth = beltPitchLength(pdA, pdB, pitch, c2c) / pitch;

writeText("pulley-a-pd", prettifyFloat(pdA));
writeText("pulley-b-pd", prettifyFloat(pdB));

writeText("ratio", prettifyFloat(teethA/teethB));

// in each direction, above and below the closest ones
const numberOfBeltsToShow = 3;
const minBeltTeeth = Math.floor(idealBeltTeeth) - numberOfBeltsToShow;
const maxBeltTeeth = Math.ceil(idealBeltTeeth) + numberOfBeltsToShow;

const beltOptions = document.getElementById("belt-options");

// remove existing non-header rows
beltOptions.querySelectorAll("tr").forEach(
(tr, i) => { if (i != 0) { tr.remove() } });

const beltOptionTemplate = document.getElementById("belt-option");
for (let teeth = minBeltTeeth; teeth <= maxBeltTeeth; teeth++) {
const beltOption = beltOptionTemplate.content.cloneNode(true);
let tds = beltOption.querySelectorAll("td");

if (teeth == Math.floor(idealBeltTeeth)
|| teeth == Math.ceil(idealBeltTeeth)) {
tds.forEach((td) => td.classList.add("closest-belt"))
}

tds[0].textContent = teeth;
tds[1].textContent = prettifyFloat(centerDistance(pdA, pdB, pitch, teeth));
tds[2].textContent = prettifyFloat(teeth * pitch);

beltOptions.appendChild(beltOption);
}
}

updateBeltCalculator();
</script>
36 changes: 11 additions & 25 deletions source/docs/common-mechanisms/power-transmission/belt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,24 @@ Like chain, belt is identified by its :term:`pitch <Pitch>` - common pitches fou
When using timing belts, correct tension is very important. There are two main ways to get your tension right. The first is easy - goBILDA and Actobotics already have belts integrated into their hole patterns. You can buy correctly sized belt directly from each vendor, and your tension will be perfect as soon as the belt is installed. As your designs gain complexity, so will your belt runs - maybe there are more than 2 pulleys, and maybe your pulleys are all different sizes. To compensate for this, the second way to ensure tension is to use a dynamic tensioner, similar to those found in complex chain runs. To design for these tensioners, we recommend planning more complex belt runs in CAD before building them in real life.


Center-to-Center calculations
-----------------------------
Belt Calculator
---------------

Just like chain, the actual calculations for precise :term:`C2C` distances for belts are complicated. Here is a `calculator <https://www.engineersedge.com/calculators/Pulley_Center_Distance/toothed_pulley_center_distance_calculator_12900.htm>`_ or `two <https://sudenga.com/resources/figuring-belt-lengths-and-distance-between-pulleys/>`_ that simplifies the work.
The actual calculations to determine which belt to use to get close to a given center-to-center (:term:`C2C`) distance are complicated. Below is a calculator to help out:

.. math::
.. card::

C=\frac{P}{8}*(2L-(N+n)+\sqrt{(2L-(N+n))^2-\frac{8}{\pi^2}*(N-n)^2})
Belt Calculator
^^^

L=\frac{2C}{P}+\frac{N+n}{2}+\frac{P(\frac{N-n}{2\pi})^2}{C}
.. only:: latex

- :math:`C=` center-to-center distance, inches
The web version of gm0 has a belt calculator available here.

- :math:`L=` belt length in pitches
.. raw:: html
:file: belt-calculator.html

- :math:`P=` pitch of belt

- :math:`N=` number of teeth in large pulley

- :math:`n=` number of teeth in small pulley

.. math:: C=\frac{L-\frac{\pi}{2}(D+d)}{4}+\sqrt{[(\frac{L-\frac{\pi}{2}(D+d)}{4})^2-\frac{(D-d)^2}{8}}

- :math:`D=` chosen diameter of large pulley

- :math:`d=` chosen diameter of small pulley

- :math:`L=` length of belt

- :math:`C=` center distance

- (all units must be the same)
SDP-SI has a `more advanced calculator <https://sdp-si.com/tools/center-distance-designer.php>`_, as does `ReCalc <https://www.reca.lc/belts>`_. The equations for calculating these values by hand can be found in `SDP-SI's Designing a Miniature Belt and Pulley Drive System Design Guide <https://www.sdp-si.com/Belt-Drive/Designing-a-miniature-belt-drive.pdf>`_.

Belt Wrap
---------
Expand Down

0 comments on commit 95dd484

Please sign in to comment.