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