Parametric Cable Clamp Generator

Inspired by Project Binky who doubtless were working from 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 online version to generate a scale drawing and a drilling list.


Clamp produced by V0.1


Clamp produced by V0.2

bracketeer.scad
//
//       +++++++++++++++++++++
//       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();
}