Added pictures

This commit is contained in:
cpu
2025-11-28 16:59:55 +01:00
parent 511c990f3c
commit 18793a8a27
16 changed files with 1343 additions and 265 deletions

View File

@@ -44,7 +44,7 @@ Using an MSLA (Masked Stereolithography) resin printer for creating PCBs is a te
Here is why the **Anycubic Photon Mono 4** specifically is well-suited for this task: Here is why the **Anycubic Photon Mono 4** specifically is well-suited for this task:
**1. Extremely High Resolution (10K Screen)** **1. Extremely High Resolution (10K Screen)**
The standout feature of this printer is the **10K (9024 x 5120)** resolution on a 7-inch screen. The standout feature of this printer is the **10K (9024 x 5120)** resolution with a pixel size of 17µm (0.017mm) on a 7-inch screen.
* **Why it helps:** In PCB fabrication, resolution dictates how thin your traces can be. A 10K screen provides an exceptionally small pixel pitch. To put this in perspective, this is equivalent to a print resolution of approximately **1500 DPI**. * **Why it helps:** In PCB fabrication, resolution dictates how thin your traces can be. A 10K screen provides an exceptionally small pixel pitch. To put this in perspective, this is equivalent to a print resolution of approximately **1500 DPI**.
* *Calculation: The screen width is 153.4mm (6.04 inches). 9024 pixels / 6.04 inches ≈ 1494 DPI.* * *Calculation: The screen width is 153.4mm (6.04 inches). 9024 pixels / 6.04 inches ≈ 1494 DPI.*
* This allows you to expose traces for fine-pitch SMD components (like TQFP or 0402 packages) with professional-grade sharpness, far exceeding what is possible with inkjet or laser-printed transparencies. * This allows you to expose traces for fine-pitch SMD components (like TQFP or 0402 packages) with professional-grade sharpness, far exceeding what is possible with inkjet or laser-printed transparencies.
@@ -68,9 +68,12 @@ The process involves exporting 2D layer images from your PCB design, converting
* Chitubox (or your printer's slicing software) * Chitubox (or your printer's slicing software)
### Hardware ### Hardware
* A resin 3D printer (e.g., Anycubic Photon Mono 4) * A resin 3D printer (e.g., Anycubic Photon Mono 4)
* Photosensitive PCB. For consistent results, a pre-sensitized board like the **Bungard positive photoresist boards** is highly recommended due to its uniform coating. Available on [www.conrad.sk](https://www.conrad.sk/sk/p/bungard-150306e50-100x60mm-zakladny-material-jednostranna-35-m-foto-vrstva-pozitiv-d-x-s-100-mm-x-60-mm-1-ks-525472.html) <img src="images/Anycubic_Photon_Mono4.png" alt="Anycubic Photon Mono 4" width="400"/>
* UV light curing Solder Mask e.g. from Mechanic * Photosensitive PCB. For consistent results, a pre-sensitized board like the **Bungard positive photoresist boards** is highly recommended due to its uniform coating. A good example is [Bungard 16x100 double sided](https://www.conrad.sk/sk/p/bungard-120306z33-zakladny-material-dvojstranna-35-m-foto-vrstva-pozitiv-d-x-s-160-mm-x-100-mm-1-ks-529176.html).
<img src="images/Bungard_PCB.png" alt="Bungard PCB" width="400"/>
* UV light curing Solder Mask e.g. from Mechanic.
<img src="images/Mechanic_UV_Solder_Mask.png" alt="Mechanic UV Solder Mask" width="400"/>
### Installation ### Installation
@@ -93,9 +96,10 @@ This guide was developed to work with Inkscape 1.2.2 and Blender 5.0.0
1. Open your PCB project in the KiCad PCB Editor. 1. Open your PCB project in the KiCad PCB Editor.
2. Go to **File -> Plot** and select `Plot format` as `SVG` and set the `Output directory`. 2. Go to **File -> Plot** and select `Plot format` as `SVG` and set the `Output directory`.
3. In the `Include Layers` section select one layer (e.g. `F.Cu`, `F.Mask` or `F.Silkscreen`). If you select multiple layers they will be ploted as separate files. 3. In the `Include Layers` section select layers `B.Cu`, `B.Mask` and `F.Silkscreen`. Each layer will be ploted as a separate SVG file.
4. Optionaly, select additional layer(s) e.g. `Edge.Cuts` in the `Plot on All Layers` section. This way you can merge layers (e.g. front copper layer with board outset) into a single svg file. 4. Optionaly, select additional layer(s) e.g. `Edge.Cuts` in the `Plot on All Layers` section. This way you can merge layers i.e. add board outset into each file generated.
5. Click **Plot** and **Close**. 5. Click **Plot** and **Close**.
<img src="images/KiCad.png" alt="KiCad" width="500"/> <img src="images/KiCad_Plot.png" alt="KiCad Plot" width="500"/>
### 2. SVG to STL Conversion ### 2. SVG to STL Conversion
@@ -212,7 +216,6 @@ THICKNESS_MM="0.1"
EXPORT_DPI=1494 EXPORT_DPI=1494
``` ```
**Usage:** **Usage:**
```bash ```bash
./svg2stl.sh my_design.svg ./svg2stl.sh my_design.svg
@@ -253,7 +256,8 @@ Since the minimum exposure time per layer is 0.1s and maximum 200s, calculate th
* **Normal Exposure Time:** `200 s` (This will apply to the 3 normal layers, giving 3*200 = 600s total). * **Normal Exposure Time:** `200 s` (This will apply to the 3 normal layers, giving 3*200 = 600s total).
4. **Crucially, turn off Anti-aliasing**. Go to the "Advanced" tab and set **Anti-aliasing**. This ensures the sharpest possible pixels for crisp traces. 4. **Crucially, turn off Anti-aliasing**. Go to the "Advanced" tab and set **Anti-aliasing**. This ensures the sharpest possible pixels for crisp traces.
5. Slice the model and save the file to the USB drive. 5. Slice the model and save the file to the USB drive.
<img src="images/Chitubox.png" alt="Chitubox" width="1000"/>
### 4. Exposing the Board ### 4. Exposing the Board

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="297.0022mm" height="210.0072mm" viewBox="0.0000 0.0000 297.0022 210.0072">
<title>SVG Image created as Step_Down_Carrier_Board-B_Mask.svg date 2025/11/28 15:32:38 </title>
<desc>Image generated by PCBNEW </desc>
<g style="fill:#000000; fill-opacity:1.0000;stroke:#000000; stroke-opacity:1.0000;
stroke-linecap:round; stroke-linejoin:round;"
transform="translate(0 0) scale(1 1)">
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="127.9000" cy="66.1000" r="1.6000" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 114.1500,72.7500
114.1690,72.6543
114.2232,72.5732
114.3043,72.5190
114.4000,72.5000
115.6000,72.5000
115.6957,72.5190
115.7768,72.5732
115.8310,72.6543
115.8500,72.7500
115.8500,74.2500
115.8310,74.3457
115.7768,74.4268
115.6957,74.4810
115.6000,74.5000
114.4000,74.5000
114.3043,74.4810
114.2232,74.4268
114.1690,74.3457
114.1500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M117.5000 73.3500
L117.5000 73.6500
" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="127.9000" cy="104.0000" r="1.6000" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="90.1000" cy="104.0000" r="1.6000" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="89.5000" cy="84.8750" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="89.5000" cy="97.1250" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="128.5000" cy="84.8750" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="128.5000" cy="97.1250" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="90.2000" cy="66.2000" r="1.6000" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 123.6500,72.7500
123.6690,72.6543
123.7232,72.5732
123.8043,72.5190
123.9000,72.5000
125.1000,72.5000
125.1957,72.5190
125.2768,72.5732
125.3310,72.6543
125.3500,72.7500
125.3500,74.2500
125.3310,74.3457
125.2768,74.4268
125.1957,74.4810
125.1000,74.5000
123.9000,74.5000
123.8043,74.4810
123.7232,74.4268
123.6690,74.3457
123.6500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M127.0000 73.3500
L127.0000 73.6500
" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 89.6500,72.7500
89.6690,72.6543
89.7232,72.5732
89.8043,72.5190
89.9000,72.5000
91.1000,72.5000
91.1957,72.5190
91.2768,72.5732
91.3310,72.6543
91.3500,72.7500
91.3500,74.2500
91.3310,74.3457
91.2768,74.4268
91.1957,74.4810
91.1000,74.5000
89.9000,74.5000
89.8043,74.4810
89.7232,74.4268
89.6690,74.3457
89.6500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M93.0000 73.3500
L93.0000 73.6500
" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:0.1000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M86.4973 62.5373
L131.5800 62.5373
" />
<path d="M131.5800 107.6800
L86.4973 107.6800
" />
<path d="M131.5800 62.5373
L131.5800 107.6800
" />
<path d="M86.4973 107.6800
L86.4973 62.5373
" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -7,7 +7,7 @@
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" version="1.1"
width="297.0022mm" height="210.0072mm" viewBox="0.0000 0.0000 297.0022 210.0072"> width="297.0022mm" height="210.0072mm" viewBox="0.0000 0.0000 297.0022 210.0072">
<title>SVG Image created as Step_Down_Carrier_Board-F_Silkscreen.svg date 2025/11/27 14:53:26 </title> <title>SVG Image created as Step_Down_Carrier_Board-F_Silkscreen.svg date 2025/11/28 15:32:38 </title>
<desc>Image generated by PCBNEW </desc> <desc>Image generated by PCBNEW </desc>
<g style="fill:#000000; fill-opacity:1.0000;stroke:#000000; stroke-opacity:1.0000; <g style="fill:#000000; fill-opacity:1.0000;stroke:#000000; stroke-opacity:1.0000;
stroke-linecap:round; stroke-linejoin:round;" stroke-linecap:round; stroke-linejoin:round;"
@@ -1681,226 +1681,6 @@ L87.9400 71.0400
<path d="M95.5600 77.0100 <path d="M95.5600 77.0100
L95.5600 71.0400 L95.5600 71.0400
" /> " />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 114.1500,72.7500
114.1690,72.6543
114.2232,72.5732
114.3043,72.5190
114.4000,72.5000
115.6000,72.5000
115.6957,72.5190
115.7768,72.5732
115.8310,72.6543
115.8500,72.7500
115.8500,74.2500
115.8310,74.3457
115.7768,74.4268
115.6957,74.4810
115.6000,74.5000
114.4000,74.5000
114.3043,74.4810
114.2232,74.4268
114.1690,74.3457
114.1500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M117.5000 73.3500
L117.5000 73.6500
" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="89.5000" cy="84.8750" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="89.5000" cy="97.1250" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="128.5000" cy="84.8750" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="128.5000" cy="97.1250" r="1.2500" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 123.6500,72.7500
123.6690,72.6543
123.7232,72.5732
123.8043,72.5190
123.9000,72.5000
125.1000,72.5000
125.1957,72.5190
125.2768,72.5732
125.3310,72.6543
125.3500,72.7500
125.3500,74.2500
125.3310,74.3457
125.2768,74.4268
125.1957,74.4810
125.1000,74.5000
123.9000,74.5000
123.8043,74.4810
123.7232,74.4268
123.6690,74.3457
123.6500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M127.0000 73.3500
L127.0000 73.6500
" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 89.6500,72.7500
89.6690,72.6543
89.7232,72.5732
89.8043,72.5190
89.9000,72.5000
91.1000,72.5000
91.1957,72.5190
91.2768,72.5732
91.3310,72.6543
91.3500,72.7500
91.3500,74.2500
91.3310,74.3457
91.2768,74.4268
91.1957,74.4810
91.1000,74.5000
89.9000,74.5000
89.8043,74.4810
89.7232,74.4268
89.6690,74.3457
89.6500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M93.0000 73.3500
L93.0000 73.6500
" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:0.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M89.5000 84.8750
L93.0000 81.3750
" />
<path d="M93.0000 81.3750
L93.0000 73.5000
" />
<path d="M117.5000 73.8750
L117.5000 73.5000
" />
<path d="M128.5000 84.8750
L117.5000 73.8750
" />
<path d="M128.5000 84.8750
L127.0000 83.3750
" />
<path d="M127.0000 83.3750
L127.0000 73.5000
" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 114.1500,72.7500
114.1690,72.6543
114.2232,72.5732
114.3043,72.5190
114.4000,72.5000
115.6000,72.5000
115.6957,72.5190
115.7768,72.5732
115.8310,72.6543
115.8500,72.7500
115.8500,74.2500
115.8310,74.3457
115.7768,74.4268
115.6957,74.4810
115.6000,74.5000
114.4000,74.5000
114.3043,74.4810
114.2232,74.4268
114.1690,74.3457
114.1500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M117.5000 73.3500
L117.5000 73.6500
" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="89.5000" cy="84.8750" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="89.5000" cy="97.1250" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="128.5000" cy="84.8750" r="1.2500" />
</g>
<g style="fill:#000000; fill-opacity:1.0000; stroke:none;">
<circle cx="128.5000" cy="97.1250" r="1.2500" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 123.6500,72.7500
123.6690,72.6543
123.7232,72.5732
123.8043,72.5190
123.9000,72.5000
125.1000,72.5000
125.1957,72.5190
125.2768,72.5732
125.3310,72.6543
125.3500,72.7500
125.3500,74.2500
125.3310,74.3457
125.2768,74.4268
125.1957,74.4810
125.1000,74.5000
123.9000,74.5000
123.8043,74.4810
123.7232,74.4268
123.6690,74.3457
123.6500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M127.0000 73.3500
L127.0000 73.6500
" />
<path style="fill:#000000; fill-opacity:1.0000; stroke:none;fill-rule:evenodd;"
d="M 89.6500,72.7500
89.6690,72.6543
89.7232,72.5732
89.8043,72.5190
89.9000,72.5000
91.1000,72.5000
91.1957,72.5190
91.2768,72.5732
91.3310,72.6543
91.3500,72.7500
91.3500,74.2500
91.3310,74.3457
91.2768,74.4268
91.1957,74.4810
91.1000,74.5000
89.9000,74.5000
89.8043,74.4810
89.7232,74.4268
89.6690,74.3457
89.6500,74.2500
Z" />
</g>
<g style="fill:none;
stroke:#000000; stroke-width:1.7000; stroke-opacity:1;
stroke-linecap:round; stroke-linejoin:round;">
<path d="M93.0000 73.3500
L93.0000 73.6500
" />
</g> </g>
<g style="fill:none; <g style="fill:none;
stroke:#000000; stroke-width:0.1000; stroke-opacity:1; stroke:#000000; stroke-width:0.1000; stroke-opacity:1;

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

BIN
images/Bungard_PCB.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 KiB

BIN
images/Chitubox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

BIN
images/KiCad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

BIN
images/KiCad_Plot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 KiB

View File

@@ -14,48 +14,53 @@ THICKNESS_MM="0.1"
# DPI based on the 3D printer resolution (e.g. 1494 for Anycubic Photon Mono 4) # DPI based on the 3D printer resolution (e.g. 1494 for Anycubic Photon Mono 4)
EXPORT_DPI=1494 EXPORT_DPI=1494
# --------------------- # Check for at least one input file
if [ "$#" -lt 1 ]; then
# 1. Check Input echo "Error: No input files provided."
if [ -z "$1" ]; then echo "Usage: ./svg2stl.sh <file1.svg> [file2.svg ...]"
echo "Error: No input file provided."
echo "Usage: ./svg2stl.sh <input.svg>"
exit 1 exit 1
fi fi
# 2. Setup Absolute Paths # Loop over all input files
INPUT_FILE="$(readlink -f "$1")" for INPUT in "$@"; do
WORK_DIR="$(dirname "$INPUT_FILE")" INPUT_FILE="$(readlink -f "$INPUT")"
BASENAME="$(basename "$INPUT_FILE" .svg)"
TEMP_SVG="$WORK_DIR/${BASENAME}_temp_processed.svg"
OUTPUT_STL="$WORK_DIR/$BASENAME.stl"
# 3. Inkscape Processing echo "Processing: $INPUT_FILE"
# Note: We do NOT resize here. We export high-res geometry and resize in Blender.
ACTIONS="select-by-element:text;delete;select-all;object-stroke-to-path;path-union;export-plain-svg;export-filename:$TEMP_SVG;export-do"
INK_ARGS="--export-dpi=$EXPORT_DPI --actions=$ACTIONS"
echo "------------------------------------------------" # Setup Absolute Paths
echo "Step 1: Inkscape Processing" WORK_DIR="$(dirname "$INPUT_FILE")"
echo "Input: $INPUT_FILE" BASENAME="$(basename "$INPUT_FILE" .svg)"
echo "------------------------------------------------" TEMP_SVG="$WORK_DIR/${BASENAME}_temp_processed.svg"
OUTPUT_STL="$WORK_DIR/$BASENAME.stl"
inkscape "$INPUT_FILE" $INK_ARGS # Inkscape Processing
# Note: We do NOT resize here. We export high-res geometry and resize in Blender.
ACTIONS="select-by-element:text;delete;select-all;object-stroke-to-path;path-union;export-plain-svg;export-filename:$TEMP_SVG;export-do"
INK_ARGS="--export-dpi=$EXPORT_DPI --actions=$ACTIONS"
if [ ! -f "$TEMP_SVG" ]; then echo "------------------------------------------------"
echo "ERROR: Inkscape failed to create the temp file." echo "Step 1: Inkscape Processing"
exit 1 echo "Input: $INPUT_FILE"
fi echo "------------------------------------------------"
echo "------------------------------------------------" inkscape "$INPUT_FILE" $INK_ARGS
echo "Step 2: Blender Processing"
echo "Target Width: ${TARGET_WIDTH_MM} mm"
echo "Target Thickness: ${THICKNESS_MM} mm"
echo "------------------------------------------------"
# Pass Width and Thickness to Python if [ ! -f "$TEMP_SVG" ]; then
blender --background --python pcb_to_stl.py -- "$TEMP_SVG" "$OUTPUT_STL" "$THICKNESS_MM" "$TARGET_WIDTH_MM" echo "ERROR: Inkscape failed to create the temp file."
exit 1
fi
# 4. Cleanup echo "------------------------------------------------"
rm "$TEMP_SVG" echo "Step 2: Blender Processing"
echo "Done! Saved to $OUTPUT_STL" echo "Target Width: ${TARGET_WIDTH_MM} mm"
echo "Target Thickness: ${THICKNESS_MM} mm"
echo "------------------------------------------------"
# Pass Width and Thickness to Python
blender --background --python pcb_to_stl.py -- "$TEMP_SVG" "$OUTPUT_STL" "$THICKNESS_MM" "$TARGET_WIDTH_MM"
# Cleanup
rm "$TEMP_SVG"
echo "Done! Saved to $OUTPUT_STL"
# ---------------------
done