Compare commits

..

No commits in common. "cef9340fd028fe2b580528f6cf9d65999b959442" and "8afcece751a73badf750eafe250aedb453f9d60e" have entirely different histories.

11 changed files with 3 additions and 12758 deletions

3
.gitignore vendored
View File

@ -1,6 +1,3 @@
*/output/points/
*/output/source/
*/output/*/demo*
*/output/pcbs/fp-info-cache
*/output/pcbs/*.kicad_pro
*/output/pcbs/*.kicad_prl

View File

@ -12,17 +12,9 @@ A 34-key single-board keyboard created with [Ergogen](https://ergogen.xyz). Powe
This keyboard is my first attempt at using Ergogen, and my first custom keyboard, so it will likely be rough around the edges. I predict there will be future keyboards listed here which refine the ideas implemented in this board.
### Pseudacris
[Source Files](https://git.sr.ht/~tgrosinger/keyboards/tree/main/item/pseudacris)
A 34-key single-board keyboard created with [Ergogen](https://ergogen.xyz). Powered by an integrated MCU, derived directly from the [nRFMicro](https://github.com/joric/nrfmicro/).
This keyboard is almost identical to Chrysemys, but switches to normal Choc switches, adds hotswap, and moves the switches closer together.
### Future Keyboards
Eventually I would like to build a keyboard which has an integrated trackpoint, trackpad, or trackball. It will likely be based on Pseudacris.
I'd like to eventually work towards putting the MCU directly on the keyboard PCB. It however does not seem wise to do this until I have a functional keyboard under my belt.
## License

View File

@ -23,13 +23,7 @@ A 34-key single-board keyboard created with [Ergogen](https://ergogen.xyz).
## Center Cover
After use, I have decided to instead place the battery under the nice!nano and omit the center cover. This does leave a hole in the middle of the keyboard, but maybe we just call it a handle.
## Firmware
- [Docs](https://zmk.dev/docs/development/build-flash#building-from-zmk-config-folder) on building firmware using the `zmk-config` from this repo.
- Note: It still needs to be built from inside the `/app` directory in the ZMK repo.
- `west build -b nice_nano_v2 -- -DSHIELD=chrysemys -DZMK_CONFIG="/workspaces/zmk-config/config"`
Work in progress
## Inspiration

View File

@ -1,10 +1,3 @@
#
# NOTES:
#
# - The thumb key nets are inverted compared to rest
# - The right half column nets are in a strange order
#
units:
cx: 18 # Keycap is 17.5mm wide
cy: 17 # Keycap is 16.5mm tall

View File

@ -1,18 +0,0 @@
# Pseudacris
A 34-key single-board keyboard created with [Ergogen](https://ergogen.xyz).
This keyboard is materially extremely similar to Chrysemys, with the intention to change the following:
- Change from Kailh Choc Mini to the normal Kailh Choc switches.
- I have not been happy with how the mini switches feel to type on. They feels as though they are going to bind up too often and especially make chords more difficult.
- This will reduce manufacturing costs because the extra cutouts needed for the mini switches requires excess milling time.
- Use hotswap sockets for the switches.
- Move the switches closer together, so there is less of a gap between key caps.
- Use an integrated MCU, based on the nRFMicro rather than a nice!nano.
## Building Firmware
The firmware for this keyboard can be found on my [ZMK fork](https://github.com/tgrosinger/zmk/tree/tgrosinger-keyboards/app/boards/arm/pseudacris). Instructions for building can be found in the readme in that directory.
If you would like to build your own key layout for this keyboard, follow the instruction for [Building from `zmk-config` folder](https://zmk.dev/docs/development/build-flash#building-from-zmk-config-folder).

View File

@ -1,95 +0,0 @@
module.exports = {
nets: {
neg: undefined,
pos: undefined,
},
body: p => `
(module BatteryPads
(layer "F.Cu")
${p.at /* parametric position */}
${'' /* TODO: Does not yet support rotation */}
(fp_text reference "BT1" (at 0 0.5) (layer "F.SilkS") hide (effects (font (size 1 1) (thickness 0.15))))
(fp_text value "Battery_Cell" (at 0 -0.5) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))))
(fp_text user "Battery_Cell" (at 0 -0.5) (layer "B.Fab") (effects (font (size 1 1) (thickness 0.15)) (justify mirror)))
(fp_text user "BT01" (at 0 0.5) (layer "B.SilkS") hide (effects (font (size 1 1) (thickness 0.15)) (justify mirror)))
(fp_text user "Battery" (at 3.175 0.79375 90) (layer "F.SilkS") hide (effects (font (size 0.8 0.8) (thickness 0.1))))
(fp_text user "Battery" (at 3.175 0.79375 90) (layer "B.SilkS") hide (effects (font (size 0.8 0.8) (thickness 0.1)) (justify mirror)))
(fp_text user "(+)" (at -1.1 -2.286) (layer "F.SilkS") (effects (font (size 0.8 0.8) (thickness 0.1))))
(fp_text user "(+)" (at -1.1 -2.286) (layer "B.SilkS") (effects (font (size 0.8 0.8) (thickness 0.1)) (justify mirror)))
(fp_text user "(-)" (at 1.1 -2.286) (layer "F.SilkS") (effects (font (size 0.8 0.8) (thickness 0.1))))
(fp_text user "(-)" (at 1.1 -2.286) (layer "B.SilkS") (effects (font (size 0.8 0.8) (thickness 0.1)) (justify mirror)))
(fp_poly (pts
(xy 0.4 -1)
(xy 0.4 1)
(xy 1.8 1)
(xy 1.8 -1)
) (layer "B.Mask") (width 0.1) (fill solid))
(fp_poly (pts
(xy -1.8 -1)
(xy -1.8 1)
(xy -0.4 1)
(xy -0.4 -1)
) (layer "B.Mask") (width 0.1) (fill solid))
(fp_poly (pts
(xy -0.401442 -1)
(xy -0.401442 1)
(xy -1.801442 1)
(xy -1.801442 -1)
) (layer "F.Mask") (width 0.1) (fill solid))
(fp_poly (pts
(xy 1.8 -1)
(xy 1.8 1)
(xy 0.4 1)
(xy 0.4 -1)
) (layer "F.Mask") (width 0.1) (fill solid))
(pad "1" thru_hole circle (at -1.1004 -1.3416) (size 0.4572 0.4572) (drill 0.3048) (layers *.Cu) ${p.net.pos.str})
(pad "1" smd custom (at -1.1 0 180) (size 1.5 2.1) (layers "F.Cu")
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy 0.179 1.3352)
(xy -0.1766 1.3352)
(xy -0.1766 0.762)
(xy 0.179 0.762)
) (width 0.1) (fill yes))
))
(pad "1" smd custom (at -1.1 0) (size 1.5 2.1) (layers "B.Cu")
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy 0.176556 -0.7618)
(xy -0.179044 -0.7618)
(xy -0.179044 -1.335)
(xy 0.176556 -1.335)
) (width 0.1) (fill yes))
))
(pad "2" thru_hole circle (at 1.1 -1.3416) (size 0.4572 0.4572) (drill 0.3048) (layers *.Cu) ${p.net.neg.str})
(pad "2" smd custom (at 1.1 0 180) (size 1.5 2.1) (layers "F.Cu")
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy 0.1786 1.3352)
(xy -0.177 1.3352)
(xy -0.177 0.762)
(xy 0.1786 0.762)
) (width 0.1) (fill yes))
))
(pad "2" smd custom (at 1.1 0) (size 1.5 2.1) (layers "B.Cu")
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy 0.1766 -0.7618)
(xy -0.179 -0.7618)
(xy -0.179 -1.335)
(xy 0.1766 -1.335)
) (width 0.1) (fill yes))
))
)
`
}

View File

@ -1,121 +0,0 @@
// Kailh Choc PG1350
// Nets
// from: corresponds to pin 1
// to: corresponds to pin 2
// Params
// hotswap: default is false
// if true, will include holes and pads for Kailh choc hotswap sockets
// reverse: default is false
// if true, will flip the footprint such that the pcb can be reversible
// keycaps: default is false
// if true, will add choc sized keycap box around the footprint
//
// note: hotswap and reverse can be used simultaneously
module.exports = {
nets: {
from: undefined,
to: undefined
},
params: {
class: 'S',
hotswap: false,
reverse: false,
keycaps: false
},
body: p => {
const standard = `
(module PG1350 (layer F.Cu) (tedit 5DD50112)
${p.at /* parametric position */}
${'' /* footprint reference */}
(fp_text reference "${p.ref}" (at 0 0) (layer F.SilkS) ${p.ref_hide} (effects (font (size 1.27 1.27) (thickness 0.15))))
(fp_text value "" (at 0 0) (layer F.SilkS) hide (effects (font (size 1.27 1.27) (thickness 0.15))))
${''/* diode box marker */}
(fp_line (start 2.868 3.326) (end 2.868 5.476) (layer "Dwgs.User") (width 0.15))
(fp_line (start -2.732 5.476) (end 2.868 5.476) (layer "Dwgs.User") (width 0.15))
(fp_line (start 2.868 3.326) (end -2.732 3.326) (layer "Dwgs.User") (width 0.15))
(fp_line (start -2.732 3.326) (end -2.732 5.476) (layer "Dwgs.User") (width 0.15))
${''/* diode direction marker */}
(fp_line (start -0.282 4.426) (end 0.318 4.026) (layer "B.SilkS") (width 0.1))
(fp_line (start 0.318 4.826) (end -0.282 4.426) (layer "B.SilkS") (width 0.1))
(fp_line (start -0.282 4.426) (end -0.282 3.876) (layer "B.SilkS") (width 0.1))
(fp_line (start -0.282 4.426) (end -0.282 4.976) (layer "B.SilkS") (width 0.1))
(fp_line (start -0.682 4.426) (end -0.282 4.426) (layer "B.SilkS") (width 0.1))
(fp_line (start 0.318 4.426) (end 0.818 4.426) (layer "B.SilkS") (width 0.1))
(fp_line (start 0.318 4.026) (end 0.318 4.826) (layer "B.SilkS") (width 0.1))
${''/* diode pads */}
(pad "" smd rect (at 1.776 4.401 ${ p.rot }) (size 1.1 1.9) (layers "B.Cu" "B.Paste" "B.Mask"))
(pad 2 smd rect (at -1.524 4.401 ${ p.rot }) (size 1.1 1.9) (layers "B.Cu" "B.Paste" "B.Mask") ${p.net.to.str})
${''/* corner marks */}
(fp_line (start -7 -6) (end -7 -7) (layer Dwgs.User) (width 0.15))
(fp_line (start -7 7) (end -6 7) (layer Dwgs.User) (width 0.15))
(fp_line (start -6 -7) (end -7 -7) (layer Dwgs.User) (width 0.15))
(fp_line (start -7 7) (end -7 6) (layer Dwgs.User) (width 0.15))
(fp_line (start 7 6) (end 7 7) (layer Dwgs.User) (width 0.15))
(fp_line (start 7 -7) (end 6 -7) (layer Dwgs.User) (width 0.15))
(fp_line (start 6 7) (end 7 7) (layer Dwgs.User) (width 0.15))
(fp_line (start 7 -7) (end 7 -6) (layer Dwgs.User) (width 0.15))
${''/* middle shaft */}
(pad "" np_thru_hole circle (at 0 0) (size 3.429 3.429) (drill 3.429) (layers *.Cu *.Mask))
${''/* stabilizers */}
(pad "" np_thru_hole circle (at 5.5 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask))
(pad "" np_thru_hole circle (at -5.5 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask))
`
const keycap = `
${'' /* keycap marks */}
(fp_line (start -9 -8.5) (end 9 -8.5) (layer Dwgs.User) (width 0.15))
(fp_line (start 9 -8.5) (end 9 8.5) (layer Dwgs.User) (width 0.15))
(fp_line (start 9 8.5) (end -9 8.5) (layer Dwgs.User) (width 0.15))
(fp_line (start -9 8.5) (end -9 -8.5) (layer Dwgs.User) (width 0.15))
`
function pins(def_neg, def_pos, def_side) {
if(p.param.hotswap) {
return `
${'' /* holes */}
(pad "" np_thru_hole circle (at ${def_pos}5 -3.75) (size 3 3) (drill 3) (layers *.Cu *.Mask))
(pad "" np_thru_hole circle (at 0 -5.95) (size 3 3) (drill 3) (layers *.Cu *.Mask))
${'' /* net pads (other pad is with diode) */}
(pad 1 smd rect (at ${def_neg}3.275 -5.95 ${p.rot}) (size 2.6 2.6) (layers ${def_side}.Cu ${def_side}.Paste ${def_side}.Mask) ${p.net.from.str})
${''/* right hotswap pad and trace to diode */}
(pad "" smd custom (at 8.275 -3.75 ${ p.rot }) (size 2.6 2.6) (layers ${def_side}.Cu ${def_side}.Paste ${def_side}.Mask)
(clearance 0.2)
(options (clearance outline) (anchor rect))
(primitives
(gr_line (start -0.5 1) (end -0.5 4.6) (width 0.2))
(gr_line (start -3.3284 7.4284) (end -6.5 7.4284) (width 0.2))
(gr_line (start -0.499981 4.599974) (end -3.328408 7.428401) (width 0.2))
))
`
} else {
return `
${''/* pins (other pad is with diode) */}
(pad 1 thru_hole circle (at ${def_pos}5 -3.8) (size 2.032 2.032) (drill 1.27) (layers *.Cu *.Mask) ${p.net.from.str})
`
}
}
if(p.param.reverse) {
return `
${standard}
${p.param.keycaps ? keycap : ''}
${pins('-', '', 'B')}
${pins('', '-', 'F')})
`
} else {
return `
${standard}
${p.param.keycaps ? keycap : ''}
${pins('-', '', 'B')})
`
}
}
}

View File

@ -1,19 +0,0 @@
module.exports = {
nets: {
from: undefined,
to: undefined,
},
body: p => `
(module TwoLeadButton
(layer "F.Cu")
${p.at /* parametric position */}
(fp_text reference "B1" (at 0 0 unlocked) (layer "F.SilkS") (effects (font (size 1 1) (thickness 0.15))))
(fp_text value "Button" (at 0 2.54 unlocked) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))))
(fp_text user "Button" (at 0 0 unlocked) (layer "F.Fab") (effects (font (size 1 1) (thickness 0.15))))
(pad "1" smd roundrect (at -2.2 0) (size 1 2) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) ${p.net.from.str})
(pad "2" smd roundrect (at 2.2 0) (size 1 2) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) ${p.net.to.str})
)
`
}

File diff suppressed because it is too large Load Diff

View File

@ -1,321 +0,0 @@
units:
cx: 17.75 # Keycap is 17.75mm wide
cy: 16.5 # Keycap is 16.5mm tall
kx: cx + 0.5 # Key spacing horizontal
ky: cy + 0.5 # Key spacing vertical
plate_padding: 2
pinky_splay: 6
ring_splay: 3
angle: 22 # Angle between two halves
mounting_hole_radius: 1.5
mcu_height: 33
mcu_width: 18
batt_width: 11.5
batt_length: 31.8
batt_padding: 1.5
points:
mirror:
ref: matrix_inner_top
distance: 50
zones:
matrix:
key:
padding: 17
footprints:
choc:
type: choc_with_diode
params:
hotswap: true
nets:
from: "=row_net"
to: "=column_net"
rotate: -angle + pinky_splay + ring_splay
columns:
pinky:
key:
column_net: P5
mirror.column_net: P18
rows:
bottom:
# [t, r, b, l]
bind: [0.5ky, 1, 0, 2.5]
home:
bind: [0.5ky, 0.5kx, 0.5ky, 2.5]
top:
bind: [0.25, 0.5kx, 0.5ky, 2.5]
ring:
rotate: -pinky_splay
stagger: 7
spread: kx + 1
key:
column_net: P6
mirror.column_net: P15
rows:
bottom:
bind: [0.5ky, 0, 0, 5]
home:
bind: [0.5ky, 0.5kx, 0.5ky, 0.5kx]
top:
bind: [0, 0.5ky, 0.5ky, 2.5]
middle:
rotate: -ring_splay
stagger: 3
spread: kx + 0.5
key:
column_net: P7
mirror.column_net: P14
rows:
bottom:
bind: [0.5ky, 5, 0, 5]
home:
bind: [0.5ky, 0.5kx, 0.5ky, 0.5kx]
top:
bind: [0, 0.5ky, 0.5ky, 2.5]
index:
stagger: -6
spread: kx
key:
column_net: P8
mirror.column_net: P16
rows:
bottom:
bind: [0.5ky, 5, 0, 0]
home:
bind: [0.5ky, 0.5kx, 0.5ky, 0.5kx]
top:
bind: [0, 0, 0.5ky, 5]
inner:
stagger: -4
spread: kx
key:
column_net: P9
mirror.column_net: P10
rows:
bottom:
bind: [0.5ky, 2, 0, 0]
home:
bind: [0.5ky, 0.5kx, 0.5ky, 0.5kx]
top:
bind: [0, 5, 0.5ky, 5]
rows:
bottom:
row_net: P3
mirror.row_net: P3
home:
row_net: P2
mirror.row_net: P2
top:
row_net: P1
mirror.row_net: P1
thumbfan:
anchor:
ref: matrix_inner_bottom
shift: [-(kx/2), -(ky + 2)]
key:
padding: 17.5
footprints:
choc:
type: choc_with_diode
params:
hotswap: true
nets:
from: "=row_net"
to: "=column_net"
columns:
near:
rows:
thumb:
bind: [10, 5, 0, 1]
column_net: P7
mirror.column_net: P14
home:
rotate: -15
spread: 18.5
origin: [-10, -9]
rows:
thumb:
bind: [5, 5, 0, 5]
column_net: P8
mirror.column_net: P16
far:
rotate: -15
spread: 18.5
origin: [-10, -9]
rows:
thumb:
bind: [5, 1, 0, 5]
column_net: P9
mirror.column_net: P10
rows:
thumb:
row_net: P4
mirror.row_net: P4
outlines:
exports:
_mcu:
- type: rectangle
size: [mcu_width, mcu_height]
anchor:
ref:
- matrix_inner_top
- mirror_matrix_inner_top
shift:
- -mcu_width/2
- -mcu_height + 1
_battery:
- type: rectangle
size: [batt_length, batt_width]
anchor:
ref:
- matrix_inner_top
- mirror_matrix_inner_top
shift:
- -batt_length/2
- -mcu_height - batt_width - 6 # Below the MCU and bat pads
_key_outline:
- type: keys
side: both
size: 16
_center_positive:
- type: polygon
points:
- ref: matrix_middle_top
shift: [cx/2, cy/2+1]
- ref: mirror_matrix_middle_top
shift: [cx/2, cy/2+1]
- ref: mirror_matrix_middle_bottom
shift: [cx/2, 0]
- ref: mirror_thumbfan_home_thumb
shift: [-cx/2, 0]
- ref: mirror_thumbfan_far_thumb
shift: [cx/2, -cy/2]
- ref: thumbfan_far_thumb
shift: [cx/2, -cy/2]
- ref: thumbfan_home_thumb
shift: [-cx/2, 0]
- ref: matrix_middle_bottom
shift: [cx/2, 0]
_bottom_center_arc:
- type: circle
anchor:
ref:
- thumbfan_far_thumb
- mirror_thumbfan_far_thumb
shift: [0, -78.5]
radius: 70
_top_center_arc:
- type: circle
anchor:
ref:
- matrix_inner_top
- mirror_matrix_inner_top
shift: [0, 116.8]
radius: 100
_bottom_arc:
- type: polygon
mirror: true
points:
- ref: matrix_pinky_bottom
shift: [cx/2, -cy/2]
- ref: thumbfan_near_thumb
shift: [-cx/2, -cy/2]
- ref: matrix_inner_bottom
shift: [cx/2, cy/2]
- ref: matrix_pinky_bottom
shift: [cx/2-1, cy/2]
- type: circle
mirror: true
operation: subtract
anchor:
ref: matrix_pinky_bottom
shift: [-0.7, -74.3]
radius: 67
_keycaps:
- type: keys
side: both
size: [cx, cy]
bound: false
_battery_mounting_holes:
- type: circle
anchor:
ref:
- matrix_inner_bottom
- mirror_matrix_inner_bottom
shift: [-22, -11]
radius: mounting_hole_radius
- type: circle
anchor:
ref:
- matrix_inner_bottom
- mirror_matrix_inner_bottom
shift: [22, -11]
radius: mounting_hole_radius
_panel:
- _key_outline
- +_center_positive
- -_top_center_arc
- -_bottom_center_arc
- +_bottom_arc
panel:
- name: _panel
fillet: 1.5
- -_battery_mounting_holes
demo_keycaps:
- panel
- ^_keycaps
demo_center:
- _center_positive
- ^_keycaps
- ^_bottom_arc
demo_battery:
- panel
- ^_mcu
- ^_keycaps
- ^_battery
pcbs:
pseudacris:
outlines:
main:
outline: panel
footprints:
mcu:
type: promicro
params:
orientation: up
anchor:
ref:
- matrix_inner_top
- mirror_matrix_inner_top
rotate: -90
shift: [0, -16]
battery_pads:
type: battery_pads
nets:
neg: GND
pos: BATT
anchor:
ref:
- matrix_inner_top
- mirror_matrix_inner_top
shift: [0, -34]
reset:
type: two_lead_button
nets:
from: RST
to: GND
anchor:
ref:
- thumbfan_far_thumb
- mirror_thumbfan_far_thumb
shift: [0, 0]
power:
type: slider
nets:
from: BATT
to: RAW
anchor:
ref:
- thumbfan_far_thumb
- mirror_thumbfan_far_thumb
shift: [0, -5.5]
rotate: 180