add sp400 etc caps

This commit is contained in:
Adrian Mariano 2022-10-15 22:28:15 -04:00
parent d003a96d23
commit 48292d9e8f
2 changed files with 124 additions and 53 deletions

View file

@ -978,6 +978,11 @@ function bottle_adapter_neck_to_neck(
// Thread specs from https://www.isbt.com/threadspecs-downloads.asp
// T = peak to peak diameter (outer diameter)
// I = Inner diameter
// S = space above top thread
// H = total height of neck
_sp_specs = [
[400, //diam T I H S tpi
[[ 18, [ 17.68, 8.26, 9.42, 0.94, 8]],
@ -1042,7 +1047,7 @@ _sp_thread_width= [
];
function _sp_thread_profile(tpi, a, S, style) =
function _sp_thread_profile(tpi, a, S, style, flip=false) =
let(
pitch = 1/tpi*INCH,
cL = a*(1-1/sqrt(3)),
@ -1052,7 +1057,7 @@ function _sp_thread_profile(tpi, a, S, style) =
: style=="M" && tpi < 12 ? [0.25, 0.25, 0.75, 0.75]
: style=="L" ? [0.38, 0.13, 0.13, 0.38]
: /* style=="M" */ [0.25, 0.25, 0.2, 0.5],
path = style=="L"
path1 = style=="L"
? round_corners([[-1/2*pitch,-a/2],
[-a/2,-a/2],
[-cL/2,0],
@ -1065,10 +1070,11 @@ function _sp_thread_profile(tpi, a, S, style) =
[-cM, 0],
[0,0],
[a/2,-a/2],
[1/2*pitch,-a/2]], radius=roundings, closed=false, $fn=24)
[1/2*pitch,-a/2]], radius=roundings, closed=false, $fn=24),
path2 = flip ? reverse(xflip(path1)) : path1
)
// Shift so that the profile is S mm from the right end to create proper length S top gap
select(right(-a/2+1/2-S,p=path),1,-2)/pitch;
select(right(-a/2+1/2-S,p=path2),1,-2)/pitch;
function sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient) = no_function("sp_neck");
@ -1132,7 +1138,89 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
}
children();
}
}
}
// Module: sp_cap()
// Usage:
// sp_neck(cap, type, wall, [style=], [top_adj=]) [ATTACHMENTS];
// Description:
// Make a SPI (Society of Plastics Industry) threaded bottle neck. You must
// supply the nominal outer diameter of the threads and the thread type, one of
// 400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410
// neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread.
// You can also choose between the L style thread, which is symmetric and
// the M style thread, which is an asymmetric buttress thread. Note that it
// is OK to mix styles, so you can put an L-style cap onto an M-style neck.
// .
// These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick.
// If you don't include this, your cap may bottom out on the bead on the neck instead of sealing
// against the top. If you set top_adj to 1 it will make the top space 1mm smaller so that the
// cap will not bottom out. The 410 and 415 caps have very long unthreaded sections at the bottom.
// The bot_adj parameter specifies am amount to reduce that bottom extension. Be careful that
// you don't shrink past the threads.
// .
// Note: there is a published SPI standard for necks, but absolutely nothing for caps. This
// cap module was designed based on the neck standard to mate reasonably well, but if you
// find ways that it does the wrong thing, file a report.
// Arguments:
// diam = nominal outer diameter of threads
// type = thread type, one of 400, 410 and 415
// wall = wall thickness
// ---
// style = Either "L" or "M" to specify the thread style. Default: "L"
// top_adj = Amount to reduce top space in the cap, which means it doesn't screw down as far. Default: 0
// bot_adj = Amount to reduce extension of cap at the bottom, which also means it doesn't screw down as far. Default: 0
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Examples:
// sp_cap(48,400,2);
// sp_cap(22,410,2);
// sp_cap(28,415,1.5,style="M");
module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, anchor, spin, orient)
{
table = struct_val(_sp_specs,type);
dum1=assert(is_def(table),"Unknown SP closure type. Type must be one of 400, 410, or 415");
entry = struct_val(table, diam);
dum2=assert(is_def(entry), str("Unknown closure nominal diameter. Allowed diameters for SP",type,": ",struct_keys(table)))
assert(style=="L" || style=="M", "style must be \"L\" or \"M\"");
T = entry[0];
I = entry[1];
H = entry[2]-1;
S = entry[3];
tpi = entry[4];
a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi);
twist = struct_val(_sp_twist, type);
dum3=assert(top_adj<S+0.75*a, str("The top_adj value is too large so the thread won't fit. It must be smaller than ",S+0.75*a));
oprofile = _sp_thread_profile(tpi,a,S+0.75*a-top_adj,style,flip=true);
bounds=pointlist_bounds(oprofile);
profile = fwd(-bounds[0].y,yflip(oprofile));
depth = a/2;
higlen = 2*a;
higang = higlen / ((T-2*depth)*PI) * 360;
echo(a=a,depth=depth,halfdepth=depth/2, tpi*pointlist_bounds(profile));
space=2*depth/10+4*get_slop();
attachable(anchor,spin,orient,r= (T+space)/2+wall, l=H-bot_adj+wall){
xrot(180)
up((H-bot_adj)/2-wall/2){
difference(){
up(wall)cyl(d=T+space+2*wall,l=H+wall-bot_adj,anchor=TOP,chamfer2=.8);
cyl(d=T+space, l=H-bot_adj+1, anchor=TOP);
}
thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=(twist+2*higang)/360, higbee=higlen, anchor=TOP, internal=true);
}
children();
}
}
// Function: sp_diameter()

View file

@ -1663,7 +1663,7 @@ module nut_trap_inline(length, spec, shape, l, height, h, nutwidth, anchor, orie
// Function: screw_info()
// Usage:
// info = screw_info(spec, [head], [drive], [thread=], [drive_size=], [oversize=], [head_oversize=])
// info = screw_info(name, [head], [drive], [thread=], [drive_size=], [oversize=], [head_oversize=])
// Description:
// Look up screw characteristics for the specified screw type.
// See [screw and nut parameters](#section-screw-and-nut-parameters) for details on the parameters that define a screw.
@ -1715,7 +1715,7 @@ module nut_trap_inline(length, spec, shape, l, height, h, nutwidth, anchor, orie
// If you want to define a custom drive for a screw you will need to provide the drive size and drive depth.
//
// Arguments:
// spec = screw specification, e.g. "M5x1" or "#8-32". See [screw naming](#subsection-screw-naming).
// name = screw specification, e.g. "M5x1" or "#8-32". See [screw naming](#subsection-screw-naming).
// head = head type. See [screw heads](#subsection-screw-heads) Default: none
// drive = drive type. See [screw heads](#subsection-screw-heads) Default: none
// ---
@ -1724,14 +1724,14 @@ module nut_trap_inline(length, spec, shape, l, height, h, nutwidth, anchor, orie
// oversize = amount to increase screw diameter for clearance holes. Default: 0
// head_oversize = amount to increase head diameter for countersink holes. Default: 0
function screw_info(spec, head, drive, thread, drive_size, threads_oversize=0, head_oversize=0, _origin) =
assert(is_string(spec), "Screw specification must be a string")
function screw_info(name, head, drive, thread, drive_size, threads_oversize=0, head_oversize=0, _origin) =
assert(is_string(name), "Screw specification must be a string")
let(
thread = is_undef(thread) || thread==true ? "coarse"
: thread==false || thread=="none" ? 0
: thread,
head = default(head,"none"),
type=_parse_screw_name(spec),
type=_parse_screw_name(name),
drive_info = _parse_drive(drive, drive_size),
drive=drive_info[0],
screwdata = type[0] == "english" ? _screw_info_english(type[1],type[2], head, thread, drive)
@ -1743,7 +1743,7 @@ function screw_info(spec, head, drive, thread, drive_size, threads_oversize=0, h
["drive_depth", drive_info[2]],
["length", type[3]],
["drive_size", drive_info[1]],
["name", spec],
["name", name],
["threads_oversize", threads_oversize],
["head_oversize", head_oversize],
["origin",_origin]
@ -1752,7 +1752,7 @@ function screw_info(spec, head, drive, thread, drive_size, threads_oversize=0, h
// Function: nut_info()
// Usage:
// nut_spec = nut_info(spec, [shape], [thickness=], [thread=], [width=], [hole_oversize=]);
// nut_spec = nut_info(name, [shape], [thickness=], [thread=], [width=], [hole_oversize=]);
// Description:
// Produces a nut specification structure that describes a nut. You can specify the width
// and thickness numerically, or you can let the width be calculated automatically from
@ -1775,7 +1775,7 @@ function screw_info(spec, head, drive, thread, drive_size, threads_oversize=0, h
// "thickness" | Thickness of the nut
// "threads_oversize" | amount to oversize the threads (not including $slop)
// Arguments:
// spec = screw specification, e.g. "M5x1" or "#8-32". See [screw naming](#subsection-screw-naming).
// name = screw name, e.g. "M5x1" or "#8-32". See [screw naming](#subsection-screw-naming).
// shape = shape of the nut, either "hex" or "square". Default: "hex"
// ---
// thread = thread type or specification. See [screw pitch](#subsection-standard-screw-pitch). Default: "coarse"
@ -1783,7 +1783,7 @@ function screw_info(spec, head, drive, thread, drive_size, threads_oversize=0, h
// width = width of nut in mm. Default: computed from thread specification
// hole_oversize = amount ot increase diameter of hole in nut. Default: 0
function nut_info(spec, shape, thickness, thread, hole_oversize=0, width, _origin) =
function nut_info(name, shape, thickness, thread, hole_oversize=0, width, _origin) =
assert(is_undef(thickness) || (is_num(thickness) && thickness>0) ||
in_list(_downcase_if_str(thickness),["thin","normal","thick","undersized","din"]),
"thickness must be a positive number of one of \"thin\", \"thick\", \"normal\", \"undersized\", or \"DIN\"")
@ -1791,11 +1791,11 @@ function nut_info(spec, shape, thickness, thread, hole_oversize=0, width, _origi
shape = _downcase_if_str(default(shape,"hex")),
thickness = _downcase_if_str(default(thickness, "normal"))
)
assert(is_string(spec), str("Nut specification must be a string ",spec))
assert(is_string(name), str("Nut nameification must be a string ",name))
assert(in_list(shape, ["hex","square"]), "Nut shape must be \"hex\" or \"square\"")
assert(is_undef(width) || (is_num(width) && width>0), "Specified width must be a positive number")
let(
type = _parse_screw_name(spec),
type = _parse_screw_name(name),
thread = is_undef(thread) || thread==true ? "coarse"
: thread==false || thread=="none" ? 0
: thread,
@ -1803,7 +1803,7 @@ function nut_info(spec, shape, thickness, thread, hole_oversize=0, width, _origi
: type[0]=="metric" ? _nut_info_metric(type[1],type[2], thread, shape, thickness, width)
: []
)
_struct_reset(nutdata, [["name", spec],
_struct_reset(nutdata, [["name", name],
["threads_oversize",hole_oversize],
["width", width],
["origin",_origin]
@ -2856,11 +2856,7 @@ http://files.engineering.com/getfile.aspx?folder=76fb0d5e-1fff-4c49-87a5-0597947
*/
// To do list
//
// Is there no way to create a mask for making threaded holes? This seems to be missing.
//
// Metric hex engagement:
// https://www.bayoucitybolt.com/socket-head-cap-screws-metric.html
//
// Torx drive depth for UTS and ISO (at least missing for "flat small", which means you can't select torx for this head type)
@ -2868,9 +2864,6 @@ http://files.engineering.com/getfile.aspx?folder=76fb0d5e-1fff-4c49-87a5-0597947
// https://www.fasteners.eu/tech-info/ISO/7721-2/
//
// How do you insert a threaded hole into a model?
// Default nut thickness
//
// JIS
//https://www.garagejournal.com/forum/media/jis-b-4633-vs-iso-8764-1-din-5260-ph.84492/
@ -2882,38 +2875,28 @@ http://files.engineering.com/getfile.aspx?folder=76fb0d5e-1fff-4c49-87a5-0597947
// thread standards:
// https://www.gewinde-normen.de/en/index.html
///////////////////////////////////////////////////////
//
// how to make screw mask: examples (e.g. for clearance hole w/ countersink)
// how to make a screw hole (a mask function?)
//
/////////////////////////////////////////////////////////////////////////////////////////*
/////////////////////////////////////////////////////////////////////////////////////////*
/////////////////////////////////////////////////////////////////////////////////////////*
///
/// TODO list:
///
/// need to make holes at actual size instead of nominal?
/// or relative to actual size?
/// That means I need to preserve thread= to specify this
/// torx depth for UTS pan head
/// $fn control
/// phillips driver spec with ph# is confusing since it still looks up depth in tables
/// and can give an error if it's not found
/// torx depths missing for pan head
/// support for square drive? (It's in the ASME standard)
///
/////////////////////////////////////////////////////////////////////////////////////////*
/////////////////////////////////////////////////////////////////////////////////////////*
/////////////////////////////////////////////////////////////////////////////////////////*
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
/*
TODO list:
anchoring for counterbores OK?: counterbore ignored for flatheads
counterbore is treated as the head for regular heads
for flathead counterbore is ignored. Need an anchor that gives
access to counterbore for the flathead case but also the top of the head(?)
anchoring for other heads: using bounding cylinder
hex head anchoring OK?
need to make holes at actual size instead of nominal?
or relative to actual size?
That means I need to preserve thread= to specify this
shoulder screws: generally how to handle these?
torx depth for UTS pan head
$fn control
phillips driver spec with ph# is confusing since it still looks up depth in tables
and can give an error if it's not found
phillips code just uses depth, not width and slot width; maybe remove excess data?
torx depths missing for pan head
support for square drive? (It's in the ASME standard)
proper support for nuts, nut traps
*/