Merge branch 'hackclub:main' into main

This commit is contained in:
End 2025-05-03 11:10:05 -07:00 committed by GitHub
commit 6d06abfcb5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
78 changed files with 802134 additions and 112837 deletions

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,584 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.05,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.1,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "hackpad v1.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "../../../../Desktop/hackpad v1.step",
"svg": "../../../../Desktop/",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"name": "Grouped By Value",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"75be8926-1ba1-4d0b-ab00-ed4bb331e974",
"Root"
]
],
"text_variables": {}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,11 @@
Hi, it was my first time designing somethoing like that. Because of that I had a lot of trouble with the firmware.
I wanted do do a macropad with nine buttons so that I could put shortcuts for davinci or fusion 360 there.
BOM
-Seeed XIAO RP2040
-MX-Style switches (9x)
-Blank DSA keycaps (9x) (Red, Black, White) (I dont care about the color, preferably one color)
-SK6812 MINI-E LEDs (9x)
M3x16mm screws (4x)
![Bildschirmfoto 2025-03-14 um 20 54 20](https://github.com/user-attachments/assets/330fcebd-0eb7-4c87-82f1-9b83a2b4d6b8)
![Bildschirmfoto 2025-03-14 um 20 53 57](https://github.com/user-attachments/assets/dba390b2-6009-4a6b-9dfe-9eb1a53036b1)

View file

@ -0,0 +1,46 @@
# ButtonMasher.exe
ButtonMasher.exe is a 5 key macropad (arranged in a D-pad shape!) with 3 leds and a rotational encoder!
## Features and Inspiration:
- EC11 Rotational encoder for screen brightness control (finally I can stop irking about setting brightness on my monitor! (tbh I was too lazy to look up how to set macros before this))
- 5 whopping keys for epic macros: one should be set up to control the leds too!
- 3 WS2812B RGB LEDs
I wanted a macropad for various bindings I don't have: everything from screen brightness to song fast-forward/rewind are in here. Lots of variety!
## CAD Model:
It's made of two pieces: a bottom case and top cover. I might rework this in the future to better show off the leds.
I learned Fusion 360 basics to do it!
<img src=assets/cad.png alt="Schematic" width="500"/>
(PS I know these pics don't show the case in full. I've got the pcb model fitted though)
## PCB
My PCB has some special sauce cooked up by a friend experienced in wojaks.
I cannot confirm or deny who might be in those drawings...
Schematic<br>
<img src=assets/pcb_schematic.png alt="Schematic" width="300"/>
PCB<br>
<img src=assets/pcb.png width="300"/>
## Firmware Overview
This hackpad uses [QMK](https://qmk.fm/) firmware for everything.
I hope to add VIA/further RGB options in the future. (hackboard idea hmmmmmmm (:
## Challenges:
I've never touched CAD or PCB design before, so almost everything I did had a learning curve. Especially fusion...
## BOM:
- 5x Cherry MX Switches
- 4x DSA Keycaps
- 3x SK6812 MINI LEDs
- 1x EC11 Rotary Encoder (can I ask for a knob matching the case color?)
- 1x XIAO RP2040
- 1x Case (2 printed parts, in black preferably)
- 4x M3x16 Bolts (and nuts)
Feel free to look at the firmware or other files for inspiration! This was a fun project

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#define ENCODER_A_PINS { GP6 }
#define ENCODER_B_PINS { GP29 }
#define WS2812_DI_PIN GP26
#define RGBLIGHT_LED_COUNT 3

View file

@ -0,0 +1,38 @@
{
"manufacturer": "Lyndon Warren",
"keyboard_name": "lyndon_hackpad",
"maintainer": "nubmonkey",
"bootloader": "rp2040",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"matrix_pins": {
"direct": [
["GP3", "GP4", "GP2", "GP1", "GP0"]
]
},
"processor": "RP2040",
"url": "",
"usb": {
"device_version": "1.0.0",
"pid": "0x0000",
"vid": "0xFEED"
},
"layouts": {
"LAYOUT": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0}
]
}
}
}

View file

@ -0,0 +1,25 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
*
* 1
*
* 5 2 3
*
* 4
*
*/
[0] = LAYOUT(
UG_NEXT, KC_MPLY, KC_MFFD, KC_MUTE, KC_MRWD
)
};
const uint16_t PROGMEM encoder_map[][1][2] = {
[0] = { ENCODER_CCW_CW(KC_BRIU, KC_BRID) },
};

View file

@ -0,0 +1,27 @@
# lyndon_hackpad
![lyndon_hackpad](imgur.com image replace me!)
* Keyboard Maintainer: [Lyndon Warren](https://github.com/nubmonkey)
* Hardware Supported: Custom PCB designed for XIAO RP2040 MCU, 4 switches, a rotational encoder, and 3 RGB LEDs!
* Hardware Availability: See full project README
Make example for this keyboard (after setting up your build environment):
make lyndon_hackpad:default
Flashing example for this keyboard:
make lyndon_hackpad:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

View file

@ -0,0 +1,7 @@
LTO_ENABLE = yes
ENCODER_ENABLE = yes
ENCODER_MAP_ENABLE = yes
RGBLIGHT_ENABLE = yes
WS2812_DRIVER = vendor

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,584 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.05,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.1,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 1.0,
"height": 2.0,
"width": 2.0
},
"silk_line_width": 0.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "hackpad.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "C:/Users/ltott/Desktop/gerbers/",
"pos_files": "",
"specctra_dsn": "",
"step": "../../../../Downloads/hackpad_pcb_3d.step",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"name": "Grouped By Value",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"82c910de-f665-48eb-85c0-b364afbacf8a",
"Root"
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View file

@ -0,0 +1,64 @@
import board
import busio
import keypad
import usb_hid
import time
from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation
from kmk.extensions.led import RGB
from kmk.extensions.display import Oled
from kmk.hid import HIDConsumerControl, HIDUsage
from adafruit_mcp230xx.mcp23017 import MCP23017
keyboard = KMKKeyboard()
i2c = busio.I2C(board.GP6, board.GP7)
mcp = MCP23017(i2c)
keyboard.matrix = keypad.KeyMatrix(
row_pins=[board.GP4, board.GP2, board.GP1],
column_pins=[board.GP26, board.GP27, board.GP28],
columns_to_anodes=False,
)
rgb = RGB(
pixel_pin=mcp.get_pin(6),
num_pixels=16,
val_limit=100,
hue_default=0,
animation='RIPPLE',
)
keyboard.extensions.append(rgb)
# OLED Setup
oled = Oled(
width=128, height=32, i2c=busio.I2C(board.GP6, board.GP7)
)
def oled_callback(oled):
oled.clear()
oled.text(f'Batt: {battery}%', 0, 0)
oled.text(f'Vol: {volume}%', 0, 10)
oled.show()
oled.set_callback(oled_callback)
keyboard.extensions.append(oled)
# Host Communication
import usb_cdc
serial = usb_cdc.data
def handle_host_commands():
if serial.in_waiting > 0:
data = serial.readline().decode().strip()
if data.startswith("BATT:"):
global battery
battery = int(data.split(":")[1])
elif data.startswith("VOL:"):
global volume
volume = int(data.split(":")[1])
if __name__ == '__main__':
while True:
handle_host_commands()
keyboard.go()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,639 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.05,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.1,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.8,
"height": 1.27,
"width": 2.54
},
"silk_line_width": 0.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"creepage": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_filters_mismatch": "ignore",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_to_hole": "warning",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"mirrored_text_on_front_layer": "warning",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"nonmirrored_text_on_back_layer": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_angle": "error",
"track_dangling": "warning",
"track_segment_length": "error",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_groove_width": 0.0,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpthpad": true,
"td_onroundshapesonly": false,
"td_onsmdpad": true,
"td_ontrackend": false,
"td_onvia": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [
0.0,
0.5
],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_pairs": [],
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"footprint_filter": "ignore",
"footprint_link_issues": "warning",
"four_way_junction": "ignore",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"label_multiple_wires": "warning",
"lib_symbol_issues": "warning",
"lib_symbol_mismatch": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"same_local_global_label": "warning",
"similar_label_and_power": "warning",
"similar_labels": "warning",
"similar_power": "warning",
"simulation_model_issue": "ignore",
"single_global_label": "ignore",
"unannotated": "error",
"unconnected_wire_endpoint": "warning",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "ControlBoard.kicad_pro",
"version": 2
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"priority": -1,
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 4
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "ControlBoard.step",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "${PROJECTNAME}.csv",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
},
{
"group_by": true,
"label": "Exclude from BOM",
"name": "${EXCLUDE_FROM_BOM}",
"show": true
},
{
"group_by": true,
"label": "Exclude from Board",
"name": "${EXCLUDE_FROM_BOARD}",
"show": true
},
{
"group_by": true,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"include_excluded_from_bom": true,
"name": "Default Editing",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"ngspice": {
"fix_include_paths": true,
"meta": {
"version": 0
},
"model_mode": 4,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"space_save_all_events": true,
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"8bbb26e9-d9bb-4432-9876-72d101001839",
"Root"
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,64 @@
import board
import busio
import keypad
import usb_hid
import time
from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation
from kmk.extensions.led import RGB
from kmk.extensions.display import Oled
from kmk.hid import HIDConsumerControl, HIDUsage
from adafruit_mcp230xx.mcp23017 import MCP23017
keyboard = KMKKeyboard()
i2c = busio.I2C(board.GP6, board.GP7)
mcp = MCP23017(i2c)
keyboard.matrix = keypad.KeyMatrix(
row_pins=[board.GP4, board.GP2, board.GP1],
column_pins=[board.GP26, board.GP27, board.GP28],
columns_to_anodes=False,
)
rgb = RGB(
pixel_pin=mcp.get_pin(6),
num_pixels=16,
val_limit=100,
hue_default=0,
animation='RIPPLE',
)
keyboard.extensions.append(rgb)
# OLED Setup
oled = Oled(
width=128, height=32, i2c=busio.I2C(board.GP6, board.GP7)
)
def oled_callback(oled):
oled.clear()
oled.text(f'Batt: {battery}%', 0, 0)
oled.text(f'Vol: {volume}%', 0, 10)
oled.show()
oled.set_callback(oled_callback)
keyboard.extensions.append(oled)
# Host Communication
import usb_cdc
serial = usb_cdc.data
def handle_host_commands():
if serial.in_waiting > 0:
data = serial.readline().decode().strip()
if data.startswith("BATT:"):
global battery
battery = int(data.split(":")[1])
elif data.startswith("VOL:"):
global volume
volume = int(data.split(":")[1])
if __name__ == '__main__':
while True:
handle_host_commands()
keyboard.go()

Binary file not shown.

View file

@ -0,0 +1,33 @@
# ControlBoard
![image](ControlBoard.png)
A 2 knob, 9 switch macropad with a 128x32 OLED.
All powered by a Seeed XIAO RP2040 along with a MCP23017.
## Why
It would help me when I don't have my mouse with me, can be used with my laptop to control volume, brightness, etc. The possibilities are endless!
## BOM:
- 9x Cherry MX Switches
- 2x EC11 Encoder WITH button
- 1x 0.91in 128x32px OLED (SSD1306)
- 1x MCP23017
- 1x PCB
- 4x M3x20mm screws
- 1x Bottom case (3D Printed)
- 1x Top plate (3D Printed)
- 1x Encoder knob (3D Printed)
- 1x Switch plate (Laser-cut acrylic)
- 1x Through-hole 4.7k resistor
- 1x Seeed XIAO RP2040
## Challenges:
I am new to PCB design and 3D design, so i had to learn a lot of things, the guides really game in handy.
Schematic | PCB | Case
:-------------------------:|:-------------------------:|:-------------------------:|
![image](https://github.com/user-attachments/assets/47e60830-810e-4c88-b23d-02feb969890a) | ![image](https://github.com/user-attachments/assets/728c2853-8688-4fe4-a8e5-acafb7fc76a6) | ![image](https://github.com/user-attachments/assets/88584854-1404-4d92-80f4-a796fb8cb5a5)

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

View file

@ -0,0 +1,141 @@
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>
#include <Encoder.h>
#include <TimeLib.h>
// Pin definitions
#define ENCODER_A_PIN 0 // D0 (GP0) Volume Encoder A
#define ENCODER_B_PIN 1 // D1 (GP1) Volume Encoder B
#define LED_ENC_A_PIN 2 // D2 (GP2) LED Encoder A
#define LED_ENC_B_PIN 3 // D3 (GP3) LED Encoder B
#define SWITCH1_PIN 6 // D6 (GP6) Switch 1 (Ctrl+A)
#define SWITCH2_PIN 7 // D7 (GP7) Switch 2 (Ctrl+C)
#define SWITCH3_PIN 8 // D8 (GP8) Switch 3 (Ctrl+V)
#define LED_PIN 9 // D9 (GP9) LED Data In
// OLED display size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// I2C address for SSD1306
#define OLED_I2C_ADDR 0x3C // Common address for 128x64 OLED displays
// Initialize OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Initialize LED strip (using NeoPixel library)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, LED_PIN, NEO_GRB + NEO_KHZ800);
// Initialize encoders
Encoder volumeEncoder(ENCODER_A_PIN, ENCODER_B_PIN);
Encoder ledEncoder(LED_ENC_A_PIN, LED_ENC_B_PIN);
// Variables for controlling LED brightness and volume
int ledBrightness = 128; // LED brightness (0 to 255)
int volumeLevel = 50; // Volume level (0 to 100)
// Last encoder positions
long lastVolumePos = -999;
long lastLedPos = -999;
// Variables for switches and color adjustments
bool switch1State = false; // Ctrl+A
bool switch2State = false; // Ctrl+C
bool switch3State = false; // Ctrl+V
bool randomColor = false; // Flag for random color mode
void setup() {
// Initialize serial monitor
Serial.begin(115200);
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDR)) {
Serial.println(F("SSD1306 allocation failed"));
while (true); // Infinite loop if initialization fails
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
// Initialize LED strip
strip.begin();
strip.setBrightness(ledBrightness);
strip.show();
// Set switch pins as input
pinMode(SWITCH1_PIN, INPUT_PULLUP);
pinMode(SWITCH2_PIN, INPUT_PULLUP);
pinMode(SWITCH3_PIN, INPUT_PULLUP);
// Set encoder pins as input
pinMode(ENCODER_A_PIN, INPUT);
pinMode(ENCODER_B_PIN, INPUT);
// Set time (you can update this with a real-time clock module if desired)
setTime(12, 0, 0, 1, 2, 2025); // Set to 12:00 PM, Feb 1, 2025
}
void loop() {
// Check switch states
switch1State = digitalRead(SWITCH1_PIN) == LOW;
switch2State = digitalRead(SWITCH2_PIN) == LOW;
switch3State = digitalRead(SWITCH3_PIN) == LOW;
// Update the volume encoder
long volumePos = volumeEncoder.read();
if (volumePos != lastVolumePos) {
volumeLevel = constrain(map(volumePos, 0, 1000, 0, 100), 0, 100);
lastVolumePos = volumePos;
}
// Update the LED encoder (for brightness)
long ledPos = ledEncoder.read();
if (ledPos != lastLedPos) {
ledBrightness = constrain(map(ledPos, 0, 1000, 0, 255), 0, 255);
strip.setBrightness(ledBrightness);
strip.show();
lastLedPos = ledPos;
}
// Update OLED display
display.clearDisplay();
display.setCursor(0, 0);
display.print("Time: ");
display.print(hour());
display.print(":");
display.print(minute());
display.print(":");
display.print(second());
display.setCursor(0, 16);
display.print("Volume: ");
display.print(volumeLevel);
display.setCursor(0, 32);
display.print("Brightness: ");
display.print(ledBrightness);
// Color adjustment (random color or set color)
if (switch1State) {
randomColor = false;
strip.setPixelColor(0, strip.Color(255, 0, 0)); // Red color
} else if (switch2State) {
randomColor = false;
strip.setPixelColor(0, strip.Color(0, 255, 0)); // Green color
} else if (switch3State) {
randomColor = !randomColor;
}
if (randomColor) {
// Generate random color
int r = random(0, 256);
int g = random(0, 256);
int b = random(0, 256);
strip.setPixelColor(0, strip.Color(r, g, b)); // Random color
}
strip.show();
display.display();
delay(100); // Update screen and strip every 100 ms
}

View file

@ -0,0 +1,91 @@
import board
import digitalio
import time
import random
import displayio
from adafruit_display_shapes.rect import Rect
from adafruit_displayio_ssd1306 import SSD1306
import adafruit_neopixel
# Pin definitions
ENCODER_A_PIN = board.GP0 # D0 (GP0) Volume Encoder A
ENCODER_B_PIN = board.GP1 # D1 (GP1) Volume Encoder B
LED_ENC_A_PIN = board.GP2 # D2 (GP2) LED Encoder A
LED_ENC_B_PIN = board.GP3 # D3 (GP3) LED Encoder B
SWITCH1_PIN = board.GP6 # D6 (GP6) Switch 1 (Ctrl+A)
SWITCH2_PIN = board.GP7 # D7 (GP7) Switch 2 (Ctrl+C)
SWITCH3_PIN = board.GP8 # D8 (GP8) Switch 3 (Ctrl+V)
LED_PIN = board.GP9 # D9 (GP9) LED Data In
# Initialize OLED display
display_bus = displayio.I2CDisplay(board.I2C(), device_address=0x3C)
display = SSD1306(display_bus, width=128, height=64)
# Initialize LED strip (NeoPixel)
strip = adafruit_neopixel.NeoPixel(LED_PIN, 1, brightness=0.5, auto_write=False)
# Initialize switch pins as input
switch1 = digitalio.DigitalInOut(SWITCH1_PIN)
switch1.switch_to_input(pull=digitalio.Pull.UP)
switch2 = digitalio.DigitalInOut(SWITCH2_PIN)
switch2.switch_to_input(pull=digitalio.Pull.UP)
switch3 = digitalio.DigitalInOut(SWITCH3_PIN)
switch3.switch_to_input(pull=digitalio.Pull.UP)
# Setup encoders (using a simple method to count steps)
last_volume_pos = 0
last_led_pos = 0
volume_level = 50 # Volume level (0 to 100)
led_brightness = 128 # LED brightness (0 to 255)
# Time setup (use built-in time module)
# Set to 12:00 PM, Feb 1, 2025
current_time = time.struct_time((2025, 2, 1, 12, 0, 0, 0, 0, 0))
# Loop
while True:
# Read switch states
switch1_state = not switch1.value
switch2_state = not switch2.value
switch3_state = not switch3.value
# Handle encoder position changes (simulate with pin states)
volume_pos = int(time.monotonic() * 10) % 1000 # Simulate volume change for testing
led_pos = int(time.monotonic() * 5) % 1000 # Simulate LED brightness change
# Update volume and LED brightness if positions change
if volume_pos != last_volume_pos:
volume_level = min(max(volume_pos // 10, 0), 100) # Map to 0-100 range
last_volume_pos = volume_pos
if led_pos != last_led_pos:
led_brightness = min(max(led_pos // 4, 0), 255) # Map to 0-255 range
strip.brightness = led_brightness / 255 # Map brightness to 0-1 range
strip.show()
last_led_pos = led_pos
# Display current time
display.fill(0) # Clear the screen
display.text(f"Time: {current_time.tm_hour}:{current_time.tm_min:02d}:{current_time.tm_sec:02d}", 0, 0)
display.text(f"Volume: {volume_level}", 0, 16)
display.text(f"Brightness: {led_brightness}", 0, 32)
# Color adjustment (random color or set color)
if switch1_state:
strip.fill((255, 0, 0)) # Red color
elif switch2_state:
strip.fill((0, 255, 0)) # Green color
elif switch3_state:
# Generate random color
if random.choice([True, False]):
r, g, b = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
strip.fill((r, g, b)) # Random color
else:
strip.fill((0, 0, 255)) # Blue color
strip.show()
display.show()
time.sleep(0.1) # Update every 100 ms

Binary file not shown.
1 ID Name Designator Footprint Quantity Manufacturer Part Manufacturer Supplier Supplier Part Price Pins Contributor JLCPCB Part Class link
2 1 DISPLAY-OLED-128X64-I2C 1 DISPLAY-OLED-128X64-I2C 1 4 Ferran Soliva Alvarez
3 2 1N4148 D1,D2,D3,D4 1N4148_1N4148W 4 2 lkjhwnsgur
4 3 SK6812MINI-EA ASM LED1,LED2,LED3,LED4,LED5,LED6 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 6 SK6812MINI-EA 欧思科光电 LCSC C5378731 0.099 4 lcsc Extended Part
5 4 10kΩ R1,R2,R3 RES_TH_250MW 3 RN 1/4W 10K F T/B A1 Tyohm(幸亚电阻) LCSC C410695 0.01 2 Deepak Sahu Extended Part
6 5 Cherry MX brown S1,S2,S3,S4 MX1A 4 MX1A-11NW Mouser 540-MX1A-11NW 2 thijsvader http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf
7 6 Seeed XIAO RP2040 ALL PINS U1 SEEED XIAO RP2040 1 102010328 Seeedstudio 20 Derick2k https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html
8 7 ROTARY_ENCODERS_EC11 U2,U3 ROTARY_ENCODERS_EC11 2 7 Gona_Order

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.
1 Designator Footprint Mid X Mid Y Ref X Ref Y Pad X Pad Y Layer Rotation Comment
2 1 DISPLAY-OLED-128X64-I2C 80.26mm 85.09mm 80.26mm 72.39mm 76.45mm 85.09mm T 0 DISPLAY-OLED-128X64-I2C
3 D1 1N4148_1N4148W 41.78mm 63.88mm 41.78mm 63.88mm 45.59mm 63.88mm T 0 1N4148
4 D2 1N4148_1N4148W 41.78mm 60.2mm 41.78mm 60.2mm 45.59mm 60.2mm T 0 1N4148
5 D3 1N4148_1N4148W 51.94mm 63.88mm 51.94mm 63.88mm 55.75mm 63.88mm T 0 1N4148
6 D4 1N4148_1N4148W 51.94mm 60.2mm 51.94mm 60.2mm 55.75mm 60.2mm T 0 1N4148
7 LED1 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 30.61mm 46.36mm 30.61mm 46.36mm 29.86mm 48.86mm T 270 SK6812MINI-EA ASM
8 LED2 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 30.61mm 33.66mm 30.61mm 33.66mm 29.86mm 36.16mm T 270 SK6812MINI-EA ASM
9 LED3 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 54.74mm 46.36mm 54.74mm 46.36mm 53.99mm 48.86mm T 270 SK6812MINI-EA ASM
10 LED4 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 54.74mm 33.66mm 54.74mm 33.66mm 53.99mm 36.16mm T 270 SK6812MINI-EA ASM
11 LED5 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 78.87mm 46.36mm 78.87mm 46.36mm 78.12mm 48.86mm T 270 SK6812MINI-EA ASM
12 LED6 LED-SMD_4P-L3.2-W2.8_SK6812MINI-EA ASM 78.87mm 33.66mm 78.87mm 33.66mm 78.12mm 36.16mm T 270 SK6812MINI-EA ASM
13 R1 RES_TH_250MW 36.58mm 85.09mm 36.58mm 85.09mm 31.43mm 85.09mm T 0 10kΩ
14 R2 RES_TH_250MW 36.58mm 80.9mm 36.58mm 80.9mm 31.43mm 80.9mm T 0 10kΩ
15 R3 RES_TH_250MW 36.58mm 76.58mm 36.58mm 76.58mm 31.43mm 76.58mm T 0 10kΩ
16 S1 MX1A 17.91mm 43.82mm 18.54mm 40.01mm 14.73mm 42.55mm T 0 Cherry MX brown
17 S2 MX1A 42.04mm 43.82mm 42.67mm 40.01mm 38.86mm 42.55mm T 0 Cherry MX brown
18 S3 MX1A 66.17mm 43.82mm 66.8mm 40.01mm 62.99mm 42.55mm T 0 Cherry MX brown
19 S4 MX1A 90.3mm 43.82mm 90.93mm 40.01mm 87.12mm 42.55mm T 0 Cherry MX brown
20 U1 SEEED XIAO RP2040 54.74mm 82.3mm 54.74mm 82.3mm 46.28mm 90.11mm T 0 Seeed XIAO RP2040 ALL PINS
21 U2 ROTARY_ENCODERS_EC11 20.38mm 80.37mm 20.07mm 81.03mm 13.98mm 80.62mm T 0 ROTARY_ENCODERS_EC11
22 U3 ROTARY_ENCODERS_EC11 20.38mm 60.81mm 20.07mm 61.47mm 13.98mm 61.06mm T 0 ROTARY_ENCODERS_EC11

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,44 @@
MacroPad V.1
This is a simple macropad with 4 switches and 2 rotary encoders. Each having the following functions:
------Switches------
1.) Ctrl+A
2.) Ctrl+C
3.) Ctrl+V
4.) LED Color and Pattern Control
------Rotary Encoders------
5.) LED Brigthness
6.) Voulme Control
Inspiration:
I was inspired by the design of Ducc's Hackpad and based my design off it.
Challenges:
The biggest challenge I faced was designing the CAD model. It was just a pain. lol
BOM:
4x Cherry MX Brown switches
2x EC11 Encoder
3x PCB (Black & Gold)
4x Through-hole 1N4148 Diodes
6x WS2812B LEDs
1x 0.96 OLED
3x Resistors 10k Ohm
6x Blank DSA Keycaps BLACK (2 as Backups)
4x M3x16 Bolt
4x M3 Heatset
**3D prints BLACK**
PCB Images:
| ![3D](https://github.com/KiaKia86/hackpad/blob/main/hackpads/Macro%20Pad%20V.1/PCB/PCB%20Picturres/3DJPG.jpg) | ![Layout](https://github.com/KiaKia86/hackpad/blob/main/hackpads/Macro%20Pad%20V.1/PCB/PCB%20Picturres/LayoutJPG.jpg) | ![Schematic](https://github.com/KiaKia86/hackpad/blob/main/hackpads/Macro%20Pad%20V.1/PCB/PCB%20Picturres/SchematicJPG.jpg) |
|---------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
Case Images:
| ![AssmembledCase](https://github.com/KiaKia86/hackpad/blob/main/hackpads/Macro%20Pad%20V.1/CAD/Case%20Pictures/AssembledCase.jpg) | ![BottomCase](https://github.com/KiaKia86/hackpad/blob/main/hackpads/Macro%20Pad%20V.1/CAD/Case%20Pictures/BottomCase.jpg) | ![TopCase](https://github.com/KiaKia86/hackpad/blob/main/hackpads/Macro%20Pad%20V.1/CAD/Case%20Pictures/TopCase.jpg) |
|-----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|

File diff suppressed because it is too large Load diff

20
ren_macropad/README.md Normal file
View file

@ -0,0 +1,20 @@
# Ren's Macropad
# Macropad
![macropad](./assets/macropad.PNG "a title")
# Schematic
![schematic](./assets/schematic.PNG "a title")
# PCB
![pcb](./assets/pcb.PNG "a title")
# BOM
* 1 x Xiao RP2040 DIP
* 1 x EC11 Rotary encoder
* 2 x SK6812 MINI-E LEDs
* 4 x M3x16mm screws
* 4 x M3 hex nuts
* 9 x Through-hole 1N4148 Diodes
* 9 x MX-Style switches
* 9 x WHITE Blank DSA keycaps

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 KiB

BIN
ren_macropad/assets/pcb.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -0,0 +1,4 @@
Autodesk isn't verifying me so I made the CAD in OnShape
Link here
https://cad.onshape.com/documents/24e0c818919de7b39e65950e/w/522bde8f70bad49a42233091/e/26df3379b8976cfb458853fe?renderMode=0&uiState=67b3f0fdfa311377b4000efa

View file

@ -0,0 +1,30 @@
import board
from kmk.kmk_keyboard import KMKKeyboard
from kmk.scanners.keypad import KeysScanner
from kmk.keys import KC
from kmk.modules.macros import Press, Release, Tap, Macros
keyboard = KMKKeyboard()
macros = Macros()
keyboard.modules.append(macros)
PINS = [board.D3, board.D4, board.D2, board.D1]
# Tell kmk we are not using a key matrix
keyboard.matrix = KeysScanner(
pins=PINS,
value_when_pressed=False,
)
# Here you define the buttons corresponding to the pins
# Look here for keycodes: https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/keycodes.md
# And here for macros: https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/macros.md
keyboard.keymap = [
[KC.A, KC.W, KC.S, KC.D,]
]
# Start kmk!
if __name__ == '__main__':
keyboard.go()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,584 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.05,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.1,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "macropad.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"name": "Grouped By Value",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"997fbc7e-9b0d-41bc-8e17-9e7023a14b22",
"Root"
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,30 @@
import board
from kmk.kmk_keyboard import KMKKeyboard
from kmk.scanners.keypad import KeysScanner
from kmk.keys import KC
from kmk.modules.macros import Press, Release, Tap, Macros
keyboard = KMKKeyboard()
macros = Macros()
keyboard.modules.append(macros)
PINS = [board.D3, board.D4, board.D2, board.D1]
# Tell kmk we are not using a key matrix
keyboard.matrix = KeysScanner(
pins=PINS,
value_when_pressed=False,
)
# Here you define the buttons corresponding to the pins
# Look here for keycodes: https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/keycodes.md
# And here for macros: https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/macros.md
keyboard.keymap = [
[KC.A, KC.W, KC.S, KC.D,]
]
# Start kmk!
if __name__ == '__main__':
keyboard.go()