333 lines
11 KiB
Text
333 lines
11 KiB
Text
{
|
|
"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
|
|
}
|