Skip to content

Commit

Permalink
Fix JLCPCB rotation automatically
Browse files Browse the repository at this point in the history
The lists in this script are incomplete, but work for the cart board
and some of the microcontroller board.
  • Loading branch information
joeyparrish committed Jul 14, 2024
1 parent 5c5709f commit 33bf889
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
7 changes: 1 addition & 6 deletions hardware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ To order boards, see hardware zip files attached to
[releases](https://github.com/joeyparrish/kinetoscope/releases). These can be
uploaded to JLCPCB.

TODO: Document ordering process, automate rotational fixes to JLCPCB placement
TODO: Document ordering process


## Boards
Expand All @@ -47,11 +47,6 @@ The stacking boards are:
- Surface Finish: ENIG
- Gold Fingers: Yes
- 30°finger chamfered: Yes
- Uncheck the following parts, which JLCPCB will mis-populate:
- J1 (pin header)
- The following parts need to be rotated 90 degrees to the right before
ordering, because JLCPCB's models disagree with KiCad's:
- Every IC that isn't U6 (flash chip)
- The following parts will have to be populated by hand:
- C2 (bulk capacitor, electrolytic, 47uF, 16+V)
- U2 (fixed low-drop-out regulator, 1.5A @ 3.3V)
Expand Down
5 changes: 5 additions & 0 deletions hardware/fab-jlcpcb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,10 @@ if ! kicad-cli sch export bom \
exit 1
fi

echo "Filtering BOM and fixing rotations for JLCPCB..."
./fix-bom-and-pos.py \
"$1-fab/$1.bom.csv" "$1-fab/$1.bom.csv" \
"$1-fab/$1-front.pos.csv" "$1-fab/$1-front.pos.csv"

echo "Zipping..."
zip -r9 "$1-fab.zip" "$1-fab/"
84 changes: 84 additions & 0 deletions hardware/fix-bom-and-pos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python3

import csv
import sys

# Packages we know need rotation.
ROTATE_PACKAGES = [
'LQFP-48_7x7mm_P0.5mm',
'SO-16_3.9x9.9mm_P1.27mm',
'SSOP-24_5.3x8.2mm_P0.65mm',
'TSSOP-16_4.4x3.6mm_P0.4mm',
'TSSOP-16_4.4x5mm_P0.65mm',
]

# Packages we know don't need rotation.
OKAY_PACKAGES = [
'C_0603_1608Metric',
'Crystal_SMD_0603-2Pin_6.0x3.5mm',
'L_0603_1608Metric',
'R_0603_1608Metric',
'TSOP-I-48_18.4x12mm_P0.5mm',
]

# Packages JLCPCB doesn't have at all AFAICT.
DONT_HAVE_PACKAGES = [
'CP_Radial_D5.0mm_P2.00mm',
'PinHeader_2x26_P2.54mm_Vertical',
'TO-220-3_Horizontal_TabDown',
]

bom_in, bom_out, pos_in, pos_out = sys.argv[1:]

with open(bom_in, 'r', newline='') as f:
reader = csv.DictReader(f)
bom_fields = reader.fieldnames
bom_rows = [row for row in reader]

with open(pos_in, 'r', newline='') as f:
reader = csv.DictReader(f)
pos_fields = reader.fieldnames
pos_rows = [row for row in reader]

skipped_names = []
with open(bom_out, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=bom_fields)
writer.writeheader()

for row in bom_rows:
part_num = row['JLCPCB Part#']
name = row['Designator']

# Only write rows we have part numbers for. The others, we don't expect
# JLCPCB to populate. They will sometimes guess a part number for us, but
# it's never right, so it's best to skip these lines.
if part_num:
writer.writerow(row)
else:
print('Skipping {}, no part number'.format(name))
skipped_names.extend(name.split(','))

with open(pos_out, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=pos_fields)
writer.writeheader()

for row in pos_rows:
package = row['Package']
name = row['Designator']
rotation = float(row['Rotation'])

# Skip anything we omitted from the BOM.
if name in skipped_names:
continue

# Correct the rotation of certain items.
if package in ROTATE_PACKAGES:
print('Fixing rotation of {}, package {}'.format(name, package))
rotation -= 90
row['Rotation'] = '{:.6f}'.format(rotation)
elif package in OKAY_PACKAGES or package in DONT_HAVE_PACKAGES:
pass
else:
print('Unsure about rotation of {}, package {}'.format(name, package))

writer.writerow(row)

0 comments on commit 33bf889

Please sign in to comment.