case.scad (19005B)
1 /* 2 * Copyright 2022 Gerd Beuster (gerd@frombelow.net). This design is 3 * free under the GNU GPL v3 license or any later version. See 4 * COPYING in the root directory for details. 5 */ 6 7 include <lasercut/lasercut.scad> 8 9 $fn=30; 10 11 // Thickness of boards 12 board_thickness = 4; 13 // Width and depth of LED matrix 14 matrix_side = 160; 15 matrix_height = 2; 16 // Additional border of back plate of LED matrix. 17 matrix_back_border = 20; 18 matrix_back_side = matrix_side + matrix_back_border*2; 19 // Distance from side of LED matrix back plate to screw holes 20 matrix_back_screw_holes_distance = matrix_back_border / 2; 21 // Diameter of holes to screw matrix back screw to acryl plate 22 matrix_back_screw_hole = 4; 23 // Screw holes for bottom plate are somewhat larger, because 24 // we use claw nuts 25 bottom_screw_hole = 5; 26 // Depth of control panel 27 panel_depth = 60; 28 // Diameter of holes for switches 29 switch = 6.6; 30 // Diameter of holes for dial 31 dial = 6.6; 32 // Diameter of holes for push buttons 33 button = 7.2; 34 // Hole for USB connector 35 usb_width = 18; 36 usb_height = 13; 37 // Diameter of hole for power supply 38 power_supply = 8; 39 40 box_height = 60; 41 // Distance from floor to bottom panel 42 bottom_panel_height = 5; 43 44 // Circuit board 45 circuit_board_width = 145; 46 circuit_board_depth = 65; 47 circuit_board_height = 1; 48 // Icestick 49 icestick_base_width = 80; 50 icestick_base_depth = 25; 51 icestick_base_height = 4; 52 icestick_strap_width = 20; 53 icestick_strap_depth = 60; 54 icestick_strap_height = 2; 55 56 module matrix() { 57 translate([matrix_back_border, 58 matrix_back_border, 59 board_thickness]) 60 cube([matrix_side, matrix_side, 2]); 61 } 62 63 // The LED matrix is fit in between the acryl plate on top 64 // and the back plate below. These three plates are hold 65 // together by screws. The acryl plate and the back plate (but 66 // not the LED matrix itself) need screw holes. 67 module acryl_plate_holder_screw_holes() { 68 // Screw holes in four corners 69 union () { 70 translate([matrix_back_border/2, 71 matrix_back_border/2, 72 0]) 73 cylinder(h=board_thickness, d=matrix_back_screw_hole, 74 center=false); 75 translate([matrix_back_side-matrix_back_border/2, 76 matrix_back_border/2, 77 0]) 78 cylinder(h=board_thickness, d=matrix_back_screw_hole, 79 center=false); 80 translate([matrix_back_border/2, 81 matrix_back_side-matrix_back_border/2, 82 0]) 83 cylinder(h=board_thickness, d=matrix_back_screw_hole, 84 center=false); 85 translate([matrix_back_side-matrix_back_border/2, 86 matrix_back_side-matrix_back_border/2, 87 0]) 88 cylinder(h=board_thickness, d=matrix_back_screw_hole, 89 center=false); 90 } 91 } 92 93 module matrix_back() { 94 difference() { 95 lasercutoutSquare(thickness=board_thickness, 96 x=matrix_back_side, y=matrix_back_side, 97 finger_joints=[ 98 [UP, 0, 4], 99 [LEFT, 1, 4], 100 [RIGHT, 0, 4] 101 ]); 102 // Cutout for power supply 103 { translate([matrix_back_side-matrix_back_border*2-25, 104 matrix_back_side-matrix_back_border*2-30, 0]) 105 cube([15, 20, board_thickness]); 106 } 107 acryl_plate_holder_screw_holes(); 108 } 109 } 110 111 module acryl_top_plate() { 112 translate([0, 0, matrix_height+board_thickness]) { 113 difference () { 114 cube([matrix_back_side, matrix_back_side, board_thickness]); 115 acryl_plate_holder_screw_holes(); 116 } 117 } 118 } 119 120 module box_left_side() { 121 difference () { 122 translate([-board_thickness, 123 -panel_depth, 124 board_thickness*2+matrix_height]) { 125 rotate([0, 90, 0]) { 126 lasercutoutSquare(thickness=board_thickness, 127 x=box_height, 128 y=matrix_side+matrix_back_border*2+panel_depth, 129 finger_joints=[ 130 [UP, 1, 2], 131 [DOWN, 0, 2], 132 ]); 133 } 134 } 135 union () { 136 // Cutout for fingers 137 matrix_back(); 138 control_panel(); 139 bottom_screw_mount_front(); 140 bottom_screw_mount_back(); 141 } 142 } 143 } 144 145 module box_right_side() { 146 difference () { 147 translate([matrix_back_side, 148 -panel_depth, 149 board_thickness*2+matrix_height]) { 150 rotate([0, 90, 0]) { 151 lasercutoutSquare(thickness=board_thickness, 152 x=box_height, 153 y=matrix_side+matrix_back_border*2+panel_depth, 154 finger_joints=[ 155 [UP, 1, 2], 156 [DOWN, 0, 2], 157 ]); 158 } 159 } 160 union () { 161 // Cutout for fingers 162 matrix_back(); 163 control_panel(); 164 bottom_screw_mount_front(); 165 bottom_screw_mount_back(); 166 // Cutout for USB connector 167 translate([matrix_back_side, 168 circuit_board_depth+usb_width*2, 169 -box_height+usb_height+bottom_panel_height+1]) { 170 cube([board_thickness, usb_width, usb_height]); 171 } 172 } 173 } 174 } 175 176 module box_front() { 177 difference () { 178 translate([-board_thickness, 179 -panel_depth, 180 board_thickness*2+matrix_height]) { 181 rotate([90, 90, 0]) { 182 lasercutoutSquare(thickness=board_thickness, 183 x=box_height, 184 y=matrix_back_side+board_thickness*2, 185 finger_joints=[ 186 ]); 187 } 188 } 189 // Cutout for fingers 190 union () { 191 box_left_side(); 192 box_right_side(); 193 control_panel(); 194 bottom_screw_mount_front(); 195 } 196 } 197 } 198 199 module box_back() { 200 difference () { 201 translate([-board_thickness, 202 matrix_side+matrix_back_border*2+board_thickness, 203 board_thickness*2+matrix_height]) { 204 rotate([90, 90, 0]) { 205 lasercutoutSquare(thickness=board_thickness, 206 x=box_height, 207 y=matrix_back_side+board_thickness*2, 208 finger_joints=[ 209 ]); 210 } 211 } 212 // Cutout for fingers 213 union () { 214 box_left_side(); 215 box_right_side(); 216 matrix_back(); 217 bottom_screw_mount_back(); 218 } 219 } 220 } 221 222 223 module control_panel() { 224 translate([0, -panel_depth, matrix_height+board_thickness]) { 225 difference() { 226 lasercutoutSquare(thickness=board_thickness, 227 x=matrix_back_side, y=panel_depth, 228 finger_joints=[ 229 [LEFT, 0, 2], 230 [RIGHT, 1, 2], 231 [DOWN, 0, 4] 232 ]); 233 // Reset Button 234 translate([matrix_back_side/10*(1-.2), 235 panel_depth/4*(3.2-.2), 236 0 ]) 237 cylinder(h=board_thickness, d=button, 238 center=false); 239 // Speed dial 240 translate([matrix_back_side/10*(2-.2), 241 panel_depth/4*(3.2-.2), 242 0 ]) 243 cylinder(h=board_thickness, d=dial, 244 center=false); 245 // Run/Single/Enter switch 246 translate([matrix_back_side/10*(3-.2), 247 panel_depth/4*(3.2-.2), 248 0 ]) 249 cylinder(h=board_thickness, d=switch, 250 center=false); 251 // Step Button 252 translate([matrix_back_side/10*(4-.2), 253 panel_depth/4*(3.2-.2), 254 0 ]) 255 cylinder(h=board_thickness, d=button, 256 center=false); 257 // Skip Button 258 translate([matrix_back_side/10*(5-.2), 259 panel_depth/4*(3.2-.2), 260 0 ]) 261 cylinder(h=board_thickness, d=button, 262 center=false); 263 // Data switches 264 for(p = [2-.2:9-.2]) { 265 translate([matrix_back_side/10*p, 266 panel_depth/4*(.8+.2), 267 0 ]) { 268 cylinder(h=board_thickness, d=switch, 269 center=false); 270 } 271 } 272 } 273 } 274 } 275 276 277 module bottom_screw_mount_front() { 278 translate([0, -panel_depth, -box_height+board_thickness*3.5+bottom_panel_height]) { 279 difference() { 280 lasercutoutSquare(thickness=board_thickness, 281 x=matrix_back_side, y=matrix_back_border, 282 finger_joints=[ 283 [DOWN, 0, 4], 284 [LEFT, 1, 2], 285 [RIGHT, 0, 2] 286 ]); 287 translate([matrix_back_border/2, matrix_back_border/2, 0]) 288 cylinder(h=board_thickness, d=bottom_screw_hole, 289 center=false); 290 translate([matrix_back_side-matrix_back_border/2, matrix_back_border/2, 0]) 291 cylinder(h=board_thickness, d=bottom_screw_hole, 292 center=false); 293 } 294 } 295 296 } 297 298 module bottom_screw_mount_back() { 299 translate([0, matrix_side+matrix_back_border, -box_height+board_thickness*3.5+bottom_panel_height]) { 300 difference() { 301 lasercutoutSquare(thickness=board_thickness, 302 x=matrix_back_side, y=matrix_back_border, 303 finger_joints=[ 304 [UP, 0, 4], 305 [LEFT, 1, 2], 306 [RIGHT, 0, 2] 307 ]); 308 translate([matrix_back_border/2, matrix_back_border/2, 0]) 309 cylinder(h=board_thickness, d=bottom_screw_hole, 310 center=false); 311 translate([matrix_back_side-matrix_back_border/2, matrix_back_border/2, 0]) 312 cylinder(h=board_thickness, d=bottom_screw_hole, 313 center=false); 314 } 315 } 316 317 } 318 319 module box_bottom() { 320 difference() { 321 translate([0, -panel_depth, -box_height+2.5*board_thickness+bottom_panel_height]) { 322 difference() { 323 // Plate 324 cube([matrix_back_side, matrix_side+panel_depth+matrix_back_border*2, board_thickness]); 325 // Screw holes for bottom 326 translate([matrix_back_border/2, matrix_back_border/2, 0]) 327 cylinder(h=board_thickness, d=bottom_screw_hole, 328 center=false); 329 translate([matrix_back_side-matrix_back_border/2, matrix_back_border/2, 0]) 330 cylinder(h=board_thickness, d=bottom_screw_hole, 331 center=false); 332 translate([matrix_back_border/2, 333 matrix_side+panel_depth+matrix_back_border*1.5, 0]) 334 cylinder(h=board_thickness, d=bottom_screw_hole, 335 center=false); 336 translate([matrix_back_side-matrix_back_border/2, 337 matrix_side+panel_depth+matrix_back_border*1.5, 0]) 338 cylinder(h=board_thickness, d=bottom_screw_hole, 339 center=false); 340 } 341 } 342 // Screw holes for circuit holder and icestick 343 circuit_board_holder_mount_holes(); 344 icestick_strap_mount_holes(); 345 } 346 } 347 348 module circuit_board_vitamin() { 349 translate([(matrix_back_side-circuit_board_width)/2, 350 0, 351 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 352 cube([circuit_board_width, circuit_board_depth, circuit_board_height]); 353 } 354 } 355 356 module circuit_board_holder_mount_holes() { 357 translate([(matrix_back_side-circuit_board_width)/2-10, 358 -10, 359 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 360 translate([10, 5, -board_thickness]) { 361 cylinder(h=2+board_thickness, d=matrix_back_screw_hole, center=false); 362 } 363 translate([10, circuit_board_depth+15, -board_thickness]) { 364 cylinder(h=2+board_thickness, d=matrix_back_screw_hole, center=false); 365 } 366 } 367 translate([(matrix_back_side+circuit_board_width)/2-10, 368 -10, 369 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 370 translate([10, 5, -board_thickness]) { 371 cylinder(h=2+board_thickness, d=matrix_back_screw_hole, center=false); 372 } 373 translate([10, circuit_board_depth+15, -board_thickness]) { 374 cylinder(h=2+board_thickness, d=matrix_back_screw_hole, center=false); 375 } 376 } 377 } 378 379 module circuit_board_holder() { 380 difference() { 381 // From left and right holders ... 382 union() { 383 // Left holder 384 translate([(matrix_back_side-circuit_board_width)/2-10, 385 -10, 386 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 387 cube([20, circuit_board_depth+20, 2]); 388 } 389 // Right holder 390 translate([(matrix_back_side+circuit_board_width)/2-10, 391 -10, 392 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 393 cube([20, circuit_board_depth+20, 2]); 394 } 395 } 396 union () { 397 // ... remove mount holes ... 398 circuit_board_holder_mount_holes(); 399 // ... remove the edges of the circuit board 400 circuit_board_vitamin(); 401 } 402 } 403 } 404 405 module icestick_base() { 406 translate([matrix_back_side-icestick_base_width-20, 407 circuit_board_depth+usb_width*2, 408 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 409 cube([icestick_base_width, usb_width, icestick_base_height]); 410 } 411 }; 412 413 module icestick_strap() { 414 difference() { 415 translate([matrix_back_side-icestick_strap_width*2, 416 circuit_board_depth+usb_width*2.5-icestick_strap_depth/2, 417 -box_height+bottom_panel_height+board_thickness*3+matrix_height]) { 418 cube([icestick_strap_width, icestick_strap_depth, icestick_strap_height]); 419 } 420 icestick_strap_mount_holes(); 421 } 422 }; 423 424 module icestick_strap_mount_holes() { 425 translate([matrix_back_side-icestick_strap_width*1.5, 426 circuit_board_depth+usb_width*2.5-icestick_strap_depth/2.5, 427 -box_height+bottom_panel_height+board_thickness*2+matrix_height]) { 428 cylinder(h=board_thickness+icestick_strap_height, d=matrix_back_screw_hole, center=false); 429 } 430 translate([matrix_back_side-icestick_strap_width*1.5, 431 circuit_board_depth+usb_width*2.5+icestick_strap_depth/2.5, 432 -box_height+bottom_panel_height+board_thickness*2+matrix_height]) { 433 cylinder(h=board_thickness+icestick_strap_height, d=matrix_back_screw_hole, center=false); 434 } 435 }; 436 437 mode = "all"; 438 // mode = "acryl_top_plate"; 439 // mode = "matrix"; 440 // mode = "matrix_back"; 441 // mode = "control_panel"; 442 // mode = "box_left_side"; 443 // mode = "box_right_side"; 444 // mode = "box_front"; 445 // mode = "box_back"; 446 // mode = "bottom_screw_mount_front"; 447 // mode = "bottom_screw_mount_back"; 448 // mode = "box_bottom"; 449 // mode = "circuit_board_holder"; 450 // mode = "icestick_base"; 451 // mode = "icestick_strap"; 452 453 454 if (mode == "all") { 455 acryl_top_plate(); 456 matrix(); 457 matrix_back(); 458 control_panel(); 459 box_left_side(); 460 box_right_side(); 461 box_front(); 462 box_back(); 463 bottom_screw_mount_front(); 464 bottom_screw_mount_back(); 465 box_bottom(); 466 circuit_board_holder(); 467 icestick_base(); 468 icestick_strap(); 469 } 470 471 if (mode == "acryl_top_plate") { 472 projection() 473 acryl_top_plate(); 474 } 475 if (mode == "matrix") { 476 projection() 477 matrix(); 478 } 479 if (mode == "matrix_back") { 480 projection() 481 matrix_back(); 482 } 483 if (mode == "control_panel") { 484 projection() 485 control_panel(); 486 } 487 if (mode == "box_left_side") { 488 projection() 489 rotate([0, 90, 0]) 490 box_left_side(); 491 } 492 if (mode == "box_right_side") { 493 projection() 494 rotate([0, -90, 0]) 495 box_right_side(); 496 } 497 if (mode == "box_front") { 498 projection() 499 rotate([-90, 0, 0]) 500 box_front(); 501 } 502 if (mode == "box_back") { 503 projection() 504 rotate([90, 0, 0]) 505 box_back(); 506 } 507 if (mode == "bottom_screw_mount_front") { 508 projection() 509 bottom_screw_mount_front(); 510 } 511 if (mode == "bottom_screw_mount_back") { 512 projection() 513 bottom_screw_mount_back(); 514 } 515 if (mode == "box_bottom") { 516 projection() 517 rotate([180, 0, 0]) 518 box_bottom(); 519 } 520 if (mode == "circuit_board_holder") { 521 circuit_board_holder(); 522 } 523 if (mode == "icestick_base") { 524 icestick_base(); 525 } 526 if (mode == "icestick_strap") { 527 icestick_strap(); 528 } 529 530 // Acryl top plates with markings for LED matrix. We use this as a 531 // template to add labels to the top plate. 532 /* 533 projection() 534 difference() { 535 acryl_top_plate(); 536 union() { 537 matrix(); 538 translate([0,0,2]) matrix(); 539 translate([0,0,4]) matrix(); 540 } 541 } 542 */