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