Merge pull request #713 from QuantumKya/main

Add my hackpad
This commit is contained in:
Taran Mittal 2025-10-11 14:26:39 +11:00 committed by GitHub
commit e46fa6905a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 135485 additions and 0 deletions

View file

@ -0,0 +1,44 @@
# RohansMacroPad
![Render](readme_images/full_render.png)
## What it is
I wanted to follow the tutorial on [hackpad.hackclub.com](hackpad.hackclub.com) accurately and make a macropad.
### Specs
BOM:
- 4x Cherry MX Switches
- 1x SK6812 MINI Leds
- 1x RotaryEncoder_Switch
- 1x XIAO RP2040
- 4x Blank DSA Keycaps
- 4x M3x16 Bolt
- 4x M3 Heatset
Others:
- KMK - main.py
- Hackpad Base.step
- Hackpad Cover.step
## What it does
Gives me one point on Highway per extra key I will now have to press and make my computer do things.
## What it looks like
This is an image of the PCB plan, from KiCad.
![PCB](readme_images/pcb.png)
This is an image of the schematic, from KiCad.
![Schematic](readme_images/schematic.png)
This is an image of the Hackpad case.
![Hackpad Case](readme_images/hackpad_render.png)
## How I made it
I followed the tutorial on Hackclub's website! It was very good at teaching me the basics of everything!
I kinda gave up for a few weeks before picking it back up again. I am working on my Summer of Making project at the same time!
I made a big mistake, and tried to submit the same thing as in the tutorial. I missed the part where it specifies that it must be something different, LOL.
I fixed it all up pretty quick after that, though, spending two days making my own unique design and submitting it.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,56 @@
# You import all the IOs of your board
import board
# These are imports from the kmk library
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
from kmk.modules.encoder import EncoderHandler
from kmk.extensions.rgb import RGB
# This is the main instance of your keyboard
keyboard = KMKKeyboard()
# Add the macro extension
macros = Macros()
keyboard.modules.append(macros)
# Rotary Encoder implementation
encoder_handler = EncoderHandler()
keyboard.modules.append(encoder_handler)
encoder_handler.pins = ((board.A0, board.A1),) # A0 = GPIO26, A1 = GPIO27
encoder_handler.map = [((KC.VOLD, KC.VOLU),)] # Rotate left/right
# LED implementation
rgb_ext = RGB(pixel_pin=board.D4, num_pixels=1)
keyboard.extensions.append(rgb_ext)
# Define your pins here!
PINS = [board.D1, board.D2, board.D4, board.D3]
# Encoder button
PINS.append(board.A2)
# 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.DELETE,
KC.MACRO("Hello world!"),
KC.Macro(Press(KC.LCMD), Tap(KC.S), Release(KC.LCMD)),
KC.ENTER,
]
]
# Start kmk!
if __name__ == '__main__':
keyboard.go()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,30 @@
M48
; DRILL file {KiCad 9.0.2} date 2025-06-28T17:49:50-0500
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2025-06-28T17:49:50-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.2
; #@! TF.FileFunction,NonPlated,1,2,NPTH
FMAT,2
METRIC
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
T1C1.700
; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill
T2C4.000
%
G90
G05
T1
X156.87Y-129.0
X167.03Y-129.0
X175.92Y-109.955
X175.92Y-129.0
X186.08Y-109.955
X186.08Y-129.0
X194.97Y-129.0
X205.13Y-129.0
T2
X161.95Y-129.0
X181.0Y-109.955
X181.0Y-129.0
X200.05Y-129.0
M30

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,53 @@
M48
; DRILL file {KiCad 9.0.2} date 2025-06-28T17:49:50-0500
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2025-06-28T17:49:50-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.2
; #@! TF.FileFunction,Plated,1,2,PTH
FMAT,2
METRIC
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T1C0.889
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T2C1.000
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T3C1.500
%
G90
G05
T1
X173.38Y-80.38
X173.38Y-82.92
X173.38Y-85.46
X173.38Y-88.0
X173.38Y-90.54
X173.38Y-93.08
X173.38Y-95.62
X188.62Y-80.38
X188.62Y-82.92
X188.62Y-85.46
X188.62Y-88.0
X188.62Y-90.54
X188.62Y-93.08
X188.62Y-95.62
T2
X193.5Y-84.0
X193.5Y-86.5
X193.5Y-89.0
X208.0Y-84.0
X208.0Y-89.0
T3
X158.14Y-126.46
X164.49Y-123.92
X177.19Y-107.415
X177.19Y-126.46
X183.54Y-104.875
X183.54Y-123.92
X196.24Y-126.46
X202.59Y-123.92
T3
X200.35Y-80.9G85X201.65Y-80.9
G05
X200.35Y-92.1G85X201.65Y-92.1
G05
M30

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,130 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 1.0,
"shapes": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": false,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
"vias",
"footprint_text",
"footprint_anchors",
"ratsnest",
"grid",
"footprints_front",
"footprints_back",
"footprint_values",
"footprint_references",
"tracks",
"drc_errors",
"drawing_sheet",
"bitmaps",
"pads",
"zones",
"drc_warnings",
"locked_item_shadows",
"conflict_shadows",
"shapes"
],
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
"zone_display_mode": 0
},
"git": {
"repo_type": "",
"repo_username": "",
"ssh_key": ""
},
"meta": {
"filename": "hackpad.kicad_prl",
"version": 5
},
"net_inspector_panel": {
"col_hidden": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
],
"col_order": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
],
"col_widths": [
149,
137,
90,
63,
90,
90,
90,
66,
90,
90
],
"custom_group_rules": [],
"expanded_rows": [],
"filter_by_net_name": true,
"filter_by_netclass": true,
"filter_text": "",
"group_by_constraint": false,
"group_by_netclass": false,
"show_unconnected_nets": false,
"show_zero_pad_nets": false,
"sort_ascending": true,
"sorting_column": 0
},
"open_jobsets": [],
"project": {
"files": []
},
"schematic": {
"selection_filter": {
"graphics": true,
"images": true,
"labels": true,
"lockedItems": false,
"otherItems": true,
"pins": true,
"symbols": true,
"text": true,
"wires": true
}
}
}

View file

@ -0,0 +1,630 @@
{
"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": true,
"text_position": 0,
"units_format": 0
},
"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": [],
"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_on_edge_cuts": "error",
"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": [],
"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_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": "hackpad.kicad_pro",
"version": 3
},
"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": 2147483647,
"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": "../../Desktop/hackpad/pcb/",
"pos_files": "",
"specctra_dsn": "",
"step": "hackpad.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
},
{
"group_by": false,
"label": "Description",
"name": "Description",
"show": false
},
{
"group_by": false,
"label": "#",
"name": "${ITEM_NUMBER}",
"show": false
}
],
"filter_string": "",
"group_symbols": true,
"include_excluded_from_bom": true,
"name": "",
"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": "",
"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": [
[
"3893d36f-897f-45a1-b90c-791583b3f0a2",
"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,56 @@
# You import all the IOs of your board
import board
# These are imports from the kmk library
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
from kmk.modules.encoder import EncoderHandler
from kmk.extensions.rgb import RGB
# This is the main instance of your keyboard
keyboard = KMKKeyboard()
# Add the macro extension
macros = Macros()
keyboard.modules.append(macros)
# Rotary Encoder implementation
encoder_handler = EncoderHandler()
keyboard.modules.append(encoder_handler)
encoder_handler.pins = ((board.A0, board.A1),) # A0 = GPIO26, A1 = GPIO27
encoder_handler.map = [((KC.VOLD, KC.VOLU),)] # Rotate left/right
# LED implementation
rgb_ext = RGB(pixel_pin=board.D4, num_pixels=1)
keyboard.extensions.append(rgb_ext)
# Define your pins here!
PINS = [board.D1, board.D2, board.D4, board.D3]
# Encoder button
PINS.append(board.A2)
# 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.DELETE,
KC.MACRO("Hello world!"),
KC.Macro(Press(KC.LCMD), Tap(KC.S), Release(KC.LCMD)),
KC.ENTER,
]
]
# Start kmk!
if __name__ == '__main__':
keyboard.go()

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB