diff --git a/printed/drag_chain.scad b/printed/drag_chain.scad index 237e58d..49447da 100644 --- a/printed/drag_chain.scad +++ b/printed/drag_chain.scad @@ -54,8 +54,8 @@ function drag_chain_outer_size(type) = //! Link outer dimensions [s.x + z, s.y + 4 * drag_chain_wall(type) + 2 * clearance, z]; -module drag_chain_link(type) { - stl(str(drag_chain_name(type), "_drag_chain_link")); +module drag_chain_link(type, start = false, end = false) { + stl(str(drag_chain_name(type), "_drag_chain_link", start ? "_start" : end ? "_end" : "")); s = drag_chain_size(type); wall = drag_chain_wall(type); @@ -64,11 +64,14 @@ module drag_chain_link(type) { os = drag_chain_outer_size(type); r = os.z / 2; pin_r = r / 2; - inner_x = s.x - wall; - roof_x = 2 * r - twall; - floor_x = 2 * r; - cam_r = inner_x - clearance - r; + inner_x_normal = s.x - wall; + inner_x = start ? 0 : s.x - inner_x_normal; + roof_x_normal = 2 * r - twall; + roof_x = start ? 0 : roof_x_normal; + floor_x = start ? 0 : 2 * r; + cam_r = inner_x_normal - clearance - r; cam_x = min(sqrt(max(sqr(cam_r) - sqr(r - twall), 0)), r); + outer_end_x = end ? os.x : s.x - clearance; for(side = [-1, 1]) rotate([90, 0, 0]) { @@ -77,15 +80,20 @@ module drag_chain_link(type) { linear_extrude(wall, center = true) difference() { hull() { - translate([r, r]) - rotate(180) - teardrop(r = r, h = 0); + if(start) + translate([floor_x, 0]) + square([eps, os.z]); + else + translate([r, r]) + rotate(180) + teardrop(r = r, h = 0); - translate([s.x - clearance - eps, 0]) + translate([outer_end_x - eps, 0]) square([eps, os.z]); } - translate([r, r]) - horihole(pin_r, r); + if(!start) + translate([r, r]) + horihole(pin_r, r); } // Inner cheeks translate_z(side * (s.y / 2 + wall / 2)) @@ -93,52 +101,61 @@ module drag_chain_link(type) { difference() { union() { hull() { - translate([s.x + r, r]) - rotate(180) - teardrop(r = r, h = 0); + if(!end) { + translate([s.x + r, r]) + rotate(180) + teardrop(r = r, h = 0); - translate([s.x + r, twall]) - square([cam_x, eps]); + translate([s.x + r, twall]) + square([cam_x, eps]); + } + else + translate([s.x + 2 * r - eps, 0]) + square([eps, os.z]); translate([inner_x, 0]) square([eps, os.z]); } } // Cutout for top wall - intersection() { - translate([s.x, 0]) - square([3 * r, twall]); // When straight + if(!end) + intersection() { + translate([s.x, 0]) + square([3 * r, twall]); // When straight - translate([s.x + r, r]) - rotate(-45) - translate([-r + roof_x, -r - twall]) // When bent fully - square(os.z); - } + translate([s.x + r, r]) + rotate(-45) + translate([-r + roof_x_normal, -r - twall]) // When bent fully + square(os.z); + } } - // Pin - translate([s.x + r, r, side * (s.y / 2 + wall + clearance)]) - horicylinder(r = pin_r, z = r, h = 2 * wall); + // Pin + if(!end) + translate([s.x + r, r, side * (s.y / 2 + wall + clearance)]) + horicylinder(r = pin_r, z = r, h = 2 * wall); - // Cheek joint - translate([inner_x, 0, side * (s.y / 2 + wall) - 0.5]) - cube([s.x - clearance - inner_x, os.z, 1]); + // Cheek joint + translate([inner_x, 0, side * (s.y / 2 + wall) - 0.5]) + cube([outer_end_x - inner_x, os.z, 1]); } - // Roof - translate([roof_x, -s.y / 2 - 0.5]) - cube([s.x + r - roof_x - twall - clearance, s.y + 1, twall]); + // Roof, actually the floor when printed + roof_end = end ? s.x + 2 * r : s.x + r - twall - clearance; + translate([roof_x, -s.y / 2 - wall]) + cube([roof_end - roof_x , s.y + 2 * wall, twall]); translate([roof_x, -os.y / 2 + 0.5]) - cube([s.x - roof_x - clearance, os.y - 1, twall]); + cube([s.x - clearance - roof_x, os.y - 1, twall]); - // Base - translate([floor_x, -s.y / 2 - 0.5, os.z - bwall]) - cube([s.x + r - floor_x, s.y + 1, bwall]); + // Base, actually the roof when printed + floor_end = end ? s.x + 2 * r : s.x + r; + translate([floor_x, -s.y / 2 - wall, os.z - bwall]) + cube([floor_end - floor_x, s.y + 2 * wall, bwall]); translate([floor_x, -os.y / 2 + 0.5, os.z - bwall]) cube([s.x - floor_x - clearance, os.y -1, bwall]); - if(show_supports()) { + if(show_supports() && !end) { for(side = [-1, 1]) { w = 2.1 * extrusion_width; translate([s.x + r + cam_x - w / 2, side * (s.y / 2 + wall / 2), twall / 2]) @@ -167,13 +184,7 @@ module drag_chain_assembly(type, pos = 0) { //! Drag chain assembly zb = z / 2; // z of bottom track c = [actual_travel / 2 + pos / 2, 0, r + zb]; // centre of bend - module link(n) // Position and colour link with origin at the hinge hole - translate([-z / 2, 0, -z / 2]) - stl_colour(n % 2 ? pp1_colour : pp2_colour) - drag_chain_link(type); - - - points = [ // Calculate lits of hinge points + points = [ // Calculate list of hinge points for(i = 0, p = [0, 0, z / 2 + 2 * r]; i < links + 5; i = i + 1, dx = p.z > c.z ? s.x : -s.x, @@ -183,10 +194,24 @@ module drag_chain_assembly(type, pos = 0) { //! Drag chain assembly : q) // Circular section p ]; + npoints = len(points); - assembly(str(drag_chain_name(type), "_drag_chain")) - for(i = [0 : len(points) - 2]) let(v = points[i+1] - points[i]) + module link(n) // Position and colour link with origin at the hinge hole + translate([-z / 2, 0, -z / 2]) + stl_colour(n % 2 ? pp1_colour : pp2_colour) + drag_chain_link(type, start = n == -1, end = n == npoints - 1); + + assembly(str(drag_chain_name(type), "_drag_chain")) { + for(i = [0 : npoints - 2]) let(v = points[i+1] - points[i]) translate(points[i]) rotate([0, -atan2(v.z, v.x), 0]) link(i); + + translate(points[0] - [s.x, 0, 0]) + link(-1); + + translate(points[npoints - 1]) + hflip() + link(npoints - 1); + } } diff --git a/readme.md b/readme.md index 40a6cb2..56dfe99 100644 --- a/readme.md +++ b/readme.md @@ -28,20 +28,20 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa Bulldogs Leadnuts SK_brackets Corner_block Gears Sphere Buttons Light_strips SMDs Door_hinge Hanging_hole Teardrops Cable_strips Linear_bearings SSRs Door_latch Horiholes - Cameras Magnets Screws Fan_guard Layout - Circlips Mains_sockets Sealing_strip Fixing_block Maths - Components Microswitches Shaft_couplings Flat_hinge Offset - DIP Microview Sheets Foot Quadrant - D_connectors Modules Spades Handle Round - Displays Nuts Spools PCB_mount Rounded_cylinder - Extrusion_brackets O_ring Springs PSU_shroud Rounded_polygon - Extrusions Opengrab Stepper_motors Printed_box Sector - Fans PCB Swiss_clips Ribbon_clamp Sweep - Fuseholder PCBs Toggles SSR_shroud Thread - Geared_steppers PSUs Transformers Screw_knob Tube - Green_terminals Panel_meters Tubings Socket_box - Hot_ends Pillars Variacs Strap_handle - Hygrometer Pin_headers Veroboard + Cameras Magnets Screws Drag_chain Layout + Circlips Mains_sockets Sealing_strip Fan_guard Maths + Components Microswitches Shaft_couplings Fixing_block Offset + DIP Microview Sheets Flat_hinge Quadrant + D_connectors Modules Spades Foot Round + Displays Nuts Spools Handle Rounded_cylinder + Extrusion_brackets O_ring Springs PCB_mount Rounded_polygon + Extrusions Opengrab Stepper_motors PSU_shroud Sector + Fans PCB Swiss_clips Printed_box Sweep + Fuseholder PCBs Toggles Ribbon_clamp Thread + Geared_steppers PSUs Transformers SSR_shroud Tube + Green_terminals Panel_meters Tubings Screw_knob + Hot_ends Pillars Variacs Socket_box + Hygrometer Pin_headers Veroboard Strap_handle IECs Pulleys Washers Inserts Wire Zipties @@ -4539,6 +4539,60 @@ Door latch for 6mm acrylic door for 3D printer. See [door_hinge](#door_hinge). | 1 | door_latch.stl | +Top + +--- + +## Drag_chain +Parametric cable drag chain to limit the bend radius of a cable run. + +Each link has a maximum bend angle, so the mininium radius is proportional to the link length. + +The travel prpoery is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel. + + +[printed/drag_chain.scad](printed/drag_chain.scad) Implementation. + +[tests/drag_chain.scad](tests/drag_chain.scad) Code for this example. + +### Properties +| Function | Description | +|:--- |:--- | +| ```drag_chain_bwall(type)``` | Bottom wall | +| ```drag_chain_name(type)``` | The name to allow more than one in a project | +| ```drag_chain_size(type)``` | The internal size and link length | +| ```drag_chain_travel(type)``` | X travel | +| ```drag_chain_twall(type)``` | Top wall | +| ```drag_chain_wall(type)``` | Side wall thickness | + +### Functions +| Function | Description | +|:--- |:--- | +| ```drag_chain(name, size, travel, wall = 1.6, bwall = 1.5, twall = 1.5)``` | Constructor | +| ```drag_chain_outer_size(type)``` | Link outer dimensions | +| ```drag_chain_radius(type)``` | The bend radius at the pivot centres | +| ```drag_chain_z(type)``` | Outside dimension of a 180 bend | + +### Modules +| Module | Description | +|:--- |:--- | +| ```drag_chain_assembly(type, pos = 0)``` | Drag chain assembly | + +![drag_chain](tests/png/drag_chain.png) + +### Printed +| Qty | Filename | +| ---:|:--- | +| 14 | x_drag_chain_link.stl | +| 1 | x_drag_chain_link_end.stl | +| 1 | x_drag_chain_link_start.stl | + +### Assemblies +| Qty | Name | +| ---:|:--- | +| 1 | x_drag_chain_assembly | + + Top --- diff --git a/tests/drag_chain.scad b/tests/drag_chain.scad index 883f609..79da5b5 100644 --- a/tests/drag_chain.scad +++ b/tests/drag_chain.scad @@ -48,5 +48,12 @@ module drag_chains() if($preview) drag_chains(); -else +else { drag_chain_link(drag_chain); + + translate([-x * 2, 0]) + drag_chain_link(drag_chain, start = true); + + translate([x * 2, 0]) + drag_chain_link(drag_chain, end = true); +} diff --git a/tests/png/drag_chain.png b/tests/png/drag_chain.png new file mode 100644 index 0000000..006c8c0 Binary files /dev/null and b/tests/png/drag_chain.png differ