├── LICENSE
├── README.md
├── dxf
├── customfan.dxf
├── fan_40.dxf
├── hk_25mm.dxf
├── hk_50mm.dxf
└── odroid.dxf
├── lib
├── antenna.scad
├── audio.scad
├── b2b.scad
├── battery.scad
├── button.scad
├── cm.scad
├── discrete.scad
├── display.scad
├── fan.scad
├── fillets.scad
├── fpc.scad
├── gpio.scad
├── header.scad
├── heatsink.scad
├── heatsinks
│ ├── Khadas_Heatsink.stl
│ ├── Khadas_Heatsink_Fan.stl
│ ├── Odroid-H2_Heatsink.stl
│ ├── Odroid-M1_Heatsink.stl
│ ├── Odroid-N2+_Heatsink.stl
│ ├── Odroid-N2_Heatsink.stl
│ ├── Radxa_Heatsink.stl
│ └── rpi5_oem.dxf
├── ic.scad
├── jst.scad
├── memory.scad
├── molex.scad
├── network.scad
├── pcb.scad
├── pcie.scad
├── pillar.scad
├── place.scad
├── power.scad
├── shape.scad
├── smd.scad
├── storage.scad
├── switch.scad
├── terminal.scad
├── uart.scad
├── usb2.scad
├── usb3.scad
├── usbc.scad
└── video.scad
├── sbc_models.cfg
├── sbc_models.png
├── sbc_models.scad
├── sbc_models_library.scad
├── sbc_models_viewer.gif
└── sbc_models_viewer.scad
/lib/antenna.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: antenna
20 | DESCRIPTION: creates antenna components.
21 | TODO:
22 |
23 | USAGE: antenna(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "ipex"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = component mask true, false
34 | mask[1] = length
35 | mask[2] = set back
36 | mask[3] = mstyle "default"
37 |
38 | */
39 |
40 | module antenna(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
41 |
42 | // type ipex surface mount
43 | if(type == "ipex" && enablemask == false) {
44 | place(loc_x, loc_y, loc_z, 2.5, 2.75, rotation, side, pcbsize_z)
45 | union() {
46 | color("white") cube([2.5,2.75,.35]);
47 | difference() {
48 | color("silver") translate([2.5/2, 2.75/2, .45]) cylinder(d=2, h=.8);
49 | color("silver") translate([2.5/2, 2.75/2, .6]) cylinder(d=1.8, h=1);
50 | }
51 | color("gold") translate([2.5/2, 2.75/2, .6]) cylinder(d=.5, h=.6);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/lib/audio.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: audio
20 | DESCRIPTION: creates audio components.
21 | TODO:
22 |
23 | USAGE: audio(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "audio_micro"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = component mask true, false
34 | mask[1] = length
35 | mask[2] = set back
36 | mask[3] = mstyle "default"
37 |
38 | type = "jack_3.5", "jack_3.5-2
39 | loc_x = x location placement
40 | loc_y = y location placement
41 | loc_z = z location placement
42 | side = "top", "bottom"
43 | rotation[] = object rotation
44 | size[0] = body size_x
45 | size[1] = body size_y
46 | size[2] = body size_z
47 | data[0] = neck diameter
48 | data[1] = z adjustment
49 | pcbsize_z = pcb thickness
50 | enablemask = true produces mask, false produces model
51 | mask[0] = component mask true, false
52 | mask[1] = length
53 | mask[2] = set back
54 | mask[3] = mstyle "default"
55 |
56 | type = "mic_round"
57 | loc_x = x location placement
58 | loc_y = y location placement
59 | loc_z = z location placement
60 | side = "top", "bottom"
61 | rotation[] = object rotation
62 | size[0] = body diameter
63 | size[1] =
64 | size[2] = body height
65 | pcbsize_z = pcb thickness
66 | enablemask = true produces mask, false produces model
67 | mask[0] = component mask true, false
68 | mask[1] = length
69 | mask[2] = set back
70 | mask[3] = mstyle "default"
71 |
72 | type = "out-in-spdif"
73 | loc_x = x location placement
74 | loc_y = y location placement
75 | loc_z = z location placement
76 | side = "top", "bottom"
77 | rotation[] = object rotation
78 | pcbsize_z = pcb thickness
79 | enablemask = true produces mask, false produces model
80 | mask[0] = component mask true, false
81 | mask[1] = length
82 | mask[2] = set back
83 | mask[3] = mstyle "default"
84 |
85 | */
86 |
87 | module audio(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
88 |
89 | cmask = mask[0];
90 | mlen = mask[1];
91 | back = mask[2];
92 | mstyle = mask[3];
93 | adj = .01;
94 | $fn = 90;
95 |
96 | // out in and spdif stacked type
97 | if(type == "out-in-spdif") {
98 |
99 | size_x = 12.7;
100 | size_y = 21.5;
101 | size_z = 35;
102 | size_xm = 13;
103 | size_ym = mlen;
104 | size_zm = 35.5;
105 |
106 | if(enablemask == true && cmask == true && mstyle == "default") {
107 | if(side == "top" && rotation == 0) {
108 | place(loc_x-(size_xm-size_x)/2, loc_y-size_ym+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
109 | cube([size_xm, mlen, size_zm]);
110 | }
111 | if(side == "top" && rotation == 90) {
112 | place(loc_x-size_ym+back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
113 | cube([size_xm, mlen, size_zm]);
114 | }
115 | if(side == "top" && rotation == 180) {
116 | place(loc_x-(size_xm-size_x)/2, loc_y+size_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
117 | cube([size_xm, mlen, size_zm]);
118 | }
119 | if(side == "top" && rotation == 270) {
120 | place(loc_x+size_y-back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
121 | cube([size_xm, mlen, size_zm]);
122 | }
123 | if(side == "bottom" && rotation == 0) {
124 | place(loc_x-(size_xm-size_x)/2, loc_y-size_ym+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
125 | cube([size_xm, mlen, size_zm]);
126 | }
127 | if(side == "bottom" && rotation == 90) {
128 | place(loc_x+size_y-back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
129 | cube([size_xm, mlen, size_zm]);
130 | }
131 | if(side == "bottom" && rotation == 180) {
132 | place(loc_x-(size_xm-size_x)/2, loc_y+size_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
133 | cube([size_xm, mlen, size_zm]);
134 | }
135 | if(side == "bottom" && rotation == 270) {
136 | place(loc_x-size_ym+back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
137 | cube([size_xm, mlen, size_zm]);
138 | }
139 | }
140 | if(enablemask == false) {
141 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
142 | union() {
143 | difference () {
144 | union() {
145 | color("silver") cube([size_x, size_y, size_z]);
146 | color("black") translate([6.35, -3.2, 17]) rotate([-90, 0, 0])
147 | cylinder(d=8, h=6.25);
148 | color("black") translate([6.35, -3.2, 29]) rotate([-90, 0, 0])
149 | cylinder(d=8, h=6.25);
150 | color("dimgray") translate([1.85, -2.0, 2]) cube([9, 2, 9]);
151 | }
152 | color("dimgray") translate([6.35, -3.25, 17]) rotate([-90, 0, 0])
153 | cylinder(d=3.75, h=9);
154 | color("dimgray") translate([6.35, -3.25, 29]) rotate([-90, 0, 0])
155 | cylinder(d=3.75, h=9);
156 | difference() {
157 | color("dimgray") translate([2.85, -2.1, 3]) cube([7, 9, 7]);
158 | color("dimgray") translate([1.85, -2, 3]) rotate([0, 45, 0]) cube([1.5, 9, 1.5]);
159 | color("dimgray") translate([8.75, -2, 3]) rotate([0, 45, 0]) cube([1.5, 9, 1.5]);
160 | }
161 | }
162 | }
163 | }
164 | }
165 |
166 | // 3.5mm jack type
167 | if(type == "jack_3.5" || type == "jack_3.5-2") {
168 |
169 | size_x = size[0];
170 | size_y = size[1];
171 | size_z = size[2];
172 | size_xm = size_x+1;
173 | size_ym = size_y;
174 | size_zm = size_z+1;
175 | bdiam = data[0];
176 | badj = data[1];
177 |
178 | if(enablemask == true && cmask == true && mstyle == "default") {
179 | if(side == "top" && rotation == 0) {
180 | place(loc_x-.5, loc_y-2.5+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
181 | union() {
182 | cube([size_xm, 2.5, size_zm]);
183 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
184 | }
185 | }
186 | if(side == "top" && rotation == 90) {
187 | place(loc_x-2.5+back, loc_y-.5, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
188 | union() {
189 | cube([size_xm, 2.5, size_zm]);
190 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
191 | }
192 | }
193 | if(side == "top" && rotation == 180) {
194 | place(loc_x-.5, loc_y+2.5-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
195 | union() {
196 | cube([size_xm, 2.5, size_zm]);
197 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
198 | }
199 | }
200 | if(side == "top" && rotation == 270) {
201 | place(loc_x+2.5-back, loc_y-.5, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
202 | union() {
203 | cube([size_xm, 2.5, size_zm]);
204 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
205 | }
206 | }
207 | if(side == "bottom" && rotation == 0) {
208 | place(loc_x-.5, loc_y-2.5+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
209 | union() {
210 | cube([size_xm, 2.5, size_zm]);
211 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
212 | }
213 | }
214 | if(side == "bottom" && rotation == 90) {
215 | place(loc_x+2.5-back, loc_y-.5, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
216 | union() {
217 | cube([size_xm, 2.5, size_zm]);
218 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
219 | }
220 | }
221 | if(side == "bottom" && rotation == 180) {
222 | place(loc_x-.5, loc_y+2.5-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
223 | union() {
224 | cube([size_xm, 2.5, size_zm]);
225 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+2, h=mlen);
226 | }
227 | }
228 | if(side == "bottom" && rotation == 270) {
229 | place(loc_x-2.5+back, loc_y-.5, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
230 | union() {
231 | cube([size_xm, 2.5, size_zm]);
232 | translate([size_xm/2, 2, (size_z/2)+badj]) rotate([90, 0, 0]) cylinder(d=bdiam+1, h=mlen);
233 | }
234 | }
235 | }
236 | if(enablemask == false) {
237 | if(type == "jack_3.5") {
238 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
239 | union() {
240 | difference () {
241 | union() {
242 | color("silver") cube([size_x, 2, size_z]);
243 | color("black") translate([0, 2-adj, 0]) cube([size_x, size_y, size_z]);
244 | color("black") translate([size_x/2, -2, (size_z/2)+badj]) rotate([-90, 0, 0]) cylinder(d=bdiam, h=6.25);
245 | }
246 | color("dimgray") translate([size_x/2, -2.5, (size_z/2)+badj]) rotate([-90, 0, 0]) cylinder(d=3.5, h=6);
247 | }
248 | }
249 | }
250 | if(type == "jack_3.5-2") {
251 | size_x = 6.5;
252 | size_y = 13.5;
253 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
254 | difference () {
255 | union() {
256 | color("dimgray") cube([size_x,size_y,3]);
257 | color("dimgray") translate([0,size_y-5.6,0]) cube([size_x,5.6,4]);
258 | color("dimgray") translate([size_x/2,0,2.25]) rotate([270,0,0]) cylinder(d=6, h=size_y);
259 | }
260 | color("gray") translate([size_x/2,-1,2.25]) rotate([270,0,0]) cylinder(d=3, h=size_y+.01);
261 | }
262 | }
263 | }
264 | }
265 |
266 | // audio micro connector type
267 | if(type == "audio_micro") {
268 |
269 | size_x = 7.5;
270 | size_y = 3.75;
271 | size_z = 4.75;
272 | size_xm = 7.5;
273 | size_ym = mlen;
274 | size_zm = 4;
275 |
276 | if(enablemask == true && cmask == true && mstyle == "default") {
277 | if(side == "top" && rotation == 0) {
278 | place(loc_x-(size_xm-size_x)/2, loc_y-size_ym+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
279 | cube([size_xm, mlen, size_zm]);
280 | }
281 | if(side == "top" && rotation == 90) {
282 | place(loc_x-size_ym+back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
283 | cube([size_xm, mlen, size_zm]);
284 | }
285 | if(side == "top" && rotation == 180) {
286 | place(loc_x-(size_xm-size_x)/2, loc_y+size_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
287 | cube([size_xm, mlen, size_zm]);
288 | }
289 | if(side == "top" && rotation == 270) {
290 | place(loc_x+size_y-back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
291 | cube([size_xm, mlen, size_zm]);
292 | }
293 | if(side == "bottom" && rotation == 0) {
294 | place(loc_x-(size_xm-size_x)/2, loc_y-size_ym+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
295 | cube([size_xm, mlen, size_zm]);
296 | }
297 | if(side == "bottom" && rotation == 90) {
298 | place(loc_x+size_y-back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
299 | cube([size_xm, mlen, size_zm]);
300 | }
301 | if(side == "bottom" && rotation == 180) {
302 | place(loc_x-(size_xm-size_x)/2, loc_y+size_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
303 | cube([size_xm, mlen, size_zm]);
304 | }
305 | if(side == "bottom" && rotation == 270) {
306 | place(loc_x-size_ym+back, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
307 | cube([size_xm, mlen, size_zm]);
308 | }
309 | }
310 | if(enablemask == false) {
311 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
312 | translate([size_xm, size_y+1.5, 3.75]) rotate([-90, 0, 180])
313 | union() {
314 | difference () {
315 | color("white") cube([size_x, size_y, size_z]);
316 | color("darkgray") translate([1.5, .5, 1]) cube([4.5, 2.75, 6]);
317 | color("white") translate([-.5, .75, -.5]) cube([1, 2.5, 6]);
318 | color("white") translate([7, .75, -.5]) cube([1, 2.5, 6]);
319 | color("darkgray") translate([2.25, -.5, 1]) cube([3, 2, 6]);
320 | }
321 | color("silver") translate ([2.75, 2, .5]) cube([.6, .6, 4]);
322 | color("silver") translate ([4.5, 2, .5]) cube([.6, .6, 4]);
323 | }
324 | }
325 | }
326 |
327 | // mic_round type
328 | if(type == "mic_round" && enablemask == false) {
329 |
330 | size_x = size[0];
331 | size_y = size[0];
332 | size_z = size[2];
333 |
334 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
335 | union() {
336 | color("silver") cylinder(d=size_x, h=size_z);
337 | color("#353535") translate ([0, 0, size_z-.01]) cylinder(d=size_x-.5, h=.15);
338 | }
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/lib/b2b.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: b2b
20 | DESCRIPTION: creates b2b headers in size, pitch and stacking height.
21 | TODO: shielded
22 |
23 | USAGE: b2b(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "df40"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = #pins
32 | size[2] = stacking height (1.5, 2, 2.5, 3, 3.5, 4)
33 | data[0] = "default"
34 | data[1] = body color
35 | data[2] = "male", "female"
36 | pcbsize_z = pcb thickness
37 | enablemask = true produces mask, false produces model
38 |
39 | */
40 |
41 | module b2b(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
42 |
43 | pins = size[0];
44 | height = size[2]-.05;
45 | style = data[0];
46 | hcolor = data[1];
47 | gender = data[2];
48 |
49 | adj = .01;
50 | $fn = 90;
51 |
52 |
53 | // df40 style header
54 | if(type=="df40" && enablemask == false) {
55 |
56 | pitch = .4;
57 | wallthick = .25;
58 | pcolor = "#fee5a6";
59 |
60 | if(gender == "female") {
61 |
62 | lead_in = 1.3;
63 | pinsize = .12;
64 | smtlead = [pinsize,.25,.15];
65 | size_x = pitch * (pins/2) + (2*lead_in);
66 | size_y = 2.88;
67 |
68 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
69 | union() {
70 | difference() {
71 | color(hcolor) cube([size_x, size_y, height]);
72 | translate([.75,-1,height-.25]) color("#252525") cube([size_x-1.5, size_y+2, 1]);
73 | translate([wallthick,wallthick,wallthick]) color("#252525")
74 | cube([size_x-(2*wallthick), .625, height]);
75 | translate([wallthick,size_y-wallthick-.625,wallthick]) color("#252525")
76 | cube([size_x-(2*wallthick), .625, height]);
77 | translate([wallthick,wallthick,wallthick]) color("#252525")
78 | cube([(lead_in-wallthick), size_y-(2*wallthick), height]);
79 | translate([size_x-wallthick-(lead_in-wallthick),wallthick,wallthick])
80 | color("#252525") cube([lead_in-wallthick, size_y-(2*wallthick), height]);
81 |
82 | }
83 | for(c=[lead_in+(pitch/2):pitch:size_x-lead_in]) {
84 | color(pcolor) translate([c-(pinsize/2), (size_y-1.5)/2-(pinsize/2)+.125, adj])
85 | cube([pinsize,pinsize,height-.25+adj]);
86 | color(pcolor) translate([c-(pinsize/2), (size_y-1.5)/2-(pinsize/2)+1.475, adj])
87 | cube([pinsize, pinsize, height-.25+adj]);
88 | color(pcolor) translate([c-(pinsize/2), -smtlead[1], 0]) cube(smtlead);
89 | color(pcolor) translate([c-(pinsize/2), size_y-adj, 0]) cube(smtlead);
90 | }
91 | }
92 | }
93 | if(gender == "male") {
94 |
95 | lead_in = .75;
96 | pinsize = .12;
97 | smtlead = [pinsize,.56,.15];
98 | size_x = pitch * (pins/2) + (2*lead_in);
99 | size_y = 1.85;
100 | height = 1.14;
101 |
102 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
103 | union() {
104 | difference() {
105 | color(hcolor) cube([size_x, size_y, height]);
106 | color("#252525") translate([wallthick*3, wallthick, wallthick])
107 | cube([size_x-(6*wallthick), size_y-(2*wallthick), height]);
108 | }
109 | for(c=[lead_in+(pitch/2):pitch:size_x-lead_in]) {
110 | color(pcolor) translate([c-(pinsize/2), wallthick-(pinsize/2), adj])
111 | cube([pinsize, pinsize, height+adj]);
112 | color(pcolor) translate([c-(pinsize/2), size_y-wallthick-(pinsize/2), adj])
113 | cube([pinsize, pinsize, height+adj]);
114 | color(pcolor) translate([c-(pinsize/2), -smtlead[1], 0]) cube(smtlead);
115 | color(pcolor) translate([c-(pinsize/2), size_y-adj, 0]) cube(smtlead);
116 | }
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib/battery.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: battery
20 | DESCRIPTION: creates batteries and support components.
21 | TODO:
22 |
23 | USAGE: battery(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "bat_hold_1", "rtc_micro"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = true enables component mask
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 | */
39 |
40 | module battery(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
41 |
42 | // type battery holder 1
43 | if(type == "bat_hold_1" && enablemask == false) {
44 |
45 | size_x = 22;
46 | size_y = 16;
47 |
48 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
49 | union() {
50 | difference() {
51 | union() {
52 | color("LightYellow") cube([size_x, size_y, 6]);
53 | color("LightYellow") translate([-3.2499, 4.5, 0]) cube([3.25, 7, 6]);
54 | color("LightYellow") translate([21.999, 4.5, 0]) cube([3.25, 7, 6]);
55 | }
56 | color("LightYellow") translate([11, 8, 2]) cylinder(d=20, h=5, $fn=360);
57 | color("LightYellow") translate([-3.259, 5, 5]) cube([28.6, 5.5, 3]);
58 | color("LightYellow") translate([-3.25, 5.5, 5]) cube([28.5, 5.5, 3]);
59 |
60 | color("LightYellow") translate([-4.251, 5, -1]) cube([2, 6, 8]);
61 | color("LightYellow") translate([.5, 5, 2]) cube([1, 6, 8]);
62 |
63 | color("LightYellow") translate([24.25, 5, -1]) cube([2, 6, 8]);
64 | color("LightYellow") translate([20, 5, 2]) cube([1, 6, 8]);
65 |
66 | color("LightYellow") translate([22, 15, -1]) rotate([0, 0, 45]) cube([2, 2, 8]);
67 |
68 | /* bottom cut outs */
69 | color("LightYellow") translate([7, 2.5, -1]) cylinder(d=2.5, h=4, $fn=360);
70 | color("LightYellow") translate([3.75, 1.25, -1]) cube([3.5, 2.5, 3.75]);
71 | color("LightYellow") translate([15, 2.5, -1]) cylinder(d=2.5, h=4, $fn=360);
72 | color("LightYellow") translate([15, 1.25, -1]) cube([3.3,2.5,3.75]);
73 | color("LightYellow") translate([7, 13.5, -1]) cylinder(d=2.5, h=4, $fn=360);
74 | color("LightYellow") translate([3.75, 12.25, -1]) cube([3.5, 2.5, 3.75]);
75 | color("LightYellow") translate([15, 13.5, -1]) cylinder(d=2.5, h=4, $fn=360);
76 | color("LightYellow") translate([15, 12.25, -1]) cube([3.3, 2.5, 3.75]);
77 | }
78 | color("Gold") translate([-2.25199, 5, 0]) cube([1, 6, 6]);
79 | color("Gold") translate([0, 5, 0]) cube([1, 6, 6]);
80 | color("Gold") translate([-2.25199, 5, 5]) cube([3, 6, 1]);
81 |
82 | color("Gold") translate([20.99, 5, 2]) cube([1, 6, 4]);
83 | color("Gold") translate([23.251, 5, 0]) cube([1, 6, 6]);
84 | color("Gold") translate([21, 5, 5]) cube([3, 6, 1]);
85 |
86 | /* right contacts */
87 | color("Gold") translate([15, 6, 2.5]) rotate([0, 5, 0]) cube([6, 1, .5]);
88 | color("Gold") translate([15, 9, 2.5]) rotate([0, 5, 0]) cube([6, 1, .5]);
89 | color("Gold") translate([20.5, 5, 2]) cube([1, 6, .5]);
90 |
91 | /* left contacts */
92 | color("Gold") translate([1.5, 6, 2.5]) rotate([0, 5, 0]) cube([.5, 1, 3]);
93 | color("Gold") translate([2, 6, 5]) rotate([0, 5, 0]) cube([.5,1 , .5]);
94 | color("Gold") translate([1.5, 9, 2.5]) rotate([0 ,5, 0]) cube([.5, 1, 3]);
95 | color("Gold") translate([2, 9, 5]) rotate([0, 5, 0]) cube([.5, 1, .5]);
96 | color("Gold") translate([1, 5, 2]) cube([1, 6, .5]);
97 | }
98 | }
99 |
100 | // rtc micro connector type
101 | if(type == "rtc_micro" && enablemask == false) {
102 | size_x = 7.5;
103 | size_y = 3.75;
104 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
105 | union() {
106 | difference () {
107 | color("white") cube([size_x, size_y, 4.75]);
108 | color("darkgray") translate([1.5, .5, 1]) cube([4.5, 2.75, 6]);
109 | color("white") translate([-.5, .75, -.5]) cube([1, 2.5, 6]);
110 | color("white") translate([7, .75, -.5]) cube([1, 2.5, 6]);
111 | color("darkgray") translate([2.25, -.5, 1]) cube([3, 2, 6]);
112 | }
113 | color("silver") translate([2.75, 2, .5]) cube([.6, .6, 4]);
114 | color("silver") translate([4.5, 2, .5]) cube([.6, .6, 4]);
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/lib/cm.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 | cm(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask)
19 | cm_holder(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask)
20 |
21 | */
22 |
23 | /*
24 |
25 | CLASS NAME: cm
26 | DESCRIPTION: creates compute modules as library components
27 | TODO: CM1,CM3,CM4S SOC location
28 |
29 | USAGE: cm(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
30 |
31 | type = "cm1","cm3","cm3l","cm4s","cm4","cm4l","jetsonnano","soedge"
32 | loc_x = x location placement
33 | loc_y = y location placement
34 | loc_z = z location placement
35 | side = "top", "bottom"
36 | rotation[] = object rotation
37 | data[0] = fan size
38 | data[1] = cm pcb color
39 | pcbsize_z = pcb thickness
40 | enablemask = true produces mask, false produces model
41 | mask[0] = true enables component mask
42 | mask[1] = mask length
43 | mask[2] = mask setback
44 | mask[3] = mstyle "default"
45 |
46 |
47 | CLASS NAME: cm_holder
48 | DESCRIPTION: creates compute module holder
49 | TODO: "cm1","cm3","cm3l","cm4s"
50 |
51 | USAGE: cm_holder(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
52 |
53 | type = "jetsonnano"
54 | loc_x = x location placement
55 | loc_y = y location placement
56 | loc_z = z location placement
57 | side = "top", "bottom"
58 | rotation[] = object rotation
59 | data[0] = cm pcb color
60 | pcbsize_z = pcb thickness
61 | enablemask = true produces mask, false produces model
62 | mask[0] = true enables component mask
63 | mask[1] = mask length
64 | mask[2] = mask setback
65 | mask[3] = mstyle "default"
66 |
67 |
68 | */
69 |
70 | module cm(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
71 |
72 | fsize = data[0];
73 | pcbcolor = data[1];
74 | cmask = mask[0];
75 | mlen = mask[1];
76 | back = mask[2];
77 | mstyle = mask[3];
78 | size_x = 67.6;
79 | size_y = type == "cm1" ? 30 : 31;
80 | size_z = 1;
81 | $fn=90;
82 |
83 | if(type == "cm1" || type == "cm3" || type == "cm3l" || type == "cm3+" || type == "cm4s") {
84 |
85 | if(enablemask == true && cmask == true && mstyle == "default") {
86 |
87 | }
88 | if(enablemask == false) {
89 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
90 | union() {
91 | difference () {
92 | union() {
93 | color(pcbcolor) cube([size_x,size_y,size_z]);
94 | color("#fee5a6") translate([3, 27, .99]) cylinder(d=5, h=.2);
95 | color("#fee5a6") translate([3, 27, -.01]) cylinder(d=5, h=.2);
96 | color("#fee5a6") translate([64.6, 27, .99]) cylinder(d=5, h=.2);
97 | color("#fee5a6") translate([64.6, 27, -.01]) cylinder(d=5,h =.2);
98 | }
99 | color(pcbcolor) translate([15.75+.5, -1, -1]) rotate([0, 0, 90]) slot(1, 5, 3);
100 | color(pcbcolor) translate([0, 21, -1]) cylinder(d=3, h=3);
101 | color(pcbcolor) translate([size_x, 21, -1]) cylinder(d=3, h=3);
102 | color(pcbcolor) translate([3, 27, -1]) cylinder(d=2.3, h=3);
103 | color(pcbcolor) translate([64.6, 27, -1]) cylinder(d=2.3, h=3);
104 | }
105 | for (i=[0:.5:14.5]) {
106 | color("#fee5a6") translate ([i+.5, 0, -.24]) cube([.25, 2, .25]);
107 | color("#fee5a6") translate ([i+.5, 0, .99]) cube([.25, 2, .25]);
108 | }
109 | for (i=[16.75:.5:66.5]) {
110 | color("#fee5a6") translate ([i+.5, 0, -.24]) cube([.25, 2, .25]);
111 | color("#fee5a6") translate ([i+.5, 0, .99]) cube([.25, 2, .25]);
112 | }
113 | }
114 | }
115 | }
116 | if(type == "cm4" || type == "cm4l") {
117 |
118 | pcbcolor = data[1];
119 | size_x = 55;
120 | size_y = 40;
121 | size_z = 1.2;
122 |
123 | if(enablemask == true && cmask == true && mstyle == "default") {
124 |
125 | }
126 | if(enablemask == false) {
127 |
128 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
129 | union() {
130 | difference () {
131 | union() {
132 | color(pcbcolor) slab([size_x, size_y, size_z],3);
133 | color("#fee5a6") translate([3.5, 3.5, -.01]) cylinder(d=5, h=size_z+.2);
134 | color("#fee5a6") translate([3.5, size_y-3.5, -.01]) cylinder(d=5, h=size_z+.2);
135 | color("#fee5a6") translate([size_x-3.5, 3.5, -.01]) cylinder(d=5, h=size_z+.2);
136 | color("#fee5a6") translate([size_x-3.5, size_y-3.5, -.01]) cylinder(d=5, h=size_z+.2);
137 | }
138 | //color(pcbcolor) translate([-1, 18.5, -1]) cube([7.5, 11, 3]);
139 | color(pcbcolor) translate([2.56, 31, -1]) cylinder(d=1.5, h=3);
140 | color(pcbcolor) translate([3.5, 3.5, -1]) cylinder(d=2.5, h=3);
141 | color(pcbcolor) translate([3.5, size_y-3.5, -1]) cylinder(d=2.5, h=3);
142 | color(pcbcolor) translate([size_x-3.5, 3.5, -1]) cylinder(d=2.5, h=3);
143 | color(pcbcolor) translate([size_x-3.5, size_y-3.5, -1]) cylinder(d=2.5, h=3);
144 | }
145 | pcbsoc("raised", 25, 10, 0, "top", 0, [13,13,1.25], data, size_z, false, [false,10,2,"default"]);
146 | if(type == "cm4") {
147 | ic("generic", 20.9, 27, 0, "top", 0, [13, 11.75, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
148 | }
149 | ic("generic", 42.5, 9.5, 0, "top", 0, [10, 15, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
150 | ic("generic", 38, 30.5, 0, "top", 0, [7, 7, 1.5], ["dimgrey"], size_z, false, [false,10,2,"default"]);
151 | ic("generic", 4.5, 9.25, 0, "top", 0, [5.25, 5.25, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
152 | ic("generic", 8.75, 21, 0, "top", 0, [11, 14, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
153 | antenna("ipex", 1.315, 29.675, 0, "top", 0, [0,0,0], [0], size_z, false, [false,10,2,"default"]);
154 | }
155 | }
156 | }
157 |
158 | if(type == "jetsonnano") {
159 |
160 | size_x = 70;
161 | size_y = 45;
162 |
163 | if(enablemask == true && cmask == true) {
164 |
165 | size_x = 58;
166 | size_y = 40;
167 |
168 | if(mstyle == "open" || mstyle == "default") {
169 |
170 | xoffset = 6.5;
171 | yoffset = 4.5;
172 | zoffset = 9.5;
173 | size_xm = 60;
174 | size_ym = 42;
175 |
176 | if(side == "top" && rotation == 0) {
177 | place(loc_x, loc_y, loc_z-back, size_xm, size_ym, rotation, side, pcbsize_z)
178 | translate([xoffset-(size_xm-size_x)/2, yoffset-(size_ym-size_y)/2, zoffset-back]) cube([size_xm, size_ym, mlen]);
179 | }
180 | }
181 | if(mstyle == "fan_open" || mstyle == "fan_1" || mstyle == "fan_2" || mstyle == "fan_hex") {
182 |
183 | xoffset = 16.25;
184 | yoffset = 6;
185 | zoffset = 26.5;
186 | size_xm = 60;
187 | size_ym = 42;
188 |
189 | place(loc_x, loc_y, loc_z-back, size_xm, size_ym, rotation, side, pcbsize_z)
190 | translate([(40-fsize)/2+xoffset-(size_xm-size_x)/2, (40-fsize)/2+yoffset-(size_ym-size_y)/2, zoffset-back])
191 | heatsink_mask(fsize, mlen, mstyle);
192 | }
193 | }
194 | if(enablemask == false) {
195 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
196 | union() {
197 | difference () {
198 |
199 | color("#151515") translate([0, 0, 7]) cube([size_x, size_y, 1.4]);
200 | color("black") translate([37, -1, 6]) cube([1, 5, 4]);
201 | color("dimgray") translate([-1, 18, 6]) cube([3, 4, 4]);
202 | color("dimgray") translate([size_x-2, 18, 6]) cube([3, 4, 4]);
203 | color("dimgray") translate([size_x-3, size_y-3, 6]) cylinder(d=3, h=3);
204 | color("dimgray") translate([3, size_y-3, 6]) cylinder(d=3, h=3);
205 |
206 | }
207 | for (i=[2:.5:36]) {
208 | color("gold") translate ([i+.5, 0, 6.8]) cube([.25, 2, .25]);
209 | color("gold") translate ([i+.5, 0, 8.4]) cube([.25, 2, .25]);
210 | }
211 | for (i=[37.5:.5:67]) {
212 | color("gold") translate ([i+.5, 0, 6.8]) cube([.25, 2, .25]);
213 | color("gold") translate ([i+.5, 0, 8.4]) cube([.25, 2, .25]);
214 | }
215 | color("dimgrey") translate([20, 13, 8.3]) cube([14, 14, 1.2]);
216 | difference() {
217 | color("black") translate([6.5, 4.5, 9.5]) cube([58, 40, 16]);
218 | color("dimgrey") translate([0, 25.375, 13.5]) rotate([90, 2.5, 90]) linear_extrude(70) {
219 | polygon(points = [[0,0], [-.5,13], [4,13], [3.5,0]]);}
220 | color("dimgrey") translate([0, 20.675, 13.5]) rotate([90, -2.5, 90]) linear_extrude(70) {
221 | polygon(points = [[0,0], [-.5,13], [4,13], [3.5,0]]);}
222 | color("dimgrey") translate([0, 30.5, 13.5]) rotate([90, 5, 90]) linear_extrude(70) {
223 | polygon(points = [[0,0], [-.5,13], [4,13], [3.5,0]]);}
224 | color("dimgrey") translate([0, 15.25, 13.5]) rotate([90, -5, 90]) linear_extrude(70) {
225 | polygon(points = [[0,0], [-.5,13], [4,13], [3.5,0]]);}
226 | color("dimgrey") translate([0, 35, 13.5]) rotate([90, 10, 90]) linear_extrude(70) {
227 | polygon(points = [[0,0], [-.5,10.5], [4,10.5], [3.5,0]]);}
228 | color("dimgrey") translate([0, 10.5, 13]) rotate([90, -10, 90]) linear_extrude(70) {
229 | polygon(points = [[0,0], [-.5,10.5], [4,10.5], [3.5,0]]);}
230 | color("dimgrey") translate([0, 36.5, 20]) cube([70, 10, 4]);
231 | color("dimgrey") translate([0, 1.5, 20]) cube([70, 10, 4]);
232 | color("dimgrey") translate([0, 39.5, 13]) rotate([90, 10, 90]) linear_extrude(70) {
233 | polygon(points = [[0,0], [0,10.5], [3,10.5], [3,0]]);}
234 | color("dimgrey") translate([0, 6.5, 12.5]) rotate([90, -10, 90]) linear_extrude(70) {
235 | polygon(points = [[0,0], [0,10.5], [3,10.5], [3,0]]);}
236 | color("dimgrey") translate([19, 9, 22]) cylinder(d=3, h=5);
237 | color("dimgrey") translate([51, 9, 22]) cylinder(d=3, h=5);
238 | color("dimgrey") translate([19, 41, 22]) cylinder(d=3, h=5);
239 | color("dimgrey") translate([51, 41, 22]) cylinder(d=3, h=5);
240 |
241 | }
242 | difference() {
243 | union() {
244 | color("silver") translate([size_x-3, size_y-3, 0]) cylinder(d=5.2, h=7, $fn=6);
245 | color("silver") translate([3, size_y-3, 0]) cylinder(d=5.2, h=7, $fn=6);
246 | }
247 | color("silver") translate([size_x-3, size_y-3, -.1]) cylinder(d=3, h=13);
248 | color("silver") translate([3, size_y-3, -.1]) cylinder(d=3, h=13);
249 | }
250 | }
251 | }
252 | }
253 |
254 |
255 | if(type == "soedge") {
256 |
257 | if(enablemask == true && cmask == true && mstyle == "default") {
258 |
259 | }
260 | if(enablemask == false) {
261 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
262 | union() {
263 | difference () {
264 | color(pcbcolor) cube([size_x,size_y,size_z]);
265 | color(pcbcolor) translate([15.75+.5, -1, -1]) rotate([0, 0, 90]) slot(1, 5, 3);
266 | color(pcbcolor) translate([0, 21, -1]) cylinder(d=3, h=3);
267 | color(pcbcolor) translate([size_x, 21, -1]) cylinder(d=3, h=3);
268 | }
269 | for (i=[0:.5:14.5]) {
270 | color("#fee5a6") translate ([i+.5, 0, -.24]) cube([.25, 2, .25]);
271 | color("#fee5a6") translate ([i+.5, 0, .99]) cube([.25, 2, .25]);
272 | }
273 | for (i=[16.75:.5:66.5]) {
274 | color("#fee5a6") translate ([i+.5, 0, -.24]) cube([.25, 2, .25]);
275 | color("#fee5a6") translate ([i+.5, 0, .99]) cube([.25, 2, .25]);
276 | }
277 | ic("generic", 28.5, 9.5, 0, "top", 0, [14.5, 14.5, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
278 | ic("generic", 47.5, 6, 0, "top", 0, [13.5, 8.5, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
279 | ic("generic", 47.5, 18, 0, "top", 0, [13.5, 8.5, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
280 | ic("generic", 8.5, 14, 0, "top", 0, [7, 7, .8], ["dimgrey"], size_z, false, [false,10,2,"default"]);
281 | button("momentary_4x2x1", 22.5, 26.5, 0, "top", 0, [7, 7, .8], ["0"], size_z, false, [false,10,2,"default"]);
282 | memory("emmc_plug", 18, 26.5, 0, "bottom", 0, [7, 7, .8], ["0"], size_z, false, [false,10,2,"default"]);
283 | }
284 | }
285 | }
286 |
287 | }
288 |
289 |
290 |
291 | module cm_holder(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
292 |
293 | // jetson nano
294 | if(type == "jetsonnano") {
295 | size_x = 73;
296 | size_y = 6.5;
297 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
298 | union() {
299 | difference () {
300 | color("dimgray") cube([size_x, size_y, 9.2]);
301 | color("dimgray") translate([1.5, -1, 5.7]) cube([70, 3, 5]);
302 | color("dimgray") translate([3.5, -1, 5.7]) cube([28.5, 5.25, .92]);
303 | color("dimgray") translate([34.5, -1, 5.7]) cube([35, 5.25, .92]);
304 | }
305 | for (i=[2:.5:31]) {
306 | color("gold") translate ([i+.5, 2, 5.7]) cube([.25, 2, .25]);
307 | }
308 | for (i=[34:.5:69]) {
309 | color("gold") translate ([i+.5, 2, 5.7]) cube([.25, 2, .25]);
310 | }
311 | }
312 | }
313 | }
314 |
315 |
--------------------------------------------------------------------------------
/lib/discrete.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: discrete
20 | DESCRIPTION: creates discrete components
21 | TODO:
22 |
23 | USAGE: discrete(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "ir_dual", "ir_3"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = true enables component mask
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 | type = "ir_1", "ir_2"
39 | loc_x = x location placement
40 | loc_y = y location placement
41 | loc_z = z location placement
42 | side = "top", "bottom"
43 | rotation[] = object rotation
44 | size[2] = height
45 | pcbsize_z = pcb thickness
46 | enablemask = true produces mask, false produces model
47 | mask[0] = true enables component mask
48 | mask[1] = mask length
49 | mask[2] = mask setback
50 | mask[3] = mstyle "default"
51 |
52 | type = "capacitor"
53 | loc_x = x location placement
54 | loc_y = y location placement
55 | loc_z = z location placement
56 | side = "top", "bottom"
57 | rotation[] = object rotation
58 | size[0] = diameter
59 | size[2] = height
60 | pcbsize_z = pcb thickness
61 | enablemask = true produces mask, false produces model
62 |
63 | type = "led"
64 | loc_x = x location placement
65 | loc_y = y location placement
66 | loc_z = z location placement
67 | side = "top", "bottom"
68 | rotation[] = object rotation
69 | size[0] = diameter
70 | size[2] = height
71 | data[0] = style "default"
72 | data[1] = led color
73 | pcbsize_z = pcb thickness
74 | enablemask = true produces mask, false produces model
75 |
76 | */
77 |
78 | // discrete class
79 | module discrete(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
80 |
81 | cmask = mask[0];
82 | mlen = mask[1];
83 | back = mask[2];
84 | mstyle = mask[3];
85 | pcolor = "#fee5a6";
86 | adj = .01;
87 | $fn = 90;
88 |
89 | // type ir
90 | if(type=="ir_1") {
91 |
92 | size_x = 7;
93 | size_y = 3;
94 | size_z = size[2];
95 | size_xm = 5;
96 | size_ym = 3.5;
97 |
98 | if(enablemask == true && cmask == true && mstyle == "default") {
99 | if(side == "top" && rotation == 0) {
100 | place(loc_x+size_x/2, loc_y+back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
101 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
102 | }
103 | if(side == "top" && rotation == 90) {
104 | place(loc_x+back, loc_y-1.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
105 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
106 | }
107 | if(side == "top" && rotation == 180) {
108 | place(loc_x-1.5, loc_y-.5-back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
109 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
110 | }
111 | if(side == "top" && rotation == 270) {
112 | place(loc_x-back, loc_y+3.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
113 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
114 | }
115 | if(side == "bottom" && rotation == 0) {
116 | place(loc_x-1.5, loc_y+back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
117 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
118 | }
119 | if(side == "bottom" && rotation == 90) {
120 | place(loc_x-back, loc_y-1.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
121 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
122 | }
123 | if(side == "bottom" && rotation == 180) {
124 | place(loc_x+size_x/2, loc_y-.5-back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
125 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
126 | }
127 | if(side == "bottom" && rotation == 270) {
128 | place(loc_x+back, loc_y+3.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
129 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
130 | }
131 | }
132 | if(enablemask == false) {
133 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
134 | union() {
135 | color("silver") translate([0, 0, size_z]) cube([size_x, size_y, 8]);
136 | color("dimgray") translate([3.5, .5, size_z+3.5]) sphere(d=5);
137 | color("silver") translate ([1, 1.25, 0]) cube([.64, .5, size_z+adj]);
138 | color("silver") translate ([3.25, 1.25, 0]) cube([.64, .5, size_z+adj]);
139 | color("silver") translate ([5.5, 1.25, 0]) cube([.64, .5, size_z+adj]);
140 | }
141 | }
142 | }
143 |
144 | if(type=="ir_2") {
145 |
146 | size_x = 5;
147 | size_y = 3;
148 | size_z = size[2];
149 | size_xm = 5;
150 | size_ym = 3.5;
151 |
152 | if(enablemask == true && cmask == true && mstyle == "default") {
153 | if(side == "top" && rotation == 0) {
154 | place(loc_x+size_x/2, loc_y+back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
155 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
156 | }
157 | if(side == "top" && rotation == 90) {
158 | place(loc_x+back, loc_y-2.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
159 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
160 | }
161 | if(side == "top" && rotation == 180) {
162 | place(loc_x-1.5, loc_y-.5-back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
163 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
164 | }
165 | if(side == "top" && rotation == 270) {
166 | place(loc_x-back, loc_y+3.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
167 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
168 | }
169 | if(side == "bottom" && rotation == 0) {
170 | place(loc_x-1.5, loc_y+back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
171 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
172 | }
173 | if(side == "bottom" && rotation == 90) {
174 | place(loc_x-back, loc_y-2.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
175 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
176 | }
177 | if(side == "bottom" && rotation == 180) {
178 | place(loc_x+size_x/2, loc_y-.5-back, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
179 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
180 | }
181 | if(side == "bottom" && rotation == 270) {
182 | place(loc_x+back, loc_y+3.5, loc_z+size_z+3.5, size_xm, size_ym, rotation, side, pcbsize_z)
183 | rotate([90, 0, 0]) cylinder(d = size_xm, h = mlen);
184 | }
185 | }
186 | if(enablemask == false) {
187 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
188 | union() {
189 | color("#353535") translate([0, 0, size_z]) cube([size_x, size_y, 6]);
190 | color("dimgray") translate([2.5, .5, size_z+3.5]) sphere(d=4);
191 | color("silver") translate ([.5, 1.25, 0]) cube([.64, .5, size_z+adj]);
192 | color("silver") translate ([2.25, 1.25, 0]) cube([.64, .5, size_z+adj]);
193 | color("silver") translate ([3.86, 1.25, 0]) cube([.64, .5, size_z+adj]);
194 | }
195 | }
196 | }
197 |
198 | if(type=="ir_3") {
199 |
200 | size_x = 4.75;
201 | size_y = 6;
202 | size_xm = 4;
203 | size_ym = 4;
204 |
205 | if(enablemask == true && cmask == true && mstyle == "default") {
206 | if(side == "top" && rotation == 0) {
207 | place(loc_x, loc_y+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
208 | translate([size_x/2,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
209 | }
210 | if(side == "top" && rotation == 90) {
211 | place(loc_x+back, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
212 | translate([1.625,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
213 | }
214 | if(side == "top" && rotation == 180) {
215 | place(loc_x, loc_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
216 | translate([1.625,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
217 | }
218 | if(side == "top" && rotation == 270) {
219 | place(loc_x-back, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
220 | translate([size_x/2,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
221 | }
222 | if(side == "bottom" && rotation == 0) {
223 | place(loc_x, loc_y+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
224 | translate([1.625,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
225 | }
226 | if(side == "bottom" && rotation == 90) {
227 | place(loc_x-back, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
228 | translate([1.625,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
229 | }
230 | if(side == "bottom" && rotation == 180) {
231 | place(loc_x, loc_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
232 | translate([size_x/2,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
233 | }
234 | if(side == "bottom" && rotation == 270) {
235 | place(loc_x+back, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
236 | translate([size_x/2,0,5.25]) rotate([90, 0, 0]) cylinder(d=size_xm, h=mlen);
237 | }
238 | }
239 | if(enablemask == false) {
240 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
241 | union() {
242 | color("#353535") translate([0, 0, 0]) cube([size_x, size_y, 7.5]);
243 | color("gray") translate([size_x/2, -2, 5.25]) rotate([270,0,0]) cylinder(d=4, h=2);
244 | color("gray") translate([size_x/2, -2, 5.25]) sphere(d=4);
245 | }
246 | }
247 | }
248 |
249 | if(type=="ir_dual") {
250 |
251 | size_x = 6.5;
252 | size_y = 2;
253 | size_xm = 3;
254 | size_ym = 6.5;
255 |
256 | if(enablemask == true && cmask == true && mstyle == "default") {
257 | if(side == "top" && rotation == 0) {
258 | place(loc_x+size_x/2, loc_y+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
259 | translate([-3.25,0,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
260 | }
261 | if(side == "top" && rotation == 90) {
262 | place(loc_x+back, loc_y-1.75, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
263 | translate([-5.25,0,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
264 | }
265 | if(side == "top" && rotation == 180) {
266 | place(loc_x-1.5, loc_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
267 | translate([-5,4.5,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
268 | }
269 | if(side == "top" && rotation == 270) {
270 | place(loc_x-4.5-back, loc_y+3.25, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
271 | translate([-3.25,0,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
272 | }
273 | if(side == "bottom" && rotation == 0) {
274 | place(loc_x-1.75, loc_y+back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
275 | translate([-5.25,0,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
276 | }
277 | if(side == "bottom" && rotation == 90) {
278 | place(loc_x-4.5-back, loc_y+.25, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
279 | translate([-3.25,0,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
280 | }
281 | if(side == "bottom" && rotation == 180) {
282 | place(loc_x+size_x/2, loc_y-back, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
283 | translate([-3.25,4.5,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
284 | }
285 | if(side == "bottom" && rotation == 270) {
286 | place(loc_x+back, loc_y+3.25, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
287 | translate([-3.25,0,1.75]) rotate([90, 0, 0]) slot(size_xm, size_ym, mlen);
288 | }
289 | }
290 | if(enablemask == false) {
291 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
292 | union() {
293 | color("silver") translate([0, 0, 0]) cube([size_x, size_y, 3.25]);
294 | color("dimgray") translate([1.5, .5, 1.75]) sphere(d=3);
295 | color("dimgray") translate([5, .5, 1.75]) sphere(d=3);
296 | }
297 | }
298 | }
299 |
300 | // can capacitor
301 | if(type=="capacitor" && enablemask == false) {
302 |
303 | size_x = size[0];
304 | size_y = size[0];
305 | height = size[2];
306 |
307 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
308 | union() {
309 | color("dimgray") cylinder(d=size_x+.5, h=.5);
310 | color("silver") translate([0, 0, .5]) cylinder(d=size_x+.5, h=.5);
311 | color("silver") translate([0, 0, 1]) cylinder(d=size_x, h=height-1);
312 | color(pcolor) translate([-size_x/3, -.32, -3.2]) cube([.64, .64, 3.3]);
313 | color(pcolor) translate([(size_x/2)-(size_x/4), -.32, -3.2]) cube([.64, .64, 3.3]);
314 | }
315 | }
316 | // led
317 | if(type=="led" && enablemask == false) {
318 |
319 | size_x = size[0];
320 | size_y = size[0];
321 | height = size[2];
322 | style = data[0];
323 | lcolor = data[1];
324 |
325 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
326 | union() {
327 | color(lcolor, .6) cylinder(d=size_x+1, h=.5);
328 | color(lcolor, .6) translate([0, 0, .4]) cylinder(d=size_x, h=height-size_x/2-.6);
329 | color(lcolor, .6) translate([0, 0, height-size_x/2]) sphere(d=size_x);
330 | color(pcolor) translate([-size_x/3, -.32, -3.2]) cube([.64,.64,3.3]);
331 | color(pcolor) translate([(size_x/2)-(size_x/4), -.32, -3.2]) cube([.64, .64, 3.3]);
332 | }
333 | }
334 | }
335 |
--------------------------------------------------------------------------------
/lib/display.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: display
20 | DESCRIPTION: creates flat panel displays
21 | TODO:
22 |
23 | USAGE: display(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "lcd_2.2", "mipi_csi", "mipi_dsi"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = component mask true, false
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 | */
39 |
40 | // display class
41 | module display(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
42 |
43 | cmask = mask[0];
44 | mlen = mask[1];
45 | back = mask[2];
46 | mstyle = mask[3];
47 |
48 | // type lcd_2.2
49 | if(type == "lcd_2.2") {
50 |
51 | size_x = 56;
52 | size_y = 38;
53 | size_xm = 45;
54 | size_ym = 34;
55 |
56 | if(enablemask == true && cmask == true && mstyle == "default") {
57 | if(side == "top" && rotation == 0) {
58 | place(loc_x+4, loc_y+1, loc_z+4, size_xm, size_ym, rotation, side, pcbsize_z)
59 | cube([size_xm, size_ym, mlen]);
60 | }
61 | if(side == "bottom" && rotation == 0) {
62 | place(loc_x+7, loc_y+1, loc_z+4, size_xm, size_ym, rotation, side, pcbsize_z)
63 | cube([size_xm, size_ym, mlen]);
64 | }
65 | }
66 | if(enablemask == false) {
67 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
68 | union() {
69 | difference() {
70 | union() {
71 | color("white") cube([size_x, size_y, 1.5]);
72 | color("grey") translate([1, 1, 1.5]) cube([size_x-2, size_y-2, 1.85]);
73 | }
74 | color("black") translate([54.5, 4, -.01]) cube([2, 30, 4]);
75 | }
76 | color("dimgrey") translate([4.25, .9, 3.35]) cube([45, 34, .25]);
77 | }
78 | }
79 | }
80 | // mipi csi port
81 | if(type=="mipi_csi" && enablemask == false) {
82 | size_x = 21;
83 | size_y = 3;
84 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
85 | union() {
86 | difference() {
87 | color("white") cube([size_x, size_y, 5]);
88 | color("white") translate([-1, -1, 3.5]) cube([23, 3.5, 5]);
89 | color("white") translate([-1, -1, 3.5]) cube([3, 5, 5]);
90 | color("white") translate([19, -1, 3.5]) cube([3, 5, 5]);
91 | }
92 | difference() {
93 | color("black") translate([-1, 0, 3.5]) cube([23, 3.5, 1]);
94 | color("dimgrey") translate([2, 2.9, 3.49]) cube([17, 3, 2]);
95 | }
96 | }
97 | }
98 | // mipi csi port
99 | if(type=="mipi_csi_90" && enablemask == false) {
100 | size_x = 21;
101 | size_y = 3;
102 | place(loc_x, loc_y-3, loc_z, size_x, size_y, rotation, side, pcbsize_z)
103 | rotate([90, 0, 0])
104 | union() {
105 | difference() {
106 | color("white") cube([size_x, size_y, 5]);
107 | color("white") translate([-1, -1, 3.5]) cube([23, 3.5, 5]);
108 | color("white") translate([-1, -1, 3.5]) cube([3, 5, 5]);
109 | color("white") translate([19, -1, 3.5]) cube([3, 5, 5]);
110 | }
111 | difference() {
112 | color("black") translate([-1, 0, 3.5]) cube([23, 3.5 ,1]);
113 | color("dimgrey") translate([2, 2.9, 3.49]) cube([17, 3, 2]);
114 | }
115 | }
116 | }
117 | // mipi dsi port
118 | if(type=="mipi_dsi" && enablemask == false) {
119 | size_x = 10;
120 | size_y = 3;
121 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
122 | union() {
123 | color("black") cube([size_x, 1.5, 2]);
124 | color("saddlebrown") translate([0, 1.5, 0]) cube([size_x, 1.5, 2]);
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/lib/fan.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: fan
20 | DESCRIPTION: creates fan support components
21 | TODO:
22 |
23 | USAGE: fan(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "fan_micro", "encl_pmw", "encl_pmw_h"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = component mask true, false
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 | */
39 |
40 | // fan class
41 | module fan(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
42 |
43 | // micro connector type
44 | if(type=="fan_micro" && enablemask == false) {
45 | size_x = 7.5;
46 | size_y = 3.75;
47 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
48 | union() {
49 | difference () {
50 | color("white") cube([size_x, size_y, 4.75]);
51 | color("darkgray") translate([1.5, .5, 1]) cube([4.5, 2.75, 6]);
52 | color("white") translate([-.5, .75, -.5]) cube([1, 2.5, 6]);
53 | color("white") translate([7, .75, -.5]) cube([1, 2.5, 6]);
54 | color("darkgray") translate([2.25, -.5, 1]) cube([3, 2, 6]);
55 | }
56 | color("silver") translate ([2.75, 2, .5]) cube([.6, .6, 4]);
57 | color("silver") translate ([4.5, 2, .5]) cube([.6, .6, 4]);
58 | }
59 | }
60 |
61 | // pmw-standard connector type
62 | if(type=="encl_pmw" && enablemask == false) {
63 | size_x = 11.6;
64 | size_y = 4.3;
65 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
66 | union() {
67 | difference () {
68 | color("white") cube([size_x, size_y, 7]);
69 | color("darkgray") translate([.5, .5, 1]) cube([10.5, 3, 8]);
70 | //color("white") translate([-.5, .75, -.5]) cube([1, 2.5, 6]);
71 | //color("white") translate([11, .75, -.5]) cube([1, 2.5, 6]);
72 | color("darkgray") translate([2.25, -.5, 1]) cube([7.5, 2, 8]);
73 | }
74 | for (i=[2:2.54:11.7]) {
75 | color("silver") translate ([i, 2.54, 2]) cylinder(d=.67, h=5, $fn=30);
76 | }
77 | }
78 | }
79 |
80 | // pmw-standard connector type horizontal and 45 degrees
81 | if(type=="encl_pmw_h" && enablemask == false) {
82 | size_x = 11.6;
83 | size_y = 4.3;
84 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
85 | translate([11.6, 0, 5]) rotate([-90, 0, -45])
86 | union() {
87 | difference () {
88 | color("white") cube([size_x, size_y, 4]);
89 | color("darkgray") translate([.5, .5, 1]) cube([10.5, 3, 8]);
90 | //color("white") translate([-.5, .75, -.5]) cube([1, 2.5, 6]);
91 | //color("white") translate([11, .75, -.5]) cube([1, 2.5, 6]);
92 | color("darkgray") translate([2.25, -.5, 1]) cube([7.5, 2, 8]);
93 | }
94 | for (i=[2:2.54:11.7]) {
95 | color("silver") translate ([i, 2.54, 2]) cylinder(d=.67, h=2, $fn=30);
96 | }
97 | }
98 | }
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/lib/fillets.scad:
--------------------------------------------------------------------------------
1 | // Stephanie Shaltes
2 | // https://github.com/StephS/i2_xends/blob/master/inc/fillets.scad
3 | //
4 | // 20200329 Additional maintenance and debug by hominoid @ www.forum.odroid.com
5 |
6 | function poly_sides_r(r) = (max(round(4 * r),3)+1);
7 |
8 | // 2d primitive for outside fillets.
9 | module fillet_2d_o(fillet_r, fillet_angle=90, fillet_fn=0) {
10 | add=0.01;
11 | f_fn=(fillet_fn>0) ? fillet_fn*4 : (ceil(poly_sides_r(fillet_r)/4)*4);
12 | if (fillet_r>0) {
13 | intersection() {
14 | circle(r=fillet_r, $fn=f_fn);
15 | polygon([
16 | [0-add, 0-add],
17 | [0-add, fillet_r],
18 | [fillet_r * tan(fillet_angle/2), fillet_r],
19 | [fillet_r * sin(fillet_angle), fillet_r * cos(fillet_angle)-add]
20 | ]);
21 | }
22 | }
23 | }
24 |
25 | // 2d primitive for inside fillets.
26 | module fillet_2d_i(fillet_r, fillet_angle=90, fillet_fn=0) {
27 | add=0.01;
28 | f_fn=(fillet_fn>0) ? fillet_fn*4 : (ceil(poly_sides_r(fillet_r)/4)*4);
29 | if (fillet_r>0) {
30 | translate([fillet_r * tan(fillet_angle/2), fillet_r, 0])
31 | difference() {
32 | polygon([
33 | [0, 0],
34 | [0, -fillet_r-add],
35 | [-fillet_r * tan(fillet_angle/2)-add, -fillet_r-add],
36 | [-fillet_r * sin(fillet_angle)-add, -fillet_r * cos(fillet_angle)]
37 | ]);
38 | circle(r=fillet_r, $fn=f_fn);
39 | }
40 | }
41 | }
42 |
43 | // 3d rotated outside fillet.
44 | module fillet_polar_o(inner_r, fillet_r, fillet_angle=90, fillet_fn=0, rotate_fn=0) {
45 | if (fillet_r>0) {
46 | rotate_extrude(convexity=8, $fn=rotate_fn) {
47 | translate([inner_r, 0, 0]) {
48 | fillet_2d_o(fillet_r, fillet_angle, fillet_fn);
49 | }
50 | }
51 | }
52 | }
53 |
54 | // 3d rotated inside fillet.
55 | module fillet_polar_i(inner_r, fillet_r, fillet_angle=90, fillet_fn=0, rotate_fn=0) {
56 | if (fillet_r>0) {
57 | rotate_extrude(convexity=8, $fn=rotate_fn) {
58 | translate([inner_r, 0, 0]) {
59 | fillet_2d_i(fillet_r, fillet_angle, fillet_fn); }
60 | }
61 | }
62 | }
63 |
64 | // 3d rotated inside fillet negative.
65 | module fillet_polar_i_n(outer_r, fillet_r, fillet_angle=90, fillet_fn=0, rotate_fn=0) {
66 | if (fillet_r>0) {
67 | rotate_extrude(convexity=8, $fn=rotate_fn) {
68 | translate([outer_r, 0, 0]) {
69 | rotate(90) fillet_2d_i(fillet_r, fillet_angle, fillet_fn); }
70 | }
71 | }
72 | }
73 |
74 | // 3d linear outside fillet.
75 | module fillet_linear_o(l, fillet_r, fillet_angle=90, fillet_fn=0, add=0.02) {
76 | if (fillet_r>0) {
77 | translate([0,0,-add/2])
78 | linear_extrude(height=l+add, center=false) {
79 | fillet_2d_o(fillet_r, fillet_angle, fillet_fn);
80 | }
81 | }
82 | }
83 |
84 | // 3d linear inside fillet.
85 | module fillet_linear_i(l, fillet_r, fillet_angle=90, fillet_fn=0, add=0.02) {
86 | if (fillet_r>0) {
87 | translate([0,0,-add/2])
88 | linear_extrude(height=l+add, center=false) {
89 | fillet_2d_i(fillet_r, fillet_angle, fillet_fn);
90 | }
91 | }
92 | }
93 |
94 | module cube_negative_fillet(size, radius=-1, vertical=[3,3,3,3], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90, vertical_fn=[0,0,0,0], top_fn=[0,0,0,0], bottom_fn=[0,0,0,0]){
95 |
96 | vertical_fn= ($fn>0) ? [$fn,$fn,$fn,$fn] : vertical_fn;
97 | top_fn= ($fn>0) ? [$fn,$fn,$fn,$fn] : top_fn;
98 | bottom_fn= ($fn>0) ? [$fn,$fn,$fn,$fn] : bottom_fn;
99 |
100 |
101 | j=[1,0,1,0];
102 |
103 | for (i=[0:3]) {
104 | if (radius > -1) {
105 | rotate([0, 0, 90*i]) translate([size[1-j[i]]/2, size[j[i]]/2, 0]) translate([0, 0, -size[2]/2]) rotate([0,0,180]) fillet_linear_i(l=size[2], fillet_r=radius, fillet_angle=90, fillet_fn=$fn); //fillet(radius, size[2], $fn=$fn);
106 | } else {
107 | rotate([0, 0, 90*i]) translate([size[1-j[i]]/2, size[j[i]]/2, 0]) translate([0, 0, -size[2]/2]) rotate([0,0,180]) fillet_linear_i(l=size[2], fillet_r=vertical[i], fillet_angle=90, fillet_fn=vertical_fn[i]); //fillet(vertical[i], size[2], $fn=$fn);
108 | }
109 | rotate([90*i, -90, 0]) translate([size[2]/2, size[j[i]]/2, 0 ]) translate([0, 0, -size[1-j[(i)]]/2]) rotate([0,0,180]) fillet_linear_i(l=size[1-j[(i)]], fillet_r=top[(i)], fillet_angle=90, fillet_fn=top_fn[i]); // fillet(top[i], size[1-j[i]], $fn=$fn);
110 | rotate([90*(4-i), 90, 0]) translate([size[2]/2, size[j[i]]/2, 0]) translate([0, 0, -size[1-j[(i)]]/2]) rotate([0,0,180]) fillet_linear_i(l=size[1-j[(i)]], fillet_r=bottom[(i)], fillet_angle=90, fillet_fn=bottom_fn[i]); //fillet(bottom[i], size[1-j[i]], $fn=$fn);
111 |
112 | }
113 | }
114 |
115 | module cube_positive_fillet(size, radius=-1, vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], vertical_angle=[90,90,90,90], top_angle=[90,90,90,90], bottom_angle=[90,90,90,90], vertical_flip=[0,0,0,0], top_flip=[0,0,0,0], bottom_flip=[0,0,0,0], $fn=0){
116 |
117 | j=[1,0,1,0];
118 |
119 | for (i=[0:3]) {
120 | if (radius > -1) {
121 | rotate([0, 0, 90*i]) translate([size[1-j[i]]/2, size[j[i]]/2, 0]) translate([0, 0, -size[2]/2]) rotate([0,0,90]) fillet_linear_i(l=size[2], fillet_r=radius, fillet_angle=90, fillet_fn=$fn); //fillet(radius, size[2], $fn=$fn);
122 | } else {
123 | rotate([0, 0, 90*i]) translate([size[1-j[i]]/2, size[j[i]]/2, 0]) translate([0, 0, -size[2]/2]) rotate([0,0,180-vertical_angle[i]+(90+vertical_angle[i])*vertical_flip[i]]) fillet_linear_i(l=size[2], fillet_r=vertical[i], fillet_angle=vertical_angle[i], fillet_fn=$fn); //fillet(vertical[i], size[2], $fn=$fn);
124 | }
125 | rotate([90*i, -90, 0]) translate([size[2]/2, size[j[i]]/2, 0 ]) translate([0, 0, -size[1-j[(i)]]/2]) rotate([0,0,(180-top_angle[i])+(90+top_angle[i])*top_flip[i]]) fillet_linear_i(l=size[1-j[(i)]], fillet_r=top[(i)], fillet_angle=180-top_angle[i], fillet_fn=$fn); // fillet(top[i], size[1-j[i]], $fn=$fn);
126 | rotate([90*(4-i), 90, 0]) translate([size[2]/2, size[j[i]]/2, 0]) translate([0, 0, -size[1-j[(i)]]/2]) rotate([0,0,180-bottom_angle[i]+(90+bottom_angle[i])*bottom_flip[i]]) fillet_linear_i(l=size[1-j[(i)]], fillet_r=bottom[(i)], fillet_angle=bottom_angle[i], fillet_fn=$fn); //fillet(bottom[i], size[1-j[i]], $fn=$fn);
127 |
128 | }
129 | }
130 |
131 | module cube_positive_fillet_corners(size, radius=-1, vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], vertical_angle=[90,90,90,90], top_angle=[90,90,90,90], bottom_angle=[90,90,90,90], vertical_flip=[0,0,0,0], top_flip=[0,0,0,0], bottom_flip=[0,0,0,0], $fn=90){
132 |
133 | j=[1,0,1,0];
134 |
135 | //bottom
136 | for (i=[0:3]) {
137 | render(convexity=4) intersection() {
138 | /*
139 | if (radius > -1) {
140 | rotate([0, 0, 90*i]) translate([size[1-j[i]]/2, size[j[i]]/2, 0]) translate([0, 0, -size[2]/2-radius]) rotate([0,0,90]) fillet_linear_i(l=size[2]+radius*2, r=radius, fillet_angle=90, fillet_fn=$fn); //fillet(radius, size[2], $fn=$fn);
141 | } else {
142 | rotate([0, 0, 90*i]) translate([size[1-j[i]]/2, size[j[i]]/2, 0]) translate([0, 0, -size[2]/2-vertical[i]]) rotate([0,0,180-vertical_angle[i]+(90+vertical_angle[i])*vertical_flip[i]]) fillet_linear_i(l=size[2]+vertical[i]*2, r=vertical[i], fillet_angle=vertical_angle[i], fillet_fn=$fn); //fillet(vertical[i], size[2], $fn=$fn);
143 | }
144 | */
145 | rotate([90*(4-i), 90, 0]) translate([size[2]/2, size[j[i]]/2, 0]) translate([0, 0, -size[1-j[(i)]]/2-bottom[(i)]]) rotate([0,0,180-bottom_angle[i]+(90+bottom_angle[i])*bottom_flip[i]]) fillet_linear_i(l=size[1-j[(i)]]+bottom[(i)]*4, fillet_r=bottom[(i)], fillet_angle=bottom_angle[i], fillet_fn=$fn); //fillet(bottom[i], size[1-j[i]], $fn=$fn);
146 | rotate([90*(4-((i+1)%4)), 90, 0]) translate([size[2]/2, size[j[((i+1)%4)]]/2, 0]) translate([0, 0, -size[1-j[((i+1)%4)]]/2-bottom[((i+1)%4)]]) rotate([0,0,180-bottom_angle[((i+1)%4)]+(90+bottom_angle[((i+1)%4)])*bottom_flip[((i+1)%4)]]) fillet_linear_i(l=size[1-j[(((i+1)%4))]]+bottom[(((i+1)%4))]*4, fillet_r=bottom[(((i+1)%4))], fillet_angle=bottom_angle[((i+1)%4)], fillet_fn=$fn); //fillet(bottom[i], size[1-j[i]], $fn=$fn);
147 | }
148 | }
149 |
150 | // top
151 | for (i=[0:3]) {
152 | render(convexity=4) intersection() {
153 | rotate([90*i, -90, 0]) translate([size[2]/2, size[j[i]]/2, 0 ]) translate([0, 0, -size[1-j[(i)]]/2-top[(i)]]) rotate([0,0,(180-top_angle[i])+(90+top_angle[i])*top_flip[i]]) fillet_linear_i(l=size[1-j[(i)]]+top[(i)]*4, fillet_r=top[(i)], fillet_angle=180-top_angle[i], fillet_fn=$fn); // fillet(top[i], size[1-j[i]], $fn=$fn);
154 | rotate([90*((i+1)%4), -90, 0]) translate([size[2]/2, size[j[((i+1)%4)]]/2, 0 ]) translate([0, 0, -size[1-j[(((i+1)%4))]]/2-top[(((i+1)%4))]]) rotate([0,0,(180-top_angle[((i+1)%4)])+(90+top_angle[((i+1)%4)])*top_flip[((i+1)%4)]]) fillet_linear_i(l=size[1-j[(((i+1)%4))]]+top[(((i+1)%4))]*4, fillet_r=top[(((i+1)%4))], fillet_angle=180-top_angle[((i+1)%4)], fillet_fn=$fn); // fillet(top[i], size[1-j[i]], $fn=$fn);
155 | }
156 | }
157 | }
158 |
159 | module cube_fillet_inside(size, radius=-1, vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90, vertical_fn=[0,0,0,0], top_fn=[0,0,0,0], bottom_fn=[0,0,0,0]){
160 | //makes CENTERED cube with round corners
161 | // if you give it radius, it will fillet vertical corners.
162 | //othervise use vertical, top, bottom arrays
163 | //when viewed from top, it starts in upper right corner (+x,+y quadrant) , goes counterclockwise
164 | //top/bottom fillet starts in direction of Y axis and goes CCW too
165 |
166 | if (radius == 0) {
167 | cube(size, center=true);
168 | } else {
169 | difference() {
170 | cube(size, center=true);
171 | cube_negative_fillet(size, radius, vertical, top, bottom, $fn, vertical_fn, top_fn, bottom_fn);
172 | }
173 | }
174 | }
175 |
176 | module cylinder_fillet_inside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=0, center=false) {
177 | c_fn=($fn>0) ? $fn : poly_sides_r(r);
178 | rotfix=(($fn>0) ? 0 : 180/c_fn);
179 | cent=(center) ? -h/2 : 0;
180 | // echo (c_fn);
181 | translate([0,0,cent])
182 | difference() {
183 | cylinder(h=h,r=r,$fn=c_fn);
184 | rotate ([0,0,rotfix]) {
185 | fillet_polar_i_n(outer_r=r, fillet_r=bottom,
186 | fillet_angle=90, fillet_fn=fillet_fn, rotate_fn=c_fn);
187 | translate([0,0,h]) mirror ([0,0,1])
188 | fillet_polar_i_n(outer_r=r, fillet_r=top,
189 | fillet_angle=90, fillet_fn=fillet_fn, rotate_fn=c_fn);
190 | }
191 | }
192 | }
193 |
194 | module cylinder_fillet_outside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=0, center=false) {
195 | c_fn=($fn>0) ? $fn : poly_sides_r(r);
196 | rotfix=(($fn>0) ? 0 : 180/c_fn);
197 | cent=(center) ? -h/2 : 0;
198 | // echo (c_fn);
199 | translate([0,0,cent]) {
200 | cylinder(h=h,r=r,$fn=c_fn);
201 | rotate ([0,0,rotfix]) {
202 | fillet_polar_i(inner_r=r, fillet_r=bottom, fillet_angle=90,
203 | fillet_fn=fillet_fn, rotate_fn=c_fn);
204 | translate([0,0,h]) mirror ([0,0,1])
205 | fillet_polar_i(inner_r=r, fillet_r=top, fillet_angle=90,
206 | fillet_fn=fillet_fn, rotate_fn=c_fn);
207 | }
208 | }
209 | }
210 |
211 |
212 | //cube([20,20,20], center=true);
213 | //cube_positive_fillet_corners([20,20,20], radius=-1, vertical=[0,0,0,0], top=[3,3,3,3], bottom=[3,3,3,3], top_angle=[90,90,90,90], top_flip=[0,0,0,0], $fn=10);
214 | //cube_positive_fillet([20,20,20], radius=-1, vertical=[0,0,0,0], top=[3,3,3,3], bottom=[3,3,3,3], top_angle=[90,90,90,90], top_flip=[0,0,0,0], $fn=10);
215 |
216 | //translate([-12,23,0]) cube_fillet_inside([20,20,20], vertical=[0,0,0,0], top=[3,3,3,3], bottom=[3,3,3,3], $fn=10);
217 |
218 | //translate([23,-12,0]) cylinder_fillet_inside(h=20, r=10, top=3, bottom=3, $fn=0, fillet_fn=10, center=true);
219 |
220 | //translate([0,0,23]) cylinder_fillet_outside(h=20, r=10, top=3, bottom=3, $fn=0, fillet_fn=10, center=true);
221 |
222 |
--------------------------------------------------------------------------------
/lib/fpc.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: fpc
20 | DESCRIPTION: creates fpc connectors
21 | TODO: add other styles
22 |
23 | USAGE: fpc(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "fh19"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = #pins
32 | data[0] = "smt"
33 | data[1] = "side"
34 | data[2] = body color
35 | data[3] = tab color
36 | pcbsize_z = pcb thickness
37 | enablemask = true produces mask, false produces model
38 | mask[0] = true enables component mask
39 | mask[1] = mask length
40 | mask[2] = mask setback
41 | mask[3] = mstyle "default"
42 |
43 | type = "fh12"
44 | loc_x = x location placement
45 | loc_y = y location placement
46 | loc_z = z location placement
47 | side = "top", "bottom"
48 | rotation[] = object rotation
49 | size[0] = #pins
50 | data[0] = "smt"
51 | data[1] = "top"
52 | data[2] = body color
53 | data[3] = tab color
54 | pcbsize_z = pcb thickness
55 | enablemask = true produces mask, false produces model
56 | mask[0] = true enables component mask
57 | mask[1] = mask length
58 | mask[2] = mask setback
59 | mask[3] = mstyle "default"
60 |
61 | */
62 |
63 | // fpc connector class
64 | module fpc(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
65 |
66 | row = size[0];
67 | style = data[0];
68 | entry = data[1];
69 | bcolor = data[2];
70 | tcolor = data[3];
71 | pcolor = "#fee5a6";
72 | cmask = mask[0];
73 | mlen = mask[1];
74 | back = mask[2];
75 | mstyle = mask[3];
76 |
77 | /*
78 | p p
79 | i i
80 | n n
81 |
82 | b t
83 | w o o
84 | b a p p t p p
85 | o l i i i
86 | d s s l n n h h n
87 | p y i i e e
88 | t i z z s x y i i s
89 | y t a e e i a a g g i
90 | p c d z d d h h z
91 | e h j y z e j j t t e
92 | */
93 | fpc_data = [
94 | ["fh19", .5, 2, 2.5, .9, .25, 1.25, 2.4, 3.4, 1, .15],
95 | ["fh12", .5, 1.9, 3.5, 3.6, .25, 1.9, 2.4, 3.4, 1, .15]
96 | ];
97 |
98 | adj = .01;
99 | $fn = 90;
100 |
101 | s = search([type],fpc_data);
102 |
103 | pitch = fpc_data[s[0]][1];
104 | body_adj = fpc_data[s[0]][2];
105 | size_x = body_adj+(row*pitch);
106 | size_y = fpc_data[s[0]][3];
107 | size_z = fpc_data[s[0]][4];
108 | wall_size = fpc_data[s[0]][5];
109 | pin_xadj = fpc_data[s[0]][6];
110 | pin_yadj = fpc_data[s[0]][7];
111 | pbheight = fpc_data[s[0]][8];
112 | ptheight = fpc_data[s[0]][9];
113 | pinsize = fpc_data[s[0]][10];
114 | smtlead = [pinsize,.5,.15];
115 | size_xm = size_x;
116 | size_ym = size_y;
117 | size_zm = 2;
118 |
119 | if(entry == "top" && enablemask == false) {
120 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
121 | union() {
122 | difference() {
123 | color(bcolor) cube([size_x, size_y, size_z]);
124 | translate([-2,-1,size_z-.5]) color(bcolor) cube([3, size_y+2, 3]);
125 | translate([size_x-1,-1,size_z-.5]) color(bcolor) cube([3, size_y+2, 3]);
126 | translate([-2,-1,size_z-.5]) color(bcolor) cube([size_x+2, size_y, 3]);
127 | translate([-.5,-5.25,-adj]) color(bcolor) cylinder(d=12, h=4);
128 | translate([size_x+.5,-5.25,-adj]) color(bcolor) cylinder(d=12, h=4);
129 | }
130 | difference() {
131 | translate([-.5,-.25,size_z-.5-adj]) color(tcolor) cube([size_x+1, size_y+.5, .45+adj]);
132 | translate([.5,size_y-.1,size_z-2]) color(tcolor) cube([size_x-1, size_y, 3]);
133 | translate([-.5,-5.5,-adj]) color(tcolor) cylinder(d=12, h=4);
134 | translate([size_x+.5,-5.5,-adj]) color(tcolor) cylinder(d=12, h=4);
135 | }
136 | if(style == "thruhole") {
137 | for(r=[pin_xadj-(pinsize/2):pitch:size_x-pitch]) {
138 | color(pcolor) translate([r, pin_yadj-(pinsize/2), -pbheight+adj])
139 | cube([pinsize, pinsize, pbheight+ptheight]);
140 | }
141 | }
142 | if(style == "smt") {
143 | for(r=[body_adj/2+pinsize:pitch:size_x-(body_adj/2)-pinsize]) {
144 | color(pcolor) translate([r, size_y-adj, 0])
145 | cube(smtlead);
146 | }
147 | }
148 | }
149 | }
150 | if(entry == "side" && enablemask == true && cmask == true && mstyle == "default") {
151 | if(side == "top" && rotation == 0) {
152 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
153 | translate([0, back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
154 | }
155 | if(side == "top" && rotation == 90) {
156 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
157 | translate([0, back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
158 | }
159 | if(side == "top" && rotation == 180) {
160 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
161 | translate([0, 1+back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
162 | }
163 | if(side == "top" && rotation == 270) {
164 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
165 | translate([0, .5+back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
166 | }
167 | if(side == "bottom" && rotation == 0) {
168 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
169 | translate([0, back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
170 | }
171 | if(side == "bottom" && rotation == 90) {
172 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
173 | translate([0, .5+back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
174 | }
175 | if(side == "bottom" && rotation == 180) {
176 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
177 | translate([0, 1+back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
178 | }
179 | if(side == "bottom" && rotation == 270) {
180 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
181 | translate([0, back, size_zm/3]) rotate([90, 0, 0]) slot(size_zm, size_x, mlen);
182 | }
183 | }
184 | if(entry == "side" && enablemask == true && cmask == true && mstyle == "block") {
185 | if(side == "top" && rotation == 270) {
186 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
187 | translate([0, -1.5+back, size_zm-5.5]) rotate([90, 0, 0]) cube([size_x, size_zm+3.5, mlen]);
188 | }
189 | }
190 | if(entry == "side" && enablemask == false) {
191 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
192 | union() {
193 | difference() {
194 | color(bcolor) cube([size_x, size_y, size_z]);
195 | color("#353535") translate([body_adj/2, -wall_size, .31])
196 | cube([size_x-body_adj, size_y, size_z]);
197 | }
198 | if(type == "fh19") {
199 | difference() {
200 | color(tcolor) translate([.125+body_adj/2, -.5,.5]) cube([size_x-body_adj-.25, 2.625, .25]);
201 | color(tcolor) translate([.115+body_adj/2, -.55,0]) cube([(size_x-body_adj-.25)/3, .25, 3]);
202 | color(tcolor) translate([(.135+body_adj/2)+(size_x-body_adj-.25)/1.5, -.55,0])
203 | cube([(size_x-body_adj-.25)/3, .25, 3]);
204 | }
205 | }
206 | if(style == "smt") {
207 | for(r=[pin_xadj-(pinsize/2):pitch:size_x-body_adj/2]) {
208 | color(pcolor) translate([r, -adj, .21])
209 | cube([pinsize, ptheight, pinsize]);
210 | color(pcolor) translate([r, size_y-adj, 0])
211 | cube(smtlead);
212 | }
213 | }
214 | }
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/lib/header.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: header
20 | DESCRIPTION: creates pin headers in any size or pitch.
21 | TODO: "angled-boxed" and male pitchs besides 2.54.
22 |
23 | USAGE: header(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "open","boxed","angled"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = #row
32 | size[1] = #columns
33 | size[2] = pin height
34 | data[0] = style ("thruhole", "smt")
35 | data[1] = header color
36 | data[2] = "male", "female"
37 | data[3] = pitch
38 | data[4] = pin color
39 | pcbsize_z = pcb thickness
40 | enablemask = true produces mask, false produces model
41 | mask[0] = true, false
42 | mask[1] = length
43 | mask[2] = set back
44 | mask[3] = mstyle "default"
45 |
46 | */
47 |
48 | // header class
49 | module header(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
50 |
51 | row = size[0];
52 | column = size[1];
53 | height = size[2];
54 | style = data[0];
55 | hcolor = data[1];
56 | gender = data[2];
57 | pitch = data[3];
58 | pcolor = data[4];
59 |
60 | size_y = pitch == 2.54 && style == "smt" ? (2.5 * column) : (pitch * column);
61 | size_x = pitch == 2.54 && style == "smt" ? (2.54 * row) : (pitch * row);
62 | bheight = pitch == 2.54 ? 2.5 : 1;
63 | pheight = pitch == 2.54 ? 3.2 : 2;
64 | pinsize = pitch == 2.54 ? .64 : .3;
65 | theight = bheight + pheight + height;
66 | smtlead = [pinsize, .925, .32];
67 | wall = .1;
68 | walloffset = pitch+wall;
69 |
70 | adj = .01;
71 | $fn = 90;
72 |
73 | // thruhole headers
74 | if(style == "thruhole" && enablemask == false) {
75 |
76 | if((type == "open" || type == "boxed") && gender == "male") {
77 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
78 | union() {
79 | color(hcolor) cube([size_x, size_y, bheight]);
80 | for(c=[pitch/2:pitch:size_x]) {
81 | for(r=[pitch/2:pitch:size_y]) {
82 | color(pcolor) translate([c-(pinsize/2), r-(pinsize/2), -pheight]) cube([pinsize, pinsize, theight+adj]);
83 | }
84 | }
85 | }
86 | if(type == "boxed") {
87 | difference() {
88 | color(hcolor) translate([-walloffset,-wall,0]) cube([size_x+2*2.56, size_y+2*wall, height+bheight]);
89 | color(hcolor) translate([-walloffset+wall,0,wall]) cube([size_x+2*walloffset-4*wall, size_y, height+bheight+adj]);
90 | }
91 | }
92 | }
93 | if(type == "open" && gender == "female") {
94 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
95 | union() {
96 | difference() {
97 | color(hcolor) cube([size_x, size_y, height]);
98 | for(c=[pitch/2:pitch:size_x]) {
99 | for(r=[pitch/2:pitch:size_y]) {
100 | color("#888888") translate([c-(pinsize/2), r-(pinsize/2), height-5+adj]) cube([pinsize, pinsize, height-1]);
101 | color("#888888") translate([c-(pinsize/2),r-(pinsize/2),-pheight]) cube([pinsize, pinsize, pheight+adj]);
102 | }
103 | }
104 | }
105 | for(c=[pitch/2:pitch:size_x]) {
106 | for(r=[pitch/2:pitch:size_y]) {
107 | color(pcolor) translate([c-(pinsize/2), r-(pinsize/2), -pheight]) cube([pinsize, pinsize, pheight+adj]);
108 | }
109 | }
110 | }
111 | }
112 | if(type == "angled" && gender == "male") {
113 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
114 | union() {
115 | color(hcolor) cube([size_x, bheight, size_y]);
116 | for(c=[pitch/2:pitch:size_x]) {
117 | for(r=[pitch/2:pitch:size_y]) {
118 | if(r <= pitch) {
119 | color(pcolor) translate([c-(pinsize/2)+pinsize, pitch+1.5*pinsize, -(pitch/2)+r+(1.5*pinsize)-adj])
120 | rotate([0,270,0]) rotate_extrude(angle=90, convexity = 0) square([pinsize, pinsize]);
121 | color(pcolor) translate([c-(pinsize/2), pitch+1.5*pinsize, -pheight-(pitch/2)+r+(1.5*pinsize)])
122 | cube([pinsize,pinsize,pheight]);
123 | color(pcolor) translate([c-(pinsize/2), -height+pinsize/2, r-(pinsize/2)])
124 | cube([pinsize, pheight + height, pinsize]);
125 | }
126 | else {
127 | color(pcolor) translate([c-(pinsize/2)+pinsize, (2*pitch)+1.5*pinsize, -(pitch/2)+r+(1.5*pinsize)-adj])
128 | rotate([0,270,0]) rotate_extrude(angle=90, convexity = 0) square([pinsize, pinsize]);
129 | color(pcolor) translate([c-(pinsize/2), 2*pitch+1.5*pinsize, -height-(pitch/2)+r+(2*pinsize)+(height-6)])
130 | cube([pinsize,pinsize,pheight+pitch]);
131 | color(pcolor) translate([c-(pinsize/2), -height+pinsize/2, r-(pinsize/2)])
132 | cube([pinsize, pheight+height+pitch, pinsize]);
133 | }
134 | }
135 | }
136 | }
137 | }
138 | if(type == "angled" && gender == "female") {
139 | size_y = pitch == 2.54 && style == "smt" ? (2.5 * column) : (pitch * column)+1;
140 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
141 | union() {
142 | difference() {
143 | color(hcolor) cube([size_x, height, size_y]);
144 | for(c=[pitch/2:pitch:size_x+pitch]) {
145 | for(r=[pitch/2:pitch:size_y]) {
146 | color("#888888") translate([c-(pinsize/2), r-(pinsize/2)-bheight, +1+pinsize/2])
147 | cube([pinsize, height-1, pinsize]);
148 | color("#888888") translate([c-(pinsize/2),r-(pinsize/2)-bheight, pheight+.5+pinsize/2])
149 | cube([pinsize, pheight+adj, pinsize]);
150 | }
151 | }
152 | }
153 | translate([0, height-1.5, .5]) for(c=[pitch/2:pitch:size_x]) {
154 | for(r=[pitch/2:pitch:size_y]) {
155 | if(r <= pitch) {
156 | color(pcolor) translate([c-(pinsize/2)+pinsize, pitch+1.5*pinsize, -(pitch/2)+r+(1.5*pinsize)-adj])
157 | rotate([0,270,0]) rotate_extrude(angle=90, convexity = 0) square([pinsize, pinsize]);
158 | color(pcolor) translate([c-(pinsize/2), pitch+1.5*pinsize, -pheight-(pitch/2)+r+(1.5*pinsize)-.5])
159 | cube([pinsize,pinsize,pheight+.5]);
160 | color(pcolor) translate([c-(pinsize/2), pinsize/2, r-(pinsize/2)])
161 | cube([pinsize, pheight, pinsize]);
162 | }
163 | else {
164 | color(pcolor) translate([c-(pinsize/2)+pinsize, (2*pitch)+1.5*pinsize, -(pitch/2)+r+(1.5*pinsize)-adj])
165 | rotate([0,270,0]) rotate_extrude(angle=90, convexity = 0) square([pinsize, pinsize]);
166 | color(pcolor) translate([c-(pinsize/2), 2*pitch+1.5*pinsize, -height-(pitch/2)+r+(2*pinsize)+(height-6)-.5])
167 | cube([pinsize,pinsize,pheight+pitch+.5]);
168 | color(pcolor) translate([c-(pinsize/2), pinsize/2, r-(pinsize/2)])
169 | cube([pinsize, pheight+pitch, pinsize]);
170 | }
171 | }
172 | }
173 | }
174 | }
175 | }
176 | // smt headers
177 | if(style == "smt" && enablemask == false) {
178 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
179 | union() {
180 | if((type == "open" || type == "boxed") && gender == "male") {
181 | union() {
182 | color(hcolor) cube([size_x, size_y, bheight]);
183 | for(c=[pitch/2:pitch:size_x]) {
184 | for(r=[pitch/2:pitch:size_y]) {
185 | color(pcolor) translate([c-(pinsize/2), r-(pinsize/2), bheight-adj]) cube([pinsize, pinsize, height]);
186 | }
187 | }
188 | }
189 | if(type == "boxed") {
190 | difference() {
191 | color(hcolor) translate([-walloffset,-wall,0]) cube([size_x+2*2.56, size_y+2*wall, height+bheight]);
192 | color(hcolor) translate([-walloffset+wall,0,wall]) cube([size_x+2*walloffset-4*wall, size_y, height+bheight+adj]);
193 | }
194 | }
195 | }
196 | if(gender == "female") {
197 | union() {
198 | difference() {
199 | color(hcolor) cube([size_x, size_y, height]);
200 | for(c=[pitch/2:pitch:size_x]) {
201 | for(r=[pitch/2:pitch:size_y]) {
202 | color("#888888") translate([c-(pinsize/2), r-(pinsize/2), adj]) cube([pinsize, pinsize, height]);
203 | }
204 | }
205 | }
206 | }
207 | }
208 | if(size_x >= size_y) {
209 | for(r=[pitch/2:pitch:size_x]) {
210 | for(c=[pitch/2:pitch:size_y]) {
211 | color(pcolor) translate ([r-(pinsize/2), -smtlead[1], 0]) cube(smtlead);
212 | color(pcolor) translate ([r-(pinsize/2), size_y-adj, 0]) cube(smtlead);
213 | }
214 | }
215 | }
216 | else {
217 | for(r=[pitch/2:pitch:size_x]) {
218 | for(c=[pitch/2:pitch:size_y]) {
219 | color(pcolor) translate ([-smtlead[1]+adj, c-(pinsize/2), 0]) cube([smtlead[1], smtlead[0], smtlead[2]]);
220 | color(pcolor) translate ([size_x-adj, c-(pinsize/2), 0]) cube([smtlead[1], smtlead[0], smtlead[2]]);
221 | }
222 | }
223 | }
224 | }
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/lib/heatsinks/Odroid-N2_Heatsink.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hominoids/SBC_Model_Framework/0128dd7014f54863a99b1c547d2d0e290dff64c4/lib/heatsinks/Odroid-N2_Heatsink.stl
--------------------------------------------------------------------------------
/lib/ic.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: ic
20 | DESCRIPTION: creates intergrated circuits
21 | TODO:
22 |
23 | USAGE: ic(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "generic"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = size_x
32 | size[1] = size_y
33 | size[2] = size_z
34 | data[0] = icolor
35 | pcbsize_z = pcb thickness
36 | enablemask = true produces mask, false produces model
37 | mask[0] = true, false
38 | mask[1] = length
39 | mask[2] = set back
40 | mask[3] = mstyle "default"
41 |
42 | */
43 |
44 | // ic class
45 | module ic(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
46 |
47 | size_x = size[0];
48 | size_y = size[1];
49 | size_z = size[2];
50 | icolor = data[0];
51 |
52 | // generic ic
53 | if (type == "generic" && enablemask == false) {
54 |
55 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
56 | color(icolor) cube([size_x, size_y, size_z]);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/jst.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 | CLASS NAME: jst
19 | DESCRIPTION: creates jst connectors for xh, ph, zh, sh, pa.
20 | TODO: flange for sh
21 |
22 | USAGE: jst(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
23 |
24 | type = "xh","ph","zh","sh","pa"
25 | loc_x = x location placement
26 | loc_y = y location placement
27 | loc_z = z location placement
28 | side = "top", "bottom"
29 | rotation[] = object rotation
30 | size[0] = #pins
31 | data[0] = "thruhole", "smt"
32 | data[1] = "top", "side"
33 | data[2] = body color
34 | pcbsize_z = pcb thickness
35 | enablemask = true, false
36 | mask[0] = true, false
37 | mask[1] = length
38 | mask[2] = set back
39 | mask[3] = mstyle "default"
40 |
41 | */
42 |
43 | // JST connector class
44 | module jst(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
45 |
46 | row = size[0];
47 | style = data[0];
48 | entry = data[1];
49 | bcolor = data[2];
50 | pcolor = "silver";
51 | cmask = mask[0];
52 | mlen = mask[1];
53 | back = mask[2];
54 | mstyle = mask[3];
55 |
56 | /*
57 | p p
58 | i i
59 | n n
60 |
61 | b t
62 | w o o
63 | b a p p t p p
64 | o l i i i
65 | d s s l n n h h n
66 | p y i i e e
67 | t i z z s x y i i s
68 | y t a e e i a a g g i
69 | p c d z d d h h z
70 | e h j y z e j j t t e
71 | */
72 | jst_data = [
73 | ["xh", 2.5, 2.45, 5.75, 7, .5, 2.35, 2.4, 3.4, 7, .64],
74 | ["ph", 2, 1.95, 4.5, 6, .5, 1.95, 1.7, 3.4, 5, .5],
75 | ["zh", 1.5, 1.5, 3.5, 4.5, .35, 1.5, 1.3, 3.4, 3.5, .5],
76 | ["sh", 1, 1, 2.9, 4.25, .35, 1, 1.25, 3.4, 4, .25],
77 | ["pa", 2, 2, 4, 8, .35, 2, 2, 3.4, 4.5, .5]
78 | ];
79 |
80 | adj = .01;
81 | $fn = 90;
82 |
83 | s = search([type],jst_data);
84 |
85 | pitch = jst_data[s[0]][1];
86 | body_adj = jst_data[s[0]][2];
87 | size_x = body_adj+(row*pitch);
88 | size_y = jst_data[s[0]][3];
89 | size_z = jst_data[s[0]][4];
90 | wall_size = jst_data[s[0]][5];
91 | pin_xadj = jst_data[s[0]][6];
92 | pin_yadj = jst_data[s[0]][7];
93 | pbheight = jst_data[s[0]][8];
94 | ptheight = jst_data[s[0]][9];
95 | pinsize = jst_data[s[0]][10];
96 | smtlead = [pinsize,.925,.32];
97 |
98 | if(entry == "top" && enablemask == false) {
99 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
100 | union() {
101 | difference() {
102 | union() {
103 | color(bcolor) cube([size_x, size_y, size_z]);
104 | if(type == "pa") {
105 | color(bcolor) translate([0, -.75+adj, 1.5]) cube([1.5, .75, size_z-3.01]);
106 | color(bcolor) translate([size_x-1.5, -.75+adj, 1.5]) cube([1.5, .75, size_z-3.01]);
107 | if(row >= 6) {
108 | color(bcolor) translate([2.5, -.75+adj, 1.5]) cube([1.5, .75, size_z-3.01]);
109 | color(bcolor) translate([size_x-4, -.75+adj, 1.5]) cube([1.5, .75, size_z-3.01]);
110 | }
111 | }
112 | }
113 | color(bcolor) translate([wall_size, wall_size, wall_size])
114 | cube([size_x-(2*wall_size), size_y-(2*wall_size), size_z]);
115 | if(type == "xh") {
116 | color(bcolor) translate([2, -.1, size_z/2]) cube([1.5, size_y-2, 4]);
117 | color(bcolor) translate([size_x-3.5, -.1, size_z/2]) cube([1.5, size_y-2, 4]);
118 | color(bcolor) translate([-1, .75, 5]) cube([2, .75, 3]);
119 | color(bcolor) translate([size_x-2, .75, 5]) cube([size_y-2, .25*size[0], 3]);
120 | }
121 | if(type == "ph") {
122 | color(bcolor) translate([2, -.1, 2]) cube([size_x-(2*pitch), size_y-2, 5]);
123 | color(bcolor) translate([-1, 1.25, 4]) cube([size_y-2, .25*size[0], size_z]);
124 | color(bcolor) translate([size_x-2, 1.25, 4]) cube([size_y-2, .25*size[0], size_z]);
125 | }
126 | if(type == "zh") {
127 | color(bcolor) translate([-1, 1.25, size_z/2]) cube([size_y-2, .25*size[0], size_z]);
128 | color(bcolor) translate([size_x-1, 1.25, size_z/2]) cube([size_y-2, 0.25*size[0], size_z]);
129 | }
130 | if(type == "sh") {
131 | color(bcolor) translate([.25, .75, size_z/2]) cube([.25, .25, size_z]);
132 | color(bcolor) translate([size_x-.5, .75, size_z/2]) cube([.25, .25, size_z]);
133 | }
134 | if(type == "pa") {
135 | color(bcolor) translate([-1., -2.5, 6]) cube([size_x+2, 5, 4]);
136 | color(bcolor) translate([1.5 ,2, size_z-1]) cube([size_x-3, 4, 4]);
137 | color(bcolor) translate([wall_size, -.75+adj+wall_size, 1.5])
138 | cube([1.5-(2*wall_size), 1, size_z-3.01]);
139 | color(bcolor) translate([size_x-1.5+wall_size, -.75+adj+wall_size, 1.5])
140 | cube([1.5-(2*wall_size), 1, size_z-3.01]);
141 | if(row >= 6) {
142 | color(bcolor) translate([2.875, -.5+adj, 1.75]) cube([1.5-(2*wall_size), 1, size_z-3.01]);
143 | color(bcolor) translate([size_x-3.675, -.5+adj, 1.75]) cube([1.5-(2*wall_size), 1, size_z-3.01]);
144 | }
145 | }
146 | }
147 | if(type == "sh") {
148 | color(bcolor) translate([.25, size_y-.75, 0]) cube([.5, .5, size_z]);
149 | color(bcolor) translate([size_x-.75, size_y-.75, 0]) cube([.5, .5, size_z]);
150 | }
151 | if(style == "thruhole") {
152 | for(r=[pin_xadj-(pinsize/2):pitch:size_x-pitch]) {
153 | color("silver") translate([r, pin_yadj-(pinsize/2), -pbheight+adj])
154 | cube([pinsize, pinsize, pbheight+ptheight]);
155 | }
156 | }
157 | if(style == "smt") {
158 | for(r=[pin_xadj-(pinsize/2):pitch:size_x-pitch]) {
159 | color("silver") translate([r, pin_yadj-(pinsize/2), adj])
160 | cube([pinsize, pinsize, ptheight]);
161 | color("silver") translate([r, size_y-adj, 0])
162 | cube(smtlead);
163 | }
164 | }
165 | }
166 | }
167 | if(entry == "side" && enablemask == false) {
168 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
169 | union() {
170 | difference() {
171 | color(bcolor) cube([size_x, size_z, size_y]);
172 | color(bcolor) translate([wall_size, -wall_size, wall_size])
173 | cube([size_x-(2*wall_size), size_z, size_y-(2*wall_size)]);
174 | if(type == "xh") {
175 | color(bcolor) translate([2, -.1, size_z/2]) cube([1.5, 4, size_y-2]);
176 | color(bcolor) translate([size_x-3.5, -.1, size_z/2]) cube([1.5, 4, size_y-2]);
177 | color(bcolor) translate([-1, -.75, 4]) cube([2, 3, .75]);
178 | color(bcolor) translate([size_x-1, -.75, 4]) cube([2, 3, .25*size[0]]);
179 | }
180 | if(type == "ph") {
181 | color(bcolor) translate([2, -.1, 3]) cube([size_x-(2*pitch), 5, 2]);
182 | color(bcolor) translate([-1, -4, size_y-2]) cube([size_y-2, size_z, 1]);
183 | color(bcolor) translate([size_x-2, -4, size_y-2]) cube([size_y-2, size_z, 1]);
184 | }
185 | if(type == "zh") {
186 | color(bcolor) translate([-1, -size_z+1.25, size_y-1.25]) cube([size_y-2, size_z, .25*size[0]]);
187 | color(bcolor) translate([size_x-1, -size_z+1.25, size_y-1.25]) cube([size_y-2, size_z, 0.25*size[0]]);
188 | }
189 | if(type == "sh") {
190 | color(bcolor) translate([.25, 0, size_z/2]) cube([.25, size_z, .25]);
191 | color(bcolor) translate([size_x-.5, 0, size_z/2]) cube([.25, size_z, .25]);
192 | }
193 | }
194 | if(type == "xh") {
195 | difference() {
196 | union() {
197 | color(bcolor) translate([0, size_z, 0]) cube([1, 3.5, 4.5]);
198 | color(bcolor) translate([size_x-1, size_z, 0]) cube([1, 3.5, 4.5]);
199 | }
200 | color(bcolor) translate([-1, size_z, 4.5]) rotate([-30, 0, 0]) cube([size_x+2, 5.5, 4]);
201 | }
202 | }
203 | if(type == "ph") {
204 | difference() {
205 | union() {
206 | color(bcolor) translate([0, size_z, 0]) cube([.75, 1.6, 3]);
207 | color(bcolor) translate([size_x-.75, size_z, 0]) cube([.75, 1.6, 3]);
208 | }
209 | color(bcolor) translate([-1, size_z, 3]) rotate([-30, 0,0 ]) cube([size_x+2, 5.5, 4]);
210 | }
211 | }
212 | if(type == "zh") {
213 | difference() {
214 | union() {
215 | color(bcolor) translate([0, size_z, 0]) cube([.5, 1.5, 2.5]);
216 | color(bcolor) translate([size_x-.5, size_z, 0]) cube([.5, 1.5, 2.5]);
217 | }
218 | color(bcolor) translate([-1, size_z, 2.5]) rotate([-30, 0, 0]) cube([size_x+2, 5.5, 4]);
219 | }
220 | }
221 | if(type == "sh") {
222 | color(bcolor) translate([wall_size, 0, wall_size]) cube([.5, size_z, .5]);
223 | color(bcolor) translate([size_x-.75, 0, wall_size]) cube([.5, size_z, .5]);
224 | }
225 | if(style == "thruhole") {
226 | for(r=[pin_xadj-(pinsize/2):pitch:size_x-pitch]) {
227 | color("silver") translate([r, -adj, size_y-(pin_yadj+(pinsize/2))])
228 | cube([pinsize, ptheight, pinsize]);
229 | color("silver") translate([r, size_z-pinsize, -pbheight+adj]) cube([pinsize, pinsize, pbheight]);
230 | }
231 | }
232 | if(style == "smt") {
233 | for(r=[pin_xadj-(pinsize/2):pitch:size_x-pitch]) {
234 | color("silver") translate([r, -adj, size_y-(pin_yadj+(pinsize/2))])
235 | cube([pinsize, ptheight, pinsize]);
236 | color("silver") translate([r, size_z-adj, 0])
237 | cube(smtlead);
238 | }
239 | }
240 | }
241 | }
242 | if(entry == "side" && enablemask == true && cmask == true && mstyle == "default") {
243 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
244 | translate([0-.5,-mlen+back,0]) cube([size_x+1, mlen, size_y+.5]);
245 | }
246 | }
--------------------------------------------------------------------------------
/lib/memory.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: memory
20 | DESCRIPTION: creates memory components
21 | TODO:
22 |
23 | USAGE: memory(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "emmc", "emmc_plug", "emmc_plug_double", "sodimm_5.2", "sodimm_9.2"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | enablemask = true produces mask, false produces model
32 | mask[0] = true enables component mask
33 | mask[1] = mask length
34 | mask[2] = mask setback
35 | mask[3] = mstyle "default"
36 |
37 | */
38 |
39 | // memory class
40 | module memory(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
41 |
42 | cmask = mask[0];
43 | mlen = mask[1];
44 | back = mask[2];
45 | mstyle = mask[3];
46 |
47 | // socketed emmc
48 | if(type == "emmc") {
49 |
50 | size_x = 13.5;
51 | size_y = 18.5;
52 | size_xm = 14.5;
53 | size_ym = 19.5;
54 | size_zm = mlen;
55 |
56 | if(enablemask == true && cmask == true && mstyle == "default") {
57 | if(side == "top" && rotation == 0) {
58 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
59 | cube([size_xm, size_ym, size_zm]);
60 | }
61 | if(side == "top" && rotation == 90) {
62 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
63 | cube([size_xm, size_ym, size_zm]);
64 | }
65 | if(side == "top" && rotation == 180) {
66 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
67 | cube([size_xm, size_ym, size_zm]);
68 | }
69 | if(side == "top" && rotation == 270) {
70 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
71 | cube([size_xm, size_ym, size_zm]);
72 | }
73 | if(side == "bottom" && rotation == 0) {
74 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
75 | cube([size_xm, size_ym, size_zm]);
76 | }
77 | if(side == "bottom" && rotation == 90) {
78 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
79 | cube([size_xm, size_ym, size_zm]);
80 | }
81 | if(side == "bottom" && rotation == 180) {
82 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
83 | cube([size_xm, size_ym, size_zm]);
84 | }
85 | if(side == "bottom" && rotation == 270) {
86 | place(loc_x-(size_xm-size_x)/2, loc_y-(size_ym-size_y)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
87 | cube([size_xm, size_ym, size_zm]);
88 | }
89 | }
90 | if(enablemask == false) {
91 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
92 | union (){
93 | color("darkred") translate([0, 0, 1.1]) cube([size_x, size_y, .8]);
94 | color("dimgray") translate([1, 2, 1.9]) cube([11.5, 13, .9]);
95 | difference() {
96 | color("dimgray") translate([2, 13.5, 0]) cube([9.3, 3.4, 1.1]);
97 | color("dimgray") translate([2.5, 14.5, -.1]) cube([8.3, .5, 1.1]);
98 | color("dimgray") translate([2.5, 15.9, -.1]) cube([8.3, .5, 1.1]);
99 | color("dimgray") translate([2.5, 14.5, -.1]) cube([.5, 1.8, 1.1]);
100 | color("dimgray") translate([10.3, 14.5, -.1]) cube([.5, 1.8, 1.1]);
101 | }
102 | }
103 | }
104 | }
105 |
106 | // emmc plug
107 | if(type == "emmc_plug" || type == "emmc_plug_double") {
108 |
109 | size_x = 8.3;
110 | size_y = 2.16;
111 | size_xm = 14.5;
112 | size_ym = 19.5;
113 | size_zm = mlen;
114 | offsetm = 2.5;
115 |
116 | if(enablemask == true && cmask == true && mstyle == "default") {
117 | if(side == "top" && rotation == 0) {
118 | place(loc_x-(size_xm-size_x)/2, loc_y-offsetm-12.34, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
119 | cube([size_xm, size_ym, size_zm]);
120 | }
121 | if(side == "top" && rotation == 90) {
122 | place(loc_x-offsetm-12.34, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
123 | cube([size_xm, size_ym, size_zm]);
124 | }
125 | if(side == "top" && rotation == 180) {
126 | place(loc_x-(size_xm-size_x)/2, loc_y-offsetm, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
127 | cube([size_xm, size_ym, size_zm]);
128 | }
129 | if(side == "top" && rotation == 270) {
130 | place(loc_x-offsetm, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
131 | cube([size_xm, size_ym, size_zm]);
132 | }
133 | if(side == "bottom" && rotation == 0) {
134 | place(loc_x-(size_xm-size_x)/2, loc_y-offsetm-12.34, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
135 | cube([size_xm, size_ym, size_zm]);
136 | }
137 | if(side == "bottom" && rotation == 90) {
138 | place(loc_x-offsetm, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
139 | cube([size_xm, size_ym, size_zm]);
140 | }
141 | if(side == "bottom" && rotation == 180) {
142 | place(loc_x-(size_xm-size_x)/2, loc_y-offsetm, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
143 | cube([size_xm, size_ym, size_zm]);
144 | }
145 | if(side == "bottom" && rotation == 270) {
146 | place(loc_x-offsetm, loc_y-(size_xm-size_x)/2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
147 | cube([size_xm, size_ym, size_zm]);
148 | }
149 | }
150 | if(enablemask == false) {
151 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
152 | union (){
153 | difference() {
154 | color("black") cube([size_x, size_y, .82]);
155 | color("black") translate([1, .25, .15]) cube([6.3, 1.65, 1]);
156 | color("black") translate([1, 0, .72]) cube([6.3, 2.5, 2]);
157 | }
158 | for (i=[1.25:.4:7.2]) {
159 | color("gold") translate ([i, -.05, 0]) cube([.16, .3, .82]);
160 | color("gold") translate ([i, 1.9, 0]) cube([.16, .3, .82]);
161 | }
162 | if(type == "emmc_plug_double") {
163 | union (){
164 | difference() {
165 | translate([0,-13,0]) color("black") cube([size_x, size_y, .82]);
166 | translate([0,-13,0]) color("black") translate([1, .25, .15]) cube([6.3, 1.65, 1]);
167 | translate([0,-13,0]) color("black") translate([1, 0, .72]) cube([6.3, 2.5, 2]);
168 | }
169 | for (i=[1.25:.4:7.2]) {
170 | translate([0,-13,0]) color("gold") translate ([i, -.05, 0]) cube([.16, .3, .82]);
171 | translate([0,-13,0]) color("gold") translate ([i, 1.9, 0]) cube([.16, .3, .82]);
172 | }
173 | }
174 | }
175 | }
176 | }
177 | }
178 |
179 | // sodimm-5.2 socket
180 | if(type == "sodimm_5.2" && enablemask == false) {
181 | size_x = 73;
182 | size_y = 6.5;
183 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
184 | union() {
185 | difference () {
186 |
187 | color("dimgray") cube([size_x, size_y, 5.2]);
188 | color("dimgray") translate([2, -1, 1.75]) cube([69, 3, 5]);
189 | color("dimgray") translate([3.5, -1, 1.75]) cube([28.5, 5.25, .92]);
190 | color("dimgray") translate([34.5, -1, 1.75]) cube([35, 5.25, .92]);
191 | }
192 | for (i=[2:.5:31]) {
193 | color("gold") translate ([i+.5, 2, 1.75]) cube([.25, 2, .25]);
194 | }
195 | for (i=[34:.5:69]) {
196 | color("gold") translate ([i+.5, 2, 1.75]) cube([.25, 2, .25]);
197 | }
198 | }
199 | }
200 |
201 | // sodimm-9.2 socket
202 | if(type == "sodimm_9.2" && enablemask == false) {
203 | size_x = 73;
204 | size_y = 6.5;
205 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
206 | union() {
207 | difference () {
208 |
209 | color("dimgray") cube([size_x, size_y, 9.2]);
210 | color("dimgray") translate([2, -1, 5.7]) cube([69, 3, 5]);
211 | color("dimgray") translate([3.5, -1, 5.7]) cube([28.5, 5.25, .92]);
212 | color("dimgray") translate([34.5, -1, 5.7]) cube([35, 5.25, .92]);
213 | }
214 | for (i=[2:.5:31]) {
215 | color("gold") translate ([i+.5, 2, 5.7]) cube([.25, 2, .25]);
216 | }
217 | for (i=[34:.5:69]) {
218 | color("gold") translate ([i+.5, 2, 5.7]) cube([.25, 2, .25]);
219 | }
220 | }
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/lib/molex.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: molex
20 | DESCRIPTION: creates molex series connectors.
21 | TODO: "5267", "5268"
22 |
23 | USAGE: molex(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "7478","5046"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = #pins
32 | data[0] = "thruhole", "smt"
33 | data[1] = "top", "side"
34 | pcbsize_z = pcb thickness
35 | enablemask = true produces mask, false produces model
36 | mask[0] = true enables component mask
37 | mask[1] = mask length
38 | mask[2] = mask setback
39 | mask[3] = mstyle "default"
40 |
41 | */
42 |
43 | // molex connector class
44 | module molex(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
45 |
46 | row = size[0];
47 | style = data[0];
48 | entry = data[1];
49 | bcolor = "white";
50 | pcolor = "silver";
51 | cmask = mask[0];
52 | mlen = mask[1];
53 | back = mask[2];
54 | mstyle = mask[3];
55 |
56 | /*
57 | p p
58 | i i
59 | n n
60 |
61 | b t p p
62 | w o o i i
63 | b a p p t p p n n
64 | o l i i i
65 | d s s l n n h h n o r
66 | p y i i e e f a
67 | t i z z s x y i i s f d
68 | y t a e e i a a g g i s i
69 | p c d z d d h h z e u
70 | e h j y z e j j t t e t s
71 | */
72 | molex_data = [
73 | ["7478", 2.54, 0, 6.5, 3.18, 0, 0, 3.25, 3.4, 9.25, .64, 3, 1.17, 0],
74 | ["5046", 2.54, 0, 6.5, 3.18, 0, 0, 0.64, 6.25, 5.75, .64, 2, 1.17, 2.62]
75 | ];
76 |
77 | adj = .01;
78 | $fn = 90;
79 |
80 | s = search([type],molex_data);
81 |
82 | pitch = molex_data[s[0]][1];
83 | body_adj = molex_data[s[0]][2];
84 | size_x = body_adj+(row*pitch);
85 | size_y = molex_data[s[0]][3];
86 | size_z = molex_data[s[0]][4];
87 | wall_size = molex_data[s[0]][5];
88 | pin_xadj = molex_data[s[0]][6];
89 | pin_yadj = molex_data[s[0]][7];
90 | pbheight = molex_data[s[0]][8];
91 | ptheight = molex_data[s[0]][9];
92 | pinsize = molex_data[s[0]][10];
93 | pinoffset = molex_data[s[0]][11];
94 | pinradius = molex_data[s[0]][12];
95 | pinbhadj = molex_data[s[0]][13];
96 | smtlead = [pinsize,.925,.32];
97 |
98 |
99 | if(entry == "top" && enablemask == false) {
100 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
101 | union() {
102 | difference() {
103 | union() {
104 | color(bcolor) cube([size_x, size_y, size_z]);
105 | if(type == "7478") {
106 | color(bcolor) translate([pitch/4, size_y-1, 0]) cube([size_x-pitch/2, 1, size_z+5.5]);
107 | color(bcolor) translate([pitch/4, size_y-1, size_z+4.5]) rotate([0, 90, 0])
108 | cylinder(d=2, h=size_x-pitch/2);
109 | }
110 | }
111 | if(type == "7478") {
112 | for(r=[pitch/2-(pinsize/2)-.5:pitch:size_x]) {
113 | color(bcolor) translate([r, -1, -1]) cube([1.5, size_y+2, 1.5]);
114 | }
115 | }
116 | }
117 | if(style == "thruhole") {
118 | for(r=[pitch/2-(pinsize/2):pitch:size_x]) {
119 | color("silver") translate([r, pin_yadj-(pinsize/2), -pbheight+adj])
120 | cube([pinsize, pinsize, pbheight+ptheight]);
121 | }
122 | }
123 | if(style == "smt") {
124 | for(r=[pitch/2-(pinsize/2):pitch:size_x-pitch]) {
125 | color("silver") translate([r, pin_yadj-(pinsize/2), adj])
126 | cube([pinsize, pinsize, ptheight]);
127 | color("silver") translate([r, size_y-adj, 0])
128 | cube(smtlead);
129 | }
130 | }
131 | }
132 | }
133 | if(entry == "side" && enablemask == true && cmask == true && mstyle == "default") {
134 |
135 | size_xm = size_x;
136 | size_ym = size_y+.5;
137 | size_zm = 5;
138 |
139 | if(side == "top" && rotation == 0) {
140 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
141 | translate([0, back, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen], .5);
142 | }
143 | if(side == "top" && rotation == 90) {
144 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
145 | translate([0, back, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen], .5);
146 | }
147 | if(side == "top" && rotation == 180) {
148 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
149 | translate([0, back+.5, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen], .5);
150 | }
151 | if(side == "top" && rotation == 270) {
152 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
153 | translate([0, back+.5, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen], .5);
154 | }
155 | if(side == "bottom" && rotation == 0) {
156 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
157 | translate([0, back, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen],.5);
158 | }
159 | if(side == "bottom" && rotation == 90) {
160 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
161 | translate([0, back+.5, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen],.5);
162 | }
163 | if(side == "bottom" && rotation == 180) {
164 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
165 | translate([0, back+.5, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen], .5);
166 | }
167 | if(side == "bottom" && rotation == 270) {
168 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
169 | translate([0, back, 0]) rotate([90, 0, 0]) slab([size_x, size_ym, mlen], .5);
170 | }
171 | }
172 | if(entry == "side" && enablemask == false) {
173 |
174 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
175 | union() {
176 | difference() {
177 | union() {
178 | color(bcolor) cube([size_x, size_z, size_y]);
179 | if(type == "7478") {
180 | color(bcolor) translate([pitch/4,-size_z-5.5,size_y-1]) cube([size_x-pitch/2, size_z+5.5, 1]);
181 | color(bcolor) translate([pitch/4, -size_z-4.5, size_y-1]) rotate([0, 90, 0])
182 | cylinder(d=2, h=size_x-pitch/2);
183 | }
184 | if(type == "5046") {
185 | color(bcolor) translate([pitch/4,-size_z-5.5,size_y-3.5]) cube([size_x-pitch/2, size_z+5.5, 1]);
186 | color(bcolor) translate([pitch/4, -size_z-1.5, size_y-2.5]) rotate([0, 90, 0])
187 | cylinder(d=2, h=size_x-pitch/2);
188 | color(bcolor) translate([0,size_z,0]) cube([.75,3,3]);
189 | color(bcolor) translate([size_x-.75,size_z,0]) cube([.75,3,3]);
190 | }
191 | }
192 | if(type == "7478" || type == "5046") {
193 | for(r=[pitch/2-(pinsize/2)-.5:pitch:size_x]) {
194 | color(bcolor) translate([r, -1,-1]) cube([1.5, size_y+2, 1.5]);
195 | }
196 | }
197 | }
198 | if(style == "thruhole") {
199 | for(r=[pitch/2-(pinsize/2):pitch:size_x]) {
200 | if(type == "7478") {
201 | color("silver") translate([r, -ptheight+adj, size_y-(pin_yadj+(pinsize/2))])
202 | cube([pinsize, ptheight+size_z+pinsize+pinsize/2, pinsize]);
203 | color("silver") translate([r, size_z+pinoffset-pinsize/2, -pbheight+adj+pinbhadj])
204 | cube([pinsize, pinsize, pbheight+pinsize+pinsize/2]);
205 | rotate([0,270,0]) translate([pinsize+(pinsize/2)+pinbhadj-(3*adj), size_z+pinsize+.04, r-size_x]) color("silver")
206 | rotate_extrude(angle=90, convexity = 10) translate([2, 0, 0]) square([pinsize, pinsize]);
207 | }
208 | if(type == "5046") {
209 | color("silver") translate([r, -ptheight+adj-3, size_y-(pin_yadj+(pinsize/2))])
210 | cube([pinsize, ptheight+size_z+pinsize+pinsize/2, pinsize]);
211 | color("silver") translate([r, size_z+pinoffset-pinsize/2, -pbheight+adj+pinbhadj])
212 | cube([pinsize, pinsize, pbheight+pinsize+pinsize/2]);
213 | rotate([0,270,0]) translate([pinsize+(pinsize/2)+pinbhadj-(3*adj), size_z+pinsize+.04-1, r-size_x]) color("silver")
214 | rotate_extrude(angle=90, convexity = 10) translate([2, 0, 0]) square([pinsize, pinsize]);
215 | }
216 | }
217 | }
218 | if(style == "smt") {
219 | for(r=[pitch/2-(pinsize/2):pitch:size_x-pitch]) {
220 | color("silver") translate([r, -adj, size_y-(pin_yadj+(pinsize/2))])
221 | cube([pinsize, ptheight, pinsize]);
222 | color("silver") translate([r, size_z-adj, 0])
223 | cube(smtlead);
224 | }
225 | }
226 | }
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/lib/pcb.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: pcbhole
20 | DESCRIPTION: creates pcb hole
21 | TODO: cu edge shapes
22 |
23 | USAGE: pcbhole(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "round"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = hole diameter
32 | data[0] = style
33 | data[1] = hole color
34 | data[2] = sidewall support("none","left","right","rear","front")
35 | data[3] = trace diameter
36 | data[4] = position "left_rear","left_front","right_rear","right_front","middle_rear","middle_front",
37 | "heatsink_left","heatsink_right","heatsink_rear","heatsink_front","pcie_1","gpio_1","misc_1"
38 | pcbsize_z = pcb thickness
39 | enablemask = true produces mask, false produces model
40 | mask[0] = true enables component mask
41 | mask[1] = mask length
42 | mask[2] = mask setback
43 | mask[3] = mstyle "default"
44 |
45 |
46 | CLASS NAME: pcbsoc
47 | DESCRIPTION: creates soc components
48 | TODO: add other styles
49 |
50 | USAGE: pcbsoc(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
51 |
52 | type = "flat", "raised", "mid-raised", "rk3399", "rk3588"
53 | loc_x = x location placement
54 | loc_y = y location placement
55 | loc_z = z location placement
56 | side = "top", "bottom"
57 | rotation[] = object rotation
58 | size[0] = size_x
59 | size[1] = size_y
60 | size[2] = size_z
61 | pcbsize_z = pcb thickness
62 | enablemask = true produces mask, false produces model
63 | mask[0] = true enables component mask
64 | mask[1] = mask length
65 | mask[2] = mask setback
66 | mask[3] = mstyle "default"
67 |
68 |
69 | CLASS NAME: pcbpad
70 | DESCRIPTION: creates pcb pads
71 | TODO:
72 |
73 | USAGE: pcbpad(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
74 |
75 | type = "round", "square", "sqround", "castellation"
76 | loc_x = x location placement
77 | loc_y = y location placement
78 | loc_z = z location placement
79 | side = "top", "bottom"
80 | rotation[] = object rotation
81 | size[0] = #pad x
82 | size[1] = #pad y
83 | data[0] = hole size
84 | data[1] = pad color
85 | data[2] = pad size
86 | data[5] = pad_trim ("front", "rear")
87 | pcbsize_z = pcb thickness
88 | enablemask = true produces mask, false produces model
89 | mask[0] = true enables component mask
90 | mask[1] = mask length
91 | mask[2] = mask setback
92 | mask[3] = mstyle "default"
93 |
94 |
95 | CLASS NAME: pcb
96 | DESCRIPTION: creates pcb and features
97 | TODO:
98 |
99 | USAGE: pcb(size[], radius)
100 |
101 | size[0] = size_x
102 | size[1] = size_y
103 | size[2] = size_z
104 | radius = corner radius
105 |
106 | */
107 |
108 | // pcb board
109 | module pcb(size, radius) {
110 | x = size[0];
111 | y = size[1];
112 | z = size[2];
113 | linear_extrude(height = z)
114 | hull() {
115 | translate([0+radius ,0+radius, 0]) circle(r = radius);
116 | translate([0+radius, y-radius, 0]) circle(r = radius);
117 | translate([x-radius, y-radius, 0]) circle(r = radius);
118 | translate([x-radius, 0+radius, 0]) circle(r = radius);
119 | }
120 | }
121 |
122 |
123 | // pcb hole additions
124 | module pcbhole(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
125 |
126 | // pcbhole class
127 | if(type == "round" && enablemask == false) {
128 |
129 | size_x = size[0];
130 | size_y = size[0];
131 | style = data[0];
132 | hcolor = data[1];
133 | support = data[2];
134 | pad_size = data[3];
135 | hole_position = data[4];
136 |
137 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
138 | difference() {
139 | color(hcolor) translate([0, 0, -.0635-pcbsize_z]) cylinder(d=pad_size, pcbsize_z+.127);
140 | color(hcolor) translate([0, 0, -1.127-pcbsize_z]) cylinder(d=size_x-.127, pcbsize_z+2);
141 | }
142 | }
143 | }
144 |
145 |
146 | // pcb soc class
147 | module pcbsoc(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
148 |
149 | size_x = size[0];
150 | size_y = size[1];
151 | size_z = size[2];
152 |
153 | if(type == "flat" && enablemask == false) {
154 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
155 | color("dimgray") cube([size_x, size_y, size_z]);
156 | }
157 | if(type == "rk3399") {
158 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
159 | union() {
160 | color("silver") cube([size_x, size_y, size_z]);
161 | translate([2, 2, size_z-.01]) color("silver") slab([size_x-4, size_y-4, .6],2);
162 | }
163 | }
164 | if(type == "raised" && enablemask == false) {
165 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
166 | union() {
167 | color("silver") cube([size_x, size_y, size_z]);
168 | translate([2, 2, size_z-.01]) color("silver") slab([size_x-4, size_y-4, .6],.5);
169 | }
170 | }
171 | if(type == "rk3588" && enablemask == false) {
172 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
173 | union() {
174 | color("silver") cube([size_x, size_y, size_z]);
175 | translate([2, 2, size_z-.01]) color("silver") slab([size_x-4, size_y-4, .6],.5);
176 | }
177 | }
178 | if(type == "mid-raised" && enablemask == false) {
179 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
180 | union() {
181 | color("silver") cube([size_x, size_y, size_z]);
182 | color("silver") translate([data[0], data[1], size_z-.01]) rotate([90,0,90]) slot(data[5], data[3], data[4]);
183 | }
184 | }
185 | }
186 |
187 |
188 | // pcb pad matrix
189 | module pcbpad(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
190 |
191 | size_x = 2.54 * (size[0]-1);
192 | size_y = 2.54 * (size[1]-1);;
193 |
194 | hole_size = data[0];
195 | hcolor = data[1];
196 | pad_size = data[2];
197 | pad_trim = data[3];
198 |
199 | adj = .01;
200 | $fn = 90;
201 |
202 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
203 | union() {
204 | for (c=[0:2.54:size_y]) {
205 | for (r=[0:2.54:size_x]) {
206 | if(type == "round") {
207 | difference() {
208 | color(hcolor) translate ([r, c, -.0635-pcbsize_z]) cylinder(d=pad_size, h=pcbsize_z+.127);
209 | color(hcolor) translate([r, c, -1.127-pcbsize_z]) cylinder(d=hole_size, h=pcbsize_z+2);
210 | }
211 | }
212 | if(type == "sqround") {
213 | if(c != 0) {
214 | difference() {
215 | color(hcolor) translate ([r, c, -.0635-pcbsize_z]) cylinder(d=pad_size, h=pcbsize_z+.127);
216 | color(hcolor) translate([r, c, -1.127-pcbsize_z]) cylinder(d=hole_size, h=pcbsize_z+2);
217 | }
218 | }
219 | else {
220 | difference() {
221 | color(hcolor) translate ([r-pad_size/2, c-pad_size/2, -.0635-pcbsize_z]) cube([pad_size, pad_size, pcbsize_z+.127]);
222 | color(hcolor) translate([r, c, -1.127-pcbsize_z]) cylinder(d=hole_size, h=pcbsize_z+2);
223 | }
224 | }
225 | }
226 | if(type == "square") {
227 | difference() {
228 | color(hcolor) translate ([r-pad_size/2, c-pad_size/2, -.0635-pcbsize_z]) cube([pad_size, pad_size, pcbsize_z+.127]);
229 | color(hcolor) translate([r, c, -1.127-pcbsize_z]) cylinder(d=hole_size, h=pcbsize_z+2);
230 | }
231 | }
232 | if(type == "castellation") {
233 | difference() {
234 | color(hcolor) translate ([r, c, -.0635-pcbsize_z]) cylinder(d=pad_size, h=pcbsize_z+.127);
235 | color(hcolor) translate([r, c, -1.127-pcbsize_z]) cylinder(d=hole_size, h=pcbsize_z+2);
236 | if(pad_trim == "rear") {
237 | color(hcolor) translate([r, c-1.5-adj, 0]) cube([3,3,5], center=true);
238 | }
239 | if(pad_trim == "front") {
240 | color(hcolor) translate([r, c+1.5+adj, 0]) cube([3,3,5], center=true);
241 | }
242 | }
243 | }
244 | }
245 | }
246 | }
247 | }
--------------------------------------------------------------------------------
/lib/pcie.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: pcie
20 | DESCRIPTION: creates pcie components
21 | TODO:
22 |
23 | USAGE: pcie(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "x1", "x4"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = true enables component mask
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 | */
39 |
40 | // pcie class
41 | module pcie(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
42 |
43 | // PCIE
44 | if ((type == "x1" || type == "x4") && enablemask == false) {
45 | size_x = type == "x1" ? 25 : 39;
46 | pin = type == "x1" ? 36/2 : 64/2;
47 | size_y = 8.5;
48 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
49 | union() {
50 | difference() {
51 | color("black") cube([size_x, size_y, 11.1]);
52 | color("dimgrey") translate([1.55, (size_y/2)-.8, 2]) cube([11.5, 1.6, 11]);
53 | color("dimgrey") translate([15.5, (size_y/2)-.8, 2]) cube([pin-10.5, 1.6, 11]);
54 | }
55 | for (i=[1:1:11.5]) {
56 | color("#fee5a6") translate ([i+1, 2.75, -3]) cube([.5, .7, 13.75]);
57 | color("#fee5a6") translate ([i+1, 4.75, -3]) cube([.5, .7, 13.75]);
58 | color("#fee5a6") translate ([i+1, 1.375, -3]) cube([.5, .7, 3.5]);
59 | color("#fee5a6") translate ([i+1, 6.125, -3]) cube([.5, .7, 3.5]);
60 | }
61 | for (i=[16:1:pin+4]) {
62 | color("#fee5a6") translate ([i, 2.75, -3]) cube([.5, .7, 13.75]);
63 | color("#fee5a6") translate ([i, 4.75, -3]) cube([.5, .7, 13.75]);
64 | color("#fee5a6") translate ([i, 1.375, -3]) cube([.5, .7, 3.5]);
65 | color("#fee5a6") translate ([i, 6.125, -3]) cube([.5, .7, 3.5]);
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/pillar.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: pillar
20 | DESCRIPTION: creates pillars
21 | TODO: add other genders and styles
22 |
23 | USAGE: pillar(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "hex", "round"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = outside dia
32 | size[1] = inside dia
33 | size[2] = height
34 | data[1] = body color
35 | pcbsize_z = pcb thickness
36 | enablemask = true produces mask, false produces model
37 | mask[0] = true enables component mask
38 | mask[1] = mask length
39 | mask[2] = mask setback
40 | mask[3] = mstyle "default"
41 |
42 | */
43 |
44 | // pillar class
45 | module pillar(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
46 |
47 | // type hex
48 | if(type=="hex" && enablemask == false) {
49 |
50 | size_x = size[0];
51 | size_y = size[1];
52 | size_z = size[2];
53 | pcolor = data[1];
54 |
55 | if(enablemask == false) {
56 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
57 | difference() {
58 | color(pcolor) rotate([rotation]) cylinder(d=size_x*2/sqrt(3), h=size_z, $fn=6);
59 | color(pcolor) translate([0, 0, -.1]) rotate([rotation]) cylinder(d=size_y, h=size_z+.2);
60 | }
61 | }
62 | }
63 | // type hex
64 | if(type=="round" && enablemask == false) {
65 |
66 | size_x = size[0];
67 | size_y = size[1];
68 | size_z = size[2];
69 | pcolor = data[1];
70 |
71 | if(enablemask == false) {
72 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
73 | difference() {
74 | color(pcolor) rotate([rotation]) cylinder(d=size_x, h=size_z, $fn=60);
75 | color(pcolor) translate([0, 0, -.1]) rotate([rotation]) cylinder(d=size_y, h=size_z+.2);
76 | }
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/lib/place.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | DESCRIPTION: places components on top or bottom and rotates in position
20 | TODO:
21 |
22 | USAGE: place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
23 |
24 | loc_x = x location placement
25 | loc_y = y location placement
26 | loc_z = z location placement
27 | size_x = object x dimension
28 | size_y = object y dimension
29 | rotation = object z-axis rotation
30 | side = "top", "bottom"
31 | pcbsize_z = pcb thickness
32 |
33 | */
34 |
35 | module place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z) {
36 |
37 | if (side == "top") {
38 | if ((rotation >= 0 && rotation < 90) || (rotation < -270 && rotation > -360))
39 | translate([loc_x, loc_y, pcbsize_z+loc_z]) rotate([0, 0, -rotation]) children();
40 |
41 | if ((rotation >= 90 && rotation < 180) || (rotation < -180 && rotation >= -270))
42 | translate([loc_x, loc_y+size_x, pcbsize_z+loc_z]) rotate([0, 0, -rotation]) children();
43 |
44 | if ((rotation >= 180 && rotation < 270) || (rotation < -90 && rotation >= -180))
45 | translate([loc_x+size_x, loc_y+size_y, pcbsize_z+loc_z]) rotate([0, 0, -rotation]) children(0);
46 |
47 | if ((rotation >= 270 && rotation < 360) || (rotation < 0 && rotation >= -90))
48 | translate([loc_x+size_y, loc_y, pcbsize_z+loc_z]) rotate([0, 0, -rotation]) children();
49 | }
50 | if (side == "bottom") {
51 | if ((rotation >= 0 && rotation < 90) || (rotation < -270 && rotation > -360))
52 | translate([loc_x+size_x, loc_y, -loc_z]) rotate([0, 180, rotation]) children();
53 |
54 | if ((rotation >= 90 && rotation < 180) || (rotation < -180 && rotation >= -270))
55 | translate([loc_x+size_y, loc_y+size_x, -loc_z]) rotate([0, 180, rotation]) children();
56 |
57 | if ((rotation >= 180 && rotation < 270) || (rotation < -90 && rotation >= -180))
58 | translate([loc_x, loc_y+size_y, -loc_z]) rotate([0, 180, rotation]) children();
59 |
60 | if ((rotation >= 270 && rotation < 360) || (rotation < 0 && rotation >= -90))
61 | translate([loc_x, loc_y, -loc_z]) rotate([0, 180, rotation]) children();
62 | }
63 | children([1:1:$children-1]);
64 | }
65 |
--------------------------------------------------------------------------------
/lib/shape.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | DESCRIPTION: creates geometric shapes
20 | TODO:
21 |
22 | USAGE: shape(type, size[], data[])
23 |
24 | type = "rectangle", "round", "slot", "polygon", "dxf"
25 | size[0] = size_x
26 | size[1] = size_y
27 | size[2] = size_z
28 | data[0] = body color
29 | data[2] = polygon data or dxf file
30 |
31 | USAGE: slab(size[], radius])
32 |
33 | size[0] = size_x
34 | size[1] = size_y
35 | size[2] = size_z
36 | radius = corner radius
37 |
38 | USAGE: slab_r(size[], radius[]])
39 |
40 | size[0] = size_x
41 | size[1] = size_y
42 | size[2] = size_z
43 | radius[0] = corner radius
44 | radius[1] = corner radius
45 | radius[2] = corner radius
46 | radius[3] = corner radius
47 |
48 | USAGE: slot(hole, length, depth)
49 |
50 | hole = radius diameter
51 | length = total length
52 | depth = thickness
53 |
54 | USAGE: long_slot(hole, length, depth)
55 |
56 | hole = radius diameter
57 | length = total length
58 | depth = thickness
59 |
60 | USAGE: knockout(width, depth, gap, thick, fillet, shape)
61 |
62 | width = length
63 | depth = width
64 | gap = space between
65 | thick = thickness
66 | fillet = corner fillet
67 | shape = "slot", "rectangle", "round"
68 |
69 | USAGE: vent(width, length, height, gap, rows, columns, orientation)
70 |
71 | width = coloumn size_x
72 | length = column size_y
73 | height = size_z
74 | gap = space between
75 | rows = #row
76 | columns = #columns
77 | orientation = "horizontal", "vertical"
78 |
79 | USAGE: vent_hex(cells_x, cells_y, thickness, cell_size, cell_spacing, orientation)
80 | cells_x = #rows
81 | cells_y = #columns
82 | thickness =
83 | cell_size = size of hex
84 | cell_spacing = space between hex
85 | orientation = "horizontal", "vertical"
86 |
87 | */
88 |
89 | /* shape module */
90 | module shape(type, size, data) {
91 |
92 | if(type == "rectangle") {
93 | cube([size[0], size[1], size[2]]);
94 | }
95 | if(type == "round") {
96 | cylinder(d=size[0], h=size[2]);
97 | }
98 | if(type == "slot") {
99 | slot(size[0], size[1], size[2]);
100 | }
101 | if(type == "polygon") {
102 | linear_extrude(height = size[2]) polygon(data[2]);
103 | }
104 | if(type == "dxf") {
105 | linear_extrude(height = size[2]) import(file = data[2], scale=data[3]);
106 | }
107 | }
108 |
109 | /* slab module */
110 | module slab(size, radius) {
111 |
112 | x = size[0];
113 | y = size[1];
114 | z = size[2];
115 | linear_extrude(height=z)
116 | hull() {
117 | translate([0+radius ,0+radius, 0]) circle(r=radius);
118 | translate([0+radius, y-radius, 0]) circle(r=radius);
119 | translate([x-radius, y-radius, 0]) circle(r=radius);
120 | translate([x-radius, 0+radius, 0]) circle(r=radius);
121 | }
122 | }
123 |
124 |
125 | /* multi-radius round slab */
126 | module slab_r(size, radius) {
127 |
128 | x = size[0];
129 | y = size[1];
130 | z = size[2];
131 | r0 = radius[0];
132 | r1 = radius[1];
133 | r2 = radius[2];
134 | r3 = radius[3];
135 |
136 | linear_extrude(height=z)
137 | hull() {
138 | translate([0+radius[0] ,0+radius[0], 0]) circle(r=radius[0]);
139 | translate([0+radius[1], y-radius[1], 0]) circle(r=radius[1]);
140 | translate([x-radius[2], y-radius[2], 0]) circle(r=radius[2]);
141 | translate([x-radius[3], 0+radius[3], 0]) circle(r=radius[3]);
142 | }
143 | }
144 |
145 |
146 | /*
147 | NAME: slot
148 | DESCRIPTION: create slot shape to length
149 | TODO: none
150 |
151 | USAGE: slot(hole, length, depth)
152 |
153 | hole = diameter of slot
154 | length = length of slot
155 | depth = thickness of slot
156 | */
157 |
158 | module slot(hole,length,depth) {
159 |
160 | hull() {
161 | translate([hole/2, 0, 0]) cylinder(d=hole, h=depth);
162 | translate([length-hole/2, 0, 0]) cylinder(d=hole, h=depth);
163 | }
164 | }
165 |
166 |
167 | /*
168 | NAME: long_slot
169 | DESCRIPTION: create slot shape with full movement of length
170 | TODO: none
171 |
172 | USAGE: long_slot(hole, length, depth)
173 |
174 | hole = diameter of slot
175 | length = length of slot
176 | depth = thickness of slot
177 | */
178 |
179 | module long_slot(hole, length, depth) {
180 |
181 | hull() {
182 | translate([0,0,0]) cylinder(d=hole,h=depth);
183 | translate([length,0,0]) cylinder(d=hole,h=depth);
184 | }
185 | }
186 |
187 |
188 | /* knockout opening */
189 | module knockout(width,depth,gap,thick,fillet,shape) {
190 |
191 | adj = .01;
192 | $fn=90;
193 |
194 | // slot knockout
195 | if(shape == "slot") {
196 | difference() {
197 | slot(depth, width, thick);
198 | translate([gap/2, 0, -adj]) slot(depth-gap, width-gap, thick+(2*adj));
199 | // cross ties
200 | translate([(depth/2), -(depth/2)-1, -adj]) cube([2, depth+2, thick+(2*adj)]);
201 | translate([(width/2)-1-(width/4)+4, -(depth/2)-1, -adj]) cube([2,depth+2, thick+(2*adj)]);
202 | translate([(width/2)-1+(width/4)-4, -(depth/2)-1, -adj]) cube([2, depth+2, thick+(2*adj)]);
203 | translate([width-(depth/2)-2, -(depth/2)-1, -adj]) cube([2, depth+2, thick+(2*adj)]);
204 | }
205 | }
206 | if(shape == "rectangle") {
207 | difference() {
208 | translate([(width/2), (depth/2), thick/2])
209 | cube_fillet_inside([width, depth, thick],
210 | vertical=[fillet, fillet, fillet, fillet],
211 | top=[0, 0, 0, 0], bottom=[0, 0, 0, 0], $fn=90);
212 | translate([(width/2), (depth/2), (thick/2)-adj])
213 | cube_fillet_inside([width-gap, depth-gap, thick+(3*adj)],
214 | vertical=[fillet, fillet, fillet, fillet],
215 | top=[0, 0, 0, 0], bottom=[0, 0, 0, 0], $fn=90);
216 | // cross ties
217 | translate([-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
218 | translate([width-4, depth-gap-1, -adj]) cube([2, gap+2, thick+(2*adj)]);
219 | translate([2, depth-gap-1, -adj]) cube([2, gap+2, thick+(2*adj)]);
220 | translate([width-gap-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
221 | translate([width-4, -1, -adj]) cube([2, gap+2, thick+(2*adj)]);
222 | translate([2, -1, -adj]) cube([2, gap+2, thick+(2*adj)]);
223 | }
224 | }
225 | if(shape == "round") {
226 | difference() {
227 | translate([(width/2),(width/2),0])
228 | cylinder(d=width, h=thick);
229 | translate([(width/2), (width/2), -adj])
230 | cylinder(d=width-gap, h=thick+2*adj);
231 | // cross ties
232 | translate([-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
233 | translate([(width/2)-1, depth-gap-1, -adj]) cube([2, gap+2, thick+(2*adj)]);
234 | translate([width-gap-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
235 | translate([(width/2)-1, -1, -adj]) cube([2, gap+2, thick+(2*adj)]);
236 | }
237 | }
238 | }
239 |
240 |
241 | /* vent opening */
242 | module vent(width,length,height,gap,rows,columns,orientation) {
243 |
244 | fillet = width/2;
245 | adj = .01;
246 | $fn=90;
247 |
248 | // vertical orientation
249 | if(orientation == "vertical") { rotate([90 ,0, 0])
250 | for (r=[0 : length+gap:rows*(length+gap)-1]) {
251 | for (c=[0 : width+(2*gap) : (columns*(width+(2*gap)))-1]) {
252 | translate ([c, r, -1]) cube([width, length, height]);
253 | }
254 | }
255 | }
256 | // horizontal orientation
257 | if(orientation == "horizontal") {
258 | for (r=[0 : length+(2*gap) : rows*(length+gap)]) {
259 | for (c=[0 : width+(2*gap) : (columns*(width+(2*gap)))-1]) {
260 | translate ([c,r,-1]) cube([width, length, height]);
261 | }
262 | }
263 | }
264 | }
265 |
266 |
267 | /* hex vent opening */
268 | module vent_hex(cells_x, cells_y, thickness, cell_size, cell_spacing, orientation) {
269 | xs = cell_size + cell_spacing;
270 | ys = xs * sqrt(3/4);
271 | rot = (orientation == "vertical") ? 90 : 0;
272 |
273 | rotate([rot, 0, 0]) translate([cell_size/2, cell_size*sqrt(1/3),-1]) {
274 | for (ix=[0 : ceil(cells_x/2)-1]) {
275 | for (iy = [0 : 2 : cells_y-1]) {
276 | translate([ix*xs, iy*ys, 0]) rotate([0, 0, 90])
277 | cylinder(r=cell_size/sqrt(3), h=thickness, $fn=6);
278 | }
279 | }
280 | for (ix=[0 : (cells_x/2)-1]) {
281 | for (iy = [1 : 2 : cells_y-1]) {
282 | translate([(ix+0.5)*xs, iy*ys, 0]) rotate([0, 0, 90])
283 | cylinder(r=cell_size/sqrt(3), h=thickness, $fn=6);
284 | }
285 | }
286 | }
287 | }
288 |
289 |
--------------------------------------------------------------------------------
/lib/smd.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: smd
20 | DESCRIPTION: creates smd components
21 | TODO: add other components
22 |
23 | USAGE: smd(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "led"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = size_x
32 | size[1] = size_y
33 | size[2] = size_z
34 | data[0] = body color
35 | pcbsize_z = pcb thickness
36 | enablemask = true produces mask, false produces model
37 | mask[0] = true enables component mask
38 | mask[1] = mask length
39 | mask[2] = mask setback
40 | mask[3] = mstyle "default"
41 |
42 | */
43 |
44 | // smd class
45 | module smd(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
46 |
47 | size_x = size[0];
48 | size_y = size[1];
49 | size_z = size[2];
50 | bcolor = data[0];
51 | adj = .01;
52 |
53 | // type led surface mount
54 | if(type=="led" && enablemask == false) {
55 |
56 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
57 | union() {
58 | color(bcolor) cube([size_x, size_y, size_z]);
59 | if(size_x >= size_y) {
60 | color("silver") translate([-adj, -adj, 0]) cube([size_x/6, size_y+(2*adj), size_z+adj]);
61 | color("silver") translate([size_x-(size_x/6)+adj, -adj, 0]) cube([size_x/6, size_y+(2*adj), size_z+adj]);
62 | }
63 | else {
64 | color("silver") translate([-adj, -adj, 0]) cube([size_x+(2*adj), (size_y/6), size_z+adj]);
65 | color("silver") translate([-adj, size_y-(size_y/6)+adj, 0]) cube([size_x+(2*adj), size_y/6, size_z+adj]);
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/switch.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: switch
20 | DESCRIPTION: creates switches
21 | TODO: add other styles
22 |
23 | USAGE: switch(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "slide_4x9", "slide_7x3.5x1"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = true enables component mask
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 | */
39 |
40 | // switch class
41 | module switch(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
42 |
43 | cmask = mask[0];
44 | mlen = mask[1];
45 | back = mask[2];
46 | mstyle = mask[3];
47 |
48 | if(type == "slide_4x9") {
49 |
50 | size_x = 9;
51 | size_y = 3.75;
52 | size_xm = 9;
53 | size_ym = 4;
54 |
55 | if(enablemask == true && cmask == true && mstyle == "default") {
56 | // switch opening
57 | if(side == "top" && rotation == 0) {
58 | place(loc_x, loc_y-mlen+back, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
59 | cube([size_xm, mlen, size_ym]);
60 | }
61 | if(side == "top" && rotation == 90) {
62 | place(loc_x-mlen+back, loc_y+5, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
63 | cube([size_xm, mlen, size_ym]);
64 | }
65 | if(side == "top" && rotation == 180) {
66 | place(loc_x+5, loc_y-5.25+mlen-back, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
67 | cube([size_xm, mlen, size_ym]);
68 | }
69 | if(side == "top" && rotation == 270) {
70 | place(loc_x-5.25+mlen-back, loc_y, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
71 | cube([size_xm, mlen, size_ym]);
72 | }
73 | if(side == "bottom" && rotation == 0) {
74 | place(loc_x+5, loc_y-mlen+back, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
75 | cube([size_xm, mlen, size_ym]);
76 | }
77 | if(side == "bottom" && rotation == 90) {
78 | place(loc_x-5.25+mlen-back, loc_y+5, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
79 | cube([size_xm, mlen, size_ym]);
80 | }
81 | if(side == "bottom" && rotation == 180) {
82 | place(loc_x, loc_y-5.25+mlen-back, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
83 | cube([size_xm, mlen, size_ym]);
84 | }
85 | if(side == "bottom" && rotation == 270) {
86 | place(loc_x-mlen+back, loc_y, loc_z+.25, size_ym, size_xm, rotation, side, pcbsize_z)
87 | cube([size_xm, mlen, size_ym]);
88 | }
89 | }
90 | if(enablemask == false) {
91 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
92 | union() {
93 | color("silver") translate([0, 0, .5]) cube([size_x, size_y, 3.5]);
94 | color("white") translate([3.75, -1.99, 1.75]) cube([3, 2, 1.5]);
95 | }
96 | }
97 | }
98 | if(type == "slide_7x3.5x1") {
99 |
100 | size_x = 7;
101 | size_y = 3.5;
102 | size_xm = 7;
103 | size_ym = 1.75;
104 |
105 | if(enablemask == true && cmask == true && mstyle == "default") {
106 | // switch opening
107 | if(side == "top" && rotation == 0) {
108 | place(loc_x, loc_y-mlen+back, loc_z, size_ym-.5, size_xm, rotation, side, pcbsize_z)
109 | cube([size_xm, mlen, size_ym]);
110 | }
111 | if(side == "top" && rotation == 90) {
112 | place(loc_x-mlen+back, loc_y+5, loc_z, size_ym-.5, size_xm, rotation, side, pcbsize_z)
113 | cube([size_xm, mlen, size_ym]);
114 | }
115 | if(side == "top" && rotation == 180) {
116 | place(loc_x+5, loc_y-5.25+mlen-back, loc_z-.5, size_ym, size_xm, rotation, side, pcbsize_z)
117 | cube([size_xm, mlen, size_ym]);
118 | }
119 | if(side == "top" && rotation == 270) {
120 | place(loc_x-5.25+mlen-back, loc_y, loc_z-.5, size_ym, size_xm, rotation, side, pcbsize_z)
121 | cube([size_xm, mlen, size_ym]);
122 | }
123 | if(side == "bottom" && rotation == 0) {
124 | place(loc_x+5, loc_y-mlen+back, loc_z-.5, size_ym, size_xm, rotation, side, pcbsize_z)
125 | cube([size_xm, mlen, size_ym]);
126 | }
127 | if(side == "bottom" && rotation == 90) {
128 | place(loc_x-5.25+mlen-back, loc_y+5, loc_z-.5, size_ym, size_xm, rotation, side, pcbsize_z)
129 | cube([size_xm, mlen, size_ym]);
130 | }
131 | if(side == "bottom" && rotation == 180) {
132 | place(loc_x, loc_y-5.25+mlen-back, loc_z-.5, size_ym, size_xm, rotation, side, pcbsize_z)
133 | cube([size_xm, mlen, size_ym]);
134 | }
135 | if(side == "bottom" && rotation == 270) {
136 | place(loc_x-mlen+back, loc_y, loc_z-.5, size_ym, size_xm, rotation, side, pcbsize_z)
137 | cube([size_xm, mlen, size_ym]);
138 | }
139 | }
140 | if(enablemask == false) {
141 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
142 | union() {
143 | color("silver") translate([0, 0, 0]) cube([size_x, size_y, 1.5]);
144 | color("white") translate([2, -.7, .25]) cube([3, .75, 1]);
145 | }
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/lib/terminal.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: terminal
20 | DESCRIPTION: creates terminal blocks
21 | TODO: add other styles
22 |
23 | USAGE: terminal(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask)
24 |
25 | type = "gtb"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | size[0] = #positions
32 | size[1] = body depth
33 | size[2] = height
34 | data[0] = pitch
35 | data[1] = body color
36 | pcbsize_z = pcb thickness
37 | enablemask = true produces mask, false produces model
38 | mask[0] = true enables component mask
39 | mask[1] = mask length
40 | mask[2] = mask setback
41 | mask[3] = mstyle "default"
42 |
43 | */
44 |
45 | // terminal block class
46 | module terminal(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
47 |
48 | cmask = mask[0];
49 | mlen = mask[1];
50 | back = mask[2];
51 | mstyle = mask[3];
52 |
53 | // type green terminal block
54 | if(type=="gtb") {
55 |
56 | pitch = data[0];
57 | hcolor = data[1];
58 | rows = size[0];
59 | size_x = pitch * rows;
60 | size_y = size[1];
61 | height = size[2];
62 | pcolor = "#fee5a6";
63 |
64 | adj = .01;
65 | $fn = 90;
66 | size_xm = size_x+2;
67 | size_ym = size_y+.5;
68 |
69 | if(enablemask == true && cmask == true && mstyle == "default") {
70 | if(side == "top" && rotation == 0) {
71 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
72 | union() {
73 | translate([0, back, 3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
74 | for(r=[pitch/2:pitch:size_x]) {
75 | translate([r, 4.15, height-back]) cylinder(d=3.7, h=mlen);
76 | }
77 | }
78 | }
79 | if(side == "top" && rotation == 90) {
80 | place(loc_x, loc_y-2, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
81 | union() {
82 | translate([0, back, 3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
83 | for(r=[pitch/2:pitch:size_x]) {
84 | translate([r, 4.15, height-back]) cylinder(d=3.7, h=mlen);
85 | }
86 | }
87 | }
88 | if(side == "top" && rotation == 180) {
89 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
90 | union() {
91 | translate([2,1+back,3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
92 | for(r=[pitch/2:pitch:size_x]) {
93 | translate([r+2, 4.5, height-back]) cylinder(d=3.7, h=mlen);
94 | }
95 | }
96 | }
97 | if(side == "top" && rotation == 270) {
98 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
99 | union() {
100 | translate([0,.5+back,3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
101 | for(r=[pitch/2:pitch:size_x]) {
102 | translate([r, 4.5, height-back]) cylinder(d=3.7, h=mlen);
103 | }
104 | }
105 | }
106 | if(side == "bottom" && rotation == 0) {
107 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
108 | union() {
109 | translate([2, back, 3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
110 | for(r=[pitch/2:pitch:size_x]) {
111 | translate([r+2, 4.15, height-back]) cylinder(d=3.7, h=mlen);
112 | }
113 | }
114 | }
115 | if(side == "bottom" && rotation == 90) {
116 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
117 | union() {
118 | translate([2, .5+back, 3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
119 | for(r=[pitch/2:pitch:size_x]) {
120 | translate([r+2, 4.5, height-back]) cylinder(d=3.7, h=mlen);
121 | }
122 | }
123 | }
124 | if(side == "bottom" && rotation == 180) {
125 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
126 | union() {
127 | translate([0, 1+back, 3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
128 | for(r=[pitch/2:pitch:size_x]) {
129 | translate([r, 4.5, height-back]) cylinder(d=3.7, h=mlen);
130 | }
131 | }
132 | }
133 | if(side == "bottom" && rotation == 270) {
134 | place(loc_x, loc_y, loc_z, size_xm, size_ym, rotation, side, pcbsize_z)
135 | union() {
136 | translate([0, back, 3]) rotate([90, 0, 0]) slot(5, size_x, mlen);
137 | for(r=[pitch/2:pitch:size_x]) {
138 | translate([r, 4.15, height-back]) cylinder(d=3.7, h=mlen);
139 | }
140 | }
141 | }
142 | }
143 | if(enablemask == false) {
144 |
145 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
146 | union() {
147 | difference() {
148 | union() {
149 | color(hcolor) cube([size_x, size_y, height/2]);
150 | color(hcolor) translate([0, 0, (height/2)-.01]) cube([size_x, size_y, height/2]);
151 | }
152 | color(hcolor) translate([-1, -3, 6.99]) rotate([-15, 0, 0]) cube([(pitch*rows)+2, 3, 10]);
153 | color(hcolor) translate([-1, 8, 10]) rotate([15, 0, 0]) cube([(pitch*rows)+2, 3, 10]);
154 | for(r=[pitch/2:pitch:size_x]) {
155 | color(hcolor) translate([r, 4.15, height-3]) cylinder(d=3.7, h=4);
156 | }
157 | for(r=[.75:pitch:size_x]) {
158 | color(hcolor) translate([r, -1, 1]) cube([3.5,5,4]);
159 | }
160 | }
161 | for(r=[pitch/2:pitch:size_x]) {
162 | color(pcolor) translate([r, 4.15, -3.2]) cube([.64, .64, 3.3]);
163 | difference() {
164 | color("silver") translate([r, 4.15, height-2.5]) cylinder(d=3.7, h=2);
165 | color("silver") translate([r-.5, 4.15-(4.15/2), height-1.25]) cube([1,4,1]);
166 | }
167 | }
168 | for(r=[1:pitch:size_x]) {
169 | color("silver") translate([r, .5, 1]) cube([3, 4, .25]);
170 | color("silver") translate([r, .5, 4.5]) cube([3, 4, .5]);
171 | }
172 | }
173 | }
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/lib/uart.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: uart
20 | DESCRIPTION: creates uart ports.
21 | TODO:
22 |
23 | USAGE: uart(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "molex_5267", "molex_5268"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = true enables component mask
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "none", "open", "knockout"
37 |
38 | */
39 |
40 | // uart class
41 | module uart(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
42 |
43 | cmask = mask[0];
44 | mlen = mask[1];
45 | back = mask[2];
46 | mstyle = mask[3];
47 | knock_gap = 2;
48 |
49 | // uart micro connector straight
50 | if(type == "molex_5267") {
51 |
52 | size_x = 12.4;
53 | size_y = 5;
54 | size_z = 6;
55 | size_xm = size_x+2;
56 | size_zm = 6;
57 |
58 | if(enablemask == true && cmask == true && mstyle == "open") {
59 |
60 | if(side == "top" && rotation == 0) {
61 | place(loc_x-(size_xm-size_x)/2, loc_y-mlen+back, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
62 | cube([size_xm, mlen, size_zm]);
63 | }
64 | if(side == "top" && rotation == 90) {
65 | place(loc_x-mlen+back, loc_y+(size_xm-size_x)/2, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
66 | cube([size_xm, mlen, size_zm]);
67 | }
68 | if(side == "top" && rotation == 180) {
69 | place(loc_x+(size_xm-size_x)/2, loc_y+size_y-back, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
70 | cube([size_xm, mlen, size_zm]);
71 | }
72 | if(side == "top" && rotation == 270) {
73 | place(loc_x+size_y-back, loc_y-(size_xm-size_x)/2, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
74 | cube([size_xm, mlen, size_zm]);
75 | }
76 | if(side == "bottom" && rotation == 0) {
77 | place(loc_x+(size_xm-size_x)/2, loc_y-mlen+back, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
78 | cube([size_xm, mlen, size_zm]);
79 | }
80 | if(side == "bottom" && rotation == 90) {
81 | place(loc_x+size_y-back, loc_y+(size_xm-size_x)/2, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
82 | cube([size_xm, mlen, size_zm]);
83 | }
84 | if(side == "bottom" && rotation == 180) {
85 | place(loc_x-(size_xm-size_x)/2, loc_y+size_y-back, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
86 | cube([size_xm, mlen, size_zm]);
87 | }
88 | if(side == "bottom" && rotation == 270) {
89 | place(loc_x-mlen+back, loc_y-(size_xm-size_x)/2, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
90 | cube([size_xm, mlen, size_zm]);
91 | }
92 | }
93 | if(enablemask == true && cmask == true && (mstyle == "knockout" || mstyle == "default")) {
94 |
95 | if(side == "top" && rotation == 0) {
96 | place(loc_x-(size_xm-size_x)/2, loc_y, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
97 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
98 | }
99 | if(side == "top" && rotation == 90) {
100 | place(loc_x, loc_y+(size_xm-size_x)/2, loc_z+5, size_x, mlen, rotation, side, pcbsize_z)
101 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
102 | }
103 | if(side == "top" && rotation == 180) {
104 | place(loc_x+(size_xm-size_x)/2, loc_y-size_y, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
105 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
106 | }
107 | if(side == "top" && rotation == 270) {
108 | place(loc_x-size_y, loc_y-(size_xm-size_x)/2, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
109 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
110 | }
111 | if(side == "bottom" && rotation == 0) {
112 | place(loc_x+(size_xm-size_x)/2, loc_y, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
113 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
114 | }
115 | if(side == "bottom" && rotation == 90) {
116 | place(loc_x-size_y, loc_y+(size_xm-size_x)/2, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
117 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
118 | }
119 | if(side == "bottom" && rotation == 180) {
120 | place(loc_x-(size_xm-size_x)/2, loc_y-size_y, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
121 | rotate([90, 0, 0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
122 | }
123 | if(side == "bottom" && rotation == 270) {
124 | place(loc_x, loc_y-(size_xm-size_x)/2, loc_z+5+back, size_x, mlen, rotation, side, pcbsize_z)
125 | rotate([90, 0, 0]) knockout(size_xm, size_zm, 1, mlen, 2, "rectangle");
126 | }
127 | }
128 | if(enablemask == false) {
129 |
130 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
131 | union() {
132 | difference() {
133 | union() {
134 |
135 | difference () {
136 | color("white") cube([size_x, size_y, 6]);
137 | color("white") translate([.5, .5, 2]) cube([11.5, 4, 6]);
138 | }
139 | color("white") translate([12, 3.75, .5]) rotate([0, 0, 45]) cube([1, 2, 5.5]);
140 | color("white") translate([-0.2, 4, .5]) rotate([0, 0, -45]) cube([1, 2, 5.5]);
141 | }
142 | color("white") translate([12.4, 0, -.5]) cube([2, 6, 7]);
143 | color("white") translate([-1, 0, -.5]) cube([1, 6, 7]);
144 | color("white") translate([-1, 5, -.5]) cube([14, 2, 7]);
145 | color("white") translate([-0.7, 4.5, -.1]) rotate([0, 0, -45]) cube([1, 2, 7]);
146 | color("white") translate([-1, 1.5, 2]) cube([14, 1, 7]);
147 | }
148 | for (i=[2.5:2.5:10]) {
149 | color("silver") translate ([i, 3, .5]) cube([.6, .6, 5]);
150 | }
151 | }
152 | }
153 | }
154 | // uart micro connector right angle
155 | if(type == "molex_5268") {
156 |
157 | size_x = 12.5;
158 | size_y = 6;
159 | size_z = 5;
160 | size_xm = size_x+2;
161 | size_zm = size_z+.5;
162 |
163 | if(enablemask == true && cmask == true && mstyle == "open") {
164 | if(side == "top" && rotation == 0) {
165 | place(loc_x-(size_xm-size_x)/2, loc_y-mlen+back, loc_z, size_x, mlen, rotation, side, pcbsize_z)
166 | cube([size_xm, mlen, size_zm]);
167 | }
168 | if(side == "top" && rotation == 90) {
169 | place(loc_x-mlen+back, loc_y+(size_xm-size_x)/2, loc_z, size_x, mlen, rotation, side, pcbsize_z)
170 | cube([size_xm, mlen, size_zm]);
171 | }
172 | if(side == "top" && rotation == 180) {
173 | place(loc_x+(size_xm-size_x)/2, loc_y+size_y-back, loc_z, size_x, mlen, rotation, side, pcbsize_z)
174 | cube([size_xm, mlen, size_zm]);
175 | }
176 | if(side == "top" && rotation == 270) {
177 | place(loc_x+size_y-back, loc_y-(size_xm-size_x)/2, loc_z, size_x, mlen, rotation, side, pcbsize_z)
178 | cube([size_xm, mlen, size_zm]);
179 | }
180 | if(side == "bottom" && rotation == 0) {
181 | place(loc_x+(size_xm-size_x)/2, loc_y-mlen+back, loc_z, size_x, mlen, rotation, side, pcbsize_z)
182 | cube([size_xm, mlen, size_zm]);
183 | }
184 | if(side == "bottom" && rotation == 90) {
185 | place(loc_x+size_y-back, loc_y+(size_xm-size_x)/2, loc_z, size_x, mlen, rotation, side, pcbsize_z)
186 | cube([size_xm, mlen, size_zm]);
187 | }
188 | if(side == "bottom" && rotation == 180) {
189 | place(loc_x-(size_xm-size_x)/2, loc_y+size_y-back, loc_z, size_x, mlen, rotation, side, pcbsize_z)
190 | cube([size_xm, mlen, size_zm]);
191 | }
192 | if(side == "bottom" && rotation == 270) {
193 | place(loc_x-mlen+back, loc_y-(size_xm-size_x)/2, loc_z, size_x, mlen, rotation, side, pcbsize_z)
194 | cube([size_xm, mlen, size_zm]);
195 | }
196 | }
197 | if(enablemask == true && cmask == true && (mstyle == "knockout" || mstyle == "default")) {
198 |
199 | if(side == "top" && rotation == 0) {
200 | place(loc_x-(size_xm-size_x)/2, loc_y, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
201 | rotate([90,0,0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
202 | }
203 | if(side == "top" && rotation == 90) {
204 | place(loc_x, loc_y+(size_xm-size_x)/2, loc_z, size_x, mlen, rotation, side, pcbsize_z)
205 | rotate([90,0,0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
206 | }
207 | if(side == "top" && rotation == 180) {
208 | place(loc_x+(size_xm-size_x)/2, loc_y-4, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
209 | rotate([90,0,0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
210 | }
211 | if(side == "top" && rotation == 270) {
212 | place(loc_x-4, loc_y-(size_xm-size_x)/2, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
213 | rotate([90,0,0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
214 | }
215 | if(side == "bottom" && rotation == 0) {
216 | place(loc_x+(size_xm-size_x)/2, loc_y, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
217 | rotate([90,0,0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
218 | }
219 | if(side == "bottom" && rotation == 90) {
220 | place(loc_x-4, loc_y+(size_xm-size_x)/2, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
221 | rotate([90,0,0]) knockout(size_xm, size_zm, 1, mlen, 2, "rectangle");
222 | }
223 | if(side == "bottom" && rotation == 180) {
224 | place(loc_x-(size_xm-size_x)/2, loc_y-4, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
225 | rotate([90,0,0]) knockout(size_xm, size_zm, 1, mlen, 2, "rectangle");
226 | }
227 | if(side == "bottom" && rotation == 270) {
228 | place(loc_x, loc_y-(size_xm-size_x)/2, loc_z+back, size_x, mlen, rotation, side, pcbsize_z)
229 | rotate([90,0,0]) knockout(size_xm, size_zm, knock_gap, mlen, 2, "rectangle");
230 | }
231 | }
232 | if(enablemask == false) {
233 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
234 | rotate([0,0,0]) translate([0, 0, 0]) union() {
235 | difference() {
236 | union() {
237 |
238 | difference () {
239 | color("white") cube([size_x, size_y, size_z]);
240 | color("white") translate([.5, -2, .5]) cube([size_x-1, size_y, size_z-1]);
241 | }
242 | color("white") translate([0, 5, 3.925]) rotate([90, 45, 0]) cube([.75, 1.5, 5]);
243 | color("white") translate([11.9675, 5, 3.40625]) rotate([90, -45, 0]) cube([.75, 1.5, 5]);
244 | }
245 | color("white") translate([-1, 6.5, 4]) rotate([90, 45, 0]) cube([1, 4, 7]);
246 | color("white") translate([-1, 4, 1]) rotate([90, 0, 0]) cube([14, 1, 7]);
247 | }
248 | for (i=[2.5:2.5:10]) {
249 | color("silver") translate ([i, 0, 2.38]) cube([.6, 5, .6]);
250 | }
251 | }
252 | }
253 | }
254 | }
--------------------------------------------------------------------------------
/lib/usbc.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 |
18 |
19 | CLASS NAME: usbc
20 | DESCRIPTION: creates usbc ports.
21 | TODO:
22 |
23 | USAGE: usbc(type, loc_x, loc_y, loc_z, side, rotation[], size[], data[], pcbsize_z, enablemask, mask[])
24 |
25 | type = "single_horizontal", "single_vertical"
26 | loc_x = x location placement
27 | loc_y = y location placement
28 | loc_z = z location placement
29 | side = "top", "bottom"
30 | rotation[] = object rotation
31 | pcbsize_z = pcb thickness
32 | enablemask = true produces mask, false produces model
33 | mask[0] = true enables component mask
34 | mask[1] = mask length
35 | mask[2] = mask setback
36 | mask[3] = mstyle "default"
37 |
38 |
39 | */
40 |
41 |
42 | // usbc port class
43 | module usbc(type, loc_x, loc_y, loc_z, side, rotation, size, data, pcbsize_z, enablemask, mask) {
44 |
45 | cmask = mask[0];
46 | mlen = mask[1];
47 | back = mask[2];
48 | mstyle = mask[3];
49 | $fn=90;
50 |
51 | // usbc horizontal type
52 | if(type == "single_horizontal") {
53 |
54 | size_x = 9;
55 | size_xm = 10;
56 | size_y = 7;
57 | dia = 3.5;
58 | diam = 4.5;
59 |
60 | if(enablemask == true && cmask == true && mstyle == "default") {
61 | // single horizontal usbc opening
62 | if(side == "top" && rotation == 0) {
63 | place(loc_x+(size_x-size_xm)/2, loc_y+back, loc_z-.125+diam/2, size_x, mlen, rotation, side, pcbsize_z)
64 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
65 | }
66 | if(side == "top" && rotation == 90) {
67 | place(loc_x+back, loc_y-(size_x-size_xm)/2, loc_z-.125+diam/2, size_x, mlen, rotation, side, pcbsize_z)
68 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
69 | }
70 | if(side == "top" && rotation == 180) {
71 | place(loc_x-(size_x-size_xm)/2, loc_y-3-back, loc_z-.375+diam/2, size_x, mlen, rotation, side, pcbsize_z)
72 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
73 | }
74 | if(side == "top" && rotation == 270) {
75 | place(loc_x-3-back, loc_y+(size_x-size_xm)/2, loc_z+diam/2, size_x, mlen, rotation, side, pcbsize_z)
76 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
77 | }
78 | if(side == "bottom" && rotation == 0) {
79 | place(loc_x-(size_x-size_xm)/2, loc_y+back, loc_z-.125+diam/2, size_x, mlen, rotation, side, pcbsize_z)
80 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
81 | }
82 | if(side == "bottom" && rotation == 90) {
83 | place(loc_x-3-back, loc_y-(size_x-size_xm)/2, loc_z+diam/2, size_x, mlen, rotation, side, pcbsize_z)
84 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
85 | }
86 | if(side == "bottom" && rotation == 180) {
87 | place(loc_x+(size_x-size_xm)/2, loc_y-3-back, loc_z+diam/2, size_x-(size_x-size_xm), mlen, rotation, side, pcbsize_z)
88 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
89 | }
90 | if(side == "bottom" && rotation == 270) {
91 | place(loc_x+back, loc_y+(size_x-size_xm)/2, loc_z-.125+diam/2, size_x, mlen, rotation, side, pcbsize_z)
92 | rotate([90, 0, 0]) slot(diam, size_xm, mlen);
93 | }
94 | }
95 | if(enablemask == false) {
96 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
97 | rotate([90, 0, 0]) translate([dia/2, dia/2, -size_y]) union() {
98 | difference () {
99 | color("silver")
100 | hull() {
101 | cylinder(d=dia, h=size_y);
102 | translate([size_x-dia, 0, 0]) cylinder(d=dia, h=size_y);
103 | }
104 | color("silver") translate([0,0,1])
105 | hull() {
106 | cylinder(d=3, h=size_y+.2);
107 | translate([size_x-dia, 0, 0]) cylinder(d=3, h=size_y+.2);
108 | }
109 | }
110 | color("black") translate([0, -1.2/2, .1]) cube([5.5, 1.2, 6]);
111 | }
112 | }
113 | }
114 |
115 | // usbc vertical type
116 | if(type == "single_vertical") {
117 |
118 | size_x = 9;
119 | size_y = 7;
120 | size_xm = 10;
121 | size_ym = 7;
122 | dia = 3.5;
123 | diam = 4;
124 | height = .5;
125 |
126 | if(enablemask == true && cmask == true && mstyle == "default") {
127 | // single vertical usbc opening
128 | if(side == "top" && rotation == 0) {
129 | place(loc_x-(diam-dia)/2+diam/2, loc_y+back, loc_z+size_xm, size_xm, mlen, rotation, side, pcbsize_z)
130 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
131 | }
132 | if(side == "top" && rotation == 90) {
133 | place(loc_x+back, loc_y-dia+(diam-dia)+height, loc_z+size_xm, size_xm, mlen, rotation, side, pcbsize_z)
134 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
135 | }
136 | if(side == "top" && rotation == 180) {
137 | place(loc_x-dia+(diam-dia)+height, loc_y-2-back, loc_z+size_xm, mlen, size_xm, rotation, side, pcbsize_z)
138 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
139 | }
140 | if(side == "top" && rotation == 270) {
141 | place(loc_x-2-back, loc_y-(diam-dia)/2+diam/2, loc_z+size_xm, mlen, size_xm, rotation, side, pcbsize_z)
142 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
143 | }
144 | if(side == "bottom" && rotation == 0) {
145 | place(loc_x-dia+(diam-dia)+height, loc_y+back, loc_z+size_xm, size_xm, mlen, rotation, side, pcbsize_z)
146 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
147 | }
148 | if(side == "bottom" && rotation == 90) {
149 | place(loc_x-back, loc_y-dia+(diam-dia)+height, loc_z+size_xm, size_xm, size_y, rotation, side, pcbsize_z)
150 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
151 | }
152 | if(side == "bottom" && rotation == 180) {
153 | place(loc_x-(diam-dia)/2+diam/2, loc_y-2-back, loc_z+size_xm, mlen, size_xm, rotation, side, pcbsize_z)
154 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
155 | }
156 | if(side == "bottom" && rotation == 270) {
157 | place(loc_x+back, loc_y-(diam-dia)/2+diam/2, loc_z+size_xm, size_xm, mlen, rotation, side, pcbsize_z)
158 | rotate([90, 90, 0]) slot(diam, size_xm, mlen);
159 | }
160 | }
161 | if(enablemask == false) {
162 | place(loc_x, loc_y, loc_z, size_x, size_y, rotation, side, pcbsize_z)
163 | rotate([90, 90 ,0]) translate([-size_y-.25-height, dia/2, -size_y])
164 | union() {
165 | difference () {
166 | color("silver")
167 | hull() {
168 | cylinder(d=dia,h=size_y);
169 | translate([size_x-dia, 0, 0]) cylinder(d=dia, h=size_y);
170 | }
171 | color("silver") translate([0 ,0, 1])
172 | hull() {
173 | cylinder(d=3, h=size_y+.2);
174 | translate([size_x-dia, 0, 0]) cylinder(d=3, h=size_y+.2);
175 | }
176 | }
177 | color("black") translate([0, -1.2/2, 1]) cube([5.5, 1.2, 6]);
178 | }
179 | }
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/sbc_models.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hominoids/SBC_Model_Framework/0128dd7014f54863a99b1c547d2d0e290dff64c4/sbc_models.png
--------------------------------------------------------------------------------
/sbc_models_library.scad:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of SBC Model Framework https://github.com/hominoids/SBC_Model_Framework
3 | Copyright 2019,2020,2021,2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
17 | */
18 |
19 | include <./lib/place.scad>
20 | include <./lib/antenna.scad>
21 | include <./lib/audio.scad>
22 | include <./lib/b2b.scad>
23 | include <./lib/battery.scad>
24 | include <./lib/button.scad>
25 | include <./lib/cm.scad>
26 | include <./lib/discrete.scad>
27 | include <./lib/display.scad>
28 | include <./lib/fan.scad>
29 | include <./lib/fillets.scad>
30 | include <./lib/fpc.scad>
31 | include <./lib/gpio.scad>
32 | include <./lib/header.scad>
33 | include <./lib/heatsink.scad>
34 | include <./lib/ic.scad>
35 | include <./lib/jst.scad>
36 | include <./lib/memory.scad>
37 | include <./lib/molex.scad>
38 | include <./lib/network.scad>
39 | include <./lib/pcb.scad>
40 | include <./lib/pcie.scad>
41 | include <./lib/pillar.scad>
42 | include <./lib/power.scad>
43 | include <./lib/shape.scad>
44 | include <./lib/smd.scad>
45 | include <./lib/storage.scad>
46 | include <./lib/switch.scad>
47 | include <./lib/terminal.scad>
48 | include <./lib/uart.scad>
49 | include <./lib/usb2.scad>
50 | include <./lib/usb3.scad>
51 | include <./lib/usbc.scad>
52 | include <./lib/video.scad>
--------------------------------------------------------------------------------
/sbc_models_viewer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hominoids/SBC_Model_Framework/0128dd7014f54863a99b1c547d2d0e290dff64c4/sbc_models_viewer.gif
--------------------------------------------------------------------------------