X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=powerbank-bike-clamp.scad;h=18b3adbd2f3869056f8f6993e490242df6463304;hb=80145b71ce928c7251252abcdd4ce010cf05594a;hp=de6a69533a7c15750a1cfe520706fda8d18393ce;hpb=9ecc9c245397e2a5326746c3396dd0c6dfff596c;p=reprap-play.git diff --git a/powerbank-bike-clamp.scad b/powerbank-bike-clamp.scad index de6a695..18b3adb 100644 --- a/powerbank-bike-clamp.scad +++ b/powerbank-bike-clamp.scad @@ -1,20 +1,29 @@ // -*- C -*- +// Print one of each: +// Main +// TubeClampRight + include tube_dia = 22.4; hinge_around = 2.5; -hinge_pin = 1.5; // xxx +hinge_pin = 1.8 + 0.75; main_th = 3; minor_wall_min = 1; screw = 5.0 + 0.75; -screw_nut_across = 10; // xxx -knob_behind_across = 15; // xxx +screw_head = 8.7 + 1.2; +screw_head_space_above = 10; +screw_nut_across = 7.9 + 0.75; +screw_nut_th = 3.9 + 0.75; + +knob_behind_across = 12.2 + 0.75; behind_knob_th = 5; +knob_standout_h = 2; -clamp_width = 15; +clamp_min_width = 20; clamp_gap = 2; @@ -22,12 +31,61 @@ lower_th = 1; overlap_l = 0.1; +bridge_slop = 1.2; + +hinge_lobe_per = 10; +hinge_gap_z = 0.75; +hinge_gap_xy = 0.75; + +$fs = 0.1; +$fa = 5; + +bank_eps_bbox_x = [149, 598]; +bank_eps_bbox_y = [274, 1452]; + +bank_y_sz = 102.25 + 0.50 + 3.2; +bank_x_sz = (26.0 + 0.5); +bank_recess_y = 5; + +strap_th = 3; +strap_w = 5; +strap_above = 2.5; + +strap_around_over = 1.0; +strap_around_attach = 2.0; + +retainer_walls = [18, 30]; + +bank_profile_scale_bodge = 1.0; + +bank_output_ctr = [ 12.5, 11.5 ]; // from nearest corner +bank_output_sz = [ 11.0, 10.5 ]; + +mounted_pos_y_offset_lim = -100; + +liner_th = 0.8; + +brace_r = 5; +brace_len = 50; + +straps_y_adj = [ 3.5, + 0, + 0 ]; + // calculated -main_r = tube_dia/2 + main_th; +straps_y = [ -bank_y_sz * 0.25, // these entries are special and used + +bank_y_sz * 0.25, // for the brace struts + 0 ]; -hinge_outer_r = hinge_around + hinge_pin/2; -hinge_y = tube_dia/2 + hinge_outer_r; +screw_head_behind = main_th; +endwall_th = main_th; + +bank_recess_dx = minor_wall_min; + +pspt_to_mm = 25.4 / 72; + +main_r = tube_dia/2 + main_th; screw_max_y_lhs = -main_r -screw_nut_across/2; screw_max_y_rhs = -main_r -knob_behind_across/2; @@ -35,10 +93,33 @@ screw_max_y_rhs = -main_r -knob_behind_across/2; screw_y = min(screw_max_y_lhs, screw_max_y_rhs); -bot_y = screw_y -max( screw_nut_across, knob_behind_across/2 ) +bot_y = screw_y -max( screw_nut_across/2, knob_behind_across/2 ) -minor_wall_min; -echo(bot_y); +holder_x_sz = bank_x_sz + bank_recess_dx*2; +bank_bot_y = strap_above + strap_th; +strap_r = strap_th; + +brace_total_len = brace_len + main_th; +brace_ctrs_y_nom = [ straps_y[0] - (brace_r + strap_w/2), + straps_y[1] + (brace_r + strap_w/2) ]; + +brace_ctrs_y = [ (straps_y + straps_y_adj)[0] + (brace_r + strap_w/2), + (straps_y + straps_y_adj)[1] + (brace_r + strap_w/2) ]; + +clamp_width_actual = max(clamp_min_width, holder_x_sz); + +hinge_lobes = floor(clamp_width_actual / hinge_lobe_per); +hinge_stride = (clamp_width_actual + hinge_gap_z) / hinge_lobes; + +hinge_outer_r = hinge_around + hinge_pin/2; +hinge_y = tube_dia/2 + hinge_outer_r; + +top_cnr_r = min(endwall_th, main_th); + +mounted_pos_y_offset = max(mounted_pos_y_offset_lim, + bot_y - (-(bank_y_sz/2 + endwall_th))); + module TubePlan(){ circle(r = tube_dia/2); } module HingePinPlan(){ translate([0, hinge_y]) circle(r= hinge_pin/2); } @@ -47,12 +128,12 @@ module HingeBodyPlan(){ translate([0, hinge_y]) circle(r= hinge_outer_r); } module TubeClampLeftPlan(){ difference(){ union(){ - polygon([[ 0, hinge_y + hinge_outer_r ], - [ -main_r + overlap_l, hinge_y + hinge_outer_r ], - [ -main_r + overlap_l, bot_y ], - [ -clamp_gap/2, bot_y ], - [ -clamp_gap/2, 0, ], - [ 0, 0, ], + polygon([[ 0, hinge_y + hinge_outer_r ], + [ -(main_r + overlap_l), hinge_y + hinge_outer_r ], + [ -(main_r + overlap_l), bot_y ], + [ -clamp_gap/2, bot_y ], + [ -clamp_gap/2, 0, ], + [ 0, 0, ], ]); HingeBodyPlan(); } @@ -62,7 +143,7 @@ module TubeClampLeftPlan(){ } module TubeClampLeft() { ////toplevel - linextr(-clamp_width/2, clamp_width/2) + linextr(-clamp_width_actual/2, clamp_width_actual/2) TubeClampLeftPlan(); } @@ -87,27 +168,257 @@ module TubeClampRightPlan(){ } } -module SomeClamp(){ +module Screws(){ + linextr_x_yz(-main_r*5, main_r*5) + translate([screw_y, 0]) + circle(r= screw/2); + + translate([0, screw_y, 0]) { + linextr_x_yz(-(clamp_gap/2 + screw_nut_th), 0) + square([screw_nut_across, + screw_nut_across / cos(30) + bridge_slop*2], + center=true); + + linextr_x_yz(-(main_r + bank_recess_y + screw_head_space_above), + -(clamp_gap/2 + screw_nut_th + screw_head_behind)) + square([screw_head, screw_head + bridge_slop*2], + center=true); + } +} + +module SomeClamp(hinge_alt=false){ difference(){ - linextr(-clamp_width/2, clamp_width/2) + linextr(-clamp_width_actual/2, clamp_width_actual/2) children(0); - linextr_x_yz(-main_r*5, main_r*5) - translate([screw_y, 0]) - circle(r= screw/2); + Screws(); + + for (i=[0 : hinge_lobes-1]) { + translate([0, + hinge_y, + -clamp_width_actual/2 + i * hinge_stride + + (hinge_alt ? hinge_stride/2 : 0) + ]) + linextr(-hinge_gap_z, hinge_stride/2) + square(hinge_outer_r*2 + hinge_gap_xy, center=true); + } + } +} + +module PowerBankItselfSidePlan(){ + translate([0, bank_bot_y]){ + minkowski(){ + circle($fn=8, r=liner_th); + scale( bank_profile_scale_bodge * + bank_x_sz / ( ( + bank_eps_bbox_x[1] - + bank_eps_bbox_x[0] + ) * pspt_to_mm )) + translate(pspt_to_mm * + [-0.5 * (bank_eps_bbox_x[0] + + bank_eps_bbox_x[1]), + -bank_eps_bbox_y[0]]) + import("powerbank-anker-10000.dxf", convexity=5); + } + } +} + +module PowerBankItself(){ ////toplevel + rotate([0,90,0]) + linextr_y_xz(-bank_y_sz/2, + +bank_y_sz/2) + PowerBankItselfSidePlan(); +} + +module PowerBankSidePlan(){ ////toplevel + render() difference(){ + rectfromto([ -holder_x_sz/2, 0 ], + [ +holder_x_sz/2, bank_recess_y + bank_bot_y ]); + + PowerBankItselfSidePlan(); + } +} + +module PowerBankStrapCut(){ ////toplevel + difference(){ + rectfromto([ -holder_x_sz, -0.05 ], + [ +holder_x_sz, strap_th + strap_r ]); + hull(){ + for (sx=[-1,+1]) { + translate([sx * (holder_x_sz/2 - strap_r + 0.1), + strap_th + strap_r]) + circle(strap_r); + } + } + } +} + +module PowerBankHolderTest(){ ////toplevel + difference(){ + linextr(-1,5) PowerBankSidePlan(); + linextr(0, strap_w) PowerBankStrapCut(); + } +} + +module EndRetainer(depth){ ////toplevel + translate([0, -bank_y_sz/2, 0]) { + linextr_y_xz(-endwall_th, 0) + rectfromto([ 0, -holder_x_sz/2 ], + [ -depth, +holder_x_sz/2 ]); + + for (m=[0,1]) { + mirror([0,0,m]) { + linextr(-holder_x_sz/2, -bank_x_sz/2){ + hull(){ + rectfromto([ 0, -endwall_th ], + [ depth, 0 ]); + rectfromto([ 0, 0 ], + [ 0.1, depth-0.1 ]); + } + } + } + } + } +} + +module BraceTubePlan(){ + intersection(){ + circle(r= brace_r); + rectfromto(brace_r * [-2, 0], + brace_r * [+2, +2]); + } +} + +module PowerBankHolder(){ ////toplevel + difference(){ + union(){ + rotate([0,90,0]) + linextr_y_xz(-(bank_y_sz/2 + 0.1), + +(bank_y_sz/2 + 0.1)) + PowerBankSidePlan(); + + EndRetainer(retainer_walls[0]); + mirror([0,1,0]) EndRetainer(retainer_walls[1]); + + translate([0,0, bank_x_sz/2]){ + for (y = brace_ctrs_y) { + translate([0,y,0]) { + linextr_x_yz(0, brace_total_len) + BraceTubePlan(); + } + } + translate([brace_total_len, 0,0]) + linextr_y_xz(brace_ctrs_y_nom[0] - brace_r, + brace_ctrs_y_nom[1] + brace_r) + BraceTubePlan(); + } + + for (strap_y = straps_y + straps_y_adj) { + translate([0, strap_y, 0]) { + linextr(-holder_x_sz/2, + +holder_x_sz/2){ + hull(){ + for (dy = [-1,+1] * + (strap_w/2 + strap_around_attach - strap_around_over)) { + translate([0, dy, 0]) + circle(r=strap_around_over); + } + } + } + } + } + } + + for (strap_y = straps_y + straps_y_adj) + translate([0, strap_y, 0]) + rotate([0,0,-90]) + rotate([0,90,0]) + linextr(-strap_w/2, + +strap_w/2) + PowerBankStrapCut(); + + translate([ bank_bot_y, -bank_y_sz/2, -bank_x_sz/2 ]) + linextr_y_xz(-50,50) + rotate([0,0,90]) + translate(bank_output_ctr) + square(center=true, bank_output_sz); + + translate([0, -(bank_y_sz/2 + endwall_th), 0] + 0.01 * [-1,-1]) { + linextr(-200,200){ + difference(){ + square(center=true, top_cnr_r*2); + translate(top_cnr_r * [1,1]) + circle(r= top_cnr_r); + } + } + } } } module TubeClampLeft() { ////toplevel - SomeClamp() - TubeClampLeftPlan(); + // We want this to print with the recess overhand to the right + // where the workpiece cooling fan is + rotate([0,0,180]){ + difference(){ + SomeClamp(true) + TubeClampLeftPlan(); + + Screws(); + } + } +} + +module PlacePowerBank(){ + translate([main_r, -mounted_pos_y_offset, 0]) + children(0); +} + +module Main(){ ////toplevel + TubeClampLeft(); + difference(){ + PlacePowerBank() + PowerBankHolder(); + rotate([0,0,180]) + Screws(); + } } module TubeClampRight() { ////toplevel - SomeClamp() - TubeClampRightPlan(); + rotate([0,0,180]) { + rotate([180,0,0]) { + difference(){ + union(){ + SomeClamp() + TubeClampRightPlan(); + + translate([clamp_gap/2 + behind_knob_th, screw_y, 0]) { + hull(){ + linextr_x_yz(-0.1, 0) + square(center=true, + [knob_behind_across, + knob_behind_across + knob_standout_h*2]); + linextr_x_yz(0, knob_standout_h) + square(center=true, + knob_behind_across); + } + } + } + Screws(); + } + } + } } -//TubeClampLeft(); -TubeClampRight(); +module TubeClampDemo() { ////toplevel + TubeClampLeft(); + rotate([180,0,0]) + TubeClampRight(); +} +module Demo() { ////toplevel + Main(); + rotate([180,0,0]) + TubeClampRight(); + PlacePowerBank() + %PowerBankItself(); +}