33Automatically assigns house MPNs to resistors and capacitors.
44"""
55
6- load("../units.zen", "Voltage", "Resistance", "Capacitance")
6+ load("../units.zen", "Voltage", "Resistance", "ResistanceRange", " Capacitance", "Power ")
77load(
88 "helpers.zen",
99 "prop",
1010 "set_primary_and_alts",
1111 "find_e_series_match",
1212 "iec60062_3digit",
1313 "iec60062_4digit",
14- "resistor_series",
14+ "panasonic_erj",
15+ "discrete_resistor_series",
1516 "murata_cap",
1617)
1718
@@ -31,16 +32,50 @@ _DIELECTRIC_RANK = {
3132# Resistor series by package
3233SERIES_BY_PKG = {
3334 "0402": [
34- resistor_series ("ERJ-H2CF", "1Ohm", "10Ohm ", "50V ", "1%", ["e96", "e24"], iec60062_4digit, "X"),
35- resistor_series ("ERJ-2RKF", "10Ohm", "1MOhm ", "50V ", "1%", ["e96", "e24"], iec60062_4digit, "X"),
36- resistor_series ("ERJ-U02J", "1MOhm", "10MOhm ", "50V ", "5%", ["e24"], iec60062_3digit, "X"),
37- resistor_series ("ERJ-PA2F", "1Ohm", "1MOhm ", "50V ", "1%", ["e96", "e24"], iec60062_4digit, "X"),
35+ panasonic_erj ("ERJ-H2CF", "1Ohm – 10Ohm ", "50V ", "0.1W ", "1%", ["e96", "e24"], "X", iec60062_4digit ),
36+ panasonic_erj ("ERJ-2RKF", "10Ohm – 1MOhm ", "50V ", "0.1W ", "1%", ["e96", "e24"], "X", iec60062_4digit ),
37+ panasonic_erj ("ERJ-U02J", "1MOhm – 10MOhm ", "50V ", "0.1W ", "5%", ["e24"], "X", iec60062_3digit ),
38+ panasonic_erj ("ERJ-PA2F", "1Ohm – 1MOhm ", "50V ", "0.1W ", "1%", ["e96", "e24"], "X", iec60062_4digit ),
3839 ],
3940 "0603": [
40- resistor_series("ERJ-H3QF", "1Ohm", "10Ohm", "75V", "1%", ["e96", "e24"], iec60062_4digit, "V"),
41- resistor_series("ERJ-3EKF", "10Ohm", "1MOhm", "75V", "1%", ["e96", "e24"], iec60062_4digit, "V"),
42- resistor_series("ERJ-U03J", "1MOhm", "10MOhm", "75V", "5%", ["e24"], iec60062_3digit, "V"),
43- resistor_series("ERJ-PA3F", "1Ohm", "1MOhm", "75V", "1%", ["e96", "e24"], iec60062_4digit, "V"),
41+ panasonic_erj("ERJ-H3QF", "1Ohm – 10Ohm", "75V", "0.333W", "1%", ["e96", "e24"], "V", iec60062_4digit),
42+ panasonic_erj("ERJ-3EKF", "10Ohm – 1MOhm", "75V", "0.333W", "1%", ["e96", "e24"], "V", iec60062_4digit),
43+ panasonic_erj("ERJ-U03J", "1MOhm – 10MOhm", "75V", "0.333W", "5%", ["e24"], "V", iec60062_3digit),
44+ panasonic_erj("ERJ-PA3F", "1Ohm – 1MOhm", "75V", "0.333W", "1%", ["e96", "e24"], "V", iec60062_4digit),
45+ ],
46+ "2512": [
47+ # Stackpole CSNL series: Current sense resistors
48+ discrete_resistor_series(
49+ "Stackpole Electronics Inc",
50+ "CSNL2512",
51+ "170V",
52+ "2W",
53+ "1%",
54+ [
55+ ("1mOhm", "CSNL2512FT1L00"),
56+ ("2mOhm", "CSNL2512FT2L00"),
57+ ("3mOhm", "CSNL2512FT3L00"),
58+ ("4mOhm", "CSNL2512FT4L00"),
59+ ("5mOhm", "CSNL2512FT5L00"),
60+ ("10mOhm", "CSNL2512FT10L0"),
61+ ],
62+ ),
63+ # YAGEO PA_E series: AEC-Q200 current sense resistors
64+ discrete_resistor_series(
65+ "YAGEO",
66+ "PA_E",
67+ "170V",
68+ "2W",
69+ "1%",
70+ [
71+ ("1mOhm", "PA2512FKF7W0R001E"),
72+ ("2mOhm", "PA2512FKF7W0R002E"),
73+ ("3mOhm", "PA2512FKF7W0R003E"),
74+ ("4mOhm", "PA2512FKF7W0R004E"),
75+ ("5mOhm", "PA2512FKF7W0R005E"),
76+ ("10mOhm", "PA2512FKF7W0R01E"),
77+ ],
78+ ),
4479 ],
4580}
4681
@@ -104,34 +139,56 @@ def assign_house_resistor(c, series_by_pkg):
104139 resistance = Resistance(prop(c, ["resistance", "Resistance"]))
105140 pkg = prop(c, ["package", "Package"])
106141 v_req = prop(c, ["Voltage", "voltage"])
107- voltage_constraint = Voltage(v_req).value if v_req else None
142+ voltage_constraint = Voltage(v_req) if v_req else None
143+ p_req = prop(c, ["Power", "power"])
144+ power_constraint = Power(p_req) if p_req else None
108145
109146 # Skip 0 ohm resistors - they can't be matched to E-series
110- if resistance.value <= 0:
147+ if resistance.value <= 0.0 :
111148 return
112149
113150 series_list = series_by_pkg.get(pkg, [])
114151 matches = []
152+ manufacturer = None
153+
115154 for spec in series_list:
116- spec_min = Resistance( spec["min"]).value
117- spec_max = Resistance( spec["max"]).value
118- spec_max_v = Voltage( spec["max_v"]).value
155+ spec_type = spec.get("type", "e_series")
156+ spec_max_v = spec["max_v"]
157+ spec_power = spec["power"]
119158 spec_tol = float(spec["tolerance"].replace("%", "")) / 100.0
120159
121160 if voltage_constraint and voltage_constraint > spec_max_v:
122161 continue
123162
124- matched = find_e_series_match(resistance, spec_tol, spec["e_series"])
125- if not matched or matched.value < spec_min or matched.value > spec_max:
163+ if power_constraint and power_constraint > spec_power:
126164 continue
127165
128- encoder = spec.get("encode", iec60062_4digit)
129- code = encoder(matched.value)
130- mpn = spec["series"] + code + spec.get("suffix", "X")
131- matches.append(mpn)
166+ if spec_type == "discrete":
167+ # Discrete series: exact value match with tolerance
168+ r_with_tol = resistance.with_tolerance(spec_tol) if resistance.tolerance <= 0 else resistance
169+
170+ for val_str, mpn in spec["values"]:
171+ val_r = Resistance(val_str).with_tolerance(spec_tol)
172+ if val_r.within(r_with_tol):
173+ matches.append(mpn)
174+ if manufacturer == None:
175+ manufacturer = spec["manufacturer"]
176+ else:
177+ # E-series: standard matching logic
178+ spec_range = spec["resistance_range"]
179+ matched = find_e_series_match(resistance, spec_tol, spec["e_series"])
180+ if not matched or matched.value < spec_range.min or matched.value > spec_range.max:
181+ continue
182+
183+ encoder = spec.get("encode", iec60062_4digit)
184+ code = encoder(matched.value)
185+ mpn = spec["series"] + code + spec.get("suffix", "X")
186+ matches.append(mpn)
187+ if manufacturer == None:
188+ manufacturer = spec["manufacturer"]
132189
133190 if matches:
134- set_primary_and_alts(c, matches[0], "Panasonic Electronic Components" , matches[1:])
191+ set_primary_and_alts(c, matches[0], manufacturer , matches[1:])
135192 c.matcher = "assign_house_resistor"
136193 return
137194
@@ -156,7 +213,7 @@ def assign_house_capacitor(c, house_caps_by_pkg):
156213 pkg = prop(c, ["package", "Package"])
157214 req_diel = prop(c, ["dielectric", "Dielectric"])
158215 v_req = prop(c, ["voltage", "Voltage"])
159- req_voltage = Voltage(v_req).value if v_req else None
216+ req_voltage = Voltage(v_req) if v_req else None
160217
161218 if cap.tolerance <= 0:
162219 cap = cap.with_tolerance(0.2)
@@ -165,8 +222,8 @@ def assign_house_capacitor(c, house_caps_by_pkg):
165222 matches = []
166223
167224 for p in parts:
168- p_cap = Capacitance( p["cap"])
169- p_voltage = Voltage( p["voltage"]).value
225+ p_cap = p["cap"]
226+ p_voltage = p["voltage"]
170227
171228 if req_diel:
172229 h_rank = _DIELECTRIC_RANK.get(p["dielectric"], 99)
@@ -180,9 +237,9 @@ def assign_house_capacitor(c, house_caps_by_pkg):
180237 if not p_cap.within(cap):
181238 continue
182239
183- err = abs( p_cap.value - cap.value ) / cap.value
240+ err = p_cap.diff( cap) / cap
184241 diel_rank = _DIELECTRIC_RANK.get(p["dielectric"], 99)
185- score = (err, p_cap.tolerance, - p_voltage, diel_rank)
242+ score = (err, p_cap.tolerance, p_voltage * -1 , diel_rank)
186243
187244 matches.append((score, p))
188245
0 commit comments