← Back to Models
Low-Friction Spool Holder

Low-Friction Spool Holder

by Mach3 ·

Interactive Preview & Customizer

3D preview with OpenSCAD rendering on parameter changes.

Loading previewLoading preview...
step 0.5
step 0.5
step 0.1
step 0.5
step 0.1
step 0.1
step 0.5
step 0.1
step 0.1
step 0.1
step 0.01
step 0.1
step 0.01
step 0.1
step 0.1
step 0.5
step 0.5
step 0.5
step 0.1
step 0.5
step 0.1
step 0.1
step 0.1
step 0.1
step 0.5
step 0.1
step 0.1
step 0.5
WASM compiler loads on first parameter change.
Download

Prompt Assets

Prompt image

Prompt reference image

Prompt

remove all references to A1 mini in code

OpenSCAD Code

// ==============================================================================
// 100% 3D-Printed Optimized Low-Friction Spool Holder
// Fully Parametric, Zero Hardware, Pure FDM Roller-Bearing Mechanism
// ==============================================================================

/* [Mode Selection] */
mode = "print_layout"; // [assembly, exploded, cutaway, print_layout, mount_core, drum, roller, cage, cap, clearance_coupon, roller_test]

/* [Basic Spool Specifications] */
spool_width             = 68.0; // Standard 1kg spool barrel width (mm)
max_spool_width         = 80.0; // Maximum spool clearance capacity
minimum_spool_bore      = 50.5; // Smallest allowable inner diameter of spool hub
recommended_spool_bore  = 53.0; // Standard nominal spool bore

/* [Roller Kinematics & Race Geometry] */
roller_count            = 4;    // Number of rolling elements (0°, 90°, 180°, 270°)
roller_od               = 10.0; // Actual maximum roller outer diameter (mm)
roller_len              = 34.0; // Active roller contact length (mm)
roller_crown            = 0.20; // Self-centering crown radius delta (mm)
roller_pin_d            = 4.0;  // Roller end guide trunnion diameter (mm)
roller_pin_len          = 3.0;  // Roller end guide trunnion length (mm)

radial_clearance        = 0.25; // Working radial gap per side (0.20 - 0.30 mm)
axial_clearance         = 0.50; // Axial running play for free rotation (mm)
cage_pocket_clearance   = 0.35; // Clearance around roller trunnions in cage (mm)

/* [Drum & Core Structural Sizing] */
inner_race_radius       = 9.5;  // Stationary spindle core outer radius (OD = 19 mm)
drum_wall_thickness     = 3.0;  // Structural race & barrel wall thickness (min 2.5 mm)
rear_flange_od          = 70.0; // Rear spool stop flange outer diameter (mm)
front_lip_od            = 49.0; // Front anti-slide-off spool lip diameter (mm)

/* [Mount Interface Calibration Parameters] */
mount_tongue_w          = 20.0; // Base slide tongue width (mm)
mount_tongue_t          = 4.8;  // Base slide tongue thickness (mm)
mount_tongue_l          = 26.0; // Slide insertion depth (mm)
mount_lip_w             = 2.4;  // Side guide step rail width (mm)
mount_lip_h             = 1.6;  // Side guide step rail depth (mm)
mount_detent_pos        = 16.0; // Insertion distance to snap detent (mm)
mount_detent_h          = 1.2;  // Detent wedge snap height (mm)
mount_arm_drop          = 28.0; // Vertical offset from spool axis to mount slide (mm)
mount_arm_thick         = 12.0; // Structural root thickness along spool axis (mm)
mount_gusset_t          = 5.0;  // Reinforcement gusset rib thickness (mm)

/* [Rendering Fidelity] */
$fn = 64;

// ==============================================================================
// DERIVED MATHEMATICAL RELATIONSHIPS & FIRST PRINCIPLES
// ==============================================================================

roller_r            = roller_od / 2;
working_radial_gap  = roller_od + (2 * radial_clearance);
outer_race_radius   = inner_race_radius + working_radial_gap;
roller_pitch_radius = inner_race_radius + radial_clearance + roller_r;

// Drum outer dimensions
drum_inner_radius   = outer_race_radius;
drum_outer_radius   = drum_inner_radius + drum_wall_thickness;
drum_outer_diameter = drum_outer_radius * 2;

// Working lengths
spool_seat_len      = spool_width + 4.0; // Free axial running room for spool
core_spindle_len    = spool_seat_len + 8.0;
cage_od             = (roller_pitch_radius + 1.2) * 2;
cage_id             = (roller_pitch_radius - 1.2) * 2;

// Circumferential clearance between 4 rollers
circ_pitch_dist     = 2 * PI * roller_pitch_radius / roller_count;
chord_clearance     = (sqrt(2) * roller_pitch_radius) - roller_od;

// ==============================================================================
// MECHANICAL VALIDATION ASSERTIONS
// ==============================================================================
assert(drum_outer_diameter < minimum_spool_bore, 
    "FATAL: Drum OD exceeds minimum spool bore! Spool will bind.");
assert(drum_wall_thickness >= 2.5, 
    "FATAL: Drum wall thickness under 2.5 mm structural threshold.");
assert(working_radial_gap - roller_od >= 2 * radial_clearance - 0.001, 
    "FATAL: Working radial race equation does not satisfy 2 * radial_clearance.");
assert(chord_clearance > 2.0, 
    "FATAL: Rollers will physically collide circumferentially!");
assert(roller_len < spool_seat_len, 
    "FATAL: Roller length exceeds available spool seat length.");

// ==============================================================================
// MODULES
// ==============================================================================

// 1. CROWNED ROLLER WITH LOW-FRICTION TRUNNIONS
module crowned_roller() {
    // Roller axis parallel to spool axis (along Z axis)
    // Generates a precision crowned profile: slightly larger OD at center for self-tracking
    // Integrated trunnion pins on both ends for lightweight cage containment
    render() rotate_extrude() {
        polygon([
            [0, -roller_len/2],
            [roller_pin_d/2, -roller_len/2],
            [roller_pin_d/2, -(roller_len/2 - roller_pin_len)],
            [roller_r - 0.35, -(roller_len/2 - roller_pin_len)],
            [roller_r - 0.08, -roller_len/4],
            [roller_r, 0],
            [roller_r - 0.08, roller_len/4],
            [roller_r - 0.35, roller_len/2 - roller_pin_len],
            [roller_pin_d/2, roller_len/2 - roller_pin_len],
            [roller_pin_d/2, roller_len/2],
            [0, roller_len/2]
        ]);
    }
}

// 2. LIGHTWEIGHT 4-ROLLER CAGE (0°, 90°, 180°, 270°)
module roller_cage() {
    ring_thick = 2.5;
    pin_pocket_r = (roller_pin_d/2) + cage_pocket_clearance;
    
    difference() {
        union() {
            // Front ring
            translate([0, 0, roller_len/2 + 0.5])
                cylinder(r=roller_pitch_radius + 1.5, h=ring_thick, center=false);
            // Rear ring
            translate([0, 0, -(roller_len/2 + 0.5 + ring_thick)])
                cylinder(r=roller_pitch_radius + 1.5, h=ring_thick, center=false);
            // 4 Low-profile interconnecting bridge struts located between rollers (at 45°, 135°, 225°, 315°)
            for (a = [45, 135, 225, 315]) {
                rotate([0, 0, a])
                    translate([roller_pitch_radius, 0, -roller_len/2])
                        cylinder(r=1.6, h=roller_len, $fn=16);
            }
        }
        // Bore through cage rings
        cylinder(r=inner_race_radius + 0.8, h=100, center=true);
        
        // Pivot sockets for roller trunnions
        for (i = [0 : roller_count-1]) {
            rotate([0, 0, i * (360/roller_count)]) {
                translate([roller_pitch_radius, 0, roller_len/2 - 0.2])
                    cylinder(r=pin_pocket_r, h=roller_pin_len + 2, $fn=24);
                translate([roller_pitch_radius, 0, -(roller_len/2 + roller_pin_len + 1.8)])
                    cylinder(r=pin_pocket_r, h=roller_pin_len + 2, $fn=24);
            }
        }
    }
}

// 3. SLIDE-IN MOUNT INTERFACE
module slide_mount() {
    // Stepped slide-in tongue matching receiver bracket socket
    difference() {
        union() {
            // Base slide body
            translate([-mount_tongue_w/2, 0, 0])
                cube([mount_tongue_w, mount_tongue_t, mount_tongue_l]);
            
            // Side guide rails / lips
            translate([-(mount_tongue_w/2 + mount_lip_w), 0, 0])
                cube([mount_lip_w, mount_tongue_t - mount_lip_h, mount_tongue_l]);
            translate([mount_tongue_w/2, 0, 0])
                cube([mount_lip_w, mount_tongue_t - mount_lip_h, mount_tongue_l]);
            
            // Lead-in insertion chamfers
            translate([-mount_tongue_w/2, 0, 0])
                rotate([-45, 0, 0])
                    cube([mount_tongue_w, 2, 2]);
        }
        
        // Integrated snap-lock flexure cantilever slot
        translate([-3.0, -1, 4.0])
            cube([6.0, mount_tongue_t + 2, mount_tongue_l - 8.0]);
    }
    
    // Retention snap detent tooth with lead-in ramp on flexible tongue
    translate([-2.5, 0, 4.5]) {
        cube([5.0, mount_tongue_t, mount_tongue_l - 9.0]);
        // Latch tooth wedge
        translate([0, mount_tongue_t, mount_detent_pos - 4.5]) {
            polyhedron(
                points=[
                    [0, 0, 0], [5.0, 0, 0], [5.0, mount_detent_h, 3.0], [0, mount_detent_h, 3.0],
                    [0, 0, 5.0], [5.0, 0, 5.0]
                ],
                faces=[
                    [0,1,2,3], [3,2,5,4], [0,3,4], [1,5,2], [0,4,5,1]
                ]
            );
        }
    }
}

// 4. REINFORCED CANTILEVER ARM & STATIONARY SPINDLE CORE
module stationary_core_and_arm() {
    // 1. Spool core inner race spindle
    difference() {
        union() {
            // Precision inner race zone
            cylinder(r=inner_race_radius, h=core_spindle_len);
            
            // Spindle shoulder / thrust ring
            cylinder(r=inner_race_radius + 2.5, h=4.0);
            
            // Front cap locking neck with bayonet notch
            translate([0, 0, core_spindle_len]) {
                cylinder(r=inner_race_radius - 2.5, h=7.0);
                // Bayonet locking pins
                translate([0, 0, 3.5])
                    rotate([0, 90, 0])
                        cylinder(r=1.5, h=(inner_race_radius - 0.5) * 2, center=true, $fn=16);
            }
            
            // 2. Heavy Root Cantilever Arm to Mount
            translate([0, -mount_arm_drop, 0]) {
                // Main rigid drop block
                translate([-mount_tongue_w/2, 0, -mount_arm_thick])
                    cube([mount_tongue_w, mount_arm_drop, mount_arm_thick]);
                
                // Massive triangular stiffener gussets
                hull() {
                    translate([-mount_tongue_w/2, 0, -mount_arm_thick])
                        cube([mount_tongue_w, 2.0, -mount_arm_thick]);
                    translate([-inner_race_radius, mount_arm_drop, -mount_arm_thick])
                        cube([inner_race_radius * 2, 2.0, mount_arm_thick]);
                }
                
                // Mount Interface slide
                translate([0, 0, -mount_tongue_l])
                    slide_mount();
            }
        }
        
        // Weight-reduction / print-speed central core bore
        cylinder(r=4.5, h=core_spindle_len + 20, center=true);
    }
}

// 5. ROTATING OUTER DRUM WITH INTEGRATED SPOOL RACE
module rotating_drum() {
    difference() {
        union() {
            // Main barrel carrying the spool
            cylinder(r=drum_outer_radius, h=spool_seat_len);
            
            // Rear spool retention guide flange
            cylinder(r=rear_flange_od/2, h=4.0);
            
            // Transition fillet cone from flange to drum
            translate([0, 0, 4.0])
                cylinder(r1=rear_flange_od/2 - 2.0, r2=drum_outer_radius, h=4.0);
            
            // Front spool retention lip (gentle angle for easy spool sliding)
            translate([0, 0, spool_seat_len - 3.5])
                cylinder(r1=drum_outer_radius, r2=front_lip_od/2, h=3.5);
        }
        
        // Calibrated outer bearing race bore for the 4 rollers
        translate([0, 0, -1])
            cylinder(r=outer_race_radius, h=roller_len + 12.0);
            
        // Front thrust clearance bore
        translate([0, 0, roller_len + 10.0])
            cylinder(r=inner_race_radius + 2.0, h=spool_seat_len, center=false);
    }
}

// 6. TOOL-LESS BAYONET AXIAL RETENTION CAP
module retaining_cap() {
    cap_od = drum_inner_radius + 1.5;
    difference() {
        union() {
            // Outer knurled gripping head
            cylinder(r=cap_od, h=3.5);
            // Internal sleeve
            translate([0, 0, 3.5])
                cylinder(r=inner_race_radius - 0.5, h=6.5);
        }
        // Central hollow bore for spindle bayonet peg
        translate([0, 0, -1])
            cylinder(r=inner_race_radius - 2.2, h=12);
        
        // Bayonet J-slots
        for (a = [0, 180]) {
            rotate([0, 0, a]) {
                translate([0, 0, 4.0])
                    cube([inner_race_radius * 2 + 2, 3.4, 3.2], center=true);
                // Entry slot
                translate([inner_race_radius - 2.2, -1.7, 3.5])
                    cube([4, 3.4, 7]);
            }
        }
    }
}

// 7. CALIBRATION CLEARANCE COUPON
module clearance_coupon() {
    // Reproduces the exact 3-body tribology stack: Inner Core, Roller, Outer Drum
    difference() {
        union() {
            // Base plate
            cube([55, 30, 3.0]);
            // Inner race segment
            translate([15, 15, 3.0])
                cylinder(r=inner_race_radius, h=10.0);
            // Outer race test segment
            translate([15, 15, 3.0])
                difference() {
                    cylinder(r=outer_race_radius + 3.0, h=10.0);
                    cylinder(r=outer_race_radius, h=12.0);
                    translate([-25, -25, -1]) cube([50, 25, 15]);
                }
        }
        // Engraved text indicator
        translate([32, 10, 2.2])
            linear_extrude(1.2) text("0.25", size=5.5);
    }
    // Matching test roller
    translate([15, 15 + roller_pitch_radius, 8.0])
        crowned_roller();
}

// 8. ROLLER TEST RIG
module roller_test_rig() {
    stationary_core_and_arm();
    translate([roller_pitch_radius, 0, 10 + roller_len/2])
        crowned_roller();
    translate([0, 0, 6.0])
        intersection() {
            rotating_drum();
            cube([60, 60, 40]);
        }
}

// ==============================================================================
// VIEW MODES & SCENE COMPOSITION
// ==============================================================================

if (mode == "assembly") {
    // @name Spindle Core and Cantilever Arm
    color([0.2, 0.2, 0.25]) stationary_core_and_arm();
    
    // @name Crowned Rollers
    color([0.85, 0.5, 0.15]) {
        for (i = [0 : roller_count-1]) {
            rotate([0, 0, i * (360/roller_count)])
                translate([roller_pitch_radius, 0, 6.0 + roller_len/2])
                    crowned_roller();
        }
    }
    
    // @name Roller Alignment Cage
    color([0.3, 0.7, 0.3, 0.7])
        translate([0, 0, 6.0 + roller_len/2])
            roller_cage();
    
    // @name Rotating Spool Drum
    color([0.15, 0.45, 0.85, 0.65])
        translate([0, 0, 5.0])
            rotating_drum();
            
    // @name Retention Cap
    color([0.9, 0.2, 0.2])
        translate([0, 0, core_spindle_len + 2.0])
            retaining_cap();
}

else if (mode == "exploded") {
    // Exploded along horizontal spindle axis (Z in SCAD coordinates)
    // @name Spindle Core and Cantilever Arm
    color([0.2, 0.2, 0.25]) stationary_core_and_arm();
    
    // @name Crowned Rollers and Cage
    translate([0, 0, 30]) {
        for (i = [0 : roller_count-1]) {
            rotate([0, 0, i * (360/roller_count)])
                translate([roller_pitch_radius + 15, 0, roller_len/2])
                    color([0.85, 0.5, 0.15]) crowned_roller();
        }
        color([0.3, 0.7, 0.3])
            translate([0, 0, roller_len/2])
                roller_cage();
    }
    
    // @name Rotating Spool Drum
    color([0.15, 0.45, 0.85])
        translate([0, 0, 95])
            rotating_drum();
            
    // @name Retention Cap
    color([0.9, 0.2, 0.2])
        translate([0, 0, 185])
            retaining_cap();
}

else if (mode == "cutaway") {
    // Half-cutaway view to inspect inner race, 4 rollers, cage, and outer drum clearances
    // @name Cutaway Inspection View
    difference() {
        union() {
            color([0.2, 0.2, 0.25]) stationary_core_and_arm();
            
            for (i = [0 : roller_count-1]) {
                rotate([0, 0, i * (360/roller_count)])
                    translate([roller_pitch_radius, 0, 6.0 + roller_len/2])
                        color([0.85, 0.5, 0.15]) crowned_roller();
            }
            
            color([0.3, 0.7, 0.3])
                translate([0, 0, 6.0 + roller_len/2])
                    roller_cage();
                    
            color([0.15, 0.45, 0.85, 0.8])
                translate([0, 0, 5.0])
                    rotating_drum();
                    
            color([0.9, 0.2, 0.2])
                translate([0, 0, core_spindle_len + 2.0])
                    retaining_cap();
        }
        // 90-degree inspection wedge cutout
        translate([0, 0, -50])
            cube([100, 100, 200]);
    }
}

else if (mode == "print_layout") {
    // Bed-level print layout: all parts seated flat at Z = 0
    
    // 1. Stationary core & cantilever arm
    // In stationary_core_and_arm(), the flat back face of the mount root is at Y = -mount_arm_drop,
    // and slide_mount tongue is in negative Z.
    // Rotating around X by 90 (or -90):
    // If rotate([90, 0, 0]), the arm back at Y = -mount_arm_drop lies in Z.
    // Let's place it flat on its back so the cantilever spindle and mount tongue print horizontally:
    // With rotate([90, 0, 0]), Z becomes Y, Y becomes -Z.
    // The spindle axis (Z) is now along Y (horizontal).
    // The arm drop is along -Y, which becomes +Z.
    // Specifically:
    // When rotate([90, 0, 0]):
    // Spindle center is at X=0, Z=0. Lowest point is the spindle cylinder outer surface at Z = -(inner_race_radius + 2.5) = -12.
    // Let's orient stationary_core_and_arm properly on the bed:
    // If rotated [0, 90, 0]: spindle is along X.
    // Or if rotated [90, 0, 0]:
    // Let's test exact resting orientation:
    // Spindle axis horizontal along Y. The drop block and slide mount are flat.
    // In stationary_core_and_arm():
    // The mount tongue back face: translate([-mount_tongue_w/2, 0, 0]) cube([mount_tongue_w, mount_tongue_t, mount_tongue_l]);
    // The mount arm drop: translate([-mount_tongue_w/2, 0, -mount_arm_thick]) cube([mount_tongue_w, mount_arm_drop, mount_arm_thick]) at Y=-mount_arm_drop.
    // So the flat back of the drop block is at Y = -mount_arm_drop.
    // If we rotate([-90, 0, 0]): Y=-mount_arm_drop goes to Z = +mount_arm_drop.
    // If we rotate([90, 0, 0]), Y becomes -Z, so Y = -mount_arm_drop goes to Z = mount_arm_drop (positive).
    // But if we rotate around X and Y so that a stable flat face is at Z = 0:
    // Notice the mount slide has flat back face at Y = -mount_arm_drop, Y in [0, mount_tongue_t] relative to that.
    // Let's check the bounding box or test.
    // Let's write the layout cleanly and check render!
    
    // @name Spindle Core and Mount
    translate([0, 10, inner_race_radius + 2.5])
        rotate([-90, 0, 0])
            stationary_core_and_arm();
            
    // 2. Rotating outer drum printed vertically on its wide rear flange (Z = 0)
    // @name Rotating Drum
    translate([65, 30, 0])
        rotating_drum();
        
    // 3. Four crowned rollers printed vertically on their flat trunnion pin base
    // @name Crowned Rollers
    for (r = [0 : 3]) {
        translate([-35, 10 + (r * 18), roller_len/2])
            crowned_roller();
    }
    
    // 4. Lightweight roller cage printed flat on rear ring
    // rear ring is at Z = -(roller_len/2 + 0.5 + ring_thick) = -(17 + 0.5 + 2.5) = -20.
    // Height offset = 20 places bottom at Z = 0!
    // @name Roller Cage
    translate([-55, -45, roller_len/2 + 0.5 + 2.5])
        roller_cage();
        
    // 5. Retention cap printed flat on its outer gripping head (Z = 0)
    // @name Retention Cap
    translate([-15, -45, 0])
        retaining_cap();
}

else if (mode == "mount_core") {
    // @name Spindle Core and Mount
    stationary_core_and_arm();
}

else if (mode == "drum") {
    // @name Rotating Drum
    rotating_drum();
}

else if (mode == "roller") {
    // @name Crowned Roller
    crowned_roller();
}

else if (mode == "cage") {
    // @name Roller Cage
    roller_cage();
}

else if (mode == "cap") {
    // @name Retention Cap
    retaining_cap();
}

else if (mode == "clearance_coupon") {
    // @name Clearance Coupon
    clearance_coupon();
}

else if (mode == "roller_test") {
    // @name Roller Test Rig
    roller_test_rig();
}

Download Model

Choose the model version and file format.

Model version