]> www.fi.muni.cz Git - bike-lights.git/blob - parts/rearlight.scad
ecc53dd8c3698414085b6004d1e973bcd0a0f9ae
[bike-lights.git] / parts / rearlight.scad
1 // Holder for Fraen FHS-HEB1-LB01-x lens for Luxeon LEDs.
2 // I use it for my rear lights.
3
4 epsilon = 0.01;
5 infty = 100;
6 debug = 0;
7
8 wall_thickness = 2;
9 fraen_diam = 30.75;
10 fraen_h = 29.8;
11 pin_diam = 4;
12 pin_offset = 10.35*1.4142;
13 pin_len = 9.2;
14 front_add = 4;
15
16 rear_pin_dist = 9.1;
17 rear_pin_diam = 3.25;
18
19 side_barrier_x_offset = 13;
20 side_barrier_pin_z_offset = 4.2;
21 side_barrier_thickness = 2;
22
23 heatsink_thickness = 2;
24
25 clip_h1 = 27; // front height (on the heatsink side)
26 clip_h2 = 20; // rear height (on the lens side)
27 clip_l  = 28;
28 clip_wall = wall_thickness;
29 clip_space = 3.5;
30 clip_bolt1_z = 6;
31 clip_bolt1_x = 20;
32 clip_bolt2_z = 22;
33 clip_bolt2_x = 23;
34 clip_angle = 24;
35 clip_top_xoff = clip_l*tan(clip_angle);
36
37 clip_y_off = 37;
38 clip_x_off = 0;
39
40 // z-axis is up
41 module bolt_mount(d, h, w1, w2, fn) {
42         difference() {
43                 translate([0, 0, -epsilon])
44                         cylinder(r1=w2/2, r2=w1/2, h=h+epsilon);
45                 translate([0, 0, -2*epsilon])
46                 cylinder(r=d/2, h=h+3*epsilon, $fn=fn);
47         };
48 };
49
50 module seat_clip() {
51         difference() {
52                 union() {
53                         // right part
54                         hull() {
55                                 translate([0, clip_space/2, 0])
56                                         cube([clip_h1, clip_wall, epsilon]);
57                                 translate([clip_top_xoff, clip_space/2, clip_l])
58                                         cube([clip_h2, clip_wall, epsilon]);
59                         };
60
61                         // left part
62                         hull() {
63                                 translate([0, -clip_space/2-clip_wall, 0])
64                                         cube([clip_h1, clip_wall, epsilon]);
65                                 translate([0+clip_top_xoff, -clip_space/2-clip_wall, clip_l])
66                                         cube([clip_h2, clip_wall, epsilon]);
67                         };
68
69                         // top part
70                         hull() {
71                                 translate([-clip_wall, -clip_space/2-clip_wall, 0])
72                                         cube([clip_wall+epsilon, 2*clip_wall+clip_space, epsilon]);
73                                 translate([-clip_wall+clip_top_xoff, -clip_space/2-clip_wall, clip_l])
74                                         cube([clip_wall+epsilon, 2*clip_wall+clip_space, epsilon]);
75                         };
76
77                         // bolt mounts
78                         translate([clip_bolt1_x, clip_space/2 + clip_wall, clip_bolt1_z])
79                         rotate([-90, 0, 0])
80                         bolt_mount(6.5, 2, 7, 12, 32);
81
82                         translate([clip_bolt1_x, -clip_space/2 - clip_wall, clip_bolt1_z])
83                         rotate([90, 0, 0])
84                         bolt_mount(6.5, 2, 7, 12, 6);
85
86                         translate([clip_bolt2_x, clip_space/2 + clip_wall, clip_bolt2_z])
87                         rotate([-90, 0, 0])
88                         bolt_mount(6.5, 2, 7, 12, 32);
89
90                         translate([clip_bolt2_x, -clip_space/2 - clip_wall, clip_bolt2_z])
91                         rotate([90, 0, 0])
92                         bolt_mount(6.5, 2, 7, 12, 6);
93                 };
94                 // bolt holes
95                 translate([clip_bolt1_x, infty/2, clip_bolt1_z])
96                         rotate([90, 0, 0])
97                         cylinder(r=2, h=infty, $fn = 6);
98                 translate([clip_bolt2_x, infty/2, clip_bolt2_z])
99                         rotate([90, 0, 0])
100                         cylinder(r=2, h=infty, $fn = 6);
101         }
102
103 }
104
105 // upper part of the lens holder
106 module round_part() {
107         difference() {
108                 cylinder(r = fraen_diam/2 + pin_diam/2 + wall_thickness,
109                         h = front_add + pin_len);
110
111                 hull() {
112                         translate([0, 0, -epsilon])
113                                 cylinder(r = fraen_diam/2,
114                                         h = pin_len + front_add + 2*epsilon);
115                         for (angle = [0, 90, 180, 270]) {
116                                 rotate([0, 0, angle+45])
117                                         translate([pin_offset, 0, -epsilon])
118                                                 cylinder(r=pin_diam/2,
119                                                         h=epsilon);
120                         };
121                 }
122
123                 // front cone
124                 translate([0, 0, pin_len + 0.5*wall_thickness - epsilon])
125                         cylinder(r1 = fraen_diam/2,
126                                 r2 = (fraen_diam+pin_diam + wall_thickness)/2,
127                                 h = front_add - 0.5*wall_thickness+ 2*epsilon);
128                 // pin holes
129                 for (angle = [0, 90, 180, 270]) {
130                         rotate([0, 0, angle+45])
131                                 translate([pin_offset, 0, epsilon])
132                                         cylinder(r=pin_diam/2,
133                                                 h=pin_len+epsilon);
134                 };
135         };
136
137         // side barriers
138         for (angle = [0, 90, 180]) // omit the bottom one
139                 rotate([0, 0, angle])
140                         intersection() {
141                                 cylinder(r=fraen_diam/2+epsilon, h=infty);
142                                 translate([-infty/2, side_barrier_x_offset,
143                                         wall_thickness + pin_len - side_barrier_pin_z_offset - side_barrier_thickness ])
144                                         cube([infty, infty, side_barrier_thickness]);
145                 };
146 };
147
148 module square_cone() {
149         difference() {
150                 hull() {
151                         translate([0, 0, fraen_h - pin_len])
152                                 cylinder(r = fraen_diam/2 + pin_diam/2 + wall_thickness,
153                                         h = epsilon);
154                         for (angle = [0, 90, 180, 270])
155                                 rotate([0, 0, angle])
156                                         translate([rear_pin_dist, rear_pin_dist, 0])
157                                                 cylinder(r=wall_thickness+3.75/2, h = epsilon);
158                 }
159                 hull() {
160                         translate([0, 0, fraen_h - pin_len + epsilon])
161                                 cylinder(r = fraen_diam/2,
162                                         h = epsilon);
163                         for (angle = [0, 90, 180, 270]) {
164                                 rotate([0, 0, angle]) 
165                                         translate([rear_pin_dist, rear_pin_dist, -epsilon])
166                                                 cylinder(r=3.75/2, h = epsilon);
167                                 rotate([0, 0, angle+45])
168                                         translate([pin_offset, 0, fraen_h - pin_len + epsilon])
169                                                 cylinder(r=pin_diam/2,
170                                                         h=epsilon);
171                         }
172                 }
173         }
174 }
175
176 rear_spring_w = 2*rear_pin_dist-rear_pin_diam-0.5;
177 rear_spring_h = 1;
178 rear_spring_center_w = 4;
179 led_zoff = 6;
180
181 module rear_spring() {
182         translate([0, 0, wall_thickness/2])
183                 cube([rear_spring_center_w, rear_spring_w, wall_thickness],
184                         center=true);
185         translate([0, rear_spring_w/2-wall_thickness/2,
186                 (led_zoff-heatsink_thickness)/2])
187                 cube([rear_spring_center_w,
188                         wall_thickness, led_zoff-heatsink_thickness],
189                         center=true);
190         translate([0, -rear_spring_w/2+wall_thickness/2,
191                 (led_zoff-heatsink_thickness)/2])
192                 cube([rear_spring_center_w,
193                         wall_thickness, led_zoff-heatsink_thickness],
194                         center=true);
195
196         for (angle=[0, 180]) {
197                 rotate([0, 0, angle])
198                 translate([5.5, 0, rear_spring_h/2])
199                         rotate([0, 0, 45]) {
200                                 cube([wall_thickness, 14, rear_spring_h],
201                                         center=true);
202                 }
203         }
204 }
205
206 module heatsink_holder() {
207         for (angle = [0, 180]) {
208                 rotate([0, 0, angle])
209                         translate([rear_pin_dist+wall_thickness, 0, led_zoff/2])
210                         cube([rear_pin_diam/2+wall_thickness, 2*rear_pin_dist-rear_pin_diam-0.5, led_zoff], center=true);
211         }
212 }
213
214 module lens_holder() {
215         difference() {
216                 union() {
217                         translate([0, 0, fraen_h - pin_len])
218                                 round_part();
219                         square_cone();
220                 };
221                 
222                 // 0.5mm hole in the bottom
223                 // translate([side_barrier_x_offset-epsilon, -0.25, -epsilon])
224                 translate([0, -0.25, (fraen_h - pin_len)/2])
225                         cube([infty, 0.5, infty]);
226
227                 // cable hole, 2*3mm
228                 translate([rear_pin_dist, 0, 6+3])
229                         rotate([0, 0, 60])
230                                 cube([infty, 2, 3]);
231
232                 // side LED hole, 3mm
233                 translate([0, 0, fraen_h - pin_len])
234                         rotate([90, 0, 0])
235                                 cylinder(r=rear_pin_diam/2, h=infty, $fn=6);
236         };
237                 
238         rear_spring();
239         heatsink_holder();
240 };
241
242 module xy_joint() {
243         hull() {
244                 intersection() {
245                         lens_holder();
246                         translate([-infty-0.5*rear_pin_dist,
247                                 rear_pin_dist+rear_pin_diam/2+0.35*wall_thickness,
248                                 0])
249                                 cube([infty, infty, clip_wall]);
250                 };
251
252                 translate([clip_x_off, clip_y_off, 0])
253                         intersection() {
254                                 seat_clip();
255                                 translate([-infty+clip_wall+0.20*clip_h1, -infty-clip_space, 0])
256                                         cube([infty, infty, clip_wall]);
257                         };
258         };
259         hull() {
260                 intersection() {
261                         lens_holder();
262                         translate([0.5*rear_pin_dist,
263                                 rear_pin_dist+rear_pin_diam/2+0.35*wall_thickness,
264                                 0])
265                                 cube([infty, infty, clip_wall]);
266                 };
267
268                 translate([clip_x_off, clip_y_off, 0])
269                         intersection() {
270                                 seat_clip();
271                                 translate([0.8*clip_h1-clip_wall, -infty-clip_space, 0])
272                                         cube([infty, infty, clip_wall]);
273                         };
274         };
275 };
276
277 module yz_joint() {
278         difference() {
279                 hull() {
280                         translate([clip_x_off, clip_y_off, 0])
281                                 intersection() {
282                                         seat_clip();
283                                         translate([-1.5*clip_wall+(fraen_h-pin_len)*tan(clip_angle), -clip_space/2-clip_wall+epsilon, 0])
284                                         cube([clip_wall, epsilon, fraen_h - pin_len]);
285                                 };
286                         translate([clip_x_off - 1.5*clip_wall+(fraen_h-pin_len)*tan(clip_angle), 0, 0])
287                    
288                                 cube([clip_wall, epsilon, (fraen_h - pin_len)]);
289                 };
290                 hull() {
291                         translate([0, 0, fraen_h - pin_len + epsilon])
292                                 cylinder(r = fraen_diam/2 + pin_diam/2 + wall_thickness/2,
293                                         h = epsilon);
294                         for (angle = [0, 90, 180, 270])
295                                 rotate([0, 0, angle])
296                                         translate([rear_pin_dist, rear_pin_dist, -epsilon])
297                                                 cylinder(r=wall_thickness/2+3.75/2, h = epsilon);
298                 };
299         };
300 };
301
302 module full_joint() {
303         difference() {
304                 hull() {
305                                 intersection() {
306                                         rotate([-90, 0, 0])
307                                         scale([0.30, 1, 1])
308                                                 cylinder(r = fraen_h-pin_len, h = rear_pin_dist + wall_thickness+rear_pin_diam/2);
309                                         translate([-infty/2, rear_pin_dist + wall_thickness + rear_pin_diam/2 - epsilon, 0])
310                                                 cube(infty);
311                                 };
312                         translate([clip_x_off, clip_y_off, 0])
313                                 intersection() {
314                                         seat_clip();
315                                         translate([(fraen_h-pin_len)*tan(clip_angle)-clip_wall, -clip_space/2-clip_wall+epsilon, 0])
316                                                 rotate([90, 0, 0])
317                                                 scale([0.45, 1, 1])
318                                                         cylinder(r = fraen_h-pin_len, h = epsilon);
319                                 };
320                 };
321                 hull() {
322                         translate([0, 0, fraen_h - pin_len + epsilon])
323                                 cylinder(r = fraen_diam/2 + pin_diam/2 + wall_thickness/2,
324                                         h = epsilon);
325                         for (angle = [0, 90, 180, 270])
326                                 rotate([0, 0, angle])
327                                         translate([rear_pin_dist, rear_pin_dist, -epsilon])
328                                                 cylinder(r=wall_thickness/2+3.75/2, h = epsilon);
329                 };
330         }
331 };
332
333 module main() {
334         lens_holder();
335         translate([clip_x_off, clip_y_off, 0])
336                 seat_clip();
337         // xy_joint();
338         // yz_joint();
339         full_joint();
340 };
341
342
343 scale([1, -1, 1]) main($fn=128);
344 // main($fn = 128);
345         // vnitrni prumer kruhu by mel byt 30.75mm
346         // vnejsi prumer aspon 35 mm
347         // pin od stredu 10.35mm na x a y
348         // prumer pinu 4 mm
349         // pin ma od cela do zabrany 4.2mm, celkove by mel mit 9.2mm
350
351         // piny by mely pokracovat jeste tak 4mm pod nulu,
352         // a pak uz muze jit konv.obal do ctverce
353         // vnitrni rozmery ctverce 21.5x21.5, zakulacene rohy prumer 3.5
354         // vrch chladice (s LEDkou) -18.5
355         // konec nozicek -24.5