case.scad: more improvements
[heater.git] / case.scad
1 lowres = 0;
2
3 eps = 0.01;
4 infty = 300;
5
6 wall = 1.5; // generic wall thickness
7
8 // 18650 is ~18mm diameter, ~65mm length, 
9 batt_diam = 18 + 0.6;
10 batt_len = 65 + 1.5;
11
12 cable_sep = 1;
13
14 // front flat area
15 front_flat_len = batt_len + 4*wall + 2*cable_sep;
16
17 // PCB-related dimensions
18 pcb_len = 36 + 1;       // length of the board
19 pcb_width = 11 + 0.5;   // width of the board
20 pcb_thick = 1.2 + 0.3;  // thickness of the board
21 pcb_comp_h = 2.2;       // height of the components on board
22 pcb_groove = 1;
23
24 body_top_h = 0.35 * batt_diam; // cube-shaped part of the body
25
26 outwire_thick = 2.2;
27 wire_thick = 2.2;
28 wire_sep = 3.5;
29 cable_out_diam = 5.2;
30
31 batt_end_h = wire_sep/2 + wire_thick/2 + 1.5;;
32
33 lid_sep = 0.5; // the lid is made this much smaller to separate from the body
34
35 sw_diam = 2.5 + 0.5;
36 led_diam = 3 + 0.5;
37 sw_xoff =  250 * 25.4/1000; // x offset of microswitches
38 pcb_xoff = 90 * 25.4/1000; // offset of the LED from the middle of the PCB
39
40 prg_len = 10; // programming connector
41 prg_width = 7;
42
43 module case_body() {
44         hull() {
45                 translate([-batt_len/2-2*wall-cable_sep, -batt_diam/2-wall, 0])
46                         cube([batt_len + 4*wall + 2*cable_sep,
47                                 batt_diam+2*wall, body_top_h]);
48                 difference() {
49                         translate([-batt_len/2-2*wall-cable_sep, 0, 0])
50                                 rotate([0, 90, 0])
51                                 cylinder(r=batt_diam/2+wall,
52                                         h = batt_len + 4*wall + 2*cable_sep);
53                         translate([-infty/2, -infty/2, eps]) cube(infty);
54                 };
55                 translate([-front_flat_len/2,
56                         batt_diam/2 - pcb_width,
57                         -batt_diam/2-2*pcb_comp_h-pcb_thick-wall])
58                         cube([front_flat_len, pcb_width+wall, eps]);
59         };
60 };
61
62 module case() {
63         difference() {
64                 case_body();
65                 // upper cube-shaped part
66                 // rotate([20, 0, 0])
67                 translate([-batt_len/2, -batt_diam/2, 0])
68                         cube([batt_len, batt_diam, batt_diam]);
69
70                 // battery cylinder for the lower part
71                 translate([-batt_len/2, 0, 0])
72                         rotate([0, 90, 0])
73                         cylinder(r=batt_diam/2, h = batt_len);
74
75                 // hole for PCB
76                 translate([-pcb_len/2-pcb_xoff,
77                         batt_diam/2-pcb_width,
78                         -batt_diam/2-pcb_thick - pcb_comp_h])
79                         cube([pcb_len, pcb_width,
80                                 batt_diam/2 + pcb_thick + pcb_comp_h + eps]);
81                 // hole above the PCB
82                 translate([-pcb_len/2-pcb_xoff-wall-2*outwire_thick,
83                         batt_diam/2-pcb_width,
84                         -batt_diam/2-pcb_comp_h])
85                         cube([pcb_len, pcb_width,
86                                 batt_diam/2 + pcb_comp_h + eps]);
87                 // hole under the PCB
88                 translate([-pcb_len/2+pcb_groove-pcb_xoff,
89                         batt_diam/2-pcb_width + pcb_groove,
90                         -batt_diam/2-pcb_thick - 2*pcb_comp_h])
91                         cube([pcb_len-2*pcb_groove, pcb_width-2*pcb_groove,
92                                 batt_diam/2 + pcb_thick + pcb_comp_h + eps]);
93                 // hole for prog connector
94                 translate([pcb_len/2-pcb_xoff-pcb_groove-eps,
95                         batt_diam/2-pcb_width/2-prg_width/2,
96                         -batt_diam/2-pcb_thick - 2*pcb_comp_h])
97                         difference() {
98                                 cube([prg_len+pcb_groove+eps, prg_width,
99                                         batt_diam/2 + pcb_thick + pcb_comp_h + eps]);
100                                 translate([prg_len/2+pcb_groove, -eps, pcb_comp_h])
101                                         cube([prg_len/2+eps, prg_width+2*eps, pcb_thick]);
102                         };
103                 // LED hole
104                 translate([0, batt_diam/2-pcb_width/2, -infty/2]) {
105                         cylinder(r=led_diam/2, h=infty, $fn=6);
106                         translate([sw_xoff, 0, 0])
107                                 cylinder(r=sw_diam/2, h=infty, $fn=6);
108                         translate([-sw_xoff, 0, 0])
109                                 cylinder(r=sw_diam/2, h=infty, $fn=6);
110                 };
111                 // cable outlet
112                 translate([-pcb_xoff-pcb_len/2-outwire_thick-wall, -6, 0])
113                         rotate([40, 0, 0])
114                         scale([2, 1, -1])
115                         cylinder(r=outwire_thick/2, h = infty, $fn=12);
116                 // space under the wire holes for battery contacts
117                 translate([-batt_len/2-2*wall-cable_sep-eps, 0, 0])
118                         difference() {
119                                 rotate([0, 90, 0])
120                                         cylinder(r = batt_diam/2-wall, h = batt_len + 4*wall + 2*cable_sep + 2*eps);
121                                 translate([-infty/2, -infty/2, -batt_end_h])
122                                         cube(infty);
123                         };
124                 // space above the wire holes for battery contacts
125                 translate([-batt_len/2-2*wall-cable_sep-eps, -batt_diam/2, batt_end_h])
126                         cube([batt_len + 4*wall + 2*cable_sep + 2*eps, 
127                                 batt_diam,
128                                 batt_end_h]);
129                 // wire holes for battery contacts
130                 for (x = [-1, 1])
131                 for (y = [-1, 1])
132                         translate([-batt_len/2-wall-eps, x*wire_sep/2, y*wire_sep/2])
133                         rotate([0, 90, 0])
134                                 cylinder(r = wire_thick/2, h = batt_len + 2*wall + 2*eps, $fn=6);
135                 // wire hole from PCB to battery contacts
136                 // translate([-batt_len/2-wall-eps, 0, -batt_diam/2-pcb_comp_h + wire_thick/2])
137                 rotate([40, 0, 0])
138                 translate([-batt_len/2-wall-eps, 0, -batt_diam/2 - wall/2 - wire_thick/2])
139                         rotate([0, 90, 0])
140                                 cylinder(r = wire_thick/2, h = batt_len + 2*wall + 2*eps, $fn=6);
141                 // hole behind the battery contacts
142                 for(x=[1, -1])
143                 scale([x, 1, 1]) translate([batt_len/2+wall, 0, 0]) hull() {
144                         translate([0, -batt_diam/2, 0])
145                                 cube([wall + cable_sep + eps, batt_diam, infty]);
146                         rotate([0, 90, 0])
147                                 cylinder(r = batt_diam/2, h = wall+cable_sep+eps);
148                         translate([0, batt_diam/2 - pcb_width,
149                                 -batt_diam/2-pcb_comp_h-pcb_thick])
150                                 cube([wall + cable_sep + eps, pcb_width, eps]);
151                         translate([cable_sep, batt_diam/2 - pcb_width + 1.5*wall,
152                                 -batt_diam/2-pcb_comp_h-pcb_thick-wall])
153                                 cube([wall + eps, pcb_width-2*wall, eps]);
154                 };
155                 // cable lead to battery contacts
156                 for (x=[1, -1]) scale([x, 1, 1])
157                         rotate([-140, 0, 0])
158                         translate([batt_len/2+wire_thick/2, 0, batt_diam/2-2*wall])
159                                 cylinder(r=wire_thick/2, h = 5);
160                 
161                 // mounting holes
162                 for(x=[-1,1]) scale([x, 1, 1])
163                 translate([batt_len/2-wall-wire_thick, batt_diam/2+2*wall, -batt_diam/2-pcb_thick-2*pcb_comp_h-wall])
164                         vert_torus();
165                         
166                 for (x = [-1, 1]) scale([x, 1, 1]) for (x0 = [0, 10])
167                         translate([batt_len/2-wall-wire_thick-x0, 0, batt_end_h-wire_thick/2])
168                         rotate([-90, 0, 0])
169                         scale([2,1,1]) cylinder (r=wire_thick/2, h=infty, $fn=16);
170         };
171         // clip barrier
172         for (x = [-1, 1]) scale([x, 1, 1])
173                 translate([batt_len/2+wall-eps, batt_diam/2-pcb_width+wall+lid_sep,
174                         -batt_diam/2-pcb_thick-pcb_comp_h + wall + lid_sep])
175                         cube([cable_sep+eps, pcb_width-2*wall-2*lid_sep, wall]);
176 };
177
178 module lid_body() {
179         translate([-batt_len/2 - wall - lid_sep, -batt_diam/2+lid_sep, -batt_diam/2 -wall])
180                 cube([batt_len + 2*wall + 2*lid_sep, batt_diam-2*lid_sep, batt_diam/2 - batt_end_h + wall - lid_sep]);
181         translate([-batt_len/2 - 2*wall - cable_sep, -batt_diam/2 - wall,
182                 -batt_diam/2-wall])
183                 cube([batt_len + 4*wall + 2*cable_sep, batt_diam + 2*wall,
184                         wall + batt_diam/2 - body_top_h - lid_sep]);
185         // clip behind the battery contacts
186         for(x=[1, -1])
187                 scale([x, 1, 1]) translate([batt_len/2+wall+lid_sep, 0, 0]) hull() {
188                         translate([0, -batt_diam/2+lid_sep, -batt_diam/2])
189                                 cube([wall+cable_sep-lid_sep, batt_diam-2*lid_sep, eps]);
190                         rotate([0, 90, 0])
191                                 cylinder(r = batt_diam/2-lid_sep, h = wall+cable_sep-lid_sep);
192                         translate([0, batt_diam/2 - pcb_width+lid_sep,
193                                 batt_diam/2+pcb_comp_h+pcb_thick-lid_sep])
194                                 cube([wall+cable_sep-lid_sep, pcb_width-2*lid_sep, eps]);
195                         translate([cable_sep+wall/2, batt_diam/2 - pcb_width + 1.5*wall +lid_sep,
196                                 batt_diam/2+pcb_comp_h+pcb_thick+wall/2-lid_sep])
197                                 cube([wall/2-lid_sep, pcb_width-2*wall-2*lid_sep, eps]);
198                 };
199 };
200
201 module lid() {
202         difference() {
203                 lid_body();
204                 translate([-batt_len/2+eps, 0, 0]) rotate([0, 90, 0])
205                         cylinder(r=batt_diam/2, h=batt_len-2*eps);
206                 hull() {
207                         difference() {
208                                 translate([-batt_len/2-cable_sep-wall, 0, 0]) rotate([0, 90, 0])
209                                         cylinder(r=batt_diam/2-wall-lid_sep, h=batt_len+2*wall+2*cable_sep);
210                                 translate([-infty/2, -batt_diam/2, -infty-wire_sep/2-wire_thick/2])
211                                         cube([infty, batt_diam, infty]);
212                         };
213                         translate([-batt_len/2-cable_sep-wall, batt_diam/2-pcb_width+0.5*wall+0.5*lid_sep, batt_diam/2 + pcb_comp_h+pcb_thick-wall-lid_sep])
214                         cube([batt_len + 2*wall + 2* cable_sep, pcb_width-1.5*wall-1.5*lid_sep, eps]);
215                 };
216         };
217 };
218
219 module vert_torus() {
220         rotate([0, 90, 0])
221         scale([1, 1, 2])
222         rotate_extrude() translate([5, 0, 0]) circle(r=wire_thick/2, $fn=16);
223 };
224
225 if (lowres) {
226         translate([0, 15, 0]) case();
227         translate([0, -15, 0]) rotate([180, 0, 0]) lid();
228 } else {
229         translate([0, 15, batt_diam/2+pcb_thick+2*pcb_comp_h+wall])
230                 case($fn=128);
231         translate([0, -15, batt_diam/2+wall])
232                 lid($fn=128);
233 }
234