Add 8HP layout with fully automated routing pipeline
- Update PCB to 8HP format (40x100mm) with v2 component placement - Add automated routing scripts (autoroute.py runs full pipeline headlessly) - Update panel spec and SVG for 8HP dimensions - Board routes in <1 second with 0 unconnected pads Scripts: - autoroute.py: Full CLI pipeline (place → export → route → import → DRC) - autoroute_full.py: Same pipeline for KiCad scripting console - place_8hp.py: Component placement only - route.sh/freeroute.sh: Routing helpers
This commit is contained in:
+7464
-131
File diff suppressed because it is too large
Load Diff
+541
-17
@@ -3,83 +3,585 @@
|
||||
"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.1,
|
||||
"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.15,
|
||||
"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.15,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.15
|
||||
"silk_text_thickness": 0.15,
|
||||
"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.2,
|
||||
"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.2,
|
||||
"min_via_annular_width": 0.15,
|
||||
"min_via_diameter": 0.5
|
||||
"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.2,
|
||||
0.3,
|
||||
0.5,
|
||||
0.8
|
||||
],
|
||||
"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.6,
|
||||
"drill": 0.3
|
||||
}
|
||||
]
|
||||
],
|
||||
"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": "SN-L00.kicad_pro",
|
||||
"version": 1
|
||||
"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
|
||||
},
|
||||
{
|
||||
"clearance": 0.3,
|
||||
"name": "Power",
|
||||
"track_width": 0.5,
|
||||
"via_diameter": 0.8,
|
||||
"via_drill": 0.4
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
]
|
||||
],
|
||||
"meta": {
|
||||
"version": 4
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"specctra_dsn": "",
|
||||
"step": ""
|
||||
"netlist": "./",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "SN-L00.dsn",
|
||||
"step": "",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 1,
|
||||
"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": [],
|
||||
@@ -90,15 +592,37 @@
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.25,
|
||||
"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": 0.0,
|
||||
"text_offset_ratio": 0.08
|
||||
},
|
||||
"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": [],
|
||||
"sheets": [
|
||||
[
|
||||
"a0e1b2c3-d4e5-f6a7-b8c9-d0e1f2a3b4c5",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
||||
|
||||
+6006
-1163
File diff suppressed because it is too large
Load Diff
@@ -1,157 +1,211 @@
|
||||
(footprint "OLED_128x32_I2C"
|
||||
(version 20240108)
|
||||
(generator "pcbnew")
|
||||
(generator_version "8.0")
|
||||
(layer "F.Cu")
|
||||
(descr "0.91 inch 128x32 OLED display module, I2C interface, 4-pin header")
|
||||
(tags "OLED SSD1306 display I2C")
|
||||
(attr through_hole)
|
||||
|
||||
;; Typical 0.91" OLED module dimensions:
|
||||
;; PCB: ~38mm x 12mm (varies by manufacturer)
|
||||
;; Active display: ~22mm x 6mm
|
||||
;; Pin header: 4 pins at 2.54mm pitch on one edge
|
||||
|
||||
;; Reference and value
|
||||
(property "Reference" "MOD2"
|
||||
(at 0 -9 0)
|
||||
(layer "F.SilkS")
|
||||
(uuid "ref-text")
|
||||
(effects
|
||||
(font (size 1 1) (thickness 0.15))
|
||||
)
|
||||
)
|
||||
(property "Value" "OLED_128x32"
|
||||
(at 0 9 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "val-text")
|
||||
(effects
|
||||
(font (size 1 1) (thickness 0.15))
|
||||
)
|
||||
)
|
||||
|
||||
;; Module PCB outline on Fab layer
|
||||
(fp_rect
|
||||
(start -19 -6)
|
||||
(end 19 6)
|
||||
(stroke (width 0.1) (type solid))
|
||||
(fill none)
|
||||
(layer "F.Fab")
|
||||
(uuid "module-outline")
|
||||
)
|
||||
|
||||
;; Silkscreen outline
|
||||
(fp_rect
|
||||
(start -19.5 -6.5)
|
||||
(end 19.5 6.5)
|
||||
(stroke (width 0.12) (type solid))
|
||||
(fill none)
|
||||
(layer "F.SilkS")
|
||||
(uuid "silk-outline")
|
||||
)
|
||||
|
||||
;; Display active area indication
|
||||
(fp_rect
|
||||
(start -11 -3)
|
||||
(end 11 3)
|
||||
(stroke (width 0.12) (type solid))
|
||||
(fill none)
|
||||
(layer "F.SilkS")
|
||||
(uuid "display-area")
|
||||
)
|
||||
(fp_text user "DISPLAY"
|
||||
(at 0 0 0)
|
||||
(layer "F.SilkS")
|
||||
(uuid "display-text")
|
||||
(effects
|
||||
(font (size 1 1) (thickness 0.15))
|
||||
)
|
||||
)
|
||||
|
||||
;; Pin 1 indicator
|
||||
(fp_circle
|
||||
(center -18 4.5)
|
||||
(end -17.5 4.5)
|
||||
(stroke (width 0.12) (type solid))
|
||||
(fill solid)
|
||||
(layer "F.SilkS")
|
||||
(uuid "pin1-dot")
|
||||
)
|
||||
|
||||
;; Courtyard
|
||||
(fp_rect
|
||||
(start -20.5 -7.5)
|
||||
(end 20.5 7.5)
|
||||
(stroke (width 0.05) (type solid))
|
||||
(fill none)
|
||||
(layer "F.CrtYd")
|
||||
(uuid "courtyard")
|
||||
)
|
||||
|
||||
;; Pin header at left edge
|
||||
;; Pins centered vertically, left edge at X=-17
|
||||
;; 4 pins at 2.54mm pitch
|
||||
|
||||
;; Pin 1: GND
|
||||
(pad "1" thru_hole rect
|
||||
(at -17 3.81)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-1")
|
||||
)
|
||||
;; Pin 2: VCC
|
||||
(pad "2" thru_hole oval
|
||||
(at -17 1.27)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-2")
|
||||
)
|
||||
;; Pin 3: SCL
|
||||
(pad "3" thru_hole oval
|
||||
(at -17 -1.27)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-3")
|
||||
)
|
||||
;; Pin 4: SDA
|
||||
(pad "4" thru_hole oval
|
||||
(at -17 -3.81)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-4")
|
||||
)
|
||||
|
||||
;; Pin labels on Fab layer
|
||||
(fp_text user "GND"
|
||||
(at -14 3.81 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-1")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "VCC"
|
||||
(at -14 1.27 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-2")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "SCL"
|
||||
(at -14 -1.27 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-3")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "SDA"
|
||||
(at -14 -3.81 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-4")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
|
||||
;; Alternative: Some modules have pins on bottom edge
|
||||
;; Uncomment and adjust if your module is different
|
||||
;; (pad "1" thru_hole rect (at -3.81 5) ...)
|
||||
(version 20241229)
|
||||
(generator "pcbnew")
|
||||
(layer "F.Cu")
|
||||
(descr "0.91 inch 128x32 OLED display module, I2C interface, 4-pin header")
|
||||
(tags "OLED SSD1306 display I2C")
|
||||
(property "Reference" "MOD"
|
||||
(at 0 -9 0)
|
||||
(layer "F.SilkS")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Value" "OLED_128x32"
|
||||
(at 0 9 0)
|
||||
(layer "F.Fab")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(attr through_hole)
|
||||
(fp_line
|
||||
(start -19.5 -6.5)
|
||||
(end 19.5 -6.5)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start 19.5 -6.5)
|
||||
(end 19.5 6.5)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start 19.5 6.5)
|
||||
(end -19.5 6.5)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start -19.5 6.5)
|
||||
(end -19.5 -6.5)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start -20.5 -7.5)
|
||||
(end 20.5 -7.5)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start 20.5 -7.5)
|
||||
(end 20.5 7.5)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start 20.5 7.5)
|
||||
(end -20.5 7.5)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start -20.5 7.5)
|
||||
(end -20.5 -7.5)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start -19 -6)
|
||||
(end 19 -6)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start 19 -6)
|
||||
(end 19 6)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start 19 6)
|
||||
(end -19 6)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start -19 6)
|
||||
(end -19 -6)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start -11 -3)
|
||||
(end 11 -3)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start 11 -3)
|
||||
(end 11 3)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start 11 3)
|
||||
(end -11 3)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start -11 3)
|
||||
(end -11 -3)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_text user "${REFERENCE}"
|
||||
(at 0 0 0)
|
||||
(layer "F.Fab")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(pad "1" thru_hole rect
|
||||
(at -17 3.81)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "2" thru_hole circle
|
||||
(at -17 1.27)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "3" thru_hole circle
|
||||
(at -17 -1.27)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "4" thru_hole circle
|
||||
(at -17 -3.81)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(embedded_fonts no)
|
||||
)
|
||||
|
||||
@@ -1,360 +1,273 @@
|
||||
(footprint "RP2040-Zero"
|
||||
(version 20240108)
|
||||
(generator "pcbnew")
|
||||
(generator_version "8.0")
|
||||
(layer "F.Cu")
|
||||
(descr "Waveshare RP2040-Zero module, 2x9 pin headers, 2.54mm pitch")
|
||||
(tags "RP2040 Pico Zero Waveshare")
|
||||
(attr through_hole)
|
||||
|
||||
;; RP2040-Zero dimensions:
|
||||
;; Board: 23.5mm x 18mm
|
||||
;; Pin rows: 2.54mm pitch, 9 pins each side
|
||||
;; Row spacing: 15.24mm (600mil) center to center
|
||||
;; USB-C on top edge
|
||||
|
||||
;; Reference and value
|
||||
(property "Reference" "MOD1"
|
||||
(at 0 -13 0)
|
||||
(layer "F.SilkS")
|
||||
(uuid "ref-text")
|
||||
(effects
|
||||
(font (size 1 1) (thickness 0.15))
|
||||
)
|
||||
)
|
||||
(property "Value" "RP2040-Zero"
|
||||
(at 0 13 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "val-text")
|
||||
(effects
|
||||
(font (size 1 1) (thickness 0.15))
|
||||
)
|
||||
)
|
||||
|
||||
;; Board outline on Fab layer
|
||||
(fp_rect
|
||||
(start -9 -11.75)
|
||||
(end 9 11.75)
|
||||
(stroke (width 0.1) (type solid))
|
||||
(fill none)
|
||||
(layer "F.Fab")
|
||||
(uuid "board-outline")
|
||||
)
|
||||
|
||||
;; Silkscreen outline (slightly larger)
|
||||
(fp_rect
|
||||
(start -9.5 -12.25)
|
||||
(end 9.5 12.25)
|
||||
(stroke (width 0.12) (type solid))
|
||||
(fill none)
|
||||
(layer "F.SilkS")
|
||||
(uuid "silk-outline")
|
||||
)
|
||||
|
||||
;; USB-C indicator on top
|
||||
(fp_rect
|
||||
(start -4.5 -11.75)
|
||||
(end 4.5 -9.5)
|
||||
(stroke (width 0.12) (type solid))
|
||||
(fill none)
|
||||
(layer "F.SilkS")
|
||||
(uuid "usb-indicator")
|
||||
)
|
||||
(fp_text user "USB-C"
|
||||
(at 0 -10.5 0)
|
||||
(layer "F.SilkS")
|
||||
(uuid "usb-text")
|
||||
(effects
|
||||
(font (size 0.8 0.8) (thickness 0.12))
|
||||
)
|
||||
)
|
||||
|
||||
;; Pin 1 indicator
|
||||
(fp_circle
|
||||
(center -8.5 -8.5)
|
||||
(end -8 -8.5)
|
||||
(stroke (width 0.12) (type solid))
|
||||
(fill solid)
|
||||
(layer "F.SilkS")
|
||||
(uuid "pin1-dot")
|
||||
)
|
||||
|
||||
;; Courtyard
|
||||
(fp_rect
|
||||
(start -10.5 -13)
|
||||
(end 10.5 13)
|
||||
(stroke (width 0.05) (type solid))
|
||||
(fill none)
|
||||
(layer "F.CrtYd")
|
||||
(uuid "courtyard")
|
||||
)
|
||||
|
||||
;; Left column pins (active low Y, starting from top)
|
||||
;; Pin spacing: 2.54mm, 9 pins = 8 gaps = 20.32mm total
|
||||
;; Center at Y=0, so pins go from Y=-10.16 to Y=+10.16
|
||||
|
||||
;; Left column (X = -7.62mm = -300mil from center)
|
||||
;; Pin 1: 5V
|
||||
(pad "1" thru_hole rect
|
||||
(at -7.62 -10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-1")
|
||||
)
|
||||
;; Pin 2: GND
|
||||
(pad "2" thru_hole oval
|
||||
(at -7.62 -7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-2")
|
||||
)
|
||||
;; Pin 3: 3V3
|
||||
(pad "3" thru_hole oval
|
||||
(at -7.62 -5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-3")
|
||||
)
|
||||
;; Pin 4: GP29
|
||||
(pad "4" thru_hole oval
|
||||
(at -7.62 -2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-4")
|
||||
)
|
||||
;; Pin 5: GP28
|
||||
(pad "5" thru_hole oval
|
||||
(at -7.62 0)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-5")
|
||||
)
|
||||
;; Pin 6: GP27
|
||||
(pad "6" thru_hole oval
|
||||
(at -7.62 2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-6")
|
||||
)
|
||||
;; Pin 7: GP26
|
||||
(pad "7" thru_hole oval
|
||||
(at -7.62 5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-7")
|
||||
)
|
||||
;; Pin 8: GP15
|
||||
(pad "8" thru_hole oval
|
||||
(at -7.62 7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-8")
|
||||
)
|
||||
;; Pin 9: GP14
|
||||
(pad "9" thru_hole oval
|
||||
(at -7.62 10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-9")
|
||||
)
|
||||
|
||||
;; Right column (X = +7.62mm = +300mil from center)
|
||||
;; Pin 10: 3V3
|
||||
(pad "10" thru_hole oval
|
||||
(at 7.62 -10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-10")
|
||||
)
|
||||
;; Pin 11: GND
|
||||
(pad "11" thru_hole oval
|
||||
(at 7.62 -7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-11")
|
||||
)
|
||||
;; Pin 12: GP0 (I2C SDA)
|
||||
(pad "12" thru_hole oval
|
||||
(at 7.62 -5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-12")
|
||||
)
|
||||
;; Pin 13: GP1 (I2C SCL)
|
||||
(pad "13" thru_hole oval
|
||||
(at 7.62 -2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-13")
|
||||
)
|
||||
;; Pin 14: GP2 (TRIG OUT)
|
||||
(pad "14" thru_hole oval
|
||||
(at 7.62 0)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-14")
|
||||
)
|
||||
;; Pin 15: GP3 (RETURN IN)
|
||||
(pad "15" thru_hole oval
|
||||
(at 7.62 2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-15")
|
||||
)
|
||||
;; Pin 16: GP4 (BTN)
|
||||
(pad "16" thru_hole oval
|
||||
(at 7.62 5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-16")
|
||||
)
|
||||
;; Pin 17: GP5
|
||||
(pad "17" thru_hole oval
|
||||
(at 7.62 7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-17")
|
||||
)
|
||||
;; Pin 18: GND
|
||||
(pad "18" thru_hole oval
|
||||
(at 7.62 10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1.0)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(uuid "pad-18")
|
||||
)
|
||||
|
||||
;; Pin labels on Fab layer
|
||||
(fp_text user "5V"
|
||||
(at -5 -10.16 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-1")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GND"
|
||||
(at -5 -7.62 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-2")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "3V3"
|
||||
(at -5 -5.08 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-3")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP29"
|
||||
(at -4.5 -2.54 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-4")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP28"
|
||||
(at -4.5 0 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-5")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP27"
|
||||
(at -4.5 2.54 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-6")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP26"
|
||||
(at -4.5 5.08 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-7")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP15"
|
||||
(at -4.5 7.62 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-8")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP14"
|
||||
(at -4.5 10.16 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-9")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "3V3"
|
||||
(at 5 -10.16 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-10")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GND"
|
||||
(at 5 -7.62 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-11")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP0"
|
||||
(at 4.5 -5.08 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-12")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP1"
|
||||
(at 4.5 -2.54 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-13")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP2"
|
||||
(at 4.5 0 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-14")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP3"
|
||||
(at 4.5 2.54 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-15")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP4"
|
||||
(at 4.5 5.08 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-16")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GP5"
|
||||
(at 4.5 7.62 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-17")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
(fp_text user "GND"
|
||||
(at 5 10.16 0)
|
||||
(layer "F.Fab")
|
||||
(uuid "lbl-18")
|
||||
(effects (font (size 0.6 0.6) (thickness 0.1)))
|
||||
)
|
||||
|
||||
;; 3D model reference (optional)
|
||||
(model "${KIPRJMOD}/3dmodels/RP2040-Zero.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
(version 20241229)
|
||||
(generator "pcbnew")
|
||||
(layer "F.Cu")
|
||||
(descr "Waveshare RP2040-Zero module, 2x9 pin headers, 2.54mm pitch")
|
||||
(tags "RP2040 Pico Zero Waveshare")
|
||||
(property "Reference" "MOD"
|
||||
(at 0 -13 0)
|
||||
(layer "F.SilkS")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(property "Value" "RP2040-Zero"
|
||||
(at 0 13 0)
|
||||
(layer "F.Fab")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(attr through_hole)
|
||||
(fp_line
|
||||
(start -9.5 -12.25)
|
||||
(end 9.5 -12.25)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start 9.5 -12.25)
|
||||
(end 9.5 12.25)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start 9.5 12.25)
|
||||
(end -9.5 12.25)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start -9.5 12.25)
|
||||
(end -9.5 -12.25)
|
||||
(stroke
|
||||
(width 0.12)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.SilkS")
|
||||
)
|
||||
(fp_line
|
||||
(start -10.5 -13)
|
||||
(end 10.5 -13)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start 10.5 -13)
|
||||
(end 10.5 13)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start 10.5 13)
|
||||
(end -10.5 13)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start -10.5 13)
|
||||
(end -10.5 -13)
|
||||
(stroke
|
||||
(width 0.05)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.CrtYd")
|
||||
)
|
||||
(fp_line
|
||||
(start -9 -11.75)
|
||||
(end 9 -11.75)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start 9 -11.75)
|
||||
(end 9 11.75)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start 9 11.75)
|
||||
(end -9 11.75)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_line
|
||||
(start -9 11.75)
|
||||
(end -9 -11.75)
|
||||
(stroke
|
||||
(width 0.1)
|
||||
(type solid)
|
||||
)
|
||||
(layer "F.Fab")
|
||||
)
|
||||
(fp_text user "${REFERENCE}"
|
||||
(at 0 0 0)
|
||||
(layer "F.Fab")
|
||||
(effects
|
||||
(font
|
||||
(size 1 1)
|
||||
(thickness 0.15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(pad "1" thru_hole rect
|
||||
(at -7.62 -10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "2" thru_hole circle
|
||||
(at -7.62 -7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "3" thru_hole circle
|
||||
(at -7.62 -5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "4" thru_hole circle
|
||||
(at -7.62 -2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "5" thru_hole circle
|
||||
(at -7.62 0)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "6" thru_hole circle
|
||||
(at -7.62 2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "7" thru_hole circle
|
||||
(at -7.62 5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "8" thru_hole circle
|
||||
(at -7.62 7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "9" thru_hole circle
|
||||
(at -7.62 10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "10" thru_hole circle
|
||||
(at 7.62 -10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "11" thru_hole circle
|
||||
(at 7.62 -7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "12" thru_hole circle
|
||||
(at 7.62 -5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "13" thru_hole circle
|
||||
(at 7.62 -2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "14" thru_hole circle
|
||||
(at 7.62 0)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "15" thru_hole circle
|
||||
(at 7.62 2.54)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "16" thru_hole circle
|
||||
(at 7.62 5.08)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "17" thru_hole circle
|
||||
(at 7.62 7.62)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(pad "18" thru_hole circle
|
||||
(at 7.62 10.16)
|
||||
(size 1.7 1.7)
|
||||
(drill 1)
|
||||
(layers "*.Cu" "*.Mask")
|
||||
(remove_unused_layers no)
|
||||
)
|
||||
(embedded_fonts no)
|
||||
)
|
||||
|
||||
Executable
+214
@@ -0,0 +1,214 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SN-L00 Fully Automated Routing Pipeline
|
||||
Works headlessly on KiCad 9+
|
||||
|
||||
Usage: python3 scripts/autoroute.py
|
||||
|
||||
Pipeline:
|
||||
1. Load board
|
||||
2. Update outline to 8HP (40x100mm)
|
||||
3. Delete existing tracks
|
||||
4. Place components (v2 layout)
|
||||
5. Export Specctra DSN
|
||||
6. Run Freerouting autorouter
|
||||
7. Import Specctra SES
|
||||
8. Save board
|
||||
9. Run DRC
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# Paths
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
KICAD_DIR = os.path.dirname(SCRIPT_DIR)
|
||||
os.chdir(KICAD_DIR)
|
||||
|
||||
PCB_FILE = "SN-L00.kicad_pcb"
|
||||
DSN_FILE = "SN-L00.dsn"
|
||||
SES_FILE = "SN-L00.ses"
|
||||
DRC_FILE = "DRC.rpt"
|
||||
FREEROUTING_JAR = "/tmp/freerouting.jar"
|
||||
FREEROUTING_URL = "https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar"
|
||||
|
||||
# Component positions for 8HP (40mm x 100mm) layout v2
|
||||
PLACEMENTS = {
|
||||
# Top - OLED display
|
||||
"MOD3": (20, 15, 90),
|
||||
# Audio jacks
|
||||
"J3": (10, 35, 0), # RETURN_IN
|
||||
"J4": (30, 35, 0), # TRIG_OUT
|
||||
# Button + LED
|
||||
"SW1": (20, 48, 0),
|
||||
"D5": (32, 48, 0),
|
||||
# RP2040-Zero
|
||||
"MOD2": (20, 62, 0),
|
||||
# Signal conditioning
|
||||
"U2": (8, 78, 0), # 74LVC1G17
|
||||
"U4": (32, 78, 0), # MCP6001
|
||||
# Decoupling caps
|
||||
"C4": (4, 78, 90),
|
||||
"C5": (14, 78, 90),
|
||||
"C6": (28, 82, 90),
|
||||
# Protection diodes
|
||||
"D3": (4, 82, 0),
|
||||
"D4": (36, 78, 0),
|
||||
# Resistors
|
||||
"R2": (4, 86, 90),
|
||||
"R3": (10, 86, 90),
|
||||
"R4": (16, 86, 90),
|
||||
"R5": (24, 86, 90),
|
||||
"R6": (30, 86, 90),
|
||||
"R7": (36, 86, 90),
|
||||
# Power section
|
||||
"J2": (20, 88, 0), # Eurorack power
|
||||
"D2": (4, 92, 0),
|
||||
"U3": (32, 94, 180), # LDO
|
||||
"C2": (10, 94, 90),
|
||||
"C3": (26, 94, 90),
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 50)
|
||||
print("SN-L00 Automated Routing Pipeline")
|
||||
print("=" * 50)
|
||||
|
||||
# Import pcbnew
|
||||
try:
|
||||
import pcbnew
|
||||
print(f"KiCad version: {pcbnew.Version()}")
|
||||
except ImportError:
|
||||
print("ERROR: pcbnew not available. Install KiCad or set PYTHONPATH.")
|
||||
sys.exit(1)
|
||||
|
||||
# Helper functions
|
||||
def mm(val):
|
||||
return pcbnew.FromMM(val)
|
||||
|
||||
def place(x, y):
|
||||
return pcbnew.VECTOR2I(mm(x), mm(y))
|
||||
|
||||
# Step 1: Load board
|
||||
print("\n[1/9] Loading board...")
|
||||
board = pcbnew.LoadBoard(PCB_FILE)
|
||||
print(f" Loaded {len(list(board.GetFootprints()))} footprints")
|
||||
|
||||
# Step 2: Update outline
|
||||
print("\n[2/9] Updating board outline to 40x100mm...")
|
||||
for drawing in board.GetDrawings():
|
||||
if drawing.GetClass() == "PCB_SHAPE":
|
||||
if drawing.GetShape() == pcbnew.SHAPE_T_RECT:
|
||||
drawing.SetStart(pcbnew.VECTOR2I(mm(0), mm(0)))
|
||||
drawing.SetEnd(pcbnew.VECTOR2I(mm(40), mm(100)))
|
||||
print(" Done")
|
||||
break
|
||||
|
||||
# Step 3: Delete tracks
|
||||
print("\n[3/9] Deleting existing tracks...")
|
||||
tracks = list(board.GetTracks())
|
||||
for track in tracks:
|
||||
board.Delete(track)
|
||||
print(f" Deleted {len(tracks)} tracks")
|
||||
|
||||
# Step 4: Place components
|
||||
print("\n[4/9] Placing components...")
|
||||
placed = 0
|
||||
for ref, (x, y, rot) in PLACEMENTS.items():
|
||||
fp = board.FindFootprintByReference(ref)
|
||||
if fp:
|
||||
fp.SetPosition(place(x, y))
|
||||
fp.SetOrientationDegrees(rot)
|
||||
placed += 1
|
||||
print(f" Placed {placed} components")
|
||||
|
||||
# Step 5: Export DSN
|
||||
print("\n[5/9] Exporting Specctra DSN...")
|
||||
board.Save(PCB_FILE) # Save first
|
||||
result = pcbnew.ExportSpecctraDSN(board, DSN_FILE)
|
||||
if result and os.path.exists(DSN_FILE):
|
||||
print(f" Created {DSN_FILE} ({os.path.getsize(DSN_FILE)} bytes)")
|
||||
else:
|
||||
print(" ERROR: DSN export failed")
|
||||
sys.exit(1)
|
||||
|
||||
# Step 6: Download and run Freerouting
|
||||
print("\n[6/9] Running Freerouting...")
|
||||
if not os.path.exists(FREEROUTING_JAR):
|
||||
print(" Downloading Freerouting...")
|
||||
subprocess.run(["curl", "-sL", "-o", FREEROUTING_JAR, FREEROUTING_URL], check=True)
|
||||
|
||||
result = subprocess.run(
|
||||
["java", "-jar", FREEROUTING_JAR,
|
||||
"-de", DSN_FILE,
|
||||
"-do", SES_FILE,
|
||||
"-mp", "200",
|
||||
"-mt", "1",
|
||||
"-oit"],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
# Parse output
|
||||
for line in (result.stdout + result.stderr).split('\n'):
|
||||
if 'auto-rout' in line.lower() or 'completed' in line.lower():
|
||||
print(f" {line.split(']')[-1].strip()}")
|
||||
|
||||
if not os.path.exists(SES_FILE):
|
||||
print(" ERROR: Freerouting failed")
|
||||
sys.exit(1)
|
||||
|
||||
# Step 7: Import SES
|
||||
print("\n[7/9] Importing routed session...")
|
||||
# Reload board to get fresh state
|
||||
board = pcbnew.LoadBoard(PCB_FILE)
|
||||
result = pcbnew.ImportSpecctraSES(board, SES_FILE)
|
||||
if result:
|
||||
print(f" Imported {len(list(board.GetTracks()))} tracks")
|
||||
else:
|
||||
print(" WARNING: SES import returned False")
|
||||
|
||||
# Step 8: Save
|
||||
print("\n[8/9] Saving board...")
|
||||
board.Save(PCB_FILE)
|
||||
print(f" Saved {PCB_FILE}")
|
||||
|
||||
# Step 9: Run DRC
|
||||
print("\n[9/9] Running DRC...")
|
||||
result = subprocess.run(
|
||||
["kicad-cli", "pcb", "drc",
|
||||
"--severity-all",
|
||||
"--units", "mm",
|
||||
"-o", DRC_FILE,
|
||||
PCB_FILE],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
# Parse DRC output
|
||||
errors = 0
|
||||
warnings = 0
|
||||
if os.path.exists(DRC_FILE):
|
||||
with open(DRC_FILE) as f:
|
||||
content = f.read()
|
||||
errors = content.count('; error')
|
||||
warnings = content.count('; warning')
|
||||
|
||||
print(f" {errors} errors, {warnings} warnings")
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 50)
|
||||
if errors == 0:
|
||||
print("SUCCESS! Board routed with no DRC errors.")
|
||||
else:
|
||||
print(f"Done. {errors} DRC errors remain - see {DRC_FILE}")
|
||||
print("=" * 50)
|
||||
|
||||
return errors == 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SN-L00 Full Autoroute Pipeline for 8HP Eurorack
|
||||
Run in KiCad PCB Editor: Tools → Scripting Console
|
||||
Then: exec(open('scripts/autoroute_full.py').read())
|
||||
|
||||
This script:
|
||||
1. Updates board outline to 8HP (40mm x 100mm)
|
||||
2. Deletes existing tracks
|
||||
3. Places all components
|
||||
4. Exports DSN file
|
||||
5. Runs Freerouting
|
||||
6. Imports routed SES file
|
||||
"""
|
||||
|
||||
import pcbnew
|
||||
import subprocess
|
||||
import os
|
||||
import time
|
||||
|
||||
board = pcbnew.GetBoard()
|
||||
board_path = board.GetFileName()
|
||||
board_dir = os.path.dirname(board_path)
|
||||
|
||||
def mm(val):
|
||||
return pcbnew.FromMM(val)
|
||||
|
||||
def place(x, y):
|
||||
return pcbnew.VECTOR2I(mm(x), mm(y))
|
||||
|
||||
print("=" * 50)
|
||||
print("SN-L00 Full Autoroute Pipeline")
|
||||
print("=" * 50)
|
||||
|
||||
# Step 1: Update board outline to 8HP (40mm x 100mm)
|
||||
print("\n[1/6] Updating board outline to 40mm x 100mm...")
|
||||
for drawing in board.GetDrawings():
|
||||
if drawing.GetClass() == "PCB_SHAPE":
|
||||
if drawing.GetShape() == pcbnew.SHAPE_T_RECT:
|
||||
drawing.SetStart(pcbnew.VECTOR2I(mm(0), mm(0)))
|
||||
drawing.SetEnd(pcbnew.VECTOR2I(mm(40), mm(100)))
|
||||
print(" Board outline updated")
|
||||
break
|
||||
|
||||
# Step 2: Delete all tracks
|
||||
print("\n[2/6] Deleting existing tracks...")
|
||||
tracks = list(board.GetTracks())
|
||||
for track in tracks:
|
||||
board.Delete(track)
|
||||
print(f" Deleted {len(tracks)} tracks")
|
||||
|
||||
# Step 3: Place components (v2 - fixed spacing)
|
||||
print("\n[3/6] Placing components...")
|
||||
placements = {
|
||||
# Top - OLED display (rotated 90°)
|
||||
"MOD3": (20, 15, 90),
|
||||
# Audio jacks - centered with good spacing
|
||||
"J3": (10, 35, 0), # RETURN_IN
|
||||
"J4": (30, 35, 0), # TRIG_OUT
|
||||
# Button + LED
|
||||
"SW1": (20, 48, 0),
|
||||
"D5": (32, 48, 0), # LED near button
|
||||
# RP2040-Zero module - centered
|
||||
"MOD2": (20, 62, 0),
|
||||
# Signal conditioning ICs - well spaced
|
||||
"U2": (8, 78, 0), # 74LVC1G17
|
||||
"U4": (32, 78, 0), # MCP6001
|
||||
# Decoupling caps near ICs
|
||||
"C4": (4, 78, 90),
|
||||
"C5": (14, 78, 90),
|
||||
"C6": (28, 82, 90),
|
||||
# Protection diodes near jacks circuits
|
||||
"D3": (4, 82, 0),
|
||||
"D4": (36, 78, 0),
|
||||
# Resistors - spread across middle
|
||||
"R2": (4, 86, 90),
|
||||
"R3": (10, 86, 90),
|
||||
"R4": (16, 86, 90),
|
||||
"R5": (24, 86, 90),
|
||||
"R6": (30, 86, 90),
|
||||
"R7": (36, 86, 90),
|
||||
# Power section - J2 moved up, components spread out
|
||||
"J2": (20, 88, 0), # Eurorack power header (extends ~6mm down)
|
||||
"D2": (4, 92, 0), # Protection diode
|
||||
"U3": (32, 94, 180), # LDO - moved left from edge
|
||||
"C2": (10, 94, 90), # Input cap
|
||||
"C3": (26, 94, 90), # Output cap
|
||||
}
|
||||
|
||||
placed = 0
|
||||
for ref, (x, y, rot) in placements.items():
|
||||
fp = board.FindFootprintByReference(ref)
|
||||
if fp:
|
||||
fp.SetPosition(place(x, y))
|
||||
fp.SetOrientationDegrees(rot)
|
||||
placed += 1
|
||||
|
||||
print(f" Placed {placed} components")
|
||||
|
||||
# Step 4: Save and export DSN
|
||||
print("\n[4/6] Saving board and exporting DSN...")
|
||||
pcbnew.Refresh()
|
||||
board.Save(board_path)
|
||||
|
||||
dsn_path = os.path.join(board_dir, "SN-L00.dsn")
|
||||
ses_path = os.path.join(board_dir, "SN-L00.ses")
|
||||
|
||||
# Export DSN
|
||||
if hasattr(pcbnew, 'ExportSpecctraDSN'):
|
||||
pcbnew.ExportSpecctraDSN(dsn_path)
|
||||
print(f" Exported: {dsn_path}")
|
||||
else:
|
||||
# Fallback for older KiCad versions
|
||||
exporter = pcbnew.SPECCTRA_DB()
|
||||
exporter.ExportPCB(dsn_path, False)
|
||||
print(f" Exported: {dsn_path}")
|
||||
|
||||
# Step 5: Run Freerouting
|
||||
print("\n[5/6] Running Freerouting...")
|
||||
freerouting_jar = "/tmp/freerouting.jar"
|
||||
|
||||
if not os.path.exists(freerouting_jar):
|
||||
print(" Downloading Freerouting...")
|
||||
url = "https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar"
|
||||
subprocess.run(["curl", "-L", "-o", freerouting_jar, url], check=True)
|
||||
|
||||
result = subprocess.run(
|
||||
["java", "-jar", freerouting_jar,
|
||||
"-de", dsn_path,
|
||||
"-do", ses_path,
|
||||
"-mp", "200",
|
||||
"-mt", "1",
|
||||
"-oit"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=board_dir
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(" Freerouting completed successfully")
|
||||
else:
|
||||
print(f" Freerouting error: {result.stderr}")
|
||||
|
||||
# Step 6: Import SES
|
||||
print("\n[6/6] Importing routed session...")
|
||||
if os.path.exists(ses_path):
|
||||
if hasattr(pcbnew, 'ImportSpecctraSES'):
|
||||
pcbnew.ImportSpecctraSES(ses_path)
|
||||
print(f" Imported: {ses_path}")
|
||||
else:
|
||||
# Fallback
|
||||
importer = pcbnew.SPECCTRA_DB()
|
||||
importer.ImportSES(ses_path)
|
||||
print(f" Imported: {ses_path}")
|
||||
|
||||
pcbnew.Refresh()
|
||||
print("\n" + "=" * 50)
|
||||
print("DONE! Save (Ctrl+S) and run DRC to verify.")
|
||||
print("=" * 50)
|
||||
else:
|
||||
print(f" ERROR: SES file not found: {ses_path}")
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# Freerouting automation script
|
||||
# Usage: ./scripts/freeroute.sh
|
||||
#
|
||||
# Prerequisites: Export DSN from KiCad first (File → Export → Specctra DSN)
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
DSN_FILE="SN-L00.dsn"
|
||||
SES_FILE="SN-L00.ses"
|
||||
FREEROUTING_JAR="/tmp/freerouting.jar"
|
||||
FREEROUTING_URL="https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar"
|
||||
|
||||
echo "=================================="
|
||||
echo "SN-L00 Freerouting Automation"
|
||||
echo "=================================="
|
||||
|
||||
# Check DSN exists
|
||||
if [ ! -f "$DSN_FILE" ]; then
|
||||
echo "ERROR: $DSN_FILE not found"
|
||||
echo "Export from KiCad: File → Export → Specctra DSN"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download Freerouting if needed
|
||||
if [ ! -f "$FREEROUTING_JAR" ]; then
|
||||
echo "Downloading Freerouting..."
|
||||
curl -L -o "$FREEROUTING_JAR" "$FREEROUTING_URL"
|
||||
fi
|
||||
|
||||
# Run Freerouting
|
||||
echo "Running Freerouting..."
|
||||
java -jar "$FREEROUTING_JAR" \
|
||||
-de "$DSN_FILE" \
|
||||
-do "$SES_FILE" \
|
||||
-mp 200 \
|
||||
-mt 1 \
|
||||
-oit
|
||||
|
||||
echo ""
|
||||
echo "=================================="
|
||||
echo "DONE! Import in KiCad:"
|
||||
echo " File → Import → Specctra Session"
|
||||
echo " Select: $SES_FILE"
|
||||
echo "=================================="
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Move board and all components to origin (0,0)
|
||||
Run in KiCad PCB Editor: Tools → Scripting Console
|
||||
Then: exec(open('scripts/move_to_origin.py').read())
|
||||
"""
|
||||
|
||||
import pcbnew
|
||||
|
||||
board = pcbnew.GetBoard()
|
||||
|
||||
# Get current board origin from edge cuts
|
||||
bbox = board.GetBoardEdgesBoundingBox()
|
||||
offset_x = bbox.GetX()
|
||||
offset_y = bbox.GetY()
|
||||
|
||||
print(f"Current board origin: ({pcbnew.ToMM(offset_x):.2f}, {pcbnew.ToMM(offset_y):.2f}) mm")
|
||||
|
||||
if offset_x == 0 and offset_y == 0:
|
||||
print("Board is already at origin!")
|
||||
else:
|
||||
# Move all footprints
|
||||
for fp in board.GetFootprints():
|
||||
pos = fp.GetPosition()
|
||||
new_pos = pcbnew.VECTOR2I(pos.x - offset_x, pos.y - offset_y)
|
||||
fp.SetPosition(new_pos)
|
||||
|
||||
# Move all drawings (including board outline)
|
||||
for drawing in board.GetDrawings():
|
||||
if hasattr(drawing, 'Move'):
|
||||
drawing.Move(pcbnew.VECTOR2I(-offset_x, -offset_y))
|
||||
|
||||
# Move all tracks
|
||||
for track in board.GetTracks():
|
||||
track.Move(pcbnew.VECTOR2I(-offset_x, -offset_y))
|
||||
|
||||
# Move all zones
|
||||
for zone in board.Zones():
|
||||
zone.Move(pcbnew.VECTOR2I(-offset_x, -offset_y))
|
||||
|
||||
print(f"Moved everything by ({-pcbnew.ToMM(offset_x):.2f}, {-pcbnew.ToMM(offset_y):.2f}) mm")
|
||||
print("Board is now at origin (0, 0)")
|
||||
|
||||
pcbnew.Refresh()
|
||||
print("\nDone! Save (Ctrl+S), delete all tracks, then run place_6hp.py")
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SN-L00 Component Placement Script for 8HP Eurorack (40mm x 100mm)
|
||||
Run in KiCad PCB Editor: Tools → Scripting Console
|
||||
Then: exec(open('scripts/place_8hp.py').read())
|
||||
"""
|
||||
|
||||
import pcbnew
|
||||
|
||||
board = pcbnew.GetBoard()
|
||||
|
||||
def mm(val):
|
||||
return pcbnew.FromMM(val)
|
||||
|
||||
def place(x, y):
|
||||
return pcbnew.VECTOR2I(mm(x), mm(y))
|
||||
|
||||
# First, update the board outline to 8HP (40mm x 100mm)
|
||||
for drawing in board.GetDrawings():
|
||||
if drawing.GetClass() == "PCB_SHAPE":
|
||||
if drawing.GetShape() == pcbnew.SHAPE_T_RECT:
|
||||
drawing.SetStart(pcbnew.VECTOR2I(mm(0), mm(0)))
|
||||
drawing.SetEnd(pcbnew.VECTOR2I(mm(40), mm(100)))
|
||||
print("Updated board outline to 40mm x 100mm (8HP)")
|
||||
|
||||
# Delete all tracks for fresh routing
|
||||
tracks = list(board.GetTracks())
|
||||
for track in tracks:
|
||||
board.Delete(track)
|
||||
print(f"Deleted {len(tracks)} tracks")
|
||||
|
||||
# Component positions for 8HP (40mm x 100mm) layout v2
|
||||
placements = {
|
||||
"MOD3": (20, 15, 90), # OLED display
|
||||
"J3": (10, 35, 0), # RETURN_IN jack
|
||||
"J4": (30, 35, 0), # TRIG_OUT jack
|
||||
"SW1": (20, 48, 0), # Button
|
||||
"D5": (32, 48, 0), # LED
|
||||
"MOD2": (20, 62, 0), # RP2040-Zero
|
||||
"U2": (8, 78, 0), # 74LVC1G17
|
||||
"U4": (32, 78, 0), # MCP6001
|
||||
"C4": (4, 78, 90), # Decoupling
|
||||
"C5": (14, 78, 90),
|
||||
"C6": (28, 82, 90),
|
||||
"D3": (4, 82, 0), # Protection diodes
|
||||
"D4": (36, 78, 0),
|
||||
"R2": (4, 86, 90), # Resistors
|
||||
"R3": (10, 86, 90),
|
||||
"R4": (16, 86, 90),
|
||||
"R5": (24, 86, 90),
|
||||
"R6": (30, 86, 90),
|
||||
"R7": (36, 86, 90),
|
||||
"J2": (20, 88, 0), # Eurorack power
|
||||
"D2": (4, 92, 0),
|
||||
"U3": (32, 94, 180), # LDO
|
||||
"C2": (10, 94, 90),
|
||||
"C3": (26, 94, 90),
|
||||
}
|
||||
|
||||
print("\nPlacing components for 8HP Eurorack layout (v2)...")
|
||||
placed = 0
|
||||
not_found = []
|
||||
|
||||
for ref, (x, y, rot) in placements.items():
|
||||
fp = board.FindFootprintByReference(ref)
|
||||
if fp:
|
||||
fp.SetPosition(place(x, y))
|
||||
fp.SetOrientationDegrees(rot)
|
||||
placed += 1
|
||||
print(f" {ref} -> ({x}, {y}) rot={rot}°")
|
||||
else:
|
||||
not_found.append(ref)
|
||||
|
||||
print(f"\nPlaced {placed} components")
|
||||
if not_found:
|
||||
print(f"Not found: {', '.join(not_found)}")
|
||||
|
||||
pcbnew.Refresh()
|
||||
print("\nDone! Save (Ctrl+S), then run: ./scripts/route.sh")
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
# Full routing and DRC workflow
|
||||
# Usage: ./scripts/route.sh
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. Run place_8hp.py in KiCad scripting console
|
||||
# 2. Export DSN: File → Export → Specctra DSN
|
||||
# 3. Save PCB
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
PCB_FILE="SN-L00.kicad_pcb"
|
||||
DSN_FILE="SN-L00.dsn"
|
||||
SES_FILE="SN-L00.ses"
|
||||
DRC_FILE="DRC.rpt"
|
||||
FREEROUTING_JAR="/tmp/freerouting.jar"
|
||||
FREEROUTING_URL="https://github.com/freerouting/freerouting/releases/download/v2.0.1/freerouting-2.0.1.jar"
|
||||
|
||||
echo "============================================"
|
||||
echo "SN-L00 Routing Pipeline"
|
||||
echo "============================================"
|
||||
|
||||
# Check DSN exists
|
||||
if [ ! -f "$DSN_FILE" ]; then
|
||||
echo ""
|
||||
echo "ERROR: $DSN_FILE not found!"
|
||||
echo ""
|
||||
echo "In KiCad:"
|
||||
echo " 1. Run: exec(open('scripts/place_8hp.py').read())"
|
||||
echo " 2. Save: Ctrl+S"
|
||||
echo " 3. Export: File → Export → Specctra DSN"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download Freerouting if needed
|
||||
if [ ! -f "$FREEROUTING_JAR" ]; then
|
||||
echo "[1/3] Downloading Freerouting..."
|
||||
curl -L -o "$FREEROUTING_JAR" "$FREEROUTING_URL"
|
||||
else
|
||||
echo "[1/3] Freerouting ready"
|
||||
fi
|
||||
|
||||
# Run Freerouting
|
||||
echo "[2/3] Running Freerouting..."
|
||||
java -jar "$FREEROUTING_JAR" \
|
||||
-de "$DSN_FILE" \
|
||||
-do "$SES_FILE" \
|
||||
-mp 200 \
|
||||
-mt 1 \
|
||||
-oit 2>&1 | grep -E "(completed|INFO.*Auto|ERROR)" || true
|
||||
|
||||
if [ ! -f "$SES_FILE" ]; then
|
||||
echo "ERROR: Routing failed - no SES file created"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[3/3] Running DRC..."
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "In KiCad: File → Import → Specctra Session"
|
||||
echo "Select: $SES_FILE"
|
||||
echo "Then save (Ctrl+S)"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "Waiting for you to import SES and save..."
|
||||
read -p "Press Enter when done: "
|
||||
|
||||
# Run DRC from CLI
|
||||
kicad-cli pcb drc \
|
||||
--severity-all \
|
||||
--units mm \
|
||||
--schematic-parity \
|
||||
-o "$DRC_FILE" \
|
||||
"$PCB_FILE" 2>&1
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "DRC Results:"
|
||||
echo "============================================"
|
||||
grep -E "^(Found|\*\*)" "$DRC_FILE" || cat "$DRC_FILE"
|
||||
echo ""
|
||||
|
||||
# Count errors vs warnings
|
||||
ERRORS=$(grep -c "error$" "$DRC_FILE" 2>/dev/null || echo "0")
|
||||
WARNINGS=$(grep -c "warning$" "$DRC_FILE" 2>/dev/null || echo "0")
|
||||
|
||||
echo "Summary: $ERRORS errors, $WARNINGS warnings"
|
||||
|
||||
if [ "$ERRORS" -eq 0 ]; then
|
||||
echo ""
|
||||
echo "✓ No DRC errors - ready for manufacturing!"
|
||||
else
|
||||
echo ""
|
||||
echo "Fix errors and re-run: ./scripts/route.sh"
|
||||
fi
|
||||
@@ -1,10 +1,10 @@
|
||||
# SN-L00 Panel Specification
|
||||
|
||||
## Eurorack 6HP Panel Dimensions
|
||||
## Eurorack 8HP Panel Dimensions
|
||||
|
||||
| Parameter | Value | Notes |
|
||||
|-----------|-------|-------|
|
||||
| Width | 30.00mm | 6 × 5.08mm (6HP) |
|
||||
| Width | 40.30mm | 8 × 5.08mm (8HP) |
|
||||
| Height | 128.50mm | 3U standard |
|
||||
| Thickness | 1.5-2.0mm | Aluminum or PCB |
|
||||
| Corner radius | 0mm | Square corners |
|
||||
@@ -16,9 +16,9 @@ Eurorack standard mounting rail positions:
|
||||
| Hole | X | Y | Diameter | Notes |
|
||||
|------|---|---|----------|-------|
|
||||
| Top Left | 7.5mm | 3.0mm | 3.2mm | Horizontal slot optional |
|
||||
| Top Right | 22.5mm | 3.0mm | 3.2mm | Horizontal slot optional |
|
||||
| Top Right | 32.8mm | 3.0mm | 3.2mm | Horizontal slot optional |
|
||||
| Bottom Left | 7.5mm | 125.5mm | 3.2mm | Horizontal slot optional |
|
||||
| Bottom Right | 22.5mm | 125.5mm | 3.2mm | Horizontal slot optional |
|
||||
| Bottom Right | 32.8mm | 125.5mm | 3.2mm | Horizontal slot optional |
|
||||
|
||||
**Note**: Slots (elongated holes) of 3.2mm × 4mm allow for rail tolerance.
|
||||
|
||||
@@ -26,47 +26,47 @@ Eurorack standard mounting rail positions:
|
||||
|
||||
| Component | X | Y | Diameter | Notes |
|
||||
|-----------|---|---|----------|-------|
|
||||
| OLED cutout | 15.0mm | 25.0mm | 28×12mm rect | Rectangular window |
|
||||
| Button | 15.0mm | 45.0mm | 7.0mm | For 6mm tactile + cap |
|
||||
| LED (power) | 24.0mm | 45.0mm | 3.0mm | For 3mm LED or light pipe |
|
||||
| Jack TRIG | 7.5mm | 95.0mm | 6.0mm | Thonkiconn PJ398SM |
|
||||
| Jack RETURN | 22.5mm | 95.0mm | 6.0mm | Thonkiconn PJ398SM |
|
||||
| OLED cutout | 20.15mm | 25.0mm | 28×12mm rect | Rectangular window |
|
||||
| Button | 20.15mm | 50.0mm | 7.0mm | For 6mm tactile + cap |
|
||||
| LED (status) | 32.0mm | 50.0mm | 3.0mm | For 3mm LED or light pipe |
|
||||
| Jack RETURN | 10.0mm | 95.0mm | 6.0mm | Thonkiconn PJ398SM |
|
||||
| Jack TRIG | 30.0mm | 95.0mm | 6.0mm | Thonkiconn PJ398SM |
|
||||
|
||||
## Panel Layout Drawing
|
||||
|
||||
```
|
||||
←───── 30.00mm ─────→
|
||||
←─────── 40.30mm ───────→
|
||||
|
||||
┌─────────────────────┐ ─┬─ 0.00mm
|
||||
│ ○ ○ │ │ 3.00mm (mounting holes)
|
||||
│ │ │
|
||||
│ SubModular │ │ 12.00mm
|
||||
│ │ │
|
||||
│ ┌───────────────┐ │ │
|
||||
│ │ │ │ │
|
||||
│ │ OLED │ │ │ 19-31mm (display window)
|
||||
│ │ DISPLAY │ │ │
|
||||
│ │ │ │ │
|
||||
│ └───────────────┘ │ │
|
||||
│ │ │
|
||||
│ SN-L00 │ │ 38.00mm
|
||||
│ │ │
|
||||
│ ◯ • │ │ 45.00mm (button + LED)
|
||||
│ BTN PWR │ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ ┌───┐ ┌───┐ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ ○ │ │ ○ │ │ │ 95.00mm (jacks)
|
||||
│ │ │ │ │ │ │
|
||||
│ └───┘ └───┘ │ │
|
||||
│ TRIG RETURN │ │ 105.00mm (labels)
|
||||
│ │ │
|
||||
│ LATENCY TESTER │ │ 115.00mm
|
||||
│ │ │
|
||||
│ ○ ○ │ │ 125.50mm (mounting holes)
|
||||
└─────────────────────┘ ─┴─ 128.50mm
|
||||
┌───────────────────────────┐ ─┬─ 0.00mm
|
||||
│ ○ ○ │ │ 3.00mm (mounting holes)
|
||||
│ │ │
|
||||
│ SubModular │ │ 12.00mm
|
||||
│ │ │
|
||||
│ ┌─────────────────┐ │ │
|
||||
│ │ │ │ │
|
||||
│ │ OLED │ │ │ 19-31mm (display window)
|
||||
│ │ DISPLAY │ │ │
|
||||
│ │ │ │ │
|
||||
│ └─────────────────┘ │ │
|
||||
│ │ │
|
||||
│ SN-L00 │ │ 42.00mm
|
||||
│ │ │
|
||||
│ ◯ • │ │ 50.00mm (button + LED)
|
||||
│ BTN PWR │ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ ┌───┐ ┌───┐ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ ○ │ │ ○ │ │ │ 95.00mm (jacks)
|
||||
│ │ │ │ │ │ │
|
||||
│ └───┘ └───┘ │ │
|
||||
│ RETURN TRIG │ │ 105.00mm (labels)
|
||||
│ │ │
|
||||
│ LATENCY TESTER │ │ 115.00mm
|
||||
│ │ │
|
||||
│ ○ ○ │ │ 125.50mm (mounting holes)
|
||||
└───────────────────────────┘ ─┴─ 128.50mm
|
||||
```
|
||||
|
||||
## OLED Display Window
|
||||
@@ -79,7 +79,7 @@ The 0.91" 128×32 OLED module dimensions:
|
||||
| Active area | ~22 × 6mm |
|
||||
| Mounting | Pin header on edge |
|
||||
|
||||
**Panel cutout**: 28mm × 10mm rectangle, centered at (15.0, 25.0)
|
||||
**Panel cutout**: 28mm × 10mm rectangle, centered at (20.15, 25.0)
|
||||
|
||||
Alternatively, a slightly larger window (30 × 12mm) gives tolerance for module alignment.
|
||||
|
||||
@@ -124,17 +124,11 @@ Soldermask: Black (or custom color)
|
||||
| Element | Position | Size | Font |
|
||||
|---------|----------|------|------|
|
||||
| "SubModular" | Top center, Y=12mm | 2.5mm | Bold sans-serif |
|
||||
| "SN-L00" | Above button, Y=38mm | 3.0mm | Bold |
|
||||
| "TRIG" | Below left jack, Y=105mm | 2.0mm | Regular |
|
||||
| "RETURN" | Below right jack, Y=105mm | 2.0mm | Regular |
|
||||
| "SN-L00" | Above button, Y=42mm | 3.0mm | Bold |
|
||||
| "RETURN" | Below left jack, Y=105mm | 2.0mm | Regular |
|
||||
| "TRIG" | Below right jack, Y=105mm | 2.0mm | Regular |
|
||||
| "LATENCY TESTER" | Bottom, Y=115mm | 1.5mm | Light |
|
||||
|
||||
### Icon Ideas
|
||||
|
||||
- Small waveform graphic near jacks
|
||||
- Clock/timer icon
|
||||
- Sub-Net logo (if available)
|
||||
|
||||
## Hole Tolerances
|
||||
|
||||
| Hole Type | Nominal | Tolerance |
|
||||
@@ -144,14 +138,11 @@ Soldermask: Black (or custom color)
|
||||
| Button | 7.0mm | +0.2/-0.0 |
|
||||
| LED | 3.0mm | +0.1/-0.0 |
|
||||
|
||||
## Files to Create
|
||||
## Files
|
||||
|
||||
For manufacturing:
|
||||
|
||||
1. **DXF/DWG** - For laser cutting (aluminum/acrylic)
|
||||
2. **KiCad PCB** - For PCB panel
|
||||
3. **SVG** - For graphics reference
|
||||
4. **PDF** - Dimensional drawing
|
||||
- **PANEL_SPEC.md** - This file
|
||||
- **SN-L00_panel.svg** - Vector graphic for manufacturing
|
||||
- **SN-L00_panel.kicad_pcb** - PCB panel (if using FR4)
|
||||
|
||||
## Assembly
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="30mm" height="128.5mm"
|
||||
viewBox="0 0 30 128.5">
|
||||
width="40.30mm" height="128.5mm"
|
||||
viewBox="0 0 40.30 128.5">
|
||||
|
||||
<title>SN-L00 Eurorack Panel</title>
|
||||
<desc>6HP Eurorack panel for SN-L00 Latency Tester</desc>
|
||||
<desc>8HP Eurorack panel for SN-L00 Latency Tester</desc>
|
||||
|
||||
<defs>
|
||||
<style>
|
||||
@@ -20,53 +20,53 @@
|
||||
</defs>
|
||||
|
||||
<!-- Panel background -->
|
||||
<rect class="panel" x="0" y="0" width="30" height="128.5"/>
|
||||
<rect class="panel" x="0" y="0" width="40.30" height="128.5"/>
|
||||
|
||||
<!-- Mounting holes (3.2mm) - RED for drill -->
|
||||
<!-- Top mounting holes -->
|
||||
<circle class="hole" cx="7.5" cy="3" r="1.6"/>
|
||||
<circle class="hole" cx="22.5" cy="3" r="1.6"/>
|
||||
<circle class="hole" cx="32.8" cy="3" r="1.6"/>
|
||||
<!-- Bottom mounting holes -->
|
||||
<circle class="hole" cx="7.5" cy="125.5" r="1.6"/>
|
||||
<circle class="hole" cx="22.5" cy="125.5" r="1.6"/>
|
||||
<circle class="hole" cx="32.8" cy="125.5" r="1.6"/>
|
||||
|
||||
<!-- OLED display window (28x10mm rectangle) - GREEN for cutout -->
|
||||
<rect class="cutout" x="1" y="20" width="28" height="10" rx="0.5"/>
|
||||
<rect class="cutout" x="6.15" y="20" width="28" height="10" rx="0.5"/>
|
||||
|
||||
<!-- Button hole (7mm) -->
|
||||
<circle class="hole" cx="15" cy="45" r="3.5"/>
|
||||
<circle class="hole" cx="20.15" cy="50" r="3.5"/>
|
||||
|
||||
<!-- LED hole (3mm) -->
|
||||
<circle class="hole" cx="24" cy="45" r="1.5"/>
|
||||
<circle class="hole" cx="32" cy="50" r="1.5"/>
|
||||
|
||||
<!-- Jack holes (6mm) -->
|
||||
<circle class="hole" cx="7.5" cy="95" r="3"/>
|
||||
<circle class="hole" cx="22.5" cy="95" r="3"/>
|
||||
<circle class="hole" cx="10" cy="95" r="3"/>
|
||||
<circle class="hole" cx="30" cy="95" r="3"/>
|
||||
|
||||
<!-- Text labels - WHITE silkscreen -->
|
||||
<text class="text text-medium" x="15" y="12" text-anchor="middle">SubModular</text>
|
||||
<text class="text text-medium" x="20.15" y="12" text-anchor="middle">SubModular</text>
|
||||
|
||||
<text class="text text-large" x="15" y="38" text-anchor="middle" font-weight="bold">SN-L00</text>
|
||||
<text class="text text-large" x="20.15" y="42" text-anchor="middle" font-weight="bold">SN-L00</text>
|
||||
|
||||
<text class="text text-small" x="15" y="52" text-anchor="middle">BTN</text>
|
||||
<text class="text text-small" x="24" y="52" text-anchor="middle">PWR</text>
|
||||
<text class="text text-small" x="20.15" y="57" text-anchor="middle">BTN</text>
|
||||
<text class="text text-small" x="32" y="57" text-anchor="middle">PWR</text>
|
||||
|
||||
<text class="text text-small" x="7.5" y="105" text-anchor="middle">TRIG</text>
|
||||
<text class="text text-small" x="22.5" y="105" text-anchor="middle">RETURN</text>
|
||||
<text class="text text-small" x="10" y="105" text-anchor="middle">RETURN</text>
|
||||
<text class="text text-small" x="30" y="105" text-anchor="middle">TRIG</text>
|
||||
|
||||
<text class="text text-small" x="15" y="115" text-anchor="middle">LATENCY TESTER</text>
|
||||
<text class="text text-small" x="20.15" y="115" text-anchor="middle">LATENCY TESTER</text>
|
||||
|
||||
<!-- Decorative elements -->
|
||||
<!-- Jack nut indicators (circles around jacks) -->
|
||||
<circle class="silkscreen" cx="7.5" cy="95" r="5"/>
|
||||
<circle class="silkscreen" cx="22.5" cy="95" r="5"/>
|
||||
<circle class="silkscreen" cx="10" cy="95" r="5"/>
|
||||
<circle class="silkscreen" cx="30" cy="95" r="5"/>
|
||||
|
||||
<!-- Display frame -->
|
||||
<rect class="silkscreen" x="0.5" y="19.5" width="29" height="11" rx="0.5"/>
|
||||
<rect class="silkscreen" x="5.65" y="19.5" width="29" height="11" rx="0.5"/>
|
||||
|
||||
<!-- Horizontal lines for visual separation -->
|
||||
<line class="silkscreen" x1="2" y1="55" x2="28" y2="55"/>
|
||||
<line class="silkscreen" x1="2" y1="85" x2="28" y2="85"/>
|
||||
<line class="silkscreen" x1="2" y1="110" x2="28" y2="110"/>
|
||||
<line class="silkscreen" x1="4" y1="60" x2="36.30" y2="60"/>
|
||||
<line class="silkscreen" x1="4" y1="85" x2="36.30" y2="85"/>
|
||||
<line class="silkscreen" x1="4" y1="110" x2="36.30" y2="110"/>
|
||||
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Reference in New Issue
Block a user