This notebook and associated python functions are meant to be first order tools for the design and analysis of helical springs.
The first Section introduces the governing equations which model ideal helical spring behavior as a function of its geometrical and material properties.
The second section calculates the spring properties of an example spring on the Efunda website as a test of the implementation used here.
The third section works through an example spring design given a set of design requirements.
The spring constant of a helical spring may be calculated: $$ k = \frac{Gd^4}{8n_aD^3} $$ Where $G$ is the shear modulus, $d$ is the diameter of the wire, $n_a$ is the number of coils active in the spring, and $D$ is the mean diameter of the coil. (The figure above has 6 active coils.)
The shear modulus is a property of the material. $$ G = \frac{E}{2(1+v)} $$ Where $E$ is Young's modulus of the material and $v$ is Poisson's ratio.
The pitch of the coil is then: $$ p = \frac{L_{free}}{n_a} $$ Where $L_{free}$ is the free length of the spring.
and the coil angle is then: $$ \alpha = tan^{-1}\frac{p}{\pi D} $$
The spring index is the ratio of mean spring diameter to wire diameter $$ C=\frac{D}{d} $$ If the spring index is small, that means that the wire diameter is large compared to the overall spring diameter and the curvatures of the spring wire are very high. This requires high stresses in the material and on the tooling used to create the tooling. As a rule of thumb, spring indexes smaller than about 4-5 are hard to manufacture.
If the spring index is too large, then the wire diameter is quite small compared to the spring diameter and the spring does not have a great deal of mechanical integrity on its own. Springs with indexes above about 15 tend to yield higher variability and are difficult to manufacture precisely.
Spring indexes between 6-12 are considered ideal and 13-15 generally doable.
These equations assume that the material stress-strain relationship is linear and elastic. For this to be true the spring must operate at stresses bellow the yield stress, especially for large numbers of cycles. A good design rule of thumb is that the shear stresses should be no more than 30% to 50% of the ultimate stress of the material.
The shear stresses may be calculated by first considering the maximum axial force on the spring: $$ F_{max} = k(L_{free} - L_{solid}) $$ The free length is often given, and the solid length can be found by multiplying the wire wire thickness by the number of coils. $$ L_{solid} = d(n_a+2) $$ The solid length can be though of the length of the spring when is is fully compressed. The maximum shear is then: $$ \tau_{max}=F_{max}\frac{8DW}{\pi d^3} $$ Where $W$ is the Wahl correction factor (a geometric correction factor taking into account the curvature of the coils): $$ W = \frac{4C-1}{4C-4} + \frac{0.615}{C} $$
The implementation will be tested by comparing results to the Efunda example here.
In [1]:
from springs import Material, Spring
import units as u
steel = Material(Material.STEEL)
d_mean = (0.500-0.035)*u.inch
d_wire = 0.035*u.inch
L_free = 1*u.inch
n_coils = 8
efunda = Spring(d_mean, d_wire, L_free, n_coils, steel)
efunda.print_properties('En', 'efunda')
These numbers match the efunda calculator reference within displayed precision.
Here we can see that the spring has a spring constant $k$=2.6 lb/in and a spring index $C$=13.3 which is toward the upper end of desirable.
The shear stress in the wire is maximally 51 ksi which is less than 30% of ~250 ksi, a typical yield stress for drawn music wire in this diameter range.
In [2]:
d_mean = (0.5-0.035)*u.inch
n_coils = 8
k = 2.6*u.lbf/u.inch
d_wire = Spring.solve_diameter(d_mean, n_coils, k, steel)
print 'The recommended spring diameter is: %.3f in (efunda)' % \
(d_wire / u.inch)
The wire diameter calculator correctly returned $d$=0.035 in, the value we input in the forward equation above.
The process of homing in on a spring design is often iterative. Given these requirements:
Pick a spring that is easy to manufacture and reliable over its life.
As a starting point, we can solve for the desired spring rate:
In [3]:
F_pre = 2*u.lbf
F_max = 4*u.lbf
travel = 1*u.inch
k = (F_max - F_pre) / (travel)
print 'The desired spring rate is %.1f lbf/in \n' % (k / u.lbf * u.inch)
As starting points, lets guess .375in for the mean diameter and 8 coils per inch as in the above example.
We also know we want a 2 lb preload on the spring and 1 inch of travel at a spring rate of 2 lbf/in. Since the so the spring must be longer than 2 inches minimum to account for spring wire thickness, lets pick 3 in in as a starting guess.
In [4]:
steel = Material(Material.STEEL)
d_mean = (0.375)*u.inch
L = F_max / k + 1*u.inch
pitch = 8 / u.inch #coils per inch
n_coils = L*pitch
d_wire = Spring.solve_diameter(d_mean, n_coils, k, steel)
s = Spring(d_mean, d_wire, L, n_coils, steel)
s.print_properties('En','Custom Spring')
On the first iteration we see that quite a few assumptions are marginal. Lets first start with the understanding that the wire diameter will be in the neighborhood of .037 in and the inside diameter too small. Lets bump the mean diameter by 0.045 and see where we come out
In [5]:
steel = Material(Material.STEEL)
d_mean = (0.375 + 0.045)*u.inch
L = F_max / k + 1*u.inch
pitch = 8 / u.inch #coils per inch
n_coils = L*pitch
d_wire = Spring.solve_diameter(d_mean, n_coils, k, steel)
s = Spring(d_mean, d_wire, L, n_coils, steel)
s.print_properties('En','Custom Spring')
The inside diameter is now as desired plus a little clearance. Next on the list we see that the total spring travel is less than 2 in, and that the max force is less than our 4lb requirements. To accommodate for this, increase the free length to 4 in.
In [6]:
steel = Material(Material.STEEL)
d_mean = (0.375 + 0.045)*u.inch
L = F_max / k + 2*u.inch
pitch = 8 / u.inch #coils per inch
n_coils = L*pitch
d_wire = Spring.solve_diameter(d_mean, n_coils, k, steel)
s = Spring(d_mean, d_wire, L, n_coils, steel)
s.print_properties('En','Custom Spring')
On this final spring the diameters, travel, and max force all look good. The spring index is in a good range and the maximum shear stress is ~30% of the yield stress of music wire in this range.
In [6]:
In [7]:
from IPython.display import HTML
from ipynb_utils import inject_css, toggle_js, inject_css2
HTML(inject_css2('custom.css'))
Out[7]:
In [7]: