# Ergogen config for the eepyBoard # # Reference information: # - Keycap size (FK MBK keycaps): 17.5mm x 16.5mm # Metadata meta: # Required version of Ergogen engine: "4.1.0" # Version of the board version: "1.2" author: binaryDiv # Define units and default values used throughout this file units: # Redefine choc units (keycap size + 1.5mm clearance) cx: 19 cy: 18 # Size of keycaps kcx: 17.5 kcy: 16.5 # Size of key rectangle in demo view (keycap size) $default_width: 17.5 $default_height: 16.5 # Actual spacing of keys $default_spread: cx $default_padding: cy # Vertical offset between function key row and main zone function_row_offset: 3 # Outline border (border between keys and PCB edge) border_left: -6 border_right: 6 border_top: 5 border_bottom: -4 # Radius of rotary encoder knob (just for visualization) rotary_encoder_radius: 10 # Define the points (primarily the keys, but also some auxiliary points for # placement of other components, e.g. rotary encoders and the controller board) points: key: # Tag all points as "is_key" unless overwritten tags: [ is_key ] # Use 5V as VCC for all RGB LEDs, except for the first one in the chain led_vcc_net: VCC zones: # Main keyboard zone main: # Set anchor to fix placement on KiCad sheet anchor: shift: [ 75, -175 ] # Key rows (from bottom to top) rows: # Modifier row (Ctrl etc., but excluding the thumb keys) mods: row_net: ROW1 led_next_key: "{{zone.name}}_{{neighbor_col_right}}_{{row}}" tags: [ is_key, flip_led ] # Bottom letter row bottom: row_net: ROW2 led_next_key: "{{zone.name}}_{{neighbor_col_left}}_{{row}}" # Home letter row home: row_net: ROW3 led_next_key: "{{zone.name}}_{{neighbor_col_right}}_{{row}}" tags: [ is_key, flip_led ] # Top letter row top: row_net: ROW4 led_next_key: "{{zone.name}}_{{neighbor_col_left}}_{{row}}" # Number row numbers: row_net: ROW5 led_next_key: "{{zone.name}}_{{neighbor_col_right}}_{{row}}" tags: [ is_key, flip_led ] # Key columns (from left to right) columns: # Left-most column (`, Tab, Shift, etc.) left: key.column_net: COL1 key.neighbor_col_right: one rows.top.led_next_key: main_left_home rows.bottom.led_next_key: main_left_mods # First letter column (1, Q) one: key.column_net: COL2 key.neighbor_col_left: left key.neighbor_col_right: two rows.mods.led_next_key: thumb_one # Second letter column (2, W) two: key.column_net: COL3 key.neighbor_col_left: one key.neighbor_col_right: three rows.mods.skip: true # Third letter column (3, E) three: key.column_net: COL4 key.neighbor_col_left: two key.neighbor_col_right: four rows.mods.skip: true # Fourth letter column (4, R) four: key.column_net: COL5 key.neighbor_col_left: three key.neighbor_col_right: five rows.mods.skip: true # Fifth letter column (5, T) five: key.column_net: COL6 key.neighbor_col_left: four key.neighbor_col_right: six rows.mods.skip: true # Sixth letter column (6, Y) six: key.column_net: COL7 key.neighbor_col_left: five key.neighbor_col_right: seven rows.mods.skip: true # Seventh letter column (7, U) seven: key.column_net: COL8 key.neighbor_col_left: six key.neighbor_col_right: eight rows.mods.skip: true # Eighth letter column (8, I) eight: key.column_net: COL9 key.neighbor_col_left: seven key.neighbor_col_right: nine rows.mods.skip: true # Nineth letter column (9, O) nine: key.column_net: COL10 key.neighbor_col_left: eight key.neighbor_col_right: ten rows.mods.skip: true # Tenth letter column (0, P) ten: key.column_net: COL11 key.neighbor_col_left: nine key.neighbor_col_right: eleven # Eleventh letter column (-, [) eleven: key.column_net: COL12 key.neighbor_col_left: ten key.neighbor_col_right: twelve # Twelfth letter column (=, ]) twelve: key.column_net: COL13 key.neighbor_col_left: eleven key.neighbor_col_right: right rows.numbers.led_next_key: main_right_top # Right-most column (Enter, Shift etc.) right: key.column_net: COL14 key.neighbor_col_left: twelve # Skip right-most key in numbers row because that wouldn't fit with the controller board rows.numbers.skip: true rows.home.led_next_key: main_right_bottom # Use placeholder to mark end of the RGB LED chain (unused net name) rows.mods.led_next_key: END_OF_CHAIN # Thumb fan thumb: # Position thumb keys based on the third key in the modifier row anchor: ref: main_one_mods shift: [ cx + 1, 0 ] # Zone-wide key settings key: row_net: ROW1 tags: [ is_key, flip_led ] # Rotate the thumb keys around the bottom-left corner of the key origin: [ -0.5cx, -0.5cy ] splay: -4 # Define thumb keys columns: one: key.column_net: COL3 key.mirror.column_net: COL10 key.led_next_key: thumb_two key.mirror.led_next_key: main_ten_mods two: key.column_net: COL4 key.mirror.column_net: COL9 key.led_next_key: thumb_three key.mirror.led_next_key: mirror_thumb_one three: key.column_net: COL5 key.mirror.column_net: COL8 key.led_next_key: thumb_center key.mirror.led_next_key: mirror_thumb_two # Mirror the thumb fan mirror: ref: main_five_bottom shift: [ 0.5cx, 0.5cy ] # Single key centered between thumb keys (space key) thumb_center: anchor: # Center between the two inner thumb keys aggregate.parts: - thumb_three - mirror_thumb_three shift: [ 0, -0.125cy ] # Key settings (instead of rows/columns) key: width: 1.5kcx row_net: ROW1 column_net: COL6 led_next_key: mirror_thumb_three tags: [ is_key, flip_led, 1_5u ] # Function key row above the main zone (Esc, F1-F12) function: # Position function key row above main zone with a vertical offset anchor: ref: main_left_numbers shift: [ 0, cy + function_row_offset ] # Single row zone: Assign row net key: row_net: ROW6 # Define function keys columns: # Escape key esc: key.column_net: COL1 key.led_next_key: main_left_numbers # F1 to F12 keys f1: key.column_net: COL2 key.led_next_key: function_esc f2: key.column_net: COL3 key.led_next_key: function_f1 f3: key.column_net: COL4 key.led_next_key: function_f2 f4: key.column_net: COL5 key.led_next_key: function_f3 f5: key.column_net: COL6 key.led_next_key: function_f4 f6: key.column_net: COL7 key.led_next_key: function_f5 f7: key.column_net: COL8 key.led_next_key: function_f6 f8: key.column_net: COL9 key.led_next_key: function_f7 f9: key.column_net: COL10 key.led_next_key: function_f8 f10: key.column_net: COL11 key.led_next_key: function_f9 f11: key.column_net: COL12 key.led_next_key: function_f10 f12: key.column_net: COL13 key.led_next_key: function_f11 # F12 is the first key in the RGB LED chain. # The first LED needs to run on a lower voltage (see explanation below). key.led_vcc_net: VCC_first_led # Rotary encoder in the top right corner of the keyboard rotary_top_right: anchor: ref: function_f12 shift: [ cx + 3, 0 ] rotate: 90 key: tags: [ is_rotary_encoder ] width: 2 * rotary_encoder_radius height: 2 * rotary_encoder_radius # Matrix position of the switch: Function row, right of F12 row_net: ROW6 column_net: COL14 # RP2040 Pico Mini controller board controller: anchor: # Place in top-right corner (right to F12, with rotary encoder on top) - ref: rotary_top_right affect: xy - shift: [ 0, -0.5cy + 2.5 ] # This is an auxiliary point to place the controller, not an actual key key: tags: [ is_controller ] width: 18 height: 36 # Generate outlines that can be used in the PCB and for 3D models outlines: # Outline of the key caps keys: # 1u keys - what: rectangle operation: stack where: [ [ is_key, -1_5u ] ] size: [ kcx, kcy ] # 1.5u keys - what: rectangle operation: stack where: [ [ is_key, 1_5u ] ] size: [ 1.5kcx, kcy ] # Rotary encoder with knob (2cm) rotary_encoder: - what: rectangle operation: stack size: [ 14, 14 ] - what: circle operation: stack radius: rotary_encoder_radius # Outline for the PCB board_outline: - what: polygon points: # Top left corner - ref: - ref: function_esc shift: [ -0.5kcx, 0.5kcy ] # Extend all corners to the sides to get a border shift: [ border_left, border_top ] # Top right corner - ref: - ref: main_right_top affect: x - ref: function_f12 affect: y - shift: [ 0.5kcx, 0.5kcy ] shift: [ border_right, border_top ] # Bottom right corner - ref: - ref: main_right_mods shift: [ 0.5kcx, -0.5kcy ] shift: [ border_right, border_bottom ] # Bottom center "corner" below space key (needs to be post-processed in KiCad to get a smooth arc, see below!) - ref: - ref: thumb_center shift: [ 0, -0.5kcy ] shift: [ 0, border_bottom ] # Bottom left corner - ref: - ref: main_left_mods shift: [ -0.5kcx, -0.5kcy ] shift: [ border_left, border_bottom ] # Round off the corners with a fillet. # NOTE: To get a smoother arc on the bottom of the board, do some post-processing in KiCad: # 1. Remove the tiny fillet arc between the two diagonal bottom lines. # 2. Select the two remaining bottom lines. Right click them and use "Shape Modification -> Extend Lines to Meet". # 3. Right click the two angled lines again. Use "Shape Modification -> Fillet Lines..." with a 300mm radius. fillet: 5 # Preview version of board with key caps and components for visualization board_preview: - board_outline - ^keys # RP2040 Pico Mini controller board - what: rectangle operation: stack where: is_controller size: [ 18, 36 ] # Rotary encoder - what: outline name: rotary_encoder operation: stack where: is_rotary_encoder # Cutouts for the switches switch_cutouts: - what: rectangle where: is_key size: 14 # Board outline with switch cutouts switch_plate: - board_outline - -switch_cutouts # Generate the PCB pcbs: eepyboard: # Define outline (edges) of the board based on the outlines defined above outlines: main: outline: board_outline # Define PCB components footprints: controller: what: rp2040_pico_mini where: is_controller params: # Mount the controller board on the backside of the PCB orientation: down # Use 5V from USB as VCC net 5V: VCC # RGB LEDs: The chain starts with the F12 key GP29: led_din_function_f12 # Matrix columns GP27: COL1 GP26: COL2 GP25: COL3 GP23: COL4 GP22: COL5 GP21: COL6 GP18: COL7 GP17: COL8 GP13: COL9 GP12: COL10 GP11: COL11 GP10: COL12 GP9: COL13 GP8: COL14 # Matrix rows GP0: ROW1 GP1: ROW2 GP2: ROW3 GP3: ROW4 GP19: ROW5 GP28: ROW6 # Rotary encoder GP6: rotary_top_right_a GP7: rotary_top_right_b choc_hotswap: what: choc_pretty where: is_key # Rotate footprint so that the hotswap socket is at the bottom and the LED can be at the top adjust.rotate: 180 params: keycaps: true hotswap: true from: "diode_{{name}}" to: "{{column_net}}" key_diode: what: diode_smd where: is_key adjust: shift: [ 7, -7 ] rotate: 90 resist: true params: side: B from: "diode_{{name}}" to: "{{row_net}}" rotary_encoder: what: rotary_encoder_ec12 where: is_rotary_encoder params: from: "diode_{{name}}" to: "{{column_net}}" A: "{{name}}_a" B: "{{name}}_b" C: GND rotary_encoder_diode: $extends: pcbs.eepyboard.footprints.key_diode where: is_rotary_encoder adjust: shift: [ 0, 0 ] rotate: 0 led_chip: what: sk6812_mini_e # Place unrotated LEDs in all rows without the flip_led tag where: [ [ is_key, -flip_led ] ] # Position LEDs on the LED hole in the Choc switches adjust: shift: [ 0, 4.7 ] params: side: B din: "led_din_{{name}}" dout: "led_din_{{led_next_key}}" VCC: "{{led_vcc_net}}" led_capacitor: what: capacitor_smd_1206 where: [ [ is_key, -flip_led ] ] adjust: shift: [ -6.5, 4.75 ] rotate: 90 resist: true params: side: B from: "{{led_vcc_net}}" to: GND led_chip_flipped: $extends: pcbs.eepyboard.footprints.led_chip # Place flipped (rotated by 180°) LEDs in all rows with the flip_led tag where: [ [ is_key, flip_led ] ] adjust.rotate: 180 led_capacitor_flipped: $extends: pcbs.eepyboard.footprints.led_capacitor where: [ [ is_key, flip_led ] ] adjust: shift: [ 6.5, 4.75 ] rotate: 270 resist: true # The first SK6812 chip in the chain has to run on a reduced voltage to serve as a makeshift level converter for # all following RGB LEDs. # This is needed because the RP2040 runs on 3.3V, but the SK6812 runs on 5V and requires at least 3.5V (5V * 0.7) # for the control signal. By reducing the power voltage with a diode, the threshold is reduced as well, so that # the signal of the RP2040 is strong enough. first_led_voltage_diode: what: diode_smd where: function_f12 adjust: shift: [ 0, 8.5 ] rotate: 0 params: side: B from: VCC to: VCC_first_led # Mounting holes: Top row (above and between Esc/F1, F4/F5, F8/F9, F12/rotary) mounting_hole_top1: what: mountinghole_m2 where: ref: function_f1 shift: [ -0.5cx, 0.5cy + 1.5 ] mounting_hole_top2: what: mountinghole_m2 where: ref: function_f5 shift: [ -0.5cx, 0.5cy + 1.5 ] mounting_hole_top3: what: mountinghole_m2 where: ref: function_f8 shift: [ 0.5cx, 0.5cy + 1.5 ] mounting_hole_top4: what: mountinghole_m2 where: ref: function_f12 shift: [ 0.5cx - 1, 0.5cy + 1.5 ] # Mounting holes: Top left corner (left of Esc) mounting_hole_top_left: what: mountinghole_m2 where: ref: function_esc shift: [ -12, 0 ] # Mounting holes: "Top" right corner (right edge, below the controller board) mounting_hole_top_right: what: mountinghole_m2 where: ref: main_right_top shift: [ 0.5cx - 0.5, 0.5cy + 1.25 ] # Mounting holes: Bottom center, below C and N keys (with copyright text in between) mounting_hole_bottom_center_left: what: mountinghole_m2 where: ref: main_four_bottom shift: [ 4, -12.25 ] mounting_hole_bottom_center_right: what: mountinghole_m2 where: ref: main_seven_bottom shift: [ -4, -12.25 ] # Mounting holes: Bottom left corner (left of Ctrl; below left thumb keys) mounting_hole_bottom_left1: what: mountinghole_m2 where: ref: main_one_mods shift: [ 0.5cx, -11.75 ] mounting_hole_bottom_left2: what: mountinghole_m2 where: ref: main_left_mods shift: [ -12, 0 ] # Mounting holes: Bottom right corner (right of bottom-right key; below right thumb keys) mounting_hole_bottom_right1: what: mountinghole_m2 where: ref: main_twelve_mods shift: [ -0.5cx, -11.75 ] mounting_hole_bottom_right2: what: mountinghole_m2 where: ref: main_right_mods shift: [ 12, 0 ] # Render text with project name and copyright onto the PCB copyright_text: what: text where: ref: thumb_center shift: [ 0, 13.25 ] params: text: |- eepyBoard v1.2 by binaryDiv (c) 2024 (MIT License)