]> git.scottworley.com Git - tattlekey/commitdiff
housing: Start
authorScott Worley <scottworley@scottworley.com>
Sat, 7 Oct 2023 08:18:21 +0000 (01:18 -0700)
committerScott Worley <scottworley@scottworley.com>
Wed, 11 Oct 2023 01:47:49 +0000 (18:47 -0700)
housing/cherryVoid.scad [new file with mode: 0644]
housing/roundedCube.scad [new file with mode: 0644]
housing/tattlekey.scad [new file with mode: 0644]

diff --git a/housing/cherryVoid.scad b/housing/cherryVoid.scad
new file mode 100644 (file)
index 0000000..419af34
--- /dev/null
@@ -0,0 +1,51 @@
+// Retrieved from https://www.thingiverse.com/thing:4120804
+
+// Riskable's Cherry MX void/cutout module for making keyboard (top) plates and key switch testers
+
+$fn = 32;
+
+use <roundedCube.scad> // Because it's nice to have rounded corners on these sorts of things
+
+// AUTHOR: Riskable <riskable@youknowwhat.com>
+// VERSION: 1.1 (Changelog is at the bottom)
+// LICENSE: Creative Commons - Attribution - Non-Commercial (if you want to use it in a commercial setting/product just ask!)
+
+// NOTES
+/*
+    * Feel free to use this .scad in your own projects to add proper Cherry MX-styled switch cutouts to keyboards, perhipherals, testers, or whatever you like.
+    * You can just copy cherry_switch_void() into your own code if you like--it's entirely self-contained and reasonably small.  Just make sure to credit, "This module was written by Riskable:" or something like that =)
+*/
+
+/* Creates the shape of a (proper) Cherry MX switch hole.
+    height: The thickness, really.  Doesn't impact PLATE_THICKNESS
+    x_extra: Extra (void) space on the X axis (e.g. to save some plastic). Doesn't change the top plate.
+    y_extra: Extra (void) space on the Y axis.  Same thing as X.
+    tolerance: Extra room on all sides (0.1 default should be good for most printers)
+    plate_thickness: How thick the top plate will be. Typical Cherry MX plates are about 1.5mm thick.
+*/
+module cherry_switch_void(height=12, x_extra=0, y_extra=0, tolerance=0.1, plate_thickness=1.5, corner_radius=0.5) { // Cherry MX body is supposed to be 11.6mm
+    switch_width = 15.6;
+    switch_length = 14; // Slightly shorter because we're making an acurate profile (see below)
+    center_space = 3.5; // Space between the cutouts on the sides of the switch
+    sides_width = (5+center_space); // Taken from the Cherry MX developer PDF
+    // Make the basic switch shape:
+    cube(
+        [switch_length+tolerance, switch_length+tolerance, height],
+        center=true);
+    // Profile for the sides:
+    translate([0,sides_width/2,0])
+        cube([switch_width-tolerance, center_space+tolerance, height], center=true);
+    translate([0,-sides_width/2,0])
+        cube([switch_width-tolerance,center_space+tolerance, height], center=true);
+    // Fill out the rest with a solid cube so that there's a top plate + empty space beneath
+    translate([0,0,plate_thickness])
+        roundedCube(
+            [switch_width+x_extra, switch_width+y_extra, height],
+            r=corner_radius, center=true);
+}
+
+/*
+CHANGELOG:
+    1.1: Now using roundedCube so the interior edges aren't so sharp.
+    1.0: Initial release
+*/
diff --git a/housing/roundedCube.scad b/housing/roundedCube.scad
new file mode 100644 (file)
index 0000000..262665d
--- /dev/null
@@ -0,0 +1,114 @@
+// Retrieved from https://www.thingiverse.com/thing:4120804
+
+/*
+       roundedCube() v1.0.3 by robert@cosmicrealms.com from https://github.com/Sembiance/openscad-modules
+       Allows you to round any edge of a cube
+       
+       Usage
+       =====
+       Prototype: roundedCube(dim, r, x, y, z, xcorners, ycorners, zcorners, $fn)
+       Arguments:
+               -      dim = Array of x,y,z numbers representing cube size
+               -        r = Radius of corners. Default: 1
+               -        x = Round the corners along the X axis of the cube. Default: false
+               -        y = Round the corners along the Y axis of the cube. Default: false
+               -        z = Round the corners along the Z axis of the cube. Default: true
+               - xcorners = Array of 4 booleans, one for each X side of the cube, if true then round that side. Default: [true, true, true, true]
+               - ycorners = Array of 4 booleans, one for each Y side of the cube, if true then round that side. Default: [true, true, true, true]
+               - zcorners = Array of 4 booleans, one for each Z side of the cube, if true then round that side. Default: [true, true, true, true]
+               -       rx = Radius of the x corners. Default: [r, r, r, r]
+               -       ry = Radius of the y corners. Default: [r, r, r, r]
+               -       rz = Radius of the z corners. Default: [r, r, r, r]
+               -   center = Whether to render the cube centered or not. Default: false
+               -      $fn = How smooth you want the rounding to be. Default: 128
+
+       Change Log
+       ==========
+       2018-08-21: v1.0.3 - Added ability to set the radius of each corner individually with vectors: rx, ry, rz
+       2017-05-15: v1.0.2 - Fixed bugs relating to rounding corners on the X axis
+       2017-04-22: v1.0.1 - Added center option
+       2017-01-04: v1.0.0 - Initial Release
+
+       Thanks to Sergio Vilches for the initial code inspiration
+*/
+
+// Example code:
+
+/*cube([5, 10, 4]);
+
+translate([8, 0, 0]) { roundedCube([5, 10, 4], r=1); }
+translate([16, 0, 0]) { roundedCube([5, 10, 4], r=1, zcorners=[true, false, true, false]); }
+
+translate([24, 0, 0]) { roundedCube([5, 10, 4], r=1, y=true, z=false); }
+translate([32, 0, 0]) { roundedCube([5, 10, 4], r=1, x=true, z=false); }
+translate([40, 0, 0]) { roundedCube([5, 10, 4], r=1, x=true, y=true, z=true); }
+*/
+
+module roundedCube(dim, r=1, x=false, y=false, z=true, xcorners=[true,true,true,true], ycorners=[true,true,true,true], zcorners=[true,true,true,true], center=false, rx=[undef, undef, undef, undef], ry=[undef, undef, undef, undef], rz=[undef, undef, undef, undef], $fn=128)
+{
+       translate([(center==true ? (-(dim[0]/2)) : 0), (center==true ? (-(dim[1]/2)) : 0), (center==true ? (-(dim[2]/2)) : 0)])
+       {
+               difference()
+               {
+                       cube(dim);
+
+                       if(z)
+                       {
+                               translate([0, 0, -0.1])
+                               {
+                                       if(zcorners[0])
+                                               translate([0, dim[1]-(rz[0]==undef ? r : rz[0])]) { rotateAround([0, 0, 90], [(rz[0]==undef ? r : rz[0])/2, (rz[0]==undef ? r : rz[0])/2, 0]) { meniscus(h=dim[2], r=(rz[0]==undef ? r : rz[0]), fn=$fn); } }
+                                       if(zcorners[1])
+                                               translate([dim[0]-(rz[1]==undef ? r : rz[1]), dim[1]-(rz[1]==undef ? r : rz[1])]) { meniscus(h=dim[2], r=(rz[1]==undef ? r : rz[1]), fn=$fn); }
+                                       if(zcorners[2])
+                                               translate([dim[0]-(rz[2]==undef ? r : rz[2]), 0]) { rotateAround([0, 0, -90], [(rz[2]==undef ? r : rz[2])/2, (rz[2]==undef ? r : rz[2])/2, 0]) { meniscus(h=dim[2], r=(rz[2]==undef ? r : rz[2]), fn=$fn); } }
+                                       if(zcorners[3])
+                                               rotateAround([0, 0, -180], [(rz[3]==undef ? r : rz[3])/2, (rz[3]==undef ? r : rz[3])/2, 0]) { meniscus(h=dim[2], r=(rz[3]==undef ? r : rz[3]), fn=$fn); }
+                               }
+                       }
+
+                       if(y)
+                       {
+                               translate([0, -0.1, 0])
+                               {
+                                       if(ycorners[0])
+                                               translate([0, 0, dim[2]-(ry[0]==undef ? r : ry[0])]) { rotateAround([0, 180, 0], [(ry[0]==undef ? r : ry[0])/2, 0, (ry[0]==undef ? r : ry[0])/2]) { rotateAround([-90, 0, 0], [0, (ry[0]==undef ? r : ry[0])/2, (ry[0]==undef ? r : ry[0])/2]) { meniscus(h=dim[1], r=(ry[0]==undef ? r : ry[0])); } } }
+                                       if(ycorners[1])
+                                               translate([dim[0]-(ry[1]==undef ? r : ry[1]), 0, dim[2]-(ry[1]==undef ? r : ry[1])]) { rotateAround([0, -90, 0], [(ry[1]==undef ? r : ry[1])/2, 0, (ry[1]==undef ? r : ry[1])/2]) { rotateAround([-90, 0, 0], [0, (ry[1]==undef ? r : ry[1])/2, (ry[1]==undef ? r : ry[1])/2]) { meniscus(h=dim[1], r=(ry[1]==undef ? r : ry[1])); } } }
+                                       if(ycorners[2])
+                                               translate([dim[0]-(ry[2]==undef ? r : ry[2]), 0]) { rotateAround([-90, 0, 0], [0, (ry[2]==undef ? r : ry[2])/2, (ry[2]==undef ? r : ry[2])/2]) { meniscus(h=dim[1], r=(ry[2]==undef ? r : ry[2])); } }
+                                       if(ycorners[3])
+                                               rotateAround([0, 90, 0], [(ry[3]==undef ? r : ry[3])/2, 0, (ry[3]==undef ? r : ry[3])/2]) { rotateAround([-90, 0, 0], [0, (ry[3]==undef ? r : ry[3])/2, (ry[3]==undef ? r : ry[3])/2]) { meniscus(h=dim[1], r=(ry[3]==undef ? r : ry[3])); } }
+                               }
+                       }
+
+                       if(x)
+                       {
+                               translate([-0.1, 0, 0])
+                               {
+                                       if(xcorners[0])
+                                               translate([0, dim[1]-(rx[0]==undef ? r : rx[0])]) { rotateAround([0, 90, 0], [(rx[0]==undef ? r : rx[0])/2, 0, (rx[0]==undef ? r : rx[0])/2]) { meniscus(h=dim[0], r=(rx[0]==undef ? r : rx[0])); } }
+                                       if(xcorners[1])
+                                               translate([0, dim[1]-(rx[1]==undef ? r : rx[1]), dim[2]-(rx[1]==undef ? r : rx[1])]) { rotateAround([90, 0, 0], [0, (rx[1]==undef ? r : rx[1])/2, (rx[1]==undef ? r : rx[1])/2]) { rotateAround([0, 90, 0], [(rx[1]==undef ? r : rx[1])/2, 0, (rx[1]==undef ? r : rx[1])/2]) { meniscus(h=dim[0], r=(rx[1]==undef ? r : rx[1])); } } }
+                                       if(xcorners[2])
+                                               translate([0, 0, dim[2]-(rx[2]==undef ? r : rx[2])]) { rotateAround([180, 0, 0], [0, (rx[2]==undef ? r : rx[2])/2, (rx[2]==undef ? r : rx[2])/2]) { rotateAround([0, 90, 0], [(rx[2]==undef ? r : rx[2])/2, 0, (rx[2]==undef ? r : rx[2])/2]) { meniscus(h=dim[0], r=(rx[2]==undef ? r : rx[2])); } } }
+                                       if(xcorners[3])
+                                               rotateAround([-90, 0, 0], [0, (rx[3]==undef ? r : rx[3])/2, (rx[3]==undef ? r : rx[3])/2]) { rotateAround([0, 90, 0], [(rx[3]==undef ? r : rx[3])/2, 0, (rx[3]==undef ? r : rx[3])/2]) { meniscus(h=dim[0], r=(rx[3]==undef ? r : rx[3])); } }
+                               }
+                       }
+               }
+       }
+}
+
+module meniscus(h, r, fn=128)
+{
+       $fn=fn;
+
+       difference()
+       {
+               cube([r+0.2, r+0.2, h+0.2]);
+               translate([0, 0, -0.1]) { cylinder(h=h+0.4, r=r); }
+       }
+}
+
+module rotateAround(a, v) { translate(v) { rotate(a) { translate(-v) { children(); } } } }
diff --git a/housing/tattlekey.scad b/housing/tattlekey.scad
new file mode 100644 (file)
index 0000000..f117e27
--- /dev/null
@@ -0,0 +1,130 @@
+use <cherryVoid.scad>
+
+key_interface_size = 19;
+key_interface_corner_r = 5;
+
+housing_inner_h = 10; // Chosen to let board fit inside
+housing_inner_w = 21;
+
+thickness = 1.7;
+
+wiring_l = 12;
+
+pico_board_l = 51.0;
+pico_board_w = 21.0;
+pico_total_h = 3.7;
+
+$fs = .1;
+$fa = 6;
+
+slop = 128;
+epsilon = 1/64;
+
+module pico_hole(d, x, y) {
+    translate([x, y, -slop/2])
+    cylinder(h=slop, d = d);
+}
+
+module pico_w(hole_d = 2.1) {    
+    board_l = pico_board_l;
+    board_w = pico_board_w;
+    board_h = 1.0;
+    
+    hole_x1 = 2.0;
+    hole_x2 = board_l - 2.0;
+    hole_y_spacing = 11.4;
+    hole_y = (board_w - hole_y_spacing)/2;
+    
+    difference() {
+        color("green")
+        cube([board_l, board_w, board_h]);
+
+        pico_hole(hole_d, hole_x1, hole_y);
+        pico_hole(hole_d, hole_x2, hole_y);
+        pico_hole(hole_d, hole_x1, hole_y + hole_y_spacing);
+        pico_hole(hole_d, hole_x2, hole_y + hole_y_spacing);
+        
+    }
+    
+    total_l = 52.3;
+    total_h = pico_total_h;
+    usb_w = 8.0;
+    usb_l = 5.6;
+    usb_h = 3.0;
+    color("lightgray")
+    translate([board_l - total_l, (board_w-usb_w)/2, total_h-usb_h])
+    cube([usb_l, usb_w, usb_h]);
+    
+    button_l = 4.2;
+    button_w = 3.4;
+    button_h = 3.5;
+    button_x = 9.9;
+    button_y = 5.2;
+    color("white")
+    translate([button_x, button_y, epsilon])
+    cube([button_l, button_w, button_h]);
+    
+    wifi_l = 10.0;
+    wifi_w = 12.0;
+    wifi_h = 2.8;
+    wifi_x = 33.0;
+    color("lightgray")
+    translate([wifi_x, (board_w-wifi_w)/2, epsilon])
+    cube([wifi_l, wifi_w, wifi_h]);
+}
+
+module at_key() {
+    translate([pico_board_l + wiring_l, 0, 0])
+    rotate([45, 0, 0])
+    rotate([0, 90, 0])
+    children();
+}
+
+module key_interface_shape(thick = thickness) {
+    inner = key_interface_size - 2*key_interface_corner_r;
+    linear_extrude(thick)
+    minkowski() {
+        square([inner, inner], center=true);
+        circle(r=key_interface_corner_r);
+    }
+}
+
+module key_interface() {
+    at_key()
+    difference() {
+        key_interface_shape();
+        
+        #translate([0, 0, 6 - epsilon])
+        cherry_switch_void();
+    }
+}
+
+module housing(length = pico_board_l) {
+    inner_squish = housing_inner_h / housing_inner_w;
+    housing_outer_w = housing_inner_w + 2 * thickness;
+    housing_outer_h = housing_inner_h + 2 * thickness;
+    outer_squish = housing_outer_h / housing_outer_w;
+    rotate([90, 0, 0])
+    rotate([0, 90, 0])
+    linear_extrude(length)
+    difference() {
+        scale([1, outer_squish])
+        circle(d = housing_outer_w);
+        scale([1, inner_squish])
+        circle(d = housing_inner_w);
+    }
+}
+
+/*
+!union() {housing(); hull() {
+    at_key() key_interface_shape(epsilon);
+    translate([pico_board_l-wiring_l, 0, 0])
+    housing(wiring_l);
+}}
+*/
+
+translate([0, -pico_board_w/2, -1])
+pico_w(hole_d = 2);
+
+key_interface();
+housing();