Autofill schematic
This commit is contained in:
parent
db698d0c7d
commit
83ada2e659
|
@ -0,0 +1,286 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# TODO: make sure it also works in python2
|
||||||
|
|
||||||
|
# version 0.0.2
|
||||||
|
|
||||||
|
# updates:
|
||||||
|
# - allow multiple input files, using the later ones only for component footprint
|
||||||
|
# and distributor
|
||||||
|
# - fix code so it works with Kicad 5
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
DISTRIBUTOR_VALUES = ["\"Digikey\""]
|
||||||
|
|
||||||
|
class Component(object):
|
||||||
|
def __init__(self, start):
|
||||||
|
self.designator = None
|
||||||
|
self.value = None
|
||||||
|
self.footprint = None
|
||||||
|
self.footprint_row = None
|
||||||
|
# distributor ids, mapped to (line_num, value, all fields
|
||||||
|
# (to make reconstruction easier)
|
||||||
|
self.distributors = dict()
|
||||||
|
self.cls = None
|
||||||
|
self.last_value = None
|
||||||
|
self.num_fields = 0
|
||||||
|
|
||||||
|
# used mainly for parser debugging
|
||||||
|
self.start = start
|
||||||
|
|
||||||
|
class DistributorData(object):
|
||||||
|
def __init__(self, id):
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
def quotesplit(line):
|
||||||
|
parts = line.split(" ")
|
||||||
|
ret = []
|
||||||
|
num_quotes = 0
|
||||||
|
incomplete_part = None
|
||||||
|
for part in parts:
|
||||||
|
num_quotes += len([None for c in part if c == '"'])
|
||||||
|
if num_quotes % 2 == 1:
|
||||||
|
if incomplete_part is None:
|
||||||
|
# just started a quoted section
|
||||||
|
incomplete_part = part
|
||||||
|
else:
|
||||||
|
incomplete_part += " " + part
|
||||||
|
else:
|
||||||
|
if incomplete_part is not None:
|
||||||
|
# ending quote is in this part
|
||||||
|
ret.append(incomplete_part + " " + part)
|
||||||
|
incomplete_part = None
|
||||||
|
else:
|
||||||
|
# normal case; pass through
|
||||||
|
ret.append(part)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def parse_lines(f):
|
||||||
|
lines = []
|
||||||
|
components = []
|
||||||
|
component_start = False
|
||||||
|
component = None
|
||||||
|
|
||||||
|
for i, line in enumerate(f):
|
||||||
|
if component_start:
|
||||||
|
if line.startswith("L"):
|
||||||
|
parts = quotesplit(line)
|
||||||
|
component.designator = parts[2].rstrip()
|
||||||
|
component.cls = component.designator[0]
|
||||||
|
elif line.startswith("F"):
|
||||||
|
parts = quotesplit(line)
|
||||||
|
component.num_fields += 1
|
||||||
|
component.last_value = i
|
||||||
|
if parts[1].isdigit():
|
||||||
|
field_type = int(parts[1])
|
||||||
|
if field_type == 1:
|
||||||
|
component.value = parts[2]
|
||||||
|
elif field_type == 2:
|
||||||
|
component.footprint_row = (i, parts)
|
||||||
|
if len(parts[2]) > 2:
|
||||||
|
component.footprint = parts[2]
|
||||||
|
elif field_type > 3:
|
||||||
|
# TODO: make case insensitive
|
||||||
|
if parts[-1][:-1] in DISTRIBUTOR_VALUES:
|
||||||
|
component.distributors[parts[-1][:-1]] = DistributorData(parts[2])
|
||||||
|
elif line.startswith("$EndComp"):
|
||||||
|
component_start = False
|
||||||
|
# ignore power nodes
|
||||||
|
if component.cls != "#":
|
||||||
|
components.append(component)
|
||||||
|
|
||||||
|
if line.startswith("$Comp"):
|
||||||
|
component_start = True
|
||||||
|
component = Component(i)
|
||||||
|
lines.append(line)
|
||||||
|
return (lines, components)
|
||||||
|
|
||||||
|
def infer_components(components):
|
||||||
|
# dictionaries in dictionaries:
|
||||||
|
# distributor = (distributor_type, id) so that non-unique ids can be captured
|
||||||
|
# filled_values[cls][value] = [(footprint, [designators], [distributors])]
|
||||||
|
filled_values = dict()
|
||||||
|
|
||||||
|
# first pass to infer footprints and distributors, second pass to fill in details
|
||||||
|
for c in components:
|
||||||
|
if c.cls is None or len(c.cls) == 0:
|
||||||
|
print("Component at {} incorrectly parsed; no cls set".format(c.start))
|
||||||
|
else:
|
||||||
|
if c.cls not in filled_values:
|
||||||
|
filled_values[c.cls] = dict()
|
||||||
|
|
||||||
|
if c.value is not None and len(c.value) > 2:
|
||||||
|
if c.value not in filled_values[c.cls]:
|
||||||
|
filled_values[c.cls][c.value] = []
|
||||||
|
|
||||||
|
if c.footprint is not None and len(c.footprint) > 2:
|
||||||
|
# print(c.designator, c.value, c.footprint, c.distributors)
|
||||||
|
tosearch = filled_values[c.cls][c.value]
|
||||||
|
# find element with matching footprint
|
||||||
|
found = None
|
||||||
|
for i, fp in enumerate(tosearch):
|
||||||
|
if fp[0] == c.footprint:
|
||||||
|
found = i
|
||||||
|
break
|
||||||
|
|
||||||
|
if found is None:
|
||||||
|
distributors = []
|
||||||
|
for dist in c.distributors:
|
||||||
|
if len(c.distributors[dist].id) > 2 and len(dist) > 2:
|
||||||
|
distributors.append((dist, c.distributors[dist].id))
|
||||||
|
tosearch.append((c.footprint, [c.designator], distributors))
|
||||||
|
else:
|
||||||
|
tosearch[i][1].append(c.designator)
|
||||||
|
# append any new distributors
|
||||||
|
for dist in c.distributors:
|
||||||
|
if len(c.distributors[dist].id) > 2 and len(dist) > 2:
|
||||||
|
if not any([dist == m[0] and c.distributors[dist].id == m[1]
|
||||||
|
for m in tosearch[i][2]]):
|
||||||
|
tosearch[i][2].append((dist, c.distributors[dist].id))
|
||||||
|
return filled_values
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Autofills components in an Eeschema schematic")
|
||||||
|
parser.add_argument("-i", "--include", action="append", help="additional files to read in, for component inference")
|
||||||
|
parser.add_argument("input", help="file to autofill")
|
||||||
|
parser.add_argument("output", help="file to write autofilled schematic to")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
lines = None
|
||||||
|
components = None
|
||||||
|
|
||||||
|
with open(args.input, 'r') as f:
|
||||||
|
(lines, components) = parse_lines(f)
|
||||||
|
|
||||||
|
print("{} lines".format(len(lines)))
|
||||||
|
print("found {} components".format(len(components)))
|
||||||
|
without_footprints = len([None for c in components if c.footprint is None])
|
||||||
|
print("found {} components without footprints".format(without_footprints))
|
||||||
|
|
||||||
|
all_components = []
|
||||||
|
all_components.extend(components)
|
||||||
|
|
||||||
|
if args.include is not None:
|
||||||
|
print("searching additional files: {}".format(" ".join(args.include)))
|
||||||
|
|
||||||
|
for filename in args.include:
|
||||||
|
with open(filename, 'r') as f:
|
||||||
|
(more_lines, more_components) = parse_lines(f)
|
||||||
|
print("{} more lines".format(len(more_lines)))
|
||||||
|
print("found {} more components".format(len(more_components)))
|
||||||
|
more_without_footprints = len([None for c in more_components if c.footprint is None])
|
||||||
|
print("found {} more components without footprints".format(more_without_footprints))
|
||||||
|
all_components.extend(more_components)
|
||||||
|
|
||||||
|
filled_values = infer_components(all_components)
|
||||||
|
|
||||||
|
entry_count = 0
|
||||||
|
conflicts = []
|
||||||
|
for cls in filled_values:
|
||||||
|
for val in filled_values[cls]:
|
||||||
|
for _ in filled_values[cls][val]:
|
||||||
|
# TODO: check for conflicts
|
||||||
|
entry_count += 1
|
||||||
|
print("found {} filled unique component classes".format(entry_count))
|
||||||
|
|
||||||
|
# TODO: allow interactive distributor choice to resolve conflicts
|
||||||
|
while len(conflicts) > 0:
|
||||||
|
print("found conflicting information, cannot autofill")
|
||||||
|
for conflict in conflicts:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
|
||||||
|
# autofill
|
||||||
|
autofill_fp = 0
|
||||||
|
autofill_dist = 0
|
||||||
|
to_append = []
|
||||||
|
for c in components:
|
||||||
|
if c.cls in filled_values:
|
||||||
|
if c.value in filled_values[c.cls]:
|
||||||
|
matches = []
|
||||||
|
if c.footprint is not None:
|
||||||
|
matches = [t for t in filled_values[c.cls][c.value] if t[0] == c.footprint]
|
||||||
|
else:
|
||||||
|
matches = filled_values[c.cls][c.value]
|
||||||
|
if len(matches) == 1:
|
||||||
|
# autofill
|
||||||
|
match = matches[0]
|
||||||
|
if ((c.footprint is None or len(c.footprint) <= 2) and
|
||||||
|
c.footprint_row is not None):
|
||||||
|
print("matched {} {} with {}".format(c.designator, c.value, match))
|
||||||
|
# rewrite footprint
|
||||||
|
c.footprint = match[0]
|
||||||
|
row = c.footprint_row[1]
|
||||||
|
row[2] = match[0]
|
||||||
|
lines[c.footprint_row[0]] = " ".join(row)
|
||||||
|
autofill_fp += 1
|
||||||
|
# add in distributors
|
||||||
|
dist_added = 0
|
||||||
|
for dist in match[2]:
|
||||||
|
if dist[0] not in c.distributors:
|
||||||
|
c.distributors[dist[0]] = DistributorData(dist[1])
|
||||||
|
# append to the field list
|
||||||
|
template_row = quotesplit(lines[c.last_value][:-1])
|
||||||
|
row = [
|
||||||
|
template_row[0],
|
||||||
|
str(c.num_fields),
|
||||||
|
dist[1]] + template_row[3:11] + [dist[0] + "\n"]
|
||||||
|
c.num_fields += 1
|
||||||
|
to_append.append((c.last_value, row))
|
||||||
|
dist_added += 1
|
||||||
|
# mark as something to do, because appending now would
|
||||||
|
# cause the row numbers to shift for all the components after this one,
|
||||||
|
# invalidating their indices
|
||||||
|
if dist_added > 0:
|
||||||
|
autofill_dist += 1
|
||||||
|
|
||||||
|
# print(c.designator, c.value, c.footprint, c.distributors)
|
||||||
|
for ta in reversed(to_append):
|
||||||
|
idx = ta[0]
|
||||||
|
row = ta[1]
|
||||||
|
lines = lines[0:idx+1] + [" ".join(row)] + lines[idx+1:]
|
||||||
|
|
||||||
|
print("autofilled {} fp, {} dist".format(autofill_fp, autofill_dist))
|
||||||
|
# dictionary of dictionaries of components without footprints
|
||||||
|
# missing[cls][value] = [designators]
|
||||||
|
missing = dict()
|
||||||
|
|
||||||
|
for c in components:
|
||||||
|
if c.cls is not None:
|
||||||
|
if c.cls not in missing:
|
||||||
|
missing[c.cls] = dict()
|
||||||
|
if c.value is not None and c.footprint is None:
|
||||||
|
if c.value not in missing[c.cls]:
|
||||||
|
missing[c.cls][c.value] = []
|
||||||
|
missing[c.cls][c.value].append(c.designator)
|
||||||
|
|
||||||
|
for cls in missing:
|
||||||
|
for value in missing[cls]:
|
||||||
|
print("NOTE: no unique footprint found for {} {}".format(value, missing[cls][value]))
|
||||||
|
|
||||||
|
# repeat for manufacturer info
|
||||||
|
missing = dict()
|
||||||
|
|
||||||
|
for c in components:
|
||||||
|
if c.cls is not None:
|
||||||
|
if c.cls not in missing:
|
||||||
|
missing[c.cls] = dict()
|
||||||
|
if c.value is not None and c.value != "\"DNP\"" and not bool(c.distributors):
|
||||||
|
if c.value not in missing[c.cls]:
|
||||||
|
missing[c.cls][c.value] = []
|
||||||
|
missing[c.cls][c.value].append(c.designator)
|
||||||
|
|
||||||
|
for cls in missing:
|
||||||
|
for value in missing[cls]:
|
||||||
|
print("NOTE: no distributor data found for {} {}".format(value, missing[cls][value]))
|
||||||
|
|
||||||
|
|
||||||
|
output = args.output or args.input
|
||||||
|
print("outputting to {}...".format(output))
|
||||||
|
with open(output, "w+") as f:
|
||||||
|
for line in lines:
|
||||||
|
f.write(line)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -33,6 +33,7 @@ F 0 "Q5" H 9600 6125 50 0000 L CNN
|
||||||
F 1 "BUK9M52-40EX" H 9600 6050 50 0000 L CNN
|
F 1 "BUK9M52-40EX" H 9600 6050 50 0000 L CNN
|
||||||
F 2 "Package_TO_SOT_SMD:LFPAK33" H 9600 5975 50 0001 L CIN
|
F 2 "Package_TO_SOT_SMD:LFPAK33" H 9600 5975 50 0001 L CIN
|
||||||
F 3 "https://assets.nexperia.com/documents/data-sheet/BUK9M52-40E.pdf" V 9400 6050 50 0001 L CNN
|
F 3 "https://assets.nexperia.com/documents/data-sheet/BUK9M52-40E.pdf" V 9400 6050 50 0001 L CNN
|
||||||
|
F 4 "1727-7317-1-ND" V 9400 6050 50 0001 L CNN "Digikey"
|
||||||
1 9400 6050
|
1 9400 6050
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -44,6 +45,7 @@ F 0 "Q3" H 9600 4075 50 0000 L CNN
|
||||||
F 1 "BUK9M52-40EX" H 9600 4000 50 0000 L CNN
|
F 1 "BUK9M52-40EX" H 9600 4000 50 0000 L CNN
|
||||||
F 2 "Package_TO_SOT_SMD:LFPAK33" H 9600 3925 50 0001 L CIN
|
F 2 "Package_TO_SOT_SMD:LFPAK33" H 9600 3925 50 0001 L CIN
|
||||||
F 3 "https://assets.nexperia.com/documents/data-sheet/BUK9M52-40E.pdf" V 9400 4000 50 0001 L CNN
|
F 3 "https://assets.nexperia.com/documents/data-sheet/BUK9M52-40E.pdf" V 9400 4000 50 0001 L CNN
|
||||||
|
F 4 "1727-7317-1-ND" V 9400 4000 50 0001 L CNN "Digikey"
|
||||||
1 9400 4000
|
1 9400 4000
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -55,6 +57,7 @@ F 0 "Q4" H 9600 5075 50 0000 L CNN
|
||||||
F 1 "BUK9M52-40EX" H 9600 5000 50 0000 L CNN
|
F 1 "BUK9M52-40EX" H 9600 5000 50 0000 L CNN
|
||||||
F 2 "Package_TO_SOT_SMD:LFPAK33" H 9600 4925 50 0001 L CIN
|
F 2 "Package_TO_SOT_SMD:LFPAK33" H 9600 4925 50 0001 L CIN
|
||||||
F 3 "https://assets.nexperia.com/documents/data-sheet/BUK9M52-40E.pdf" V 9400 5000 50 0001 L CNN
|
F 3 "https://assets.nexperia.com/documents/data-sheet/BUK9M52-40E.pdf" V 9400 5000 50 0001 L CNN
|
||||||
|
F 4 "1727-7317-1-ND" V 9400 5000 50 0001 L CNN "Digikey"
|
||||||
1 9400 5000
|
1 9400 5000
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -222,8 +225,9 @@ U 1 1 5FED6801
|
||||||
P 3000 5900
|
P 3000 5900
|
||||||
F 0 "C3" H 3010 5970 50 0000 L CNN
|
F 0 "C3" H 3010 5970 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 3010 5820 50 0000 L CNN
|
F 1 "0.1 uF" H 3010 5820 50 0000 L CNN
|
||||||
F 2 "" H 3000 5900 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 3000 5900 50 0001 C CNN
|
||||||
F 3 "~" H 3000 5900 50 0001 C CNN
|
F 3 "~" H 3000 5900 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 3000 5900 50 0001 C CNN "Digikey"
|
||||||
1 3000 5900
|
1 3000 5900
|
||||||
0 1 -1 0
|
0 1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -233,8 +237,9 @@ U 1 1 5FED7456
|
||||||
P 3600 5900
|
P 3600 5900
|
||||||
F 0 "C4" H 3610 5970 50 0000 L CNN
|
F 0 "C4" H 3610 5970 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 3610 5820 50 0000 L CNN
|
F 1 "0.1 uF" H 3610 5820 50 0000 L CNN
|
||||||
F 2 "" H 3600 5900 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 3600 5900 50 0001 C CNN
|
||||||
F 3 "~" H 3600 5900 50 0001 C CNN
|
F 3 "~" H 3600 5900 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 3600 5900 50 0001 C CNN "Digikey"
|
||||||
1 3600 5900
|
1 3600 5900
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -465,8 +470,9 @@ U 1 1 5FF425D8
|
||||||
P 3700 2500
|
P 3700 2500
|
||||||
F 0 "R4" H 3730 2520 50 0000 L CNN
|
F 0 "R4" H 3730 2520 50 0000 L CNN
|
||||||
F 1 "1kR" H 3730 2460 50 0000 L CNN
|
F 1 "1kR" H 3730 2460 50 0000 L CNN
|
||||||
F 2 "" H 3700 2500 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 3700 2500 50 0001 C CNN
|
||||||
F 3 "~" H 3700 2500 50 0001 C CNN
|
F 3 "~" H 3700 2500 50 0001 C CNN
|
||||||
|
F 4 "RMCF0603FT1K00CT-ND" H 3700 2500 50 0001 C CNN "Digikey"
|
||||||
1 3700 2500
|
1 3700 2500
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -476,8 +482,9 @@ U 1 1 5FF42CBE
|
||||||
P 3700 2600
|
P 3700 2600
|
||||||
F 0 "R5" H 3730 2620 50 0000 L CNN
|
F 0 "R5" H 3730 2620 50 0000 L CNN
|
||||||
F 1 "1kR" H 3730 2560 50 0000 L CNN
|
F 1 "1kR" H 3730 2560 50 0000 L CNN
|
||||||
F 2 "" H 3700 2600 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 3700 2600 50 0001 C CNN
|
||||||
F 3 "~" H 3700 2600 50 0001 C CNN
|
F 3 "~" H 3700 2600 50 0001 C CNN
|
||||||
|
F 4 "RMCF0603FT1K00CT-ND" H 3700 2600 50 0001 C CNN "Digikey"
|
||||||
1 3700 2600
|
1 3700 2600
|
||||||
0 -1 1 0
|
0 -1 1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -495,8 +502,9 @@ U 1 1 5FF49237
|
||||||
P 9000 5000
|
P 9000 5000
|
||||||
F 0 "R10" H 9030 5020 50 0000 L CNN
|
F 0 "R10" H 9030 5020 50 0000 L CNN
|
||||||
F 1 "1kR" H 9030 4960 50 0000 L CNN
|
F 1 "1kR" H 9030 4960 50 0000 L CNN
|
||||||
F 2 "" H 9000 5000 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 9000 5000 50 0001 C CNN
|
||||||
F 3 "~" H 9000 5000 50 0001 C CNN
|
F 3 "~" H 9000 5000 50 0001 C CNN
|
||||||
|
F 4 "RMCF0603FT1K00CT-ND" H 9000 5000 50 0001 C CNN "Digikey"
|
||||||
1 9000 5000
|
1 9000 5000
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -534,8 +542,9 @@ U 1 1 5FF5E5F4
|
||||||
P 9000 6050
|
P 9000 6050
|
||||||
F 0 "R11" H 9030 6070 50 0000 L CNN
|
F 0 "R11" H 9030 6070 50 0000 L CNN
|
||||||
F 1 "1kR" H 9030 6010 50 0000 L CNN
|
F 1 "1kR" H 9030 6010 50 0000 L CNN
|
||||||
F 2 "" H 9000 6050 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 9000 6050 50 0001 C CNN
|
||||||
F 3 "~" H 9000 6050 50 0001 C CNN
|
F 3 "~" H 9000 6050 50 0001 C CNN
|
||||||
|
F 4 "RMCF0603FT1K00CT-ND" H 9000 6050 50 0001 C CNN "Digikey"
|
||||||
1 9000 6050
|
1 9000 6050
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -545,8 +554,9 @@ U 1 1 5FF5ECB6
|
||||||
P 9000 2950
|
P 9000 2950
|
||||||
F 0 "R8" H 9030 2970 50 0000 L CNN
|
F 0 "R8" H 9030 2970 50 0000 L CNN
|
||||||
F 1 "1kR" H 9030 2910 50 0000 L CNN
|
F 1 "1kR" H 9030 2910 50 0000 L CNN
|
||||||
F 2 "" H 9000 2950 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 9000 2950 50 0001 C CNN
|
||||||
F 3 "~" H 9000 2950 50 0001 C CNN
|
F 3 "~" H 9000 2950 50 0001 C CNN
|
||||||
|
F 4 "RMCF0603FT1K00CT-ND" H 9000 2950 50 0001 C CNN "Digikey"
|
||||||
1 9000 2950
|
1 9000 2950
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -639,8 +649,9 @@ U 1 1 5FF87E62
|
||||||
P 1400 6750
|
P 1400 6750
|
||||||
F 0 "R1" H 1430 6770 50 0000 L CNN
|
F 0 "R1" H 1430 6770 50 0000 L CNN
|
||||||
F 1 "10kR" H 1430 6710 50 0000 L CNN
|
F 1 "10kR" H 1430 6710 50 0000 L CNN
|
||||||
F 2 "" H 1400 6750 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 1400 6750 50 0001 C CNN
|
||||||
F 3 "~" H 1400 6750 50 0001 C CNN
|
F 3 "~" H 1400 6750 50 0001 C CNN
|
||||||
|
F 4 "RNCP0603FTD10K0CT-ND" H 1400 6750 50 0001 C CNN "Digikey"
|
||||||
1 1400 6750
|
1 1400 6750
|
||||||
-1 0 0 -1
|
-1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -650,8 +661,9 @@ U 1 1 5FF895C9
|
||||||
P 1500 6750
|
P 1500 6750
|
||||||
F 0 "R2" H 1530 6770 50 0000 L CNN
|
F 0 "R2" H 1530 6770 50 0000 L CNN
|
||||||
F 1 "10kR" H 1530 6710 50 0000 L CNN
|
F 1 "10kR" H 1530 6710 50 0000 L CNN
|
||||||
F 2 "" H 1500 6750 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 1500 6750 50 0001 C CNN
|
||||||
F 3 "~" H 1500 6750 50 0001 C CNN
|
F 3 "~" H 1500 6750 50 0001 C CNN
|
||||||
|
F 4 "RNCP0603FTD10K0CT-ND" H 1500 6750 50 0001 C CNN "Digikey"
|
||||||
1 1500 6750
|
1 1500 6750
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -732,8 +744,9 @@ U 1 1 5FFAF9CF
|
||||||
P 7250 2450
|
P 7250 2450
|
||||||
F 0 "R7" H 7280 2470 50 0000 L CNN
|
F 0 "R7" H 7280 2470 50 0000 L CNN
|
||||||
F 1 "10kR" H 7280 2410 50 0000 L CNN
|
F 1 "10kR" H 7280 2410 50 0000 L CNN
|
||||||
F 2 "" H 7250 2450 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 7250 2450 50 0001 C CNN
|
||||||
F 3 "~" H 7250 2450 50 0001 C CNN
|
F 3 "~" H 7250 2450 50 0001 C CNN
|
||||||
|
F 4 "RNCP0603FTD10K0CT-ND" H 7250 2450 50 0001 C CNN "Digikey"
|
||||||
1 7250 2450
|
1 7250 2450
|
||||||
-1 0 0 -1
|
-1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -829,8 +842,9 @@ U 1 1 5FFE9A97
|
||||||
P 9700 1800
|
P 9700 1800
|
||||||
F 0 "C12" H 9710 1870 50 0000 L CNN
|
F 0 "C12" H 9710 1870 50 0000 L CNN
|
||||||
F 1 "47 uF" H 9710 1720 50 0000 L CNN
|
F 1 "47 uF" H 9710 1720 50 0000 L CNN
|
||||||
F 2 "" H 9700 1800 50 0001 C CNN
|
F 2 "Capacitor_THT:CP_Radial_D5.0mm_P2.00mm" H 9700 1800 50 0001 C CNN
|
||||||
F 3 "~" H 9700 1800 50 0001 C CNN
|
F 3 "~" H 9700 1800 50 0001 C CNN
|
||||||
|
F 4 "732-8596-1-ND" H 9700 1800 50 0001 C CNN "Digikey"
|
||||||
1 9700 1800
|
1 9700 1800
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -840,8 +854,9 @@ U 1 1 5FFE9BAB
|
||||||
P 10050 1800
|
P 10050 1800
|
||||||
F 0 "C13" H 10060 1870 50 0000 L CNN
|
F 0 "C13" H 10060 1870 50 0000 L CNN
|
||||||
F 1 "4.7 uF" H 10060 1720 50 0000 L CNN
|
F 1 "4.7 uF" H 10060 1720 50 0000 L CNN
|
||||||
F 2 "" H 10050 1800 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0603_1608Metric" H 10050 1800 50 0001 C CNN
|
||||||
F 3 "~" H 10050 1800 50 0001 C CNN
|
F 3 "~" H 10050 1800 50 0001 C CNN
|
||||||
|
F 4 "1276-1044-1-ND" H 10050 1800 50 0001 C CNN "Digikey"
|
||||||
1 10050 1800
|
1 10050 1800
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -851,8 +866,9 @@ U 1 1 5FFF0DD5
|
||||||
P 6500 1850
|
P 6500 1850
|
||||||
F 0 "C8" H 6510 1920 50 0000 L CNN
|
F 0 "C8" H 6510 1920 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 6510 1770 50 0000 L CNN
|
F 1 "0.1 uF" H 6510 1770 50 0000 L CNN
|
||||||
F 2 "" H 6500 1850 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 6500 1850 50 0001 C CNN
|
||||||
F 3 "~" H 6500 1850 50 0001 C CNN
|
F 3 "~" H 6500 1850 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 6500 1850 50 0001 C CNN "Digikey"
|
||||||
1 6500 1850
|
1 6500 1850
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -862,8 +878,9 @@ U 1 1 5FFF1CD2
|
||||||
P 6500 1500
|
P 6500 1500
|
||||||
F 0 "C7" H 6510 1570 50 0000 L CNN
|
F 0 "C7" H 6510 1570 50 0000 L CNN
|
||||||
F 1 "4.7 uF" H 6510 1420 50 0000 L CNN
|
F 1 "4.7 uF" H 6510 1420 50 0000 L CNN
|
||||||
F 2 "" H 6500 1500 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0603_1608Metric" H 6500 1500 50 0001 C CNN
|
||||||
F 3 "~" H 6500 1500 50 0001 C CNN
|
F 3 "~" H 6500 1500 50 0001 C CNN
|
||||||
|
F 4 "1276-1044-1-ND" H 6500 1500 50 0001 C CNN "Digikey"
|
||||||
1 6500 1500
|
1 6500 1500
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -901,8 +918,9 @@ U 1 1 600041FE
|
||||||
P 5600 1850
|
P 5600 1850
|
||||||
F 0 "C6" H 5610 1920 50 0000 L CNN
|
F 0 "C6" H 5610 1920 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 5610 1770 50 0000 L CNN
|
F 1 "0.1 uF" H 5610 1770 50 0000 L CNN
|
||||||
F 2 "" H 5600 1850 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 5600 1850 50 0001 C CNN
|
||||||
F 3 "~" H 5600 1850 50 0001 C CNN
|
F 3 "~" H 5600 1850 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 5600 1850 50 0001 C CNN "Digikey"
|
||||||
1 5600 1850
|
1 5600 1850
|
||||||
0 1 -1 0
|
0 1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -912,8 +930,9 @@ U 1 1 60004204
|
||||||
P 5600 1500
|
P 5600 1500
|
||||||
F 0 "C5" H 5610 1570 50 0000 L CNN
|
F 0 "C5" H 5610 1570 50 0000 L CNN
|
||||||
F 1 "4.7 uF" H 5610 1420 50 0000 L CNN
|
F 1 "4.7 uF" H 5610 1420 50 0000 L CNN
|
||||||
F 2 "" H 5600 1500 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0603_1608Metric" H 5600 1500 50 0001 C CNN
|
||||||
F 3 "~" H 5600 1500 50 0001 C CNN
|
F 3 "~" H 5600 1500 50 0001 C CNN
|
||||||
|
F 4 "1276-1044-1-ND" H 5600 1500 50 0001 C CNN "Digikey"
|
||||||
1 5600 1500
|
1 5600 1500
|
||||||
0 1 -1 0
|
0 1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1058,8 +1077,9 @@ U 1 1 6007F9F6
|
||||||
P 5550 5550
|
P 5550 5550
|
||||||
F 0 "R6" H 5580 5570 50 0000 L CNN
|
F 0 "R6" H 5580 5570 50 0000 L CNN
|
||||||
F 1 "10kR" H 5580 5510 50 0000 L CNN
|
F 1 "10kR" H 5580 5510 50 0000 L CNN
|
||||||
F 2 "" H 5550 5550 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 5550 5550 50 0001 C CNN
|
||||||
F 3 "~" H 5550 5550 50 0001 C CNN
|
F 3 "~" H 5550 5550 50 0001 C CNN
|
||||||
|
F 4 "RNCP0603FTD10K0CT-ND" H 5550 5550 50 0001 C CNN "Digikey"
|
||||||
1 5550 5550
|
1 5550 5550
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1148,8 +1168,9 @@ U 1 1 600E0348
|
||||||
P 7300 4800
|
P 7300 4800
|
||||||
F 0 "C10" H 7310 4870 50 0000 L CNN
|
F 0 "C10" H 7310 4870 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 7310 4720 50 0000 L CNN
|
F 1 "0.1 uF" H 7310 4720 50 0000 L CNN
|
||||||
F 2 "" H 7300 4800 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 7300 4800 50 0001 C CNN
|
||||||
F 3 "~" H 7300 4800 50 0001 C CNN
|
F 3 "~" H 7300 4800 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 7300 4800 50 0001 C CNN "Digikey"
|
||||||
1 7300 4800
|
1 7300 4800
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1177,8 +1198,9 @@ U 1 1 600EB00A
|
||||||
P 6500 4800
|
P 6500 4800
|
||||||
F 0 "C9" H 6510 4870 50 0000 L CNN
|
F 0 "C9" H 6510 4870 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 6510 4720 50 0000 L CNN
|
F 1 "0.1 uF" H 6510 4720 50 0000 L CNN
|
||||||
F 2 "" H 6500 4800 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 6500 4800 50 0001 C CNN
|
||||||
F 3 "~" H 6500 4800 50 0001 C CNN
|
F 3 "~" H 6500 4800 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 6500 4800 50 0001 C CNN "Digikey"
|
||||||
1 6500 4800
|
1 6500 4800
|
||||||
0 1 1 0
|
0 1 1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1219,8 +1241,9 @@ U 1 1 60160CD6
|
||||||
P 2900 1650
|
P 2900 1650
|
||||||
F 0 "C?" H 2910 1720 50 0000 L CNN
|
F 0 "C?" H 2910 1720 50 0000 L CNN
|
||||||
F 1 "0.1 uF" H 2910 1570 50 0000 L CNN
|
F 1 "0.1 uF" H 2910 1570 50 0000 L CNN
|
||||||
F 2 "" H 2900 1650 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 2900 1650 50 0001 C CNN
|
||||||
F 3 "~" H 2900 1650 50 0001 C CNN
|
F 3 "~" H 2900 1650 50 0001 C CNN
|
||||||
|
F 4 "1276-6720-1-ND" H 2900 1650 50 0001 C CNN "Digikey"
|
||||||
1 2900 1650
|
1 2900 1650
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1248,8 +1271,9 @@ U 1 1 6016D10C
|
||||||
P 3600 5550
|
P 3600 5550
|
||||||
F 0 "C?" H 3610 5620 50 0000 L CNN
|
F 0 "C?" H 3610 5620 50 0000 L CNN
|
||||||
F 1 "47 uF" H 3610 5470 50 0000 L CNN
|
F 1 "47 uF" H 3610 5470 50 0000 L CNN
|
||||||
F 2 "" H 3600 5550 50 0001 C CNN
|
F 2 "Capacitor_THT:CP_Radial_D5.0mm_P2.00mm" H 3600 5550 50 0001 C CNN
|
||||||
F 3 "~" H 3600 5550 50 0001 C CNN
|
F 3 "~" H 3600 5550 50 0001 C CNN
|
||||||
|
F 4 "732-8596-1-ND" H 3600 5550 50 0001 C CNN "Digikey"
|
||||||
1 3600 5550
|
1 3600 5550
|
||||||
0 -1 -1 0
|
0 -1 -1 0
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1285,8 +1309,9 @@ U 1 1 60192054
|
||||||
P 7650 3350
|
P 7650 3350
|
||||||
F 0 "R?" H 7680 3370 50 0000 L CNN
|
F 0 "R?" H 7680 3370 50 0000 L CNN
|
||||||
F 1 "10kR" H 7680 3310 50 0000 L CNN
|
F 1 "10kR" H 7680 3310 50 0000 L CNN
|
||||||
F 2 "" H 7650 3350 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 7650 3350 50 0001 C CNN
|
||||||
F 3 "~" H 7650 3350 50 0001 C CNN
|
F 3 "~" H 7650 3350 50 0001 C CNN
|
||||||
|
F 4 "RNCP0603FTD10K0CT-ND" H 7650 3350 50 0001 C CNN "Digikey"
|
||||||
1 7650 3350
|
1 7650 3350
|
||||||
-1 0 0 -1
|
-1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1300,8 +1325,9 @@ U 1 1 60198AF9
|
||||||
P 7800 3350
|
P 7800 3350
|
||||||
F 0 "R?" H 7830 3370 50 0000 L CNN
|
F 0 "R?" H 7830 3370 50 0000 L CNN
|
||||||
F 1 "10kR" H 7830 3310 50 0000 L CNN
|
F 1 "10kR" H 7830 3310 50 0000 L CNN
|
||||||
F 2 "" H 7800 3350 50 0001 C CNN
|
F 2 "Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolder" H 7800 3350 50 0001 C CNN
|
||||||
F 3 "~" H 7800 3350 50 0001 C CNN
|
F 3 "~" H 7800 3350 50 0001 C CNN
|
||||||
|
F 4 "RNCP0603FTD10K0CT-ND" H 7800 3350 50 0001 C CNN "Digikey"
|
||||||
1 7800 3350
|
1 7800 3350
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
@ -1329,8 +1355,9 @@ U 1 1 601CC9F4
|
||||||
P 7800 3900
|
P 7800 3900
|
||||||
F 0 "C?" H 7810 3970 50 0000 L CNN
|
F 0 "C?" H 7810 3970 50 0000 L CNN
|
||||||
F 1 "1 nF" H 7810 3820 50 0000 L CNN
|
F 1 "1 nF" H 7810 3820 50 0000 L CNN
|
||||||
F 2 "" H 7800 3900 50 0001 C CNN
|
F 2 "Capacitor_SMD:C_0402_1005Metric" H 7800 3900 50 0001 C CNN
|
||||||
F 3 "~" H 7800 3900 50 0001 C CNN
|
F 3 "~" H 7800 3900 50 0001 C CNN
|
||||||
|
F 4 "478-1101-1-ND" H 7800 3900 50 0001 C CNN "Digikey"
|
||||||
1 7800 3900
|
1 7800 3900
|
||||||
1 0 0 -1
|
1 0 0 -1
|
||||||
$EndComp
|
$EndComp
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Generates a Digikey BOM from Joost's KiCAD BOM")
|
||||||
|
parser.add_argument("input", help="input BOM")
|
||||||
|
parser.add_argument("output", help="output BOM")
|
||||||
|
parser.add_argument("--m", help="quantity multiplier", default="1")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
multiplier = 1 if args.m is None else int(args.m)
|
||||||
|
|
||||||
|
print("multiplier: {}".format(multiplier))
|
||||||
|
|
||||||
|
digikey_idx = None
|
||||||
|
count_idx = None
|
||||||
|
components = []
|
||||||
|
with open(args.input, 'r') as f:
|
||||||
|
reader = csv.reader(f)
|
||||||
|
parts = next(reader)
|
||||||
|
for i, part in enumerate(parts):
|
||||||
|
if 'Digikey' == part:
|
||||||
|
digikey_idx = i
|
||||||
|
elif 'Quantity' == part:
|
||||||
|
count_idx = i
|
||||||
|
|
||||||
|
if digikey_idx is None or count_idx is None:
|
||||||
|
print("Unable to find headers")
|
||||||
|
return
|
||||||
|
|
||||||
|
for i, parts in enumerate(reader):
|
||||||
|
if len(parts) < max(digikey_idx, count_idx):
|
||||||
|
print("[WARN] line {} is missing fields".format(i + 1))
|
||||||
|
continue
|
||||||
|
part_num = parts[digikey_idx]
|
||||||
|
count = parts[count_idx]
|
||||||
|
if len(part_num) == 0:
|
||||||
|
print("[WARN] line {} is missing part number".format(i + 1))
|
||||||
|
print(parts)
|
||||||
|
continue
|
||||||
|
if count == 0:
|
||||||
|
print("[WARN] line {} has zero quantity".format(i + 1))
|
||||||
|
if part_num == 'NoPart':
|
||||||
|
continue
|
||||||
|
components.append((part_num, count))
|
||||||
|
|
||||||
|
with open(args.output, 'w') as f:
|
||||||
|
# header is necessary if you don't want to miss the first part
|
||||||
|
f.write("Digikey,Quantity\n")
|
||||||
|
for c in components:
|
||||||
|
f.write("{},{}\n".format(c[0], multiplier*int(c[1])))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue