====== Parametric Cable Clamp Generator ======
**Inspired by Project Binky who doubtless were working from [[https://en.wikipedia.org/wiki/Carroll_Smith#Publications|Screw To Win]].**
Generates split-block cable and pipe clamps in OpenSCAD for you to mill or 3D print or just use the measurements to work out where to drill!
If you want instant gratification you can also use the [[http://fuddymuckers.co.uk/tools/bracketeer.php|online version]] to generate a scale drawing and a drilling list.
{{ http://fuddymuckers.co.uk/gallery/s/h300/cnc/scad_bracket.png }}\\
Clamp produced by V0.1
{{ http://fuddymuckers.co.uk/gallery/s/h300/cnc/scad_bracket_v0p2.png }}\\
Clamp produced by V0.2
//
// +++++++++++++++++++++
// Binky Bracketeer V0.2
// +++++++++++++++++++++
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2019 Fuddymuckers.co.uk
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Parametrically create cable/hose clamps a-la Project Binky or Screw To Win
//
// No warranty, guarantee, claims of suitability, delusions of adequacy.
// High likelihood of tragedy, death, fire, pestilence and plague if used.
//
// ================================
// TODO:
// -----
// Optional single mounting, centre mounting
// Optional locating features
// Rounded ends
// Add labels / text, logo, flames, go-faster stripes...
//
// Revision history:
// -----------------
// V0.2 - Added hole chamfering, counterbore, split options
// ---
// V0.1 - 1st stab, very basic
// ---
// +++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Configuration options below this line, change as required
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Do we split this in half and mill/print it as two pieces?
// Advantage: can be made in one operation on a 3-axis mill or 3D printer
// Disadvantage: Not as neat, more complicated
//
split = 1; // 1 = Yes, 0 = No, 5 is right out.
//
// Overall dimension of finished piece - width will be calculated
//
height = 20; // Height of block in mm
depth = 20; // Depth of holes in mm
//
// Clamping holes
//
holes = [6,4,7,4,10]; // Holes to make, in mm, add/remove as required
space = 5; // Space between each hole, mm
chamfer = 1; // Amount to chamfer the holes, 0 = don't.
//
// Mounting holes, currently at either end only.
//
mounting_hole = 6; // Mounting holes, in mm
space_to_edge = 10; // Space from mounting hole to edge of piece
space_to_hole = 0; // Space from mounting hole to through-hole (space will be added too)
num_mounts = 2; // Leave at 2 - other numbers as yet unhandled
counterbore = 1; // 1=enable, 0=disable
screw_head_dia = 10; // Diameter of hole to counterbore, mm
screw_head_depth = 5; // How deep to counterbore, mm
// Smoother holes - RTFM
$fn = 50;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Code below this line, shouldn't need touching for intended use
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Count number of holes in matrix
num_holes = len(holes)-1;
// How much space one mount requires
mount_space = (mounting_hole + space_to_edge + space_to_hole);
// Simple matrix adding up from TFM
function add(v) = [for(p=v) 1]*v;
// Add matrix starting at element i
function add2(v, i, r = 0) = i < len(v) ? add2(v, i + 1, r + v[i]) : r;
// Add matrix stopping at element e
function add3(v, e, i = 0, r = 0) = i < min(len(v), e) ? add3(v, e, i + 1, r + v[i]) : r;
tot_hole_space = add(holes) + (num_holes * space);
tot_mount_space = mount_space * num_mounts;
width = tot_hole_space + tot_mount_space;
start = mount_space;
echo("Width=", width, " Height=", height, " Depth=", depth);
module bracket()
{
difference()
{
// Solid base chunk
cube([width, depth, height]);
// Visual-only split
translate([-1,(depth/2)-0.5,-1])
{
// % means show but don't use - ghost object
%cube([width+2, 1, height+2]);
}
// Things to remove from base - or "holes" as they're known
union()
{
// Make clamping holes
union()
{
for(n=[0:num_holes])
{
dia = holes[n];
ct = add3(holes, n);
xt = start + (space * (n)) + ct + dia/2;
echo("Hole=", n, " Dia=", dia, " Tot=", ct, " Offset=", xt);
translate([xt,height/2,-1])
{
cylinder(depth+2,d=dia, false);
}
if(chamfer > 0)
{
hc = chamfer/2;
translate([xt,height/2,depth-chamfer])
{
cylinder(chamfer+1,d1=dia, d2=dia+chamfer+2, false);
}
translate([xt,height/2,0-chamfer])
{
cylinder(chamfer+1,d2=dia, d1=dia+chamfer+2, false);
}
}
}
}
// Make mounting holes
union()
{
translate([space_to_edge,depth+1,height/2])
{
rotate([90,0,0])
{
cylinder(depth+2,d=mounting_hole, false);
if(counterbore == 1)
{
cylinder(screw_head_depth+1,d=screw_head_dia, false);
}
}
}
translate([width - space_to_edge,depth+1,height/2])
{
rotate([90,0,0])
{
cylinder(depth+2,d=mounting_hole, false);
if(counterbore == 1)
{
cylinder(screw_head_depth+1,d=screw_head_dia, false);
}
}
}
}
}
}
}
//
// Do we draw the basic thing or split it in half?
//
if(split > 0)
{
difference()
{
// Draw two brackets, laid opposite each other
union()
{
translate([0,0 - (depth+5),height])
{
rotate([-90,0,0])
{
bracket();
}
}
translate([0,(depth+5),0])
{
rotate([90,0,0])
{
bracket();
}
}
}
// Draw a cube to slice the top off
translate([-1,0-(depth+10),height/2])
{
cube(size=[width+2,((depth + 10) * 2), height/2+1]);
}
}
}
else
{
bracket();
}