-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPi4with2hatsCase.scad
255 lines (250 loc) · 19.2 KB
/
Pi4with2hatsCase.scad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
// Comments
// Openscad model of a Raspberry pi 4 case with space and holes for pivoyager and pilotiot hats.
// Original file maintained in https://github.com/Vayatoalla/OpenScadModels
// Based on a design by George Onoufriou (https://github.com/DreamingRaven/RavenSCAD/blob/master/LICENSE)
// |-=========---------| <-The back right of the board is the point everything else is relative to
// | o o |
// | o o |
// ||_|----------------|
//Variables
board_thickness = 1.5; // the space for the board itself only
boardw1hat_thickness = 15; // the space of the rpi board with the first hat. Will need it for the holes in the card
boardw2hat_thickness = 28; // the space of the rpi board with two hats. Will need it for the holes in the card
inhibitionzone_height_noups =boardw2hat_thickness-board_thickness-5;
pin_space = 3;//2.2; // the min space that the throughhole components require underneath - Height of the mounts (up and down)
$fn = 20; // how detailed the circular components are (holes + mounts), not super important
extension = 20; // extension to lengths so case can be subtractiveley created
inhibitionzone_height= 34.5; //inhibition zone for 3g and pivoyager hats
case_thickness = 2; // sets the case thickness
pil = 87; // this is the length of the pi board only
pid = 57; // this is the width / depth of the pi board only
pih = board_thickness;
sd_height = case_thickness+pin_space+0.5; // is how tall the sd card part sticking out
mount_pin_height = 2*board_thickness + 2*case_thickness + pin_space + inhibitionzone_height; // this is the most awkward one of the set as it sets the mount point pin size
// I want a rounded box. I will achieve it using Minkowsky addition
mink_functs_height = 0.5; //the height we are using in the cylinders, in Minkowsky functions. Not importante, only keep low
case_int_radio = 3; //internal radio or the cases corner. Used in Minkowsky functions
nuts_height = 2.2; //the height of the nuts holes (and the screw heads)
// Added Space For Battery And Hats
battd = 20; //width / depth space for battery
upscardd = 30.5; //the UPS board width / depth
eth_height = 13.6;
usbs_height = 15.6;
intrabatth = 5; //height of the separation/nerves inserted between battery and the raspberry
y_antenna_eth_conn = 11; //y axis of the antenna over the eth port (both antennas are symetrical in the y axis).
x_to_first_mount_center = 23;
mount_diameter = 7;
screw_head_diam = 5; // screw head hole, will be over the case
xmountspace = 58.8; //x distance between mounts
ymountspace = 49.8; //y distance between mounts
x_upsusbconn = 31; //x of ups usb connector
x_step_begin = x_upsusbconn-2; //the UPS USB step initial point is just before ups connector plus space for the cable connector
antennaholeradio = 5;
xmounts=1.25; //x position of the first mount (apart from x_to_fist_mount_center translate)
ymounts=1.25; //y position of the first mount
// comment here what you dont want to generate
// translate([-40,0,inhibitionzone_height + case_thickness + board_thickness]) rotate([0,270,0]) intersection(){rpi4_case(); topSelector();} // top of case
translate([-40,0,0]) rotate([0,270,0]) intersection(){rpi4_case(); topSelector();} // top of case
translate([-90,120,case_thickness]) rotate([0,0,0]) difference(){rpi4_case(); topSelector(); } // bottom of case
//translate([-pil,pid+case_thickness*2+5]) rpi4_case(); // the whole unsplit case
//translate([extension+17.44+30,pid+case_thickness*2+5,0]) rpi4andbatt(); // the raspberry pi 4 and associated tolerances
//rpi4andbatt(); // the raspberry pi 4 and associated tolerances
// here follows all the modules used to generate what you want.
//mounts();
//topSelector();
module topSelector()
translate([-case_thickness,0,0]) {
difference(){ // this difference selects the top and bottom parts of the case with a small lip for the IO
union(){
cube([pil-case_int_radio-case_thickness,pid+battd+case_thickness,inhibitionzone_height+board_thickness]); // test hull
translate([0,0,inhibitionzone_height+board_thickness-pin_space-case_thickness])
cube([pil+case_thickness,pid+battd+case_thickness,pin_space+case_thickness]); // just under top of case (to take the mounts).
translate([0,-case_thickness,inhibitionzone_height+board_thickness])
cube([pil+2*case_thickness,pid+battd+2*case_thickness,case_thickness]); // top top of case
translate([pil-case_int_radio-case_thickness,battd+case_thickness+upscardd,inhibitionzone_height_noups+board_thickness])
{
cube([3*case_thickness+case_int_radio,pid-upscardd,3*case_thickness+pin_space+4]); // ups corner
translate([0,0,-pin_space]) cube([2*case_thickness+case_int_radio,pid-upscardd,pin_space]); //The mounts
}
translate([0,pid+battd+case_thickness,3.6+board_thickness]) {
cube([pil+2*case_thickness,case_thickness,inhibitionzone_height-(3.6)+board_thickness+case_thickness]); // over hdmi side
translate([case_thickness,0,0]) rotate([0,90,0]) linear_extrude(height=pil) polygon(points=[[0,0],[0,case_thickness],[1.8*case_thickness,0]]); //little angle, to fit well up and down
}
}
union(){
cube([case_thickness+2*case_int_radio,18.45+battd+case_thickness,board_thickness+eth_height]); //Over Eth case
translate([0,18.45+battd+case_thickness,0]) cube([case_thickness+2*case_int_radio,pid+battd-(18.45+battd),board_thickness+usbs_height-3]); //Over USB case
//translate([pil+case_thickness-case_int_radio,0,inhibitionzone_height+board_thickness-pin_space-case_thickness]) cube([case_int_radio,case_int_radio,pin_space+case_thickness]); //little correction at end right corner
translate([case_thickness, 0,0]) cube([pil,mount_diameter+2,inhibitionzone_height+board_thickness-pin_space]); //batt mounts selector
}
}
translate([0,pid+battd-1,3.6+board_thickness])
cube([case_thickness+case_int_radio,case_thickness+1,inhibitionzone_height-(3.6)+board_thickness+case_thickness]); // over hdmi side corner
}
module basic_case() //this is the shell case. We will substract the rpi model from it.
difference(){ // subtracts the rpi4 step from a cube to generate the basic case
minkowski(){
translate([(case_int_radio+case_thickness),(case_int_radio+case_thickness),0]){
cube([pil+(2*case_thickness)-2*(case_int_radio+case_thickness),
pid+battd+(3*case_thickness)-2*(case_int_radio+case_thickness),
pin_space+inhibitionzone_height+board_thickness+(2*case_thickness)-mink_functs_height]);
} // the case itself
cylinder(mink_functs_height, r=case_int_radio+case_thickness);
}
translate([x_step_begin+case_thickness,upscardd+battd+(3*case_thickness), pin_space+inhibitionzone_height_noups+board_thickness+(2*case_thickness)]) //Side of UPS Card
cube([pil-x_step_begin+case_thickness,pid-upscardd,inhibitionzone_height-inhibitionzone_height_noups]); // avoid screw hole
}
module rpi4_case() //the whole case
difference() { // subtracts the rpi4 model from a cube to generate the case
translate([-case_thickness,-case_thickness,-(case_thickness + pin_space)]) basic_case(); // the case itself
translate([0,(battd+case_thickness),0]) {
union(){
rpi4andbatt();
pins(); // generating the pins themselves so the holes can be inhibited
nuts();
}
}
}
module rpi4andbatt() //this module adds the battery space
difference() {
union() {
rpi4();
translate([intrabatth,-case_thickness,0])
cube([(pil-2*intrabatth), case_thickness, (inhibitionzone_height+board_thickness-intrabatth)]); // nerves between batt and rpi
translate([0,-(battd+case_thickness),-pin_space])
minkowski() {
translate([case_int_radio,case_int_radio,0])
cube([pil-2*case_int_radio,battd-2*case_int_radio,pin_space+inhibitionzone_height+board_thickness-mink_functs_height]);
cylinder(mink_functs_height, r=case_int_radio);
}
}
translate([0,0,board_thickness]) mounts();
}
module rpi4() {
difference() { // this creates the mount holes and the UPS connector corner
translate([0,0,board_thickness]) { // two translations cancel out but make maths simpler before they do
translate([0,0,-(board_thickness)]) union() { // the translation which ^ cancels out
// These two Minkowsky adds the boards just to substract their holes
minkowski() {
translate([case_int_radio,case_int_radio,0])
cube([pil-2*case_int_radio,pid-2*case_int_radio,boardw1hat_thickness-mink_functs_height]); // first 2 boards only (not the underpins)
cylinder(mink_functs_height, r=case_int_radio);
}
minkowski() {
translate([case_int_radio,case_int_radio,0])
cube([pil-2*case_int_radio,upscardd-2*case_int_radio,boardw2hat_thickness-mink_functs_height]); // ups cube, overlaps the first cube
cylinder(mink_functs_height, r=case_int_radio);
}
}
// these are the big surface level components
translate([-(2.81+extension),2,0]) cube([21.3+extension,17,eth_height]); // Ethernet port
translate([-(2.81+extension),22.2,0]) cube([17.44+extension,14.2,usbs_height]); // USB 3.0 Deja 4.15. Acaba en 36.1
translate([-(2.81+extension),18.6,17.1]) cube([17.44+extension,12,7]); // Over USB connection to 3G card
translate([-(2.81+extension),40.4,0]) cube([17.44+extension,13.7,usbs_height]); // USB 2.0 Deja 4.5
translate([27.36,1,0]) cube([50.7,5.0,8.6+extension]); // GPIO pins
translate([21,7.15,0]) cube([5.0,5.0,8.6+extension]); // Power over ethernet pins
translate([48.0,16.3,0]) cube([15.0,15.0,2.5]); // cpu
// translate([67.5,6.8,0]) cube([10.8,13.1,1.8]); // onboard wifi
translate([79,17.3,0]) cube([2.5,22.15,5.4+extension]); // display connector
translate([70,pid,0]) cube([10.5,extension,4]); // USB type C power
translate([56,pid,0]) cube([8.5,extension,3.9]); // Micro HDMI0
translate([42,pid,0]) cube([8.5,extension,3.9]); // Micro HDMI1
// translate([37.4,34.1,0]) cube([2.5,22.15,5.4+extension]); // CSI camera connector, I dont need here
translate([27.3,pid,0]) cube([8.5,extension,6.9]); // Audio jack
// other components (not surface ones)
translate([42,pid,12.5]) cube([14,extension,3]); // SIM Card slot
translate([pil,9,boardw2hat_thickness-board_thickness-1.5]) cube([extension,3,2.5]); // UPS button, height similar to UPS USB connector
translate([pil,21,-(pin_space+case_thickness+board_thickness)]) cube([extension,14,sd_height]); // SD card (poking out)
//YASPIT holes
ld = 1.5; //letter diameter
gs = 10; //greater scale
ms = 5; //middle scale
ls = 3; //liettle scale
translate([pil,-10,13]) rotate ([-30,0,0]) scale ([1,1,gs]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,-11,17]) rotate ([0,0,0]) scale ([1,1,ls]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,-5,13]) rotate ([-30,0,0]) scale ([1,1,gs]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,-1.5,13]) rotate ([0,0,0]) scale ([1,1,gs-1]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,3,9]) rotate ([-45,0,0]) scale ([1,1,ms]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,4,13]) rotate ([15,0,0]) scale ([1,1,ls]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,5,17]) rotate ([-45,0,0]) scale ([1,1,ms]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,9,13]) rotate ([-30,0,0]) scale ([1,1,gs]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil+1,10.5,15.5]) rotate([0,90,0]) rotate_extrude(angle=160) translate([3.5,0,0]) square(size=[1,case_thickness], center=true);
translate([pil,17,13]) rotate ([-30,0,0]) scale ([1,1,gs]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,23,13]) rotate ([-30,0,0]) scale ([1,1,gs]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
translate([pil,25,16]) rotate ([-60,0,0]) scale ([1,1,ms]) rotate([0,90,0]) cylinder(extension,d=ld, center=false);
// Batt side holes
holepacing3=14;
for (n=[0:4]) { // lateral holes
translate([14+n*holepacing3,-battd,inhibitionzone_height/2]) rotate([90,30,0]) scale([1,5,1]) cylinder(extension, d=5, center=false);
translate([14,pid,inhibitionzone_height/2]) rotate([270,60,0]) scale([5,1,1]) cylinder(extension, d=5, center=false);
}
// Under and below big spaces
difference() { // this creates the mount points around the mount holes esp the underneath ones
union() {
minkowski() {
translate([case_int_radio,case_int_radio,0])
cube([pil-2*case_int_radio, pid-2*case_int_radio, inhibitionzone_height-mink_functs_height]); // cpu
cylinder(mink_functs_height, r=case_int_radio);
}
translate([0,0,-(pin_space+board_thickness)]) minkowski() {
translate([case_int_radio,case_int_radio,0])
cube([pil-2*case_int_radio, pid-2*case_int_radio, pin_space-mink_functs_height]); // underpins only
cylinder(mink_functs_height, r=case_int_radio);
}
}
mounts(); // the material which is above and below the board to keep it in place which the pins go through
}
} // end of translation cancel
union() {
translate([x_step_begin-case_thickness,upscardd, inhibitionzone_height_noups+board_thickness]) //create corner of UPS connector. Z must avoid the antenna connector
cube([pil+(1*case_thickness)-x_step_begin,pid-upscardd+case_thickness,inhibitionzone_height-inhibitionzone_height_noups+case_thickness]);
pins(); // the hole which will be screwed into to put both halves of the case and board together
}
}
translate([x_upsusbconn,upscardd,inhibitionzone_height_noups+board_thickness]) cube([9,case_thickness,8]); // UPS-USB connector, must be after the corner difference
translate([53,7.8,0]) { // the air holes dont need the first translate and must be after the ups connector corner difference.
scale([10,1,1]){ // scale 10 of d=5 moves 12.5 less than scale 15
translate([0,0,-extension-pin_space]) cylinder(extension,d=5, center=false); // under-side air hole
translate([0,40,-extension-pin_space]) cylinder(extension,d=5, center=false); // under-side air hole
translate([0,-4,inhibitionzone_height]) cylinder(extension,d=5, center=false); // over-side middle (little) air hole
}
holepacing1=10;
scale([15,1,1]) for (n=[0:2]) { // under-side air holes
translate([-0.6,10+holepacing1*n,-extension-pin_space]) cylinder(extension,d=5, center=false);
}
scale([10,1,1]) for (n=[0:1]) translate([0,-25+10*n,inhibitionzone_height]) cylinder(extension,d=5, center=false); // over-batt air holes
scale([12,1,1]) for (n=[0:1]) translate([0,6+10*n,inhibitionzone_height]) cylinder(extension,d=5, center=false); // over-side air holes
holepacing2=10;
scale([6,1,1]) for (n=[0:1]) //over-side under UPS step
translate([0,30+n*holepacing2,inhibitionzone_height_noups]) cylinder(extension+inhibitionzone_height-inhibitionzone_height_noups,d=5, center=false);
}
// antenna holes
translate([antennaholeradio,y_antenna_eth_conn,inhibitionzone_height]) cylinder(extension,d=2*antennaholeradio, center=false);
translate([antennaholeradio,pid-y_antenna_eth_conn-0.6,inhibitionzone_height]) cylinder(extension,d=2*antennaholeradio, center=false);
translate([x_step_begin-case_thickness,pid-y_antenna_eth_conn-0.6, inhibitionzone_height_noups]) scale([1,1.5,1]) cylinder(2*case_thickness,d=2*antennaholeradio, center=false); // space for antenna connector
}
module mounts() {
translate([xmounts,ymounts,-(board_thickness+pin_space)]) {
for(n=[0:1]) translate([2.2+(20+xmountspace)*n,2-battd-board_thickness,0]) cylinder(inhibitionzone_height+board_thickness,d=mount_diameter+2, center=false); // mount bot-battery
for(n=[0:1]) for(m=[0:1]) translate([x_to_first_mount_center+xmountspace*n,2+ymountspace*m,0]) cylinder(pin_space-0.1,d=mount_diameter, center=false); // mount bot-r/l
}
translate([xmounts,ymounts,inhibitionzone_height-pin_space]) for(n=[0:1]) translate([x_to_first_mount_center+xmountspace*n,2,0]) cylinder(pin_space,d=mount_diameter, center=false); // mount top-r
translate([xmounts,ymounts,inhibitionzone_height-pin_space]) for(n=[0:1]) translate([2.2+(20+xmountspace)*n,2-battd-board_thickness,0]) cylinder(pin_space,d=mount_diameter+2, center=false); // mount top batt
translate([xmounts,ymounts,inhibitionzone_height-pin_space]) translate([x_to_first_mount_center,2+ymountspace,0]) cylinder(pin_space,d=mount_diameter, center=false); // mount top-l near 0x
translate([xmounts,ymounts,inhibitionzone_height_noups-pin_space]) translate([x_to_first_mount_center+xmountspace,2+ymountspace,0]) cylinder(pin_space,d=mount_diameter, center=false); // mount top-l near farest x
}
module pins()
translate([xmounts,ymounts,(0.5*mount_pin_height)-(board_thickness+case_thickness+pin_space)]) { // this is to move all the pins
for(n=[0:1]) for(m=[0:1]) translate([x_to_first_mount_center+xmountspace*n,2+ymountspace*m,0]) cylinder(mount_pin_height,d=3.5, center=true); // hole top/bot-r/l
for(n=[0:1]) translate([2.2+(20+xmountspace)*n,2-battd-board_thickness,0]) cylinder(mount_pin_height,d=3.5, center=true); // hole top/bot-battd
}
module nuts()
// Max 6 mm de diameter. The screw may measure 5 mm. The nuts vary from 5.45 to 5.77. Height of the nuts between 1.75 and 2
translate([xmounts,ymounts,0]) { // this is to move all the nut holes
for(n=[0:1]) for(m=[0:1]) translate([x_to_first_mount_center+xmountspace*n,2+ymountspace*m,-(case_thickness+pin_space)]) linear_extrude(height=nuts_height) circle(d=6.2,$fn=6);
for(n=[0:1]) translate([x_to_first_mount_center+xmountspace*n,2,(inhibitionzone_height+board_thickness+case_thickness)-nuts_height]) linear_extrude(height=nuts_height) circle(d=screw_head_diam);
translate([x_to_first_mount_center,2+ymountspace,(inhibitionzone_height+board_thickness+case_thickness)-nuts_height]) linear_extrude(height=nuts_height) circle(d=screw_head_diam);
translate([x_to_first_mount_center+58,2+ymountspace,(inhibitionzone_height_noups+board_thickness+case_thickness)-nuts_height]) linear_extrude(height=nuts_height) circle(d=screw_head_diam);
for(n=[0:1]) translate([2.2+(20+xmountspace)*n,2-battd-board_thickness,-(case_thickness+pin_space)]) linear_extrude(height=(inhibitionzone_height-0.5*pin_space)+case_thickness, center=false) circle(d=6.2,$fn=6);
for(n=[0:1]) translate([2.2+(20+xmountspace)*n,2-battd-board_thickness,(inhibitionzone_height+board_thickness+case_thickness)-nuts_height]) linear_extrude(height=nuts_height) circle(d=screw_head_diam);
}