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