Investigate and fix JLCPCB CPL rotation for a component using mathematical pin alignment analysis
Mathematically analyze and fix the JLCPCB CPL rotation for a component.
Argument: Component reference designator (e.g., U5).
Read these files to collect component info:
release_jlcpcb/bom.csv — get LCSC part number and footprintrelease_jlcpcb/cpl.csv — get current position, rotation, layerscripts/generate_pcb/footprints.py — get pad positions and sizesscripts/generate_pcb/board.py — get placement (x, y, rot, layer)scripts/generate_pcb/jlcpcb_export.py — get current override/correctionFor each pad in the footprint:
footprints.pyVerify by reading actual pad positions from hardware/kicad/esp32-emu-turbo.kicad_pcb.
For common packages:
For each JLCPCB CPL rotation (0, 90, 180, 270):
JLCPCB convention (bottom-side):
x' = x*cos(a) + y*sin(a), y' = -x*sin(a) + y*cos(a)Compare transformed model positions with gerber pad positions. Compute max error.
Print an ASCII table:
Rotation | Max Error | Pin 1 Match | Status
---------|-----------|-------------|-------
0 | 9.1mm | NO | MISMATCH
90 | 0.0mm | YES | ALIGN <-- CPL
180 | 9.1mm | NO | MISMATCH
270 | 0.0mm | YES | ALIGN (mirrored)
Use SW11 (bottom, rot=90) as reference:
Create 4 test CPL files:
cd /Users/pierrejonnycau/Documents/WORKS/esp32-emu-turbo
for rot in 0 90 180 270; do
cp release_jlcpcb/cpl.csv release_jlcpcb/cpl_${REF,,}_rot${rot}.csv
# Replace the rotation value for this component
done
Update scripts/generate_pcb/jlcpcb_export.py:
_JLCPCB_ROT_OVERRIDES = {
"REF": RECOMMENDED_ROTATION,
}
Then regenerate: python3 -m scripts.generate_pcb hardware/kicad
Update scripts/verify_dfm_v2.py to expect the new rotation value.
scripts/generate_pcb/jlcpcb_export.py — _JLCPCB_ROT_OVERRIDES, _JLCPCB_POS_CORRECTIONSscripts/generate_pcb/footprints.py — get_pads(), _pre_rotate_element(), _mirror_pad_x()scripts/generate_pcb/board.py — _component_placeholders()scripts/verify_dfm_v2.py — test_u5_pin_alignment()release_jlcpcb/cpl.csv — Current CPLFor bottom-side components, JLCPCB 3D viewer applies:
Our generic formula:
rot = (rot - 180) % 360 # mirror correction for bottom
rot = (rot + correction) % 360 # per-footprint DB correction
Per-footprint corrections (JLCKicadTools DB):