This commit is contained in:
Ricardo (XenGi) Band 2023-05-24 23:53:03 +02:00
commit bbad6e3bad
No known key found for this signature in database
30 changed files with 580 additions and 13 deletions

16
.editorconfig Normal file
View file

@ -0,0 +1,16 @@
# EditorConfig is awesome: https://EditorConfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
[*.scad]
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab

86
.gitignore vendored
View file

@ -1,10 +1,82 @@
.idea/
*.gcode
*.stl *.stl
*.3mf *.3mf
*.amf *.amf
*.scad *.gcode
__pycache__/
*.pyc # Created by https://www.toptal.com/developers/gitignore/api/windows,linux,macos
.venv # Edit at https://www.toptal.com/developers/gitignore?templates=windows,linux,macos
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,macos

View file

@ -24,7 +24,8 @@ from mkbd65.util import PCB_WIDTH
@click.argument("config_file") @click.argument("config_file")
def cli(layout, variant, stl, emf, amf, detail, config_file): def cli(layout, variant, stl, emf, amf, detail, config_file):
if layout == "ansi" and variant == "de": if layout == "ansi" and variant == "de":
click.echo("There is no german ansi variant. German keyboards need one more key and therefore use the ISO layout.") click.echo("There is no german ansi variant. German keyboards need one more key and therefore use the ISO "
"layout.")
sys.exit() sys.exit()
config = ConfigParser() config = ConfigParser()

View file

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before After
Before After

View file

@ -1,4 +1,4 @@
from solid import OpenSCADObject, translate, minkowski, cube, cylinder from solid import OpenSCADObject, translate, minkowski, cube, cylinder, linear_extrude, hull, circle, square
def _generic_bump(width: float, height: float, thickness: float, radius: float) -> OpenSCADObject: def _generic_bump(width: float, height: float, thickness: float, radius: float) -> OpenSCADObject:
@ -24,3 +24,25 @@ def oneplus_8t() -> OpenSCADObject:
return translate(v=(6, 7, 0))( return translate(v=(6, 7, 0))(
_generic_bump(width=39, height=25, thickness=1, radius=5) _generic_bump(width=39, height=25, thickness=1, radius=5)
) )
def samsung_s22plus() -> OpenSCADObject:
"""
Camra bump of the Samsung S22+
:return:
"""
return linear_extrude(height=1)(
hull()(
circle(r=10),
translate(v=(20, 40, 0))(
circle(r=10)
),
translate(v=(20, 0, 0))(
square(size=(20, 20), center=True)
),
translate(v=(0, 40, 0))(
square(size=(20, 20), center=True)
)
)
)

View file

@ -0,0 +1,99 @@
"""
All sizes are in millimeters.
"""
from solid import OpenSCADObject, hull, translate, cylinder, intersection, sphere, scale
def lower_case(width: float, height: float) -> OpenSCADObject:
"""
Generates lower half of the case
:param width: length from top to bottom (landscape)
:param height: length from left to right (landscape)
:return:
"""
length = 160.7
width = 74.1
height = 5
radius = 5
corners = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
for x, y in corners:
hull()(
[scale(v=(sx, sy, 1))(
# upper cylindrical part
translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height - radius)
) if height > radius else None,
translate(v=(length / 2 - radius, width / 2 - radius, height - radius))(
sphere(r=radius)
) * translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height)
) if height < 2 * radius else None
) for sx in [-1, 1]]
)
for sx in [-1, 1]:
for sy in [-1, 1]:
scale(v=(sx, sy, 1))(
# upper cylindrical part
if height > radius:
translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height - radius)
)
# upper spheric part
intersection()(
# sphere
translate(v=(length / 2 - radius, width / 2 - radius, height - radius))(
sphere(r=radius)
),
# clip sphere at bottom plane
translate(v=(length / 2 - radius, width / 2 - radius, 0))(
cylinder(r=radius, h=height)
) if height < 2 * radius else None
)
)
return hull()(
)
return linear_extrude(height=thickness)(
round_rect(width=width, height=height, radius=corner_radius)
)
//hull() {
// for(sx=[-1,1]) {
// for(sy=[-1,1]) {
// scale([sx,sy,1]) {
// // lower cylindric part
// /*if(height>radius) {
// translate([length/2-radius,width/2-radius,0]) {
// cylinder(r=radius,h=height-radius);
// }
// }*/
// // upper spheric part
// intersection() {
// // sphere
// translate([length/2-radius,width/2-radius,height-radius]) {
// sphere(r=radius);
// }
// // clip sphere at bottom plane
// if(height<2*radius) {
// translate([length/2-radius,width/2-radius,0]) {
// cylinder(r=radius,h=height);
// }
// }
// }
// }
// }
// }
//}

BIN
OLD/poc/mechanism.skp Normal file

Binary file not shown.

2
OLD/requirements.txt Normal file
View file

@ -0,0 +1,2 @@
solidpython~=1.1
click~=8.1

18
OLD/samsung_s22plus.ini Normal file
View file

@ -0,0 +1,18 @@
# Samsung S22+
[phone]
width = 157.4
height = 75.8
thickness = 7.6
corner_radius = 10
side_radius = 0
[key_mat]
margin = 1
padding = 1
thickness = 0.5
key_width = 9
key_height = 6
key_corner_radius = 1
key_thickness = 2
font = DejaVu Sans:style=Bold

View file

@ -1,8 +1,50 @@
mkbd65 case mkbd65 case
=========== ===========
_The case for mkbd65 is still a work in progress!_ _The case and key set for mkbd65 is still a work in progress!_
This is the case for mkbd65. It is build using [OpenSCAD][openscad] to be able to generate multiple cases fitting
different phones from a single file.
Follow the guide at https://mkbd65.xengi.de to build a case for your phone.
## Generate a case
_TBA_
## Generate a key set
To generate the key set you can either use a predefined layout or generate your own. There are two predefined layouts
for English US International and German. You can generate the 3D files for them with the following commands:
```shell
make keys:en-us-intl
make keys:de
```
This will generate the neccessary 3MF and STL files that you can use for your 3D printers slicer software. I recommend a
flexible filament like Filaflex 95A for the best typing experience.
### Custom layout
If you want to build your own custom layout follow the instruction in the file `custom_keyset.scad`. It will explain how
to write the openscad code for a key set and generate the 3MF and STL files. You can use any of the keys from a 5x14
matrix and also combine them however you like. Remember that you have to duplicate the keys in the config of the QMK
software for every non 1x1 key too. Because electrically every switch is still a single unique key and gets detected as
such.
So if you want to create a 3x1 space bar at position (0, 5) you can create a key cap by using `key(x=0, y=5, w=3)`. In
the QMK config you have to create 3 distinct space bar keys next to each other.
In theory the maximum width of a key is 3. You can use more then that but the key will get sliced at different points to
avoid accidental duble presses of the switches underneath.
---
[openscad]: https://openscad.org
---
**old docs**
Generate CAD files Generate CAD files
------------------ ------------------
@ -50,7 +92,7 @@ OpenSCAD files
The generator script will create multiple files. The generator script will create multiple files.
| File | Material | Description | | File | Material | Description |
| ---------------------- | -------- | -------------------------------------- | |------------------------| -------- | -------------------------------------- |
| mkbd65_key_mat.scad | TPU | 3D printable | | mkbd65_key_mat.scad | TPU | 3D printable |
| mkbd65_pcb.scad | - | Just a spacer for the 3D model fitting | | mkbd65_pcb.scad | - | Just a spacer for the 3D model fitting |
| mkbd65_top_plate.scad | Acrylic | Laser cut on a CNC | | mkbd65_top_plate.scad | Acrylic | Laser cut on a CNC |

72
keyset_de.scad Normal file
View file

@ -0,0 +1,72 @@
// en-us-intl layout
use <lib/mat.scad>;
use <lib/key.scad>;
mat();
key(x=0, y=0, label="Esc");
key(x=1, y=0, label="1 !");
key(x=2, y=0, label="2 \"");
key(x=3, y=0, label="3 §");
key(x=4, y=0, label="4 $");
key(x=5, y=0, label="5 %");
key(x=6, y=0, label="6 &");
key(x=7, y=0, label="7 /");
key(x=8, y=0, label="8 (");
key(x=9, y=0, label="9 )");
key(x=10, y=0, label="0 =");
key(x=11, y=0, w=2, label="Bksp");
key(x=0, y=1, label="Q");
key(x=1, y=1, label="W");
key(x=2, y=1, label="E");
key(x=3, y=1, label="R");
key(x=4, y=1, label="T");
key(x=5, y=1, label="Z");
key(x=6, y=1, label="U");
key(x=7, y=1, label="I");
key(x=8, y=1, label="O");
key(x=9, y=1, label="P");
key(x=10, y=1, label="Ü");
key(x=11, y=1, label="+ *");
key(x=0, y=2, label="A");
key(x=1, y=2, label="S");
key(x=2, y=2, label="D");
key(x=3, y=2, label="F");
key(x=4, y=2, label="G");
key(x=5, y=2, label="H");
key(x=6, y=2, label="J");
key(x=7, y=2, label="K");
key(x=8, y=2, label="L");
key(x=9, y=2, label="Ö");
key(x=10, y=2, label="Ä");
key(x=11, y=2, h=2, label="Ret");
key(x=0, y=3, label="Y");
key(x=1, y=3, label="X");
key(x=2, y=3, label="C");
key(x=3, y=3, label="V");
key(x=4, y=3, label="B");
key(x=5, y=3, label="N");
key(x=6, y=3, label="M");
key(x=7, y=3, label=", ;");
key(x=8, y=3, label=". :");
key(x=9, y=3, label="- _");
key(x=10, y=3, label="Up");
key(x=11, y=3, label="< >");
key(x=12, y=3, label="Shift");
key(x=0, y=4, label="Ctrl");
key(x=1, y=4, label="Fn");
key(x=2, y=4, label="Shift");
key(x=3, y=4, label="Alt");
key(x=4, y=4, w=3, label="---"); // Space
key(x=7, y=4, label="ß ?");
key(x=8, y=4, label="´ `");
key(x=9, y=4, label="Left");
key(x=10, y=4, label="Down");
key(x=11, y=4, label="Right");
key(x=12, y=4, label="Ctrl");

72
keyset_en-us-intl.scad Normal file
View file

@ -0,0 +1,72 @@
// en-us-intl layout
use <lib/mat.scad>;
use <lib/key.scad>;
mat();
key(x=0, y=0, label="Esc");
key(x=1, y=0, label="1 !");
key(x=2, y=0, label="2 @");
key(x=3, y=0, label="3 #");
key(x=4, y=0, label="4 $");
key(x=5, y=0, label="5 %");
key(x=6, y=0, label="6 ^");
key(x=7, y=0, label="7 &");
key(x=8, y=0, label="8 *");
key(x=9, y=0, label="9 (");
key(x=10, y=0, label="0 )");
key(x=11, y=0, w=2, label="Bksp");
key(x=0, y=1, label="Q");
key(x=1, y=1, label="W");
key(x=2, y=1, label="E");
key(x=3, y=1, label="R");
key(x=4, y=1, label="T");
key(x=5, y=1, label="Y");
key(x=6, y=1, label="U");
key(x=7, y=1, label="I");
key(x=8, y=1, label="O");
key(x=9, y=1, label="P");
key(x=10, y=1, label="[ {");
key(x=11, y=1, label="] }");
key(x=12, y=1, label="\\ |");
key(x=0, y=2, label="A");
key(x=1, y=2, label="S");
key(x=2, y=2, label="D");
key(x=3, y=2, label="F");
key(x=4, y=2, label="G");
key(x=5, y=2, label="H");
key(x=6, y=2, label="J");
key(x=7, y=2, label="K");
key(x=8, y=2, label="L");
key(x=9, y=2, label="; :");
key(x=10, y=2, label="' \"");
key(x=11, y=2, w=2, label="Ret");
key(x=0, y=3, label="Z");
key(x=1, y=3, label="X");
key(x=2, y=3, label="C");
key(x=3, y=3, label="V");
key(x=4, y=3, label="B");
key(x=5, y=3, label="N");
key(x=6, y=3, label="M");
key(x=7, y=3, label=", <");
key(x=8, y=3, label=". >");
key(x=9, y=3, label="/ ?");
key(x=10, y=3, label="Up");
key(x=11, y=3, w=2, label="Shift");
key(x=0, y=4, label="Ctrl");
key(x=1, y=4, label="Fn");
key(x=2, y=4, label="Shift");
key(x=3, y=4, label="Alt");
key(x=4, y=4, w=3, label="---"); // Space
key(x=7, y=4, label="- _");
key(x=8, y=4, label="= +");
key(x=9, y=4, label="Left");
key(x=10, y=4, label="Down");
key(x=11, y=4, label="Right");
key(x=12, y=4, label="Ctrl");

24
lib/key.scad Normal file
View file

@ -0,0 +1,24 @@
// Generate a key cap at a specific position in the matrix
module key(x, y, w=1, h=1, label="") {
spacing_h = 1;
spacing_v = 1;
key_thickness = 1;
key_radius = 1;
key_width = 1;
key_height = 1;
mat_thickness = 1;
color("DarkSlateGray");
translate([x*spacing_h, y*spacing_v, mat_thickness]) difference() {
union() {
hull() {
translate([key_radius, key_radius, 0]) cylinder(h=key_thickness, r=key_radius);
translate([key_radius, key_height-key_radius, 0]) cylinder(h=key_thickness, r=key_radius);
translate([key_width-key_radius, key_radius, 0]) cylinder(h=key_thickness, r=key_radius);
translate([key_width-key_radius, key_height-key_radius, 0]) cylinder(h=key_thickness, r=key_radius);
}
}
// TODO: subtract label from key cap
}
}

37
lib/pcb.scad Normal file
View file

@ -0,0 +1,37 @@
$fn = 64;
pcb_radius = 5;
pcb_width = 147;
pcb_height = 65;
pcb_thickness = 1;
module switch() {
thickness = 0.8;
width = 6;
height = 4;
color("white") linear_extrude(thickness*0.7) polygon([[-width/2, 2.3/2], [-4.5/2, height/2], [4.5/2, height/2], [width/2, 2.3/2], [width/2, -2.3/2], [4.5/2, -height/2], [-4.5/2, -height/2], [-width/2, -2.3/2]]);
color("black") cylinder(h=thickness, d=1.2);
}
module pcb_body() {
color("purple") difference() {
hull() {
translate([-pcb_width/2+pcb_radius, -pcb_height/2+pcb_radius, 0]) cylinder(h=pcb_thickness, r=pcb_radius);
translate([pcb_width/2-pcb_radius, -pcb_height/2+pcb_radius, 0]) cylinder(h=pcb_thickness, r=pcb_radius);
translate([pcb_width/2-pcb_radius, pcb_height/2-pcb_radius, 0]) cylinder(h=pcb_thickness, r=pcb_radius);
translate([-pcb_width/2+pcb_radius, pcb_height/2-pcb_radius, 0]) cylinder(h=pcb_thickness, r=pcb_radius);
}
}
// switches
cols = 5;
rows = 13;
switch_spacing_h = 10;
switch_spacing_v = 7;
translate([-1*(rows*switch_spacing_h)/2+switch_spacing_h/2, -61+pcb_height/2, 0]) for(x=[0:rows-1]) {
for(y=[0:cols-1]) {
translate([x*switch_spacing_h, y*switch_spacing_v, pcb_thickness]) switch();
}
}
}

28
main.scad Normal file
View file

@ -0,0 +1,28 @@
$fn = 64;
// replace with your phone
include <phones/s22plus.scad>;
// phone_width
// phone_length
// phone_thickness
// phone_corner_rad
// phone_body
// camera_bump
use <lib/pcb.scad>;
//phone_body();
// upper case
upper_case_thickness = 2;
difference() {
translate([0,0,-upper_case_thickness]) hull() {
translate([-phone_width/2+phone_corner_rad, phone_length/2-phone_corner_rad, 0]) cylinder(h=upper_case_thickness, r=phone_corner_rad);
translate([-phone_width/2+phone_corner_rad, -phone_length/2+phone_corner_rad, 0]) cylinder(h=upper_case_thickness, r=phone_corner_rad);
translate([phone_width/2-phone_corner_rad, phone_length/2-phone_corner_rad, 0]) cylinder(h=upper_case_thickness, r=phone_corner_rad);
translate([phone_width/2-phone_corner_rad, -phone_length/2+phone_corner_rad, 0]) cylinder(h=upper_case_thickness, r=phone_corner_rad);
}
camera_bump();
}
// lower case

64
phones/s22plus.scad Normal file
View file

@ -0,0 +1,64 @@
/*
* Samsung Galaxy S22+
*
* Every phone file must expose the following variables and modules:
* - phone_width: the phone width in mm
* - phone_length: the phones length in mm
* - phone_thickness: the phones thickness in mm
* - phone_corner_rad: the radius of the phones corners in mm
* - phone_body: module creating the phones body centered around the origin
* - camera_bump: module creating the phones camera bump to cut it out from the case
*
* If you hold youphone in landscape the longer edge is considered it's width/x axis.
* The short edge is therefore the length/y axis. The thickness should be self explanatory.
*
* /\
* / \
* / \ x/width
* / \
* |\ \
* \\ \
* \\ /
* \\ /
* \\ / y/length
* \/
* z/thickness
*
* The phones main body (w/o camera bump) is centered on the x and y axis. The phones back
* is flat on the origin and not centered. The camera bump and other things like flah light
* cone are only in the sectors that have negative z.
* The bump and flash light cone are used to subtract them from the case.
*/
phone_width = 157.4;
phone_length = 75.8;
phone_thickness = 7.6;
phone_corner_rad = 10;
module phone_body() {
$fn = 64;
hull() {
translate([phone_width/2-phone_corner_rad,phone_length/2-phone_corner_rad,0]) cylinder(h=phone_thickness, r=phone_corner_rad);
translate([-1*(phone_width/2-phone_corner_rad),phone_length/2-phone_corner_rad,0]) cylinder(h=phone_thickness, r=phone_corner_rad);
translate([phone_width/2-phone_corner_rad,-1*(phone_length/2-phone_corner_rad),0]) cylinder(h=phone_thickness, r=phone_corner_rad);
translate([-1*(phone_width/2-phone_corner_rad),-1*(phone_length/2-phone_corner_rad),0]) cylinder(h=phone_thickness, r=phone_corner_rad);
}
}
module camera_bump() {
$fn = 64;
bump_thickness = 1.5;
bump_width = 50;
bump_length = 22;
translate([-phone_width/2, phone_length/2, -bump_thickness]) hull() {
translate([phone_corner_rad, -phone_corner_rad, 0]) cylinder(h=bump_thickness, r1=phone_corner_rad-1, r2=phone_corner_rad);
translate([2,-bump_length+1,0]) cylinder(h=bump_thickness, r1=1, r2=2);
translate([bump_width-phone_corner_rad,-bump_length+phone_corner_rad, 0]) cylinder(h=bump_thickness, r1=phone_corner_rad-1, r2=phone_corner_rad);
translate([bump_width-2,-2,0]) cylinder(h=bump_thickness, r1=1, r2=2);
}
// flashlight
translate([-phone_width/2+11,phone_length/2-27,-10]) cylinder(h=10, r1=10, r2=3);
}

View file

@ -1,2 +0,0 @@
solidpython
click