2023-11-11 14:21:39 -05:00
|
|
|
$fn = 72;
|
2023-11-11 04:28:53 -05:00
|
|
|
|
2023-11-15 13:03:23 -05:00
|
|
|
include <keyboard.scad>
|
2023-11-13 15:14:25 -05:00
|
|
|
|
2023-11-13 15:39:20 -05:00
|
|
|
module keyboard_base_plate(pcb_dimensions, pcb_screw_holes, switch_z_range) {
|
2023-11-13 15:14:25 -05:00
|
|
|
pcb_width = pcb_dimensions[0];
|
|
|
|
pcb_length = pcb_dimensions[1];
|
|
|
|
pcb_height = pcb_dimensions[2];
|
|
|
|
|
|
|
|
switch_z_min = switch_z_range[0];
|
|
|
|
switch_z_max = switch_z_range[1];
|
2023-11-11 19:47:32 -05:00
|
|
|
|
2023-11-11 14:21:39 -05:00
|
|
|
pcb_clearance_edge = 1.0;
|
2023-11-13 15:14:25 -05:00
|
|
|
pcb_clearance_bottom = -switch_z_min - pcb_height + 0.5;
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-14 18:52:26 -05:00
|
|
|
pcb_screw_diameter = 2.5;
|
|
|
|
pcb_screw_hole_diameter = 2.5;
|
2023-11-13 15:14:25 -05:00
|
|
|
pcb_screw_height = 3.0;
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 02:47:45 -05:00
|
|
|
thickness = 1.75;
|
2023-11-13 12:54:41 -05:00
|
|
|
corner_radius = 0.2;
|
2023-11-11 04:24:21 -05:00
|
|
|
|
2023-11-12 02:47:45 -05:00
|
|
|
case_color = [0.5, 0.5, 0.5, 1.0];
|
|
|
|
|
2023-11-12 23:09:49 -05:00
|
|
|
wall_width = pcb_width + 2 * (pcb_clearance_edge + thickness) - 2 * corner_radius;
|
|
|
|
wall_length = pcb_length + 2 * (pcb_clearance_edge + thickness) - 2 * corner_radius;
|
2023-11-13 15:14:25 -05:00
|
|
|
wall_height = pcb_screw_height + pcb_height + switch_z_max;
|
2023-11-12 21:33:04 -05:00
|
|
|
|
2023-11-12 21:57:41 -05:00
|
|
|
bottom_width = 2 * (pcb_clearance_edge) + pcb_width;
|
|
|
|
bottom_length = 2 * (pcb_clearance_edge) + pcb_length;
|
|
|
|
bottom_height = thickness;
|
2023-11-12 01:06:25 -05:00
|
|
|
|
2023-11-14 12:10:29 -05:00
|
|
|
module round_corner(rotation) {
|
2023-11-12 01:06:25 -05:00
|
|
|
color(case_color)
|
2023-11-11 14:21:39 -05:00
|
|
|
rotate(rotation)
|
|
|
|
rotate_extrude(angle=90) {
|
|
|
|
intersection() {
|
|
|
|
circle(r=corner_radius);
|
|
|
|
square(corner_radius*2);
|
|
|
|
}
|
2023-11-11 04:24:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:10:29 -05:00
|
|
|
module round_edge(rotation, length) {
|
2023-11-12 01:06:25 -05:00
|
|
|
color(case_color)
|
2023-11-11 14:21:39 -05:00
|
|
|
rotate(rotation)
|
|
|
|
linear_extrude(length)
|
2023-11-11 04:24:21 -05:00
|
|
|
intersection() {
|
2023-11-11 04:28:53 -05:00
|
|
|
circle(r=corner_radius);
|
|
|
|
square(corner_radius*2);
|
2023-11-11 04:24:21 -05:00
|
|
|
}
|
|
|
|
}
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-14 12:10:29 -05:00
|
|
|
module panel(dimensions) {
|
2023-11-12 01:06:25 -05:00
|
|
|
color(case_color)
|
2023-11-11 18:12:21 -05:00
|
|
|
linear_extrude(dimensions[2])
|
|
|
|
square([dimensions[0], dimensions[1]], false);
|
|
|
|
}
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-14 12:10:29 -05:00
|
|
|
module wall_corner(rotation, radius, length) {
|
2023-11-12 01:06:25 -05:00
|
|
|
color(case_color)
|
2023-11-11 18:53:21 -05:00
|
|
|
rotate(rotation)
|
|
|
|
linear_extrude(length)
|
|
|
|
intersection() {
|
|
|
|
circle(r=radius);
|
|
|
|
square([radius, radius], false);
|
|
|
|
}
|
|
|
|
}
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-14 12:10:29 -05:00
|
|
|
module screw_post(h, d) {
|
2023-11-13 15:14:25 -05:00
|
|
|
diameter_outer = 3 * d;
|
|
|
|
diameter_inner = d;
|
|
|
|
|
2023-11-12 01:06:25 -05:00
|
|
|
color(case_color)
|
2023-11-11 19:47:32 -05:00
|
|
|
difference() {
|
2023-11-13 15:14:25 -05:00
|
|
|
cylinder(h=h, r1 = (diameter_outer / 2.0) * 1.5);
|
|
|
|
cylinder(h=h, r = diameter_inner / 2.0);
|
2023-11-11 19:47:32 -05:00
|
|
|
}
|
|
|
|
}
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 21:19:19 -05:00
|
|
|
module ridges(width, height) {
|
2023-11-12 20:46:01 -05:00
|
|
|
horizontal = [
|
2023-11-12 21:13:58 -05:00
|
|
|
(bottom_length / 3),
|
|
|
|
(bottom_length / 3) * 2
|
2023-11-12 20:46:01 -05:00
|
|
|
];
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 20:46:01 -05:00
|
|
|
vertical = [
|
2023-11-12 21:19:19 -05:00
|
|
|
(bottom_width / 3),
|
|
|
|
(bottom_width / 3) * 2
|
2023-11-12 20:46:01 -05:00
|
|
|
];
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 20:46:01 -05:00
|
|
|
for (y = horizontal) {
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([0 - pcb_clearance_edge, y, 0])
|
|
|
|
panel([bottom_width, width, height]);
|
2023-11-12 20:46:01 -05:00
|
|
|
}
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 20:46:01 -05:00
|
|
|
for (x = vertical) {
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([x, 0 - pcb_clearance_edge, 0])
|
|
|
|
panel([width, bottom_length, height]);
|
2023-11-12 20:46:01 -05:00
|
|
|
}
|
|
|
|
}
|
2023-11-12 23:09:49 -05:00
|
|
|
|
|
|
|
/* Upper wall */
|
2023-11-14 12:10:29 -05:00
|
|
|
|
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
pcb_clearance_edge + pcb_length,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
panel([wall_width, thickness, wall_height + thickness - corner_radius]);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 23:09:49 -05:00
|
|
|
/* Right wall */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([ pcb_clearance_edge + pcb_width,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
panel([thickness, wall_length, wall_height + thickness - corner_radius]);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 23:09:49 -05:00
|
|
|
/* Lower wall */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
panel([wall_width, thickness, wall_height + thickness - corner_radius]);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 23:09:49 -05:00
|
|
|
/* Left wall */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
panel([thickness, wall_length, wall_height + thickness - corner_radius]);
|
2023-11-12 23:09:49 -05:00
|
|
|
|
2023-11-12 23:17:10 -05:00
|
|
|
/* Upper right wall corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([pcb_clearance_edge + thickness + pcb_width - corner_radius,
|
|
|
|
pcb_clearance_edge + thickness + pcb_length - corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
wall_corner([0, 0, 0],
|
2023-11-12 23:17:10 -05:00
|
|
|
corner_radius,
|
2023-11-12 23:33:01 -05:00
|
|
|
wall_height + thickness - corner_radius);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 23:17:10 -05:00
|
|
|
/* Lower right wall corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([ pcb_clearance_edge + thickness + pcb_width - corner_radius,
|
2023-11-13 15:35:09 -05:00
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
2023-11-14 12:10:29 -05:00
|
|
|
-thickness + corner_radius])
|
|
|
|
wall_corner([0, 0, 270],
|
2023-11-12 23:17:10 -05:00
|
|
|
corner_radius,
|
2023-11-12 23:33:01 -05:00
|
|
|
wall_height + thickness - corner_radius);
|
2023-11-12 23:17:10 -05:00
|
|
|
|
|
|
|
/* Lower left wall corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
wall_corner([0, 0, 180],
|
2023-11-12 23:17:10 -05:00
|
|
|
corner_radius,
|
2023-11-12 23:33:01 -05:00
|
|
|
wall_height + thickness - corner_radius);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 23:17:10 -05:00
|
|
|
/* Upper left wall corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
pcb_clearance_edge + pcb_length + thickness - corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
wall_corner([0, 0, 90],
|
2023-11-12 23:17:10 -05:00
|
|
|
corner_radius,
|
2023-11-12 23:33:01 -05:00
|
|
|
wall_height + thickness - corner_radius);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 23:33:01 -05:00
|
|
|
/* Bottom plate */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness])
|
|
|
|
panel([bottom_width + 2 * thickness - 2 * corner_radius,
|
2023-11-13 00:44:16 -05:00
|
|
|
bottom_length + 2 * thickness - 2 * corner_radius,
|
|
|
|
thickness]);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-11 18:12:21 -05:00
|
|
|
/* Upper edge */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
pcb_clearance_edge + thickness + pcb_length - corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_edge([0, 90, 0], wall_width);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-11 14:21:39 -05:00
|
|
|
/* Right edge */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([ pcb_clearance_edge + thickness + pcb_width - corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_edge([270, 0, 0], wall_length);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-11 18:12:21 -05:00
|
|
|
/* Lower edge */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_edge([90, 180, 90], wall_width);
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-11 14:21:39 -05:00
|
|
|
/* Left edge */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_edge([270, 90, 0], wall_length);
|
2023-11-11 14:21:39 -05:00
|
|
|
|
2023-11-12 23:33:01 -05:00
|
|
|
/* Upper right corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([pcb_clearance_edge + thickness + pcb_width - corner_radius,
|
|
|
|
pcb_clearance_edge + thickness + pcb_length - corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_corner([90, 90, 90]);
|
2023-11-12 23:33:01 -05:00
|
|
|
|
|
|
|
/* Lower right corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([ pcb_clearance_edge + thickness + pcb_width - corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_corner([180, 90, 90]);
|
2023-11-12 23:33:01 -05:00
|
|
|
|
|
|
|
/* Lower left corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_corner([-90, 90, 90]);
|
2023-11-12 23:33:01 -05:00
|
|
|
|
|
|
|
/* Upper left corner */
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([-pcb_clearance_edge - thickness + corner_radius,
|
|
|
|
pcb_clearance_edge + thickness + pcb_length - corner_radius,
|
|
|
|
-thickness + corner_radius])
|
|
|
|
round_corner([0, 90, 90]);
|
2023-11-12 23:33:01 -05:00
|
|
|
|
2023-11-11 19:47:32 -05:00
|
|
|
/* Screw holes */
|
2023-11-13 15:39:20 -05:00
|
|
|
for (screw_hole = pcb_screw_holes) {
|
2023-11-14 12:10:29 -05:00
|
|
|
translate([screw_hole[0], screw_hole[1], 0])
|
|
|
|
screw_post(pcb_screw_height,
|
2023-11-13 15:14:25 -05:00
|
|
|
pcb_screw_diameter);
|
2023-11-12 23:41:46 -05:00
|
|
|
}
|
2023-11-12 23:57:34 -05:00
|
|
|
|
2023-11-12 21:19:19 -05:00
|
|
|
/* Ridges (for rigidity!) */
|
|
|
|
ridges(thickness * 2, pcb_clearance_bottom / 2);
|
2023-11-11 14:21:39 -05:00
|
|
|
}
|
|
|
|
|
2023-11-15 13:03:23 -05:00
|
|
|
keyboard_base_plate([keyboard_pcb_width, keyboard_pcb_length, keyboard_pcb_height],
|
|
|
|
keyboard_pcb_screw_holes,
|
|
|
|
[-keyboard_switch_leg_length, keyboard_switch_height]);
|