chiark / gitweb /
powerbank-bike-clamp: mid strap
[reprap-play.git] / powerbank-bike-clamp.scad
1 // -*- C -*-
2
3 // Print one of each:
4 //    Main
5 //    TubeClampRight
6
7 include <utils.scad>
8
9 tube_dia = 22.4;
10
11 hinge_around = 2.5;
12 hinge_pin = 1.8 + 0.75;
13 main_th = 3;
14 minor_wall_min = 1;
15
16 screw = 5.0 + 0.75;
17 screw_head = 8.7 + 1.2;
18 screw_nut_across = 7.9 + 0.75;
19 screw_nut_th = 3.9 + 0.75;
20
21 knob_behind_across = 12.2 + 0.75;
22 behind_knob_th = 5;
23 knob_standout_h = 2;
24
25 clamp_min_width = 20;
26
27 clamp_gap = 2;
28
29 lower_th = 1;
30
31 overlap_l = 0.1;
32
33 bridge_slop = 1.2;
34
35 hinge_lobe_per = 10;
36 hinge_gap_z = 0.75;
37 hinge_gap_xy = 0.75;
38
39 $fs = 0.1;
40 $fa = 5;
41
42 bank_eps_bbox_x = [149, 598];
43 bank_eps_bbox_y = [274, 1452];
44
45 bank_y_sz = 102.25 + 0.50 + 3.2;
46 bank_x_sz = (26.0 + 0.5);
47 bank_recess_y = 5;
48
49 strap_th = 3;
50 strap_w = 5;
51 strap_above = 2.5;
52
53 retainer_walls = [18, 30];
54
55 bank_profile_scale_bodge = 1.0;
56
57 bank_output_ctr = [ 12.5, 11.5 ]; // from nearest corner
58 bank_output_sz  = [ 11.0, 10.5 ];
59
60 mounted_pos_y_offset_lim = -100;
61
62 liner_th = 0.8;
63
64 brace_r = 5;
65 brace_len = 50;
66
67 // calculated
68
69 straps_y = [ -bank_y_sz * 0.25, // these entries are special and used
70              +bank_y_sz * 0.25, //  for the brace struts
71              0 ];
72
73 screw_head_behind = main_th;
74 endwall_th = main_th;
75
76 bank_recess_dx = minor_wall_min;
77
78 pspt_to_mm = 25.4 / 72;
79
80 main_r = tube_dia/2 + main_th;
81
82 screw_max_y_lhs = -main_r -screw_nut_across/2;
83 screw_max_y_rhs = -main_r -knob_behind_across/2;
84
85 screw_y = min(screw_max_y_lhs,
86               screw_max_y_rhs);
87
88 bot_y = screw_y -max( screw_nut_across/2, knob_behind_across/2 )
89   -minor_wall_min;
90
91 holder_x_sz = bank_x_sz + bank_recess_dx*2;
92 bank_bot_y = strap_above + strap_th;
93 strap_r = strap_th;
94
95 brace_total_len = brace_len + main_th;
96 brace_ctrs_y = [ straps_y[0] - (brace_r + strap_w/2),
97                  straps_y[1] + (brace_r + strap_w/2) ];
98
99 clamp_width_actual = max(clamp_min_width, holder_x_sz);
100
101 hinge_lobes = floor(clamp_width_actual / hinge_lobe_per);
102 hinge_stride = (clamp_width_actual + hinge_gap_z) / hinge_lobes;
103
104 hinge_outer_r = hinge_around + hinge_pin/2;
105 hinge_y = tube_dia/2 + hinge_outer_r;
106
107 top_cnr_r = min(endwall_th, main_th);
108
109 mounted_pos_y_offset = max(mounted_pos_y_offset_lim,
110                            bot_y - (-(bank_y_sz/2 + endwall_th)));
111
112
113 module TubePlan(){ circle(r = tube_dia/2); }
114 module HingePinPlan(){ translate([0, hinge_y]) circle(r= hinge_pin/2); }
115 module HingeBodyPlan(){ translate([0, hinge_y]) circle(r= hinge_outer_r); }
116
117 module TubeClampLeftPlan(){
118   difference(){
119     union(){
120       polygon([[ 0,                      hinge_y + hinge_outer_r ],
121                [ -(main_r + overlap_l),  hinge_y + hinge_outer_r ],
122                [ -(main_r + overlap_l),  bot_y                   ],
123                [ -clamp_gap/2,           bot_y                   ],
124                [ -clamp_gap/2,           0,                      ],
125                [ 0,                      0,                      ],
126                ]);
127       HingeBodyPlan();
128     }
129     TubePlan();
130     HingePinPlan();
131   }
132 }
133
134 module TubeClampLeft() { ////toplevel
135   linextr(-clamp_width_actual/2, clamp_width_actual/2)
136     TubeClampLeftPlan();
137 }
138
139 module TubeClampRightPlan(){
140   difference(){
141     union(){
142       rectfromto([ clamp_gap/2,                   bot_y ],
143                  [ clamp_gap/2 + behind_knob_th,  0     ]);
144       intersection(){
145         circle(r= main_r);
146         union(){
147           rectfromto([0,0],
148                       main_r *  [5,5]);
149           rectfromto([ clamp_gap/2, main_r*5 ],
150                       main_r * [2,-5]);
151         }
152       }
153       HingeBodyPlan();
154     }
155     TubePlan();
156     HingePinPlan();
157   }
158 }
159
160 module Screws(){
161   linextr_x_yz(-main_r*5, main_r*5)
162     translate([screw_y, 0])
163     circle(r= screw/2);
164
165   translate([0, screw_y, 0]) {
166     linextr_x_yz(-(clamp_gap/2 + screw_nut_th), 0)
167       square([screw_nut_across,
168               screw_nut_across / cos(30) + bridge_slop*2],
169              center=true);
170
171     linextr_x_yz(-200,
172                  -(clamp_gap/2 + screw_nut_th + screw_head_behind))
173       square([screw_head, screw_head + bridge_slop*2],
174              center=true);
175   }
176 }
177
178 module SomeClamp(hinge_alt=false){
179   difference(){
180     linextr(-clamp_width_actual/2, clamp_width_actual/2)
181       children(0);
182
183     Screws();
184
185     for (i=[0 : hinge_lobes-1]) {
186       translate([0,
187                  hinge_y,
188                  -clamp_width_actual/2 + i * hinge_stride
189                  + (hinge_alt ? hinge_stride/2 : 0)
190                  ])
191         linextr(-hinge_gap_z, hinge_stride/2)
192         square(hinge_outer_r*2 + hinge_gap_xy, center=true);
193     }
194   }
195 }
196
197 module PowerBankItselfSidePlan(){
198   translate([0, bank_bot_y]){
199     minkowski(){
200       circle($fn=8, r=liner_th);
201       scale( bank_profile_scale_bodge *
202              bank_x_sz / ( (
203                             bank_eps_bbox_x[1] -
204                             bank_eps_bbox_x[0]
205                             ) * pspt_to_mm ))
206         translate(pspt_to_mm *
207                   [-0.5 * (bank_eps_bbox_x[0] +
208                            bank_eps_bbox_x[1]),
209                    -bank_eps_bbox_y[0]])
210         import("powerbank-anker-10000.dxf", convexity=5);
211     }
212   }
213 }
214
215 module PowerBankItself(){ ////toplevel
216   rotate([0,90,0])
217     linextr_y_xz(-bank_y_sz/2,
218                  +bank_y_sz/2)
219     PowerBankItselfSidePlan();
220 }
221
222 module PowerBankSidePlan(){ ////toplevel
223   render() difference(){
224     rectfromto([ -holder_x_sz/2,  0 ],
225                [ +holder_x_sz/2,  bank_recess_y + bank_bot_y ]);
226
227     PowerBankItselfSidePlan();
228   }
229 }
230
231 module PowerBankStrapCut(){ ////toplevel
232   difference(){
233     rectfromto([ -holder_x_sz, -0.05 ],
234                [ +holder_x_sz, strap_th + strap_r ]);
235     hull(){
236       for (sx=[-1,+1]) {
237         translate([sx * (holder_x_sz/2 - strap_r + 0.1),
238                    strap_th + strap_r])
239           circle(strap_r);
240       }
241     }
242   }
243 }
244
245 module PowerBankHolderTest(){ ////toplevel
246   difference(){
247     linextr(-1,5) PowerBankSidePlan();
248     linextr(0, strap_w) PowerBankStrapCut();
249   }
250 }
251
252 module EndRetainer(depth){ ////toplevel
253   translate([0, -bank_y_sz/2, 0]) {
254     linextr_y_xz(-endwall_th, 0)
255     rectfromto([ 0,         -holder_x_sz/2 ],
256                [ -depth,    +holder_x_sz/2 ]);
257     
258     for (m=[0,1]) {
259       mirror([0,0,m]) {
260         linextr(-holder_x_sz/2, -bank_x_sz/2){
261           hull(){
262             rectfromto([ 0, -endwall_th ],
263                        [ depth, 0 ]);
264             rectfromto([ 0, 0 ],
265                        [ 0.1, depth-0.1 ]);
266           }
267         }
268       }
269     }
270   }
271 }
272
273 module BraceTubePlan(){
274   intersection(){
275     circle(r= brace_r);
276     rectfromto(brace_r * [-2,  0],
277                brace_r * [+2, +2]);
278   }
279 }
280
281 module PowerBankHolder(){ ////toplevel
282   difference(){
283     union(){
284       rotate([0,90,0])
285         linextr_y_xz(-(bank_y_sz/2 + 0.1),
286                      +(bank_y_sz/2 + 0.1))
287         PowerBankSidePlan();
288
289       EndRetainer(retainer_walls[0]);
290       mirror([0,1,0]) EndRetainer(retainer_walls[1]);
291
292       translate([0,0, bank_x_sz/2]){
293         for (y = brace_ctrs_y) {
294           translate([0,y,0]) {
295             linextr_x_yz(0, brace_total_len)
296               BraceTubePlan();
297           }
298         }
299         translate([brace_total_len, 0,0])
300           linextr_y_xz(brace_ctrs_y[0] - brace_r,
301                        brace_ctrs_y[1] + brace_r)
302           BraceTubePlan();
303       }
304     }
305
306     for (strap_y = straps_y)
307       translate([0, strap_y, 0])
308         rotate([0,0,-90])
309         rotate([0,90,0])
310         linextr(-strap_w/2,
311                 +strap_w/2)
312         PowerBankStrapCut();
313
314     translate([ bank_bot_y, -bank_y_sz/2, -bank_x_sz/2 ])
315       linextr_y_xz(-50,50)
316        rotate([0,0,90])
317        translate(bank_output_ctr)
318        square(center=true, bank_output_sz);
319
320     translate([0, -(bank_y_sz/2 + endwall_th), 0] + 0.01 * [-1,-1]) {
321       linextr(-200,200){
322         difference(){
323           square(center=true, top_cnr_r*2);
324           translate(top_cnr_r * [1,1])
325             circle(r= top_cnr_r);
326         }
327       }
328     }
329   }
330 }
331
332 module TubeClampLeft() { ////toplevel
333   // We want this to print with the recess overhand to the right
334   // where the workpiece cooling fan is
335   rotate([0,0,180]){
336     difference(){
337       SomeClamp(true)
338         TubeClampLeftPlan();
339
340       Screws();
341     }
342   }
343 }
344
345 module PlacePowerBank(){
346   translate([main_r, -mounted_pos_y_offset, 0])
347     children(0);
348 }
349
350 module Main(){ ////toplevel
351   TubeClampLeft();
352   difference(){
353     PlacePowerBank()
354       PowerBankHolder();
355     rotate([0,0,180])
356       Screws();
357   }
358 }
359
360 module TubeClampRight() { ////toplevel
361   rotate([0,0,180]) {
362     rotate([180,0,0]) {
363       difference(){
364         union(){
365           SomeClamp()
366             TubeClampRightPlan();
367
368           translate([clamp_gap/2 + behind_knob_th, screw_y, 0]) {
369             hull(){
370               linextr_x_yz(-0.1, 0)
371                 square(center=true,
372                        [knob_behind_across,
373                         knob_behind_across + knob_standout_h*2]);
374               linextr_x_yz(0, knob_standout_h)
375                 square(center=true,
376                        knob_behind_across);
377             }
378           }
379         }
380         Screws();
381       }
382     }
383   }
384 }
385
386 module TubeClampDemo() { ////toplevel
387   TubeClampLeft();
388   rotate([180,0,0])
389     TubeClampRight();
390 }
391
392 module Demo() { ////toplevel
393   Main();
394   rotate([180,0,0])
395     TubeClampRight();
396   PlacePowerBank()
397     %PowerBankItself();
398 }