monorail-pcb/Libraries/JLCPCB-Kicad-Library-main/libraryCreatorScript.ipynb

334 lines
11 KiB
Text
Raw Normal View History

2025-06-13 01:24:58 +02:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "XVhK72Pu1cJL"
},
"source": [
"## Setup\n",
"\n",
"\n",
"[Setup Python Virtual Environment in VSCode](/venv_setup.md)\n",
"\n",
"\n",
"**Security Note:** Using fixed package versions ensures stability and reproducibility, but may expose you to security vulnerabilities if not regularly updated. Balance stability and security by periodically reviewing and updating packages."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2024-03-13T01:30:41.127178Z",
"iopub.status.busy": "2024-03-13T01:30:41.126569Z",
"iopub.status.idle": "2024-03-13T01:30:44.444253Z",
"shell.execute_reply": "2024-03-13T01:30:44.443409Z"
},
"id": "7rZnJaGTWQw0"
},
"outputs": [],
"source": [
"# Install required packages in a virtual environment (Currently only tested with Python 3.12)\n",
"%pip install --upgrade pip\n",
"%pip install pandas==2.2.*\n",
"%pip install requests==2.32.*\n",
"%pip install JLC2KiCadLib==1.0.32"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Download JLCPCB Parts CSV File "
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Deleted existing file: jlcpcb-components-basic-preferred.csv\n",
"Downloaded https://cdfer.github.io/jlcpcb-parts-database/jlcpcb-components-basic-preferred.csv to jlcpcb-components-basic-preferred.csv\n"
]
}
],
"source": [
"import requests\n",
"import os\n",
"\n",
"\n",
"def download_file(url, filename):\n",
" try:\n",
" # Check if the file already exists\n",
" if os.path.exists(filename):\n",
" # Delete the existing file\n",
" os.remove(filename)\n",
" print(f\"Deleted existing file: {filename}\")\n",
"\n",
" response = requests.get(f\"{url}/{filename}\", stream=True)\n",
" response.raise_for_status() # Raise an exception for bad status codes\n",
" with open(filename, \"wb\") as f:\n",
" for chunk in response.iter_content(None):\n",
" f.write(chunk)\n",
" print(f\"Downloaded {url}/{filename} to {filename}\")\n",
" except requests.RequestException as e:\n",
" print(f\"Download {url} failed: {e}\")\n",
"\n",
"\n",
"# URL\n",
"url = \"https://cdfer.github.io/jlcpcb-parts-database\"\n",
"\n",
"# Download the file\n",
"download_file(url, \"jlcpcb-components-basic-preferred.csv\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ToDo:\n",
"\n",
"Create Symbols/Footprints for:\n",
"20617924\n",
"20617927\n",
"28646267\n",
"\n",
"3rd Pin on Inductor: C2858862\n",
"\n",
"Ferrite Bead Symbol Value\n",
"\n",
"Cleanup .step files\n",
"\n",
"Merge in display driver symbol lib\n",
"\n",
"Add TVS diodes to Mosfet Footprints\n",
"\n",
"Extended Components\n",
"Addressable LED (low cost, rgbW)\n",
"ESP32 Chips (OG,S2,S3,C3)\n",
"40Mhz Crystal\n",
"RP2040\n",
"USB C Connectors (Low cost, full 24P, )\n",
"Encoder (alps?)\n",
"GPS Module\n",
"GPS patch antenna (25x25?)\n",
"Humidity Module\n",
"Motor Driver\n",
"Display (ssd1306?)\n",
"RiscV (CH32V003?)\n",
"USB Hub IC\n",
"Cellular (SIM7080G)\n",
"Relay\n",
"Accelerometer\n",
"Stepper Driver\n",
"USB-Serial (CH340?)\n",
"VEML7700\n",
"TCS34725\n",
"ATGM332D-5N31"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [],
"source": [
"import JLC2KiCadLib\n",
"import JLC2KiCadLib.JLC2KiCadLib as JLC\n",
"import os\n",
"\n",
"componentList = [\n",
"2841497\n",
"]\n",
"\n",
"os.chdir(\"..\")\n",
"\n",
"class Args:\n",
" def __init__(self):\n",
" self.footprint_creation = True\n",
" self.symbol_creation = False\n",
" self.footprint_lib = \"JLCPCB-Kicad-Footprints\"\n",
" self.output_dir = \"JLCPCB-Kicad-Library\"\n",
" self.model_base_variable = \"\"\n",
" self.model_dir = \"3dModels\"\n",
" self.models = [\"STEP\"]\n",
" self.skip_existing = True\n",
" self.symbol_lib = \"JLCPCB-Diode-Packages\"\n",
" self.symbol_lib_dir = \"JLCPCB-Kicad-Symbols\"\n",
"\n",
"\n",
"args = Args()\n",
"\n",
"for component in componentList:\n",
" JLC.add_component(f\"C{component}\", args)\n",
"\n",
"os.chdir(\"JLCPCB-Kicad-Library\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cleanup footprints"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import re\n",
"import os\n",
"\n",
"def read_kicad_mod_file(filename):\n",
" with open(filename, 'r') as file:\n",
" lines = file.readlines()\n",
" return lines\n",
"\n",
"\n",
"def write_kicad_mod_file(filename, lines):\n",
" with open(filename, 'w') as file:\n",
" file.writelines(lines)\n",
"\n",
"\n",
"def round_coordinates(lines):\n",
" for i, line in enumerate(lines):\n",
" if line.startswith('\\t\\t(at ') or line.startswith('\\t\\t(start ') or line.startswith('\\t\\t(mid ') or line.startswith('\\t\\t(end ') or line.startswith('\\t\\t\\t(width ') or line.startswith('\\t\\t(size ') or line.startswith('\\t\\t(center '):\n",
" parts = re.findall(r'-?\\d+(?:\\.\\d+)?', line)\n",
" rounded_parts = []\n",
" \n",
" for part in parts:\n",
" if '.' in part:\n",
" rounded_part = f\"{float(part):.2f}\".rstrip('0').rstrip('.')\n",
" if rounded_part == '-0': rounded_part = '0'\n",
" else:\n",
" rounded_part = part\n",
" rounded_parts.append(rounded_part)\n",
" \n",
" rounded_line = line\n",
" for old, new in zip(parts, rounded_parts):\n",
" rounded_line = rounded_line.replace(old, new)\n",
" \n",
" lines[i] = rounded_line\n",
" if line != rounded_line:\n",
" print(f'{repr(rounded_line)} <= {repr(line)}')\n",
" return lines\n",
"\n",
"# Example usage:\n",
"footprint_names = [os.path.splitext(filename)[0] \n",
" for filename in os.listdir('JLCPCB-Kicad-Footprints') \n",
" if filename.endswith('.kicad_mod')]\n",
"\n",
"for filename in footprint_names:\n",
" path = f\"{os.path.join('JLCPCB-Kicad-Footprints', filename)}.kicad_mod\"\n",
" footprint_lines = read_kicad_mod_file(path)\n",
" rounded_lines = round_coordinates(footprint_lines)\n",
" write_kicad_mod_file(path, rounded_lines)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import re\n",
"\n",
"def read_kicad_mod_file(filename):\n",
" with open(filename, 'r') as file:\n",
" lines = file.readlines()\n",
" return lines\n",
"\n",
"\n",
"def write_kicad_mod_file(filename, lines):\n",
" with open(filename, 'w') as file:\n",
" file.writelines(lines)\n",
"\n",
"\n",
"def set_silkscreen_width(lines, width=0.15):\n",
" new_lines = []\n",
" updating_width = False\n",
" width_line_index = 0\n",
"\n",
" for i, line in enumerate(lines):\n",
" # Debug print: Show the current line and its index\n",
" # print(f\"Line {i}: {repr(line)}\")\n",
" \n",
" # Check if the line starts an line element\n",
" if re.search(r'\\s*(fp_line|fp_arc|fp_circle)', line):\n",
" updating_width = True\n",
" print(f\" Detected an element: {repr(line)}\")\n",
" \n",
" # Check if the line starts the stroke property\n",
" elif updating_width and re.search(r'\\s*stroke', line):\n",
" print(f\" Detected stroke property: {repr(line)}\")\n",
" \n",
" # Check if the line defines the width\n",
" elif updating_width and re.search(r'\\s*width', line):\n",
" # Debug print: Show the line before replacement\n",
" print(f\" Found width property on Line {i}: {repr(line)}\")\n",
" width_line_index=i\n",
" \n",
" # If the line ends a silkscreen element, stop updating width\n",
" elif re.search(r'\\s*\\(layer \"F.SilkS\"\\)', line) and updating_width:\n",
" # Replace the width value with the new one\n",
" new_lines[width_line_index] = re.sub(r'\\s*width\\s+[0-9.]+\\s*', f'width {width}', new_lines[width_line_index])\n",
" # Debug print: Show the line after replacement\n",
" print(f\" Updated width property: {repr(new_lines[width_line_index])}\")\n",
" updating_width = False\n",
" \n",
" # Append the line to new_lines\n",
" new_lines.append(line)\n",
"\n",
" return new_lines\n",
"\n",
"\n",
"\n",
"# Example usage:\n",
"footprint_names = [os.path.splitext(filename)[0] \n",
" for filename in os.listdir('JLCPCB-Kicad-Footprints') \n",
" if filename.endswith('.kicad_mod')]\n",
"\n",
"for filename in footprint_names:\n",
" path = f\"{os.path.join('JLCPCB-Kicad-Footprints', filename)}.kicad_mod\"\n",
" footprint_lines = read_kicad_mod_file(path)\n",
" fixed_lines = set_silkscreen_width(footprint_lines, width=0.15)\n",
" write_kicad_mod_file(path, fixed_lines)\n"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"name": "time_series.ipynb",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.0"
}
},
"nbformat": 4,
"nbformat_minor": 0
}