# 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 #>