feat: focus library on custom components only

- Remove all JLCPCB/LCSC related files and documentation
- Clean up README files to focus on custom components not in standard library
- Translate CHANGELOG to English
- Add .gitkeep files to preserve directory structure
- Library now focused on: missing 3D models, custom artwork, personal logos
This commit is contained in:
2025-12-09 15:16:14 +01:00
parent dda87cfbae
commit 5bffe55486
21 changed files with 56 additions and 2634 deletions

2
scripts/.gitkeep Normal file
View File

@@ -0,0 +1,2 @@
# This file ensures the scripts/ directory is tracked by git
# Place automation scripts here

View File

@@ -1,453 +0,0 @@
# KiCad Symbol Generator for JLCPCB Basic Parts
# Generates KiCad symbol libraries with Fabrication Toolkit compatible properties
# Compatible with bennymeg/JLC-Plugin-for-KiCad
param(
[Parameter(Mandatory=$true)]
[string]$CsvPath,
[Parameter(Mandatory=$true)]
[string]$OutputPath,
[switch]$CreateSymbols = $true,
[switch]$GenerateReport = $true,
[switch]$DryRun = $false
)
Write-Host "KiCad JLCPCB Basic Parts Symbol Generator" -ForegroundColor Green
Write-Host "=========================================" -ForegroundColor Green
# Validate input file
if (-not (Test-Path $CsvPath)) {
Write-Error "CSV file not found: $CsvPath"
exit 1
}
# Import CSV data
Write-Host "Loading JLCPCB Basic Parts database: $CsvPath" -ForegroundColor Yellow
try {
$parts = Import-Csv $CsvPath
Write-Host "Successfully loaded $($parts.Count) parts" -ForegroundColor Green
} catch {
Write-Error "Failed to load CSV file: $_"
exit 1
}
# Group parts by component type
$resistors = $parts | Where-Object { $_.Component -eq "R" }
$capacitors = $parts | Where-Object { $_.Component -eq "C" }
$inductors = $parts | Where-Object { $_.Component -eq "L" }
$ics = $parts | Where-Object { $_.Component -eq "IC" }
$crystals = $parts | Where-Object { $_.Component -eq "XTAL" }
$leds = $parts | Where-Object { $_.Component -eq "LED" }
$diodes = $parts | Where-Object { $_.Component -eq "D" }
Write-Host "Component distribution:" -ForegroundColor Cyan
Write-Host " Resistors: $($resistors.Count)" -ForegroundColor White
Write-Host " Capacitors: $($capacitors.Count)" -ForegroundColor White
Write-Host " Inductors: $($inductors.Count)" -ForegroundColor White
Write-Host " ICs: $($ics.Count)" -ForegroundColor White
Write-Host " Crystals: $($crystals.Count)" -ForegroundColor White
Write-Host " LEDs: $($leds.Count)" -ForegroundColor White
Write-Host " Diodes: $($diodes.Count)" -ForegroundColor White
# Function to convert package size to metric footprint name
function Get-KiCadFootprint {
param($component, $package)
switch ($component) {
"R" {
switch ($package) {
"0402" { "Resistor_SMD:R_0402_1005Metric" }
"0603" { "Resistor_SMD:R_0603_1608Metric" }
"0805" { "Resistor_SMD:R_0805_2012Metric" }
"1206" { "Resistor_SMD:R_1206_3216Metric" }
default { "Resistor_SMD:R_$package" }
}
}
"C" {
switch ($package) {
"0402" { "Capacitor_SMD:C_0402_1005Metric" }
"0603" { "Capacitor_SMD:C_0603_1608Metric" }
"0805" { "Capacitor_SMD:C_0805_2012Metric" }
"1206" { "Capacitor_SMD:C_1206_3216Metric" }
default { "Capacitor_SMD:C_$package" }
}
}
"L" {
switch ($package) {
"0603" { "Inductor_SMD:L_0603_1608Metric" }
"0805" { "Inductor_SMD:L_0805_2012Metric" }
"1206" { "Inductor_SMD:L_1206_3216Metric" }
default { "Inductor_SMD:L_$package" }
}
}
"IC" {
switch ($package) {
"SOIC-8" { "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm" }
"SOIC-14" { "Package_SO:SOIC-14_3.9x8.7mm_P1.27mm" }
"SOIC-16" { "Package_SO:SOIC-16_3.9x9.9mm_P1.27mm" }
"SOIC-18" { "Package_SO:SOIC-18W_7.5x11.6mm_P1.27mm" }
"LQFP-48" { "Package_QFP:LQFP-48_7x7mm_P0.5mm" }
"TSSOP-20" { "Package_SO:TSSOP-20_4.4x6.5mm_P0.65mm" }
"SOT-223" { "Package_TO_SOT_SMD:SOT-223-3_TabPin2" }
"SSOP-28" { "Package_SO:SSOP-28_5.3x10.2mm_P0.65mm" }
"MODULE" { "RF_Module:ESP32-WROOM-32" } # Special case for modules
default { "Package_SO:$package" }
}
}
"XTAL" {
switch ($package) {
"HC-49S" { "Crystal:Crystal_HC49-SD_SMD" }
"3215" { "Crystal:Crystal_SMD_3215-2Pin_3.2x1.5mm" }
default { "Crystal:Crystal_$package" }
}
}
"LED" {
switch ($package) {
"0603" { "LED_SMD:LED_0603_1608Metric" }
"0805" { "LED_SMD:LED_0805_2012Metric" }
default { "LED_SMD:LED_$package" }
}
}
"D" {
switch ($package) {
"SOD-123" { "Diode_SMD:D_SOD-123" }
"SOD-123FL" { "Diode_SMD:D_SOD-123F" }
default { "Diode_SMD:D_$package" }
}
}
default { "Unknown:$package" }
}
}
# Function to generate KiCad symbol template
function Get-SymbolTemplate {
param($part, $referencePrefix)
$symbolName = "$($part.Value)_$($part.Package)_$($part.'LCSC Part #')"
$footprint = Get-KiCadFootprint $part.Component $part.Package
$datasheet = "https://lcsc.com/product-detail/$($part.'LCSC Part #').html"
# Clean up special characters in symbol name for KiCad compatibility
$symbolName = $symbolName -replace '[µ]', 'u'
return @"
(symbol "$symbolName" (in_bom yes) (on_board yes)
(property "Reference" "$referencePrefix" (at 0 2.54 0)
(effects (font (size 1.27 1.27))))
(property "Value" "$($part.Value)" (at 0 -2.54 0)
(effects (font (size 1.27 1.27))))
(property "Footprint" "$footprint" (at 0 -5.08 0)
(effects (font (size 1.27 1.27)) hide))
(property "Datasheet" "$datasheet" (at 0 -7.62 0)
(effects (font (size 1.27 1.27)) hide))
(property "Description" "$($part.Description)" (at 0 -10.16 0)
(effects (font (size 1.27 1.27)) hide))
(property "LCSC Part #" "$($part.'LCSC Part #')" (at 0 -12.70 0)
(effects (font (size 1.27 1.27)) hide))
(property "Manufacturer" "$($part.Manufacturer)" (at 0 -15.24 0)
(effects (font (size 1.27 1.27)) hide))
(property "MFG Part #" "$($part.'MFG Part #')" (at 0 -17.78 0)
(effects (font (size 1.27 1.27)) hide))
(property "Package" "$($part.Package)" (at 0 -20.32 0)
(effects (font (size 1.27 1.27)) hide))
(property "FT Rotation Offset" "$($part.'FT Rotation Offset')" (at 0 -22.86 0)
(effects (font (size 1.27 1.27)) hide))
$(Get-SymbolGraphics $part.Component $symbolName)
)
"@
}
# Function to generate symbol graphics based on component type
function Get-SymbolGraphics {
param($componentType, $symbolName)
switch ($componentType) {
"R" {
return @"
(symbol "${symbolName}_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))))
(symbol "${symbolName}_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
"@
}
"C" {
return @"
(symbol "${symbolName}_0_1"
(polyline
(pts (xy -2.032 -0.762) (xy 2.032 -0.762))
(stroke (width 0.508) (type default))
(fill (type none)))
(polyline
(pts (xy -2.032 0.762) (xy 2.032 0.762))
(stroke (width 0.508) (type default))
(fill (type none))))
(symbol "${symbolName}_1_1"
(pin passive line (at 0 2.54 270) (length 1.778)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 0 -2.54 90) (length 1.778)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
"@
}
"L" {
return @"
(symbol "${symbolName}_0_1"
(arc (start 0 -2.54) (mid 0.635 -1.905) (end 0 -1.27)
(stroke (width 0) (type default))
(fill (type none)))
(arc (start 0 -1.27) (mid 0.635 -0.635) (end 0 0)
(stroke (width 0) (type default))
(fill (type none)))
(arc (start 0 0) (mid 0.635 0.635) (end 0 1.27)
(stroke (width 0) (type default))
(fill (type none)))
(arc (start 0 1.27) (mid 0.635 1.905) (end 0 2.54)
(stroke (width 0) (type default))
(fill (type none))))
(symbol "${symbolName}_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "1" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "2" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
"@
}
"IC" {
# For ICs, create a simple rectangle - actual pinout would need manual definition
return @"
(symbol "${symbolName}_0_1"
(rectangle (start -7.62 5.08) (end 7.62 -5.08)
(stroke (width 0.254) (type default))
(fill (type background))))
(symbol "${symbolName}_1_1"
(pin input line (at -10.16 0 0) (length 2.54)
(name "VCC" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin input line (at 10.16 0 180) (length 2.54)
(name "GND" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
"@
}
"LED" {
return @"
(symbol "${symbolName}_0_1"
(polyline
(pts (xy -1.27 -1.27) (xy -1.27 1.27))
(stroke (width 0.254) (type default))
(fill (type none)))
(polyline
(pts (xy -1.27 0) (xy 1.27 0))
(stroke (width 0) (type default))
(fill (type none)))
(polyline
(pts (xy 1.27 -1.27) (xy 1.27 1.27) (xy -1.27 0) (xy 1.27 -1.27))
(stroke (width 0.254) (type default))
(fill (type none))))
(symbol "${symbolName}_1_1"
(pin passive line (at -3.81 0 0) (length 2.54)
(name "K" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 3.81 0 180) (length 2.54)
(name "A" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
"@
}
default {
# Generic two-pin component
return @"
(symbol "${symbolName}_0_1"
(rectangle (start -1.27 1.27) (end 1.27 -1.27)
(stroke (width 0.254) (type default))
(fill (type none))))
(symbol "${symbolName}_1_1"
(pin passive line (at -2.54 0 0) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 2.54 0 180) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
"@
}
}
}
# Generate symbol libraries
if ($CreateSymbols -and -not $DryRun) {
Write-Host "Generating KiCad symbol libraries..." -ForegroundColor Yellow
# Create output directory
$symbolsDir = Join-Path $OutputPath "symbols"
if (-not (Test-Path $symbolsDir)) {
New-Item -Path $symbolsDir -ItemType Directory -Force | Out-Null
}
# Generate Standard Passives library
if ($resistors.Count -gt 0 -or $capacitors.Count -gt 0 -or $inductors.Count -gt 0) {
Write-Host " Creating Standard_Passives.kicad_sym..." -ForegroundColor Cyan
$passivesHeader = @"
(kicad_symbol_lib (version 20211014) (generator "JLCPCB-Generator")
(symbol_lib_info (name "Standard_Passives") (description "JLCPCB Basic Parts - Passives with Fabrication Toolkit properties"))
"@
$passivesSymbols = @()
foreach ($resistor in $resistors) { $passivesSymbols += Get-SymbolTemplate $resistor "R" }
foreach ($capacitor in $capacitors) { $passivesSymbols += Get-SymbolTemplate $capacitor "C" }
foreach ($inductor in $inductors) { $passivesSymbols += Get-SymbolTemplate $inductor "L" }
$passivesContent = $passivesHeader + "`n" + ($passivesSymbols -join "`n") + "`n)"
$passivesPath = Join-Path $symbolsDir "Standard_Passives.kicad_sym"
$passivesContent | Out-File -FilePath $passivesPath -Encoding UTF8
Write-Host " Created: $passivesPath" -ForegroundColor Green
}
# Generate Standard ICs library
if ($ics.Count -gt 0) {
Write-Host " Creating Standard_ICs.kicad_sym..." -ForegroundColor Cyan
$icsHeader = @"
(kicad_symbol_lib (version 20211014) (generator "JLCPCB-Generator")
(symbol_lib_info (name "Standard_ICs") (description "JLCPCB Basic Parts - ICs with Fabrication Toolkit properties"))
"@
$icsSymbols = @()
foreach ($ic in $ics) { $icsSymbols += Get-SymbolTemplate $ic "U" }
$icsContent = $icsHeader + "`n" + ($icsSymbols -join "`n") + "`n)"
$icsPath = Join-Path $symbolsDir "Standard_ICs.kicad_sym"
$icsContent | Out-File -FilePath $icsPath -Encoding UTF8
Write-Host " Created: $icsPath" -ForegroundColor Green
}
# Generate Standard Components library (LEDs, Diodes, Crystals)
if ($leds.Count -gt 0 -or $diodes.Count -gt 0 -or $crystals.Count -gt 0) {
Write-Host " Creating Standard_Components.kicad_sym..." -ForegroundColor Cyan
$componentsHeader = @"
(kicad_symbol_lib (version 20211014) (generator "JLCPCB-Generator")
(symbol_lib_info (name "Standard_Components") (description "JLCPCB Basic Parts - LEDs, Diodes, Crystals with Fabrication Toolkit properties"))
"@
$componentsSymbols = @()
foreach ($led in $leds) { $componentsSymbols += Get-SymbolTemplate $led "D" }
foreach ($diode in $diodes) { $componentsSymbols += Get-SymbolTemplate $diode "D" }
foreach ($crystal in $crystals) { $componentsSymbols += Get-SymbolTemplate $crystal "Y" }
$componentsContent = $componentsHeader + "`n" + ($componentsSymbols -join "`n") + "`n)"
$componentsPath = Join-Path $symbolsDir "Standard_Components.kicad_sym"
$componentsContent | Out-File -FilePath $componentsPath -Encoding UTF8
Write-Host " Created: $componentsPath" -ForegroundColor Green
}
}
# Generate BOM template for JLCPCB
if ($GenerateReport) {
Write-Host "Generating JLCPCB BOM template..." -ForegroundColor Yellow
$bomHeader = @"
# JLCPCB Assembly BOM Template
# Generated from JLCPCB Basic Parts Database
# Compatible with JLC Plugin for KiCad (bennymeg)
Comment,Designator,Footprint,LCSC Part #,Manufacturer,MFG Part #
"@
$bomLines = @()
foreach ($part in $parts) {
$footprint = (Get-KiCadFootprint $part.Component $part.Package) -replace ".*:", ""
$bomLines += "$($part.Value),REF**,$footprint,$($part.'LCSC Part #'),$($part.Manufacturer),$($part.'MFG Part #')"
}
$bomContent = $bomHeader + "`n" + ($bomLines -join "`n")
$bomPath = Join-Path $OutputPath "docs/JLCPCB_BOM_Template.csv"
if (-not $DryRun) {
New-Item -Path (Split-Path $bomPath) -ItemType Directory -Force | Out-Null
$bomContent | Out-File -FilePath $bomPath -Encoding UTF8
Write-Host " Created: $bomPath" -ForegroundColor Green
}
}
# Generate statistics report
Write-Host "`n" + "="*50 -ForegroundColor Green
Write-Host "GENERATION SUMMARY" -ForegroundColor Green
Write-Host "="*50 -ForegroundColor Green
Write-Host "Components by package:" -ForegroundColor Cyan
$packageStats = $parts | Group-Object Package | Sort-Object Count -Descending
foreach ($stat in $packageStats) {
Write-Host " $($stat.Name): $($stat.Count) parts" -ForegroundColor White
}
Write-Host "`nComponents by manufacturer:" -ForegroundColor Cyan
$mfgStats = $parts | Group-Object Manufacturer | Sort-Object Count -Descending
foreach ($stat in $mfgStats) {
Write-Host " $($stat.Name): $($stat.Count) parts" -ForegroundColor White
}
# Calculate total cost for starter kit
$totalCost = ($parts | Where-Object { $_.'Price 1k' -match '^\d+\.?\d*$' } | Measure-Object { [double]$_.'Price 1k' } -Sum).Sum
Write-Host "`nCost analysis:" -ForegroundColor Cyan
Write-Host " Total cost for complete basic parts kit (1k each): `$$([math]::Round($totalCost, 2))" -ForegroundColor White
if ($DryRun) {
Write-Host "`n[DRY RUN] No files were created" -ForegroundColor Yellow
} else {
Write-Host "`nGeneration completed successfully!" -ForegroundColor Green
}
<#
.SYNOPSIS
Generates KiCad symbol libraries for JLCPCB Basic Parts with Fabrication Toolkit support
.DESCRIPTION
This script reads a CSV database of JLCPCB Basic Parts and generates:
- KiCad symbol libraries (.kicad_sym) with proper Fabrication Toolkit properties
- BOM templates compatible with JLCPCB assembly service
- Cost analysis and component statistics
The generated symbols include all necessary properties for the Fabrication Toolkit:
- LCSC Part # (for automatic part matching)
- Manufacturer and MFG Part # (for verification)
- FT Rotation Offset (for pick-and-place orientation)
- Standard KiCad footprint references
.PARAMETER CsvPath
Path to the JLCPCB_Basic_Parts.csv database file
.PARAMETER OutputPath
Output directory for generated files
.PARAMETER CreateSymbols
Generate KiCad symbol libraries (default: true)
.PARAMETER GenerateReport
Generate BOM templates and reports (default: true)
.PARAMETER DryRun
Show what would be generated without creating files
.EXAMPLE
.\Generate_JLCPCB_Symbols.ps1 -CsvPath ".\docs\JLCPCB_Basic_Parts.csv" -OutputPath "."
.EXAMPLE
.\Generate_JLCPCB_Symbols.ps1 -CsvPath ".\docs\JLCPCB_Basic_Parts.csv" -OutputPath "." -DryRun
.NOTES
Requires PowerShell 5.0+ and Write permissions to output directory
Generated symbols use standard KiCad footprints - no custom footprints needed
#>

View File

@@ -1,554 +0,0 @@
#!/bin/bash
# KiCad Symbol Generator for JLCPCB Basic Parts
# Generates KiCad symbol libraries with Fabrication Toolkit compatible properties
# Compatible with bennymeg/JLC-Plugin-for-KiCad
set -euo pipefail
# Default values
CSV_PATH=""
OUTPUT_PATH=""
CREATE_SYMBOLS=true
GENERATE_REPORT=true
DRY_RUN=false
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
NC='\033[0m' # No Color
# Function to print colored output
print_color() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}
# Function to show usage
usage() {
cat << EOF
Usage: $0 -c CSV_PATH -o OUTPUT_PATH [options]
KiCad Symbol Generator for JLCPCB Basic Parts
Required arguments:
-c, --csv-path PATH Path to JLCPCB_Basic_Parts.csv file
-o, --output-path PATH Output directory for generated files
Optional arguments:
-s, --skip-symbols Skip symbol generation
-r, --skip-report Skip report generation
-d, --dry-run Show what would be generated without creating files
-h, --help Show this help message
Examples:
$0 -c ./docs/JLCPCB_Basic_Parts.csv -o .
$0 -c ./docs/JLCPCB_Basic_Parts.csv -o . --dry-run
EOF
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-c|--csv-path)
CSV_PATH="$2"
shift 2
;;
-o|--output-path)
OUTPUT_PATH="$2"
shift 2
;;
-s|--skip-symbols)
CREATE_SYMBOLS=false
shift
;;
-r|--skip-report)
GENERATE_REPORT=false
shift
;;
-d|--dry-run)
DRY_RUN=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option $1"
usage
exit 1
;;
esac
done
# Validate required arguments
if [[ -z "$CSV_PATH" || -z "$OUTPUT_PATH" ]]; then
echo "Error: Both CSV path and output path are required"
usage
exit 1
fi
# Validate input file
if [[ ! -f "$CSV_PATH" ]]; then
print_color $RED "Error: CSV file not found: $CSV_PATH"
exit 1
fi
print_color $GREEN "KiCad JLCPCB Basic Parts Symbol Generator"
print_color $GREEN "========================================="
print_color $YELLOW "Loading JLCPCB Basic Parts database: $CSV_PATH"
# Check if we have required tools
if ! command -v awk &> /dev/null; then
print_color $RED "Error: awk is required but not installed"
exit 1
fi
# Read and parse CSV file
if [[ ! -r "$CSV_PATH" ]]; then
print_color $RED "Error: Cannot read CSV file: $CSV_PATH"
exit 1
fi
# Count components by type (skip comments and empty lines)
RESISTOR_COUNT=$(awk -F',' 'NR>1 && $1=="R" {count++} END {print count+0}' "$CSV_PATH")
CAPACITOR_COUNT=$(awk -F',' 'NR>1 && $1=="C" {count++} END {print count+0}' "$CSV_PATH")
INDUCTOR_COUNT=$(awk -F',' 'NR>1 && $1=="L" {count++} END {print count+0}' "$CSV_PATH")
IC_COUNT=$(awk -F',' 'NR>1 && $1=="IC" {count++} END {print count+0}' "$CSV_PATH")
LED_COUNT=$(awk -F',' 'NR>1 && $1=="LED" {count++} END {print count+0}' "$CSV_PATH")
DIODE_COUNT=$(awk -F',' 'NR>1 && $1=="D" {count++} END {print count+0}' "$CSV_PATH")
CRYSTAL_COUNT=$(awk -F',' 'NR>1 && $1=="XTAL" {count++} END {print count+0}' "$CSV_PATH")
TOTAL_COUNT=$(awk -F',' 'NR>1 && $1!~/^#/ && $1!="" {count++} END {print count+0}' "$CSV_PATH")
print_color $GREEN "Successfully loaded $TOTAL_COUNT parts"
print_color $CYAN "Component distribution:"
print_color $WHITE " Resistors: $RESISTOR_COUNT"
print_color $WHITE " Capacitors: $CAPACITOR_COUNT"
print_color $WHITE " Inductors: $INDUCTOR_COUNT"
print_color $WHITE " ICs: $IC_COUNT"
print_color $WHITE " LEDs: $LED_COUNT"
print_color $WHITE " Diodes: $DIODE_COUNT"
print_color $WHITE " Crystals: $CRYSTAL_COUNT"
# Function to get KiCad footprint based on component type and package
get_kicad_footprint() {
local component=$1
local package=$2
case $component in
"R")
case $package in
"0402") echo "Resistor_SMD:R_0402_1005Metric" ;;
"0603") echo "Resistor_SMD:R_0603_1608Metric" ;;
"0805") echo "Resistor_SMD:R_0805_2012Metric" ;;
"1206") echo "Resistor_SMD:R_1206_3216Metric" ;;
*) echo "Resistor_SMD:R_$package" ;;
esac
;;
"C")
case $package in
"0402") echo "Capacitor_SMD:C_0402_1005Metric" ;;
"0603") echo "Capacitor_SMD:C_0603_1608Metric" ;;
"0805") echo "Capacitor_SMD:C_0805_2012Metric" ;;
"1206") echo "Capacitor_SMD:C_1206_3216Metric" ;;
*) echo "Capacitor_SMD:C_$package" ;;
esac
;;
"L")
case $package in
"0603") echo "Inductor_SMD:L_0603_1608Metric" ;;
"0805") echo "Inductor_SMD:L_0805_2012Metric" ;;
"1206") echo "Inductor_SMD:L_1206_3216Metric" ;;
*) echo "Inductor_SMD:L_$package" ;;
esac
;;
"IC")
case $package in
"SOIC-8") echo "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm" ;;
"SOIC-14") echo "Package_SO:SOIC-14_3.9x8.7mm_P1.27mm" ;;
"SOIC-16") echo "Package_SO:SOIC-16_3.9x9.9mm_P1.27mm" ;;
"SOIC-18") echo "Package_SO:SOIC-18W_7.5x11.6mm_P1.27mm" ;;
"LQFP-48") echo "Package_QFP:LQFP-48_7x7mm_P0.5mm" ;;
"TSSOP-20") echo "Package_SO:TSSOP-20_4.4x6.5mm_P0.65mm" ;;
"SOT-223") echo "Package_TO_SOT_SMD:SOT-223-3_TabPin2" ;;
"SSOP-28") echo "Package_SO:SSOP-28_5.3x10.2mm_P0.65mm" ;;
"MODULE") echo "RF_Module:ESP32-WROOM-32" ;;
*) echo "Package_SO:$package" ;;
esac
;;
"LED")
case $package in
"0603") echo "LED_SMD:LED_0603_1608Metric" ;;
"0805") echo "LED_SMD:LED_0805_2012Metric" ;;
*) echo "LED_SMD:LED_$package" ;;
esac
;;
"D")
case $package in
"SOD-123") echo "Diode_SMD:D_SOD-123" ;;
"SOD-123FL") echo "Diode_SMD:D_SOD-123F" ;;
*) echo "Diode_SMD:D_$package" ;;
esac
;;
"XTAL")
case $package in
"HC-49S") echo "Crystal:Crystal_HC49-SD_SMD" ;;
"3215") echo "Crystal:Crystal_SMD_3215-2Pin_3.2x1.5mm" ;;
*) echo "Crystal:Crystal_$package" ;;
esac
;;
*) echo "Unknown:$package" ;;
esac
}
# Function to generate symbol graphics based on component type
get_symbol_graphics() {
local component=$1
local symbol_name=$2
case $component in
"R")
cat << EOF
(symbol "${symbol_name}_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))))
(symbol "${symbol_name}_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
EOF
;;
"C")
cat << EOF
(symbol "${symbol_name}_0_1"
(polyline
(pts (xy -2.032 -0.762) (xy 2.032 -0.762))
(stroke (width 0.508) (type default))
(fill (type none)))
(polyline
(pts (xy -2.032 0.762) (xy 2.032 0.762))
(stroke (width 0.508) (type default))
(fill (type none))))
(symbol "${symbol_name}_1_1"
(pin passive line (at 0 2.54 270) (length 1.778)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 0 -2.54 90) (length 1.778)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
EOF
;;
"L")
cat << EOF
(symbol "${symbol_name}_0_1"
(arc (start 0 -2.54) (mid 0.635 -1.905) (end 0 -1.27)
(stroke (width 0) (type default))
(fill (type none)))
(arc (start 0 -1.27) (mid 0.635 -0.635) (end 0 0)
(stroke (width 0) (type default))
(fill (type none)))
(arc (start 0 0) (mid 0.635 0.635) (end 0 1.27)
(stroke (width 0) (type default))
(fill (type none)))
(arc (start 0 1.27) (mid 0.635 1.905) (end 0 2.54)
(stroke (width 0) (type default))
(fill (type none))))
(symbol "${symbol_name}_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "1" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "2" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
EOF
;;
"LED")
cat << EOF
(symbol "${symbol_name}_0_1"
(polyline
(pts (xy -1.27 -1.27) (xy -1.27 1.27))
(stroke (width 0.254) (type default))
(fill (type none)))
(polyline
(pts (xy -1.27 0) (xy 1.27 0))
(stroke (width 0) (type default))
(fill (type none)))
(polyline
(pts (xy 1.27 -1.27) (xy 1.27 1.27) (xy -1.27 0) (xy 1.27 -1.27))
(stroke (width 0.254) (type default))
(fill (type none))))
(symbol "${symbol_name}_1_1"
(pin passive line (at -3.81 0 0) (length 2.54)
(name "K" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin passive line (at 3.81 0 180) (length 2.54)
(name "A" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
EOF
;;
*)
# Generic two-pin component for ICs, diodes, crystals
cat << EOF
(symbol "${symbol_name}_0_1"
(rectangle (start -7.62 5.08) (end 7.62 -5.08)
(stroke (width 0.254) (type default))
(fill (type background))))
(symbol "${symbol_name}_1_1"
(pin input line (at -10.16 0 0) (length 2.54)
(name "VCC" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))))
(pin input line (at 10.16 0 180) (length 2.54)
(name "GND" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))))
EOF
;;
esac
}
# Function to generate a symbol template
generate_symbol() {
local component=$1
local value=$2
local package=$3
local lcsc=$4
local manufacturer=$5
local mfg_part=$6
local description=$7
local rotation=$8
local ref_prefix=$9
# Clean up special characters for KiCad compatibility
local symbol_name=$(echo "${value}_${package}_${lcsc}" | sed 's/µ/u/g')
local footprint=$(get_kicad_footprint "$component" "$package")
local datasheet="https://lcsc.com/product-detail/${lcsc}.html"
cat << EOF
(symbol "$symbol_name" (in_bom yes) (on_board yes)
(property "Reference" "$ref_prefix" (at 0 2.54 0)
(effects (font (size 1.27 1.27))))
(property "Value" "$value" (at 0 -2.54 0)
(effects (font (size 1.27 1.27))))
(property "Footprint" "$footprint" (at 0 -5.08 0)
(effects (font (size 1.27 1.27)) hide))
(property "Datasheet" "$datasheet" (at 0 -7.62 0)
(effects (font (size 1.27 1.27)) hide))
(property "Description" "$description" (at 0 -10.16 0)
(effects (font (size 1.27 1.27)) hide))
(property "LCSC Part #" "$lcsc" (at 0 -12.70 0)
(effects (font (size 1.27 1.27)) hide))
(property "Manufacturer" "$manufacturer" (at 0 -15.24 0)
(effects (font (size 1.27 1.27)) hide))
(property "MFG Part #" "$mfg_part" (at 0 -17.78 0)
(effects (font (size 1.27 1.27)) hide))
(property "Package" "$package" (at 0 -20.32 0)
(effects (font (size 1.27 1.27)) hide))
(property "FT Rotation Offset" "$rotation" (at 0 -22.86 0)
(effects (font (size 1.27 1.27)) hide))
$(get_symbol_graphics "$component" "$symbol_name")
)
EOF
}
# Generate symbol libraries
if [[ "$CREATE_SYMBOLS" == true ]]; then
print_color $YELLOW "Generating KiCad symbol libraries..."
if [[ "$DRY_RUN" == false ]]; then
# Create output directory
mkdir -p "$OUTPUT_PATH/symbols"
fi
# Generate Standard Passives library
if [[ $((RESISTOR_COUNT + CAPACITOR_COUNT + INDUCTOR_COUNT)) -gt 0 ]]; then
print_color $CYAN " Creating Standard_Passives.kicad_sym..."
local passives_file="$OUTPUT_PATH/symbols/Standard_Passives.kicad_sym"
if [[ "$DRY_RUN" == false ]]; then
# Write header
cat > "$passives_file" << EOF
(kicad_symbol_lib (version 20211014) (generator "JLCPCB-Generator")
(symbol_lib_info (name "Standard_Passives") (description "JLCPCB Basic Parts - Passives with Fabrication Toolkit properties"))
EOF
# Process resistors, capacitors, and inductors
awk -F',' '
NR>1 && ($1=="R" || $1=="C" || $1=="L") && $1!~/^#/ {
# Escape quotes in description
gsub(/"/, "\\\"", $7)
ref = ($1=="R") ? "R" : ($1=="C") ? "C" : "L"
print $1 "," $2 "," $3 "," $4 "," $5 "," $6 "," $7 "," $8 "," ref
}' "$CSV_PATH" | while IFS=',' read -r component value package lcsc manufacturer mfg_part description rotation ref_prefix; do
generate_symbol "$component" "$value" "$package" "$lcsc" "$manufacturer" "$mfg_part" "$description" "$rotation" "$ref_prefix" >> "$passives_file"
done
# Write footer
echo ")" >> "$passives_file"
print_color $GREEN " Created: $passives_file"
else
print_color $BLUE " Would create: $passives_file"
fi
fi
# Generate Standard ICs library
if [[ $IC_COUNT -gt 0 ]]; then
print_color $CYAN " Creating Standard_ICs.kicad_sym..."
local ics_file="$OUTPUT_PATH/symbols/Standard_ICs.kicad_sym"
if [[ "$DRY_RUN" == false ]]; then
# Write header
cat > "$ics_file" << EOF
(kicad_symbol_lib (version 20211014) (generator "JLCPCB-Generator")
(symbol_lib_info (name "Standard_ICs") (description "JLCPCB Basic Parts - ICs with Fabrication Toolkit properties"))
EOF
# Process ICs
awk -F',' '
NR>1 && $1=="IC" && $1!~/^#/ {
# Escape quotes in description
gsub(/"/, "\\\"", $7)
print $1 "," $2 "," $3 "," $4 "," $5 "," $6 "," $7 "," $8 ",U"
}' "$CSV_PATH" | while IFS=',' read -r component value package lcsc manufacturer mfg_part description rotation ref_prefix; do
generate_symbol "$component" "$value" "$package" "$lcsc" "$manufacturer" "$mfg_part" "$description" "$rotation" "$ref_prefix" >> "$ics_file"
done
# Write footer
echo ")" >> "$ics_file"
print_color $GREEN " Created: $ics_file"
else
print_color $BLUE " Would create: $ics_file"
fi
fi
# Generate Standard Components library (LEDs, Diodes, Crystals)
if [[ $((LED_COUNT + DIODE_COUNT + CRYSTAL_COUNT)) -gt 0 ]]; then
print_color $CYAN " Creating Standard_Components.kicad_sym..."
local components_file="$OUTPUT_PATH/symbols/Standard_Components.kicad_sym"
if [[ "$DRY_RUN" == false ]]; then
# Write header
cat > "$components_file" << EOF
(kicad_symbol_lib (version 20211014) (generator "JLCPCB-Generator")
(symbol_lib_info (name "Standard_Components") (description "JLCPCB Basic Parts - LEDs, Diodes, Crystals with Fabrication Toolkit properties"))
EOF
# Process LEDs, Diodes, Crystals
awk -F',' '
NR>1 && ($1=="LED" || $1=="D" || $1=="XTAL") && $1!~/^#/ {
# Escape quotes in description
gsub(/"/, "\\\"", $7)
ref = ($1=="LED" || $1=="D") ? "D" : "Y"
print $1 "," $2 "," $3 "," $4 "," $5 "," $6 "," $7 "," $8 "," ref
}' "$CSV_PATH" | while IFS=',' read -r component value package lcsc manufacturer mfg_part description rotation ref_prefix; do
generate_symbol "$component" "$value" "$package" "$lcsc" "$manufacturer" "$mfg_part" "$description" "$rotation" "$ref_prefix" >> "$components_file"
done
# Write footer
echo ")" >> "$components_file"
print_color $GREEN " Created: $components_file"
else
print_color $BLUE " Would create: $components_file"
fi
fi
fi
# Generate BOM template
if [[ "$GENERATE_REPORT" == true ]]; then
print_color $YELLOW "Generating JLCPCB BOM template..."
local bom_file="$OUTPUT_PATH/docs/JLCPCB_BOM_Template.csv"
if [[ "$DRY_RUN" == false ]]; then
mkdir -p "$OUTPUT_PATH/docs"
# Write BOM header
cat > "$bom_file" << EOF
# JLCPCB Assembly BOM Template
# Generated from JLCPCB Basic Parts Database
# Compatible with JLC Plugin for KiCad (bennymeg)
Comment,Designator,Footprint,LCSC Part #,Manufacturer,MFG Part #
EOF
# Process all parts for BOM
awk -F',' '
NR>1 && $1!~/^#/ && $1!="" {
footprint_full = ""
component = $1
package = $3
# Get footprint name (remove library prefix)
if (component == "R") {
if (package == "0603") footprint_full = "R_0603_1608Metric"
else if (package == "0805") footprint_full = "R_0805_2012Metric"
else footprint_full = "R_" package
}
else if (component == "C") {
if (package == "0603") footprint_full = "C_0603_1608Metric"
else if (package == "0805") footprint_full = "C_0805_2012Metric"
else footprint_full = "C_" package
}
else if (component == "L") {
if (package == "0603") footprint_full = "L_0603_1608Metric"
else if (package == "0805") footprint_full = "L_0805_2012Metric"
else footprint_full = "L_" package
}
else if (component == "LED") {
if (package == "0603") footprint_full = "LED_0603_1608Metric"
else footprint_full = "LED_" package
}
else {
footprint_full = package
}
print $2 ",REF**," footprint_full "," $4 "," $5 "," $6
}' "$CSV_PATH" >> "$bom_file"
print_color $GREEN " Created: $bom_file"
else
print_color $BLUE " Would create: $bom_file"
fi
fi
# Generate statistics
print_color $GREEN "\n$(printf '=%.0s' {1..50})"
print_color $GREEN "GENERATION SUMMARY"
print_color $GREEN "$(printf '=%.0s' {1..50})"
print_color $CYAN "Components by package:"
awk -F',' 'NR>1 && $1!~/^#/ && $1!="" {packages[$3]++} END {for (p in packages) printf " %-10s: %d parts\n", p, packages[p]}' "$CSV_PATH" | sort -k3 -nr
print_color $CYAN "\nComponents by manufacturer:"
awk -F',' 'NR>1 && $1!~/^#/ && $1!="" {mfgs[$5]++} END {for (m in mfgs) printf " %-20s: %d parts\n", m, mfgs[m]}' "$CSV_PATH" | sort -k3 -nr
# Calculate total cost
TOTAL_COST=$(awk -F',' '
NR>1 && $1!~/^#/ && $1!="" && $10 ~ /^[0-9]+\.?[0-9]*$/ {
total += $10
}
END {
printf "%.2f", total
}' "$CSV_PATH")
print_color $CYAN "\nCost analysis:"
print_color $WHITE " Total cost for complete basic parts kit (1k each): \$$TOTAL_COST"
if [[ "$DRY_RUN" == true ]]; then
print_color $YELLOW "\n[DRY RUN] No files were created"
else
print_color $GREEN "\nGeneration completed successfully!"
fi