def simulate_amplification_factor_core(R1,R2,RC,RE,RL,C1,C2,V,w): circuit = Circuit('Amplifier') circuit.R(1, 5, 2, R1@u_kΩ) #kOhm circuit.R(2, 2, 0, R2@u_kΩ) #kOhm circuit.R('C', 5, 4, RC@u_kΩ) #kOhm circuit.R('E', 3, 0, RE@u_kΩ) #kOhm circuit.R('Load', 'out', 0, RL@u_MΩ) #MOhm circuit.C(1, 'inp', 2, C1@u_uF) #uF circuit.C(2, 4, 'out', C2@u_uF) #uF circuit.BJT(1, 4, 2, 3, model='bjt') # Q is mapped to BJT ! circuit.model('bjt', 'npn', bf=80, cjc=pico(5), rb=100) circuit.V('power', 5, circuit.gnd, 15@u_V) circuit.V('var','inp',circuit.gnd, f'DC 0 AC {V} SIN(0 {V}V {w})') T = 25 simulator = circuit.simulator(temperature=T, nominal_temperature=T) analysis = simulator.transient(step_time = (2*np.pi/w/20)@u_s,end_time=(2*np.pi/w*4)@u_s) return [float(min(analysis['out']))]
def simulate_amplifier(): circuit = Circuit('Amplifier') R_1 = [100] R_2 = [20] R_C = [10] R_E = [2] R_L = [1] C_1 = [10] C_2 = [10] R1 = random.choice(R_1) R2 = random.choice(R_2) RC = random.choice(R_C) RE = random.choice(R_E) RL = random.choice(R_L) C1 = random.choice(C_1) C2 = random.choice(C_2) circuit.R(1, 5, 2, R1@u_kΩ) #kOhm circuit.R(2, 2, 0, R2@u_kΩ) #kOhm circuit.R('C', 5, 4, RC@u_kΩ) #kOhm circuit.R('E', 3, 0, RE@u_kΩ) #kOhm circuit.R('Load', 'out', 0, RL@u_MΩ) #MOhm circuit.C(1, 'in', 2, C1@u_uF) #uF circuit.C(2, 4, 'out', C2@u_uF) #uF circuit.BJT(1, 4, 2, 3, model='bjt') # Q is mapped to BJT ! circuit.model('bjt', 'npn', bf=80, cjc=pico(5), rb=100) V_vector = [0.5] w_vector = [1E3] V = random.choice(V_vector) w = random.choice(w_vector) circuit.V('power', 5, circuit.gnd, 15@u_V) circuit.V('var','in',circuit.gnd, f'DC 0 AC {V} SIN(0 {V}V {w})') simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.transient(step_time = (1/w/25)@u_s,end_time=(4/w)@u_s) figure = plt.figure(1, (20, 10)) axe = plt.subplot(111) plt.title('') plt.xlabel('Time [s]') plt.ylabel('Voltage [V]') plt.grid() plot(analysis['in'], axis=axe) plot(analysis.out, axis=axe) plt.legend(('input', 'output'), loc=(.05,.1)) plt.tight_layout() plt.savefig('gallery/amplifier.png') return
def make_database_core(R1,R2,RC,RE,RL,C1,C2,V,w,l=False): circuit = Circuit('Amplifier') circuit.R(1, 5, 2, R1@u_kΩ) #kOhm circuit.R(2, 2, 0, R2@u_kΩ) #kOhm circuit.R('C', 5, 4, RC@u_kΩ) #kOhm circuit.R('E', 3, 0, RE@u_kΩ) #kOhm circuit.R('Load', 'out', 0, RL@u_MΩ) #MOhm circuit.C(1, 'inp', 2, C1@u_uF) #uF circuit.C(2, 4, 'out', C2@u_uF) #uF circuit.BJT(1, 4, 2, 3, model='bjt') # Q mapped to BJT circuit.model('bjt', 'npn', bf=80, cjc=pico(5), rb=100) circuit.V('power', 5, circuit.gnd, 15@u_V) circuit.V('var','inp',circuit.gnd, f'DC 0 AC {V} SIN(0 {V}V {w})') circuit.include(spice_library['D1N4148']) circuit.X('diode','D1N4148',3,2) T = 25 simulator = circuit.simulator(temperature=T, nominal_temperature=T) analysis = simulator.transient(step_time = (1/w/10)@u_s,end_time=(2/w)@u_s) treshold = 4 return [R1,R2,RC,RE,RL,C1,C2,V,w, int(treshold<float(max(analysis['3']-analysis['2'])))]
#################################################################################################### #r# We define a basic circuit to drive an NPN transistor (2n2222a) using two voltage sources. #f# circuit_macros('transistor.m4') circuit = Circuit('Transistor') Vbase = circuit.V('base', '1', circuit.gnd, 1@u_V) circuit.R('base', 1, 'base', 1@u_kΩ) Vcollector = circuit.V('collector', '2', circuit.gnd, 0@u_V) circuit.R('collector', 2, 'collector', 1@u_kΩ) # circuit.BJT(1, 'collector', 'base', circuit.gnd, model='generic') # circuit.model('generic', 'npn') circuit.include(spice_library['2n2222a']) circuit.BJT(1, 'collector', 'base', circuit.gnd, model='2n2222a') #r# We plot the base-emitter diode curve :math:`Ib = f(Vbe)` using a DC sweep simulation. simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.dc(Vbase=slice(0, 3, .01)) axe1 = plt.subplot(221) axe1.plot(analysis.base, u_mA(-analysis.Vbase)) # Fixme: I_Vbase axe1.axvline(x=.65, color='red') axe1.legend(('Base-Emitter Diode curve',), loc=(.1,.8)) axe1.grid() axe1.set_xlabel('Vbe [V]') axe1.set_ylabel('Ib [mA]') ####################################################################################################
def mkschematic(ind, nnodes, nodelist, spice_library): circuit = Circuit('generated circuit') circuit.V('vcc', 'vcc', circuit.gnd, '5V') circuit.V('vdd', 'vdd', circuit.gnd, '-5V') circuit.Sinusoidal('input', 'vin', circuit.gnd, amplitude=5) nodes = 0 for i in range(nnodes): if ind[5 * i] == 1: circuit.R( nodes, nodelist[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, nodelist[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, values.E12R[ind[5 * i + 1]]) elif ind[5 * i] == 2: circuit.C( nodes, nodelist[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, nodelist[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, values.E12C[ind[5 * i + 1]]) elif ind[5 * i] == 3: circuit.include(spice_library['2n2222a']) circuit.BJT( nodes, nodelist[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, nodelist[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, nodelist[ind[5 * i + 4]] if ind[5 * i + 4] != 0 else circuit.gnd, '2n2222a') elif ind[5 * i] == 4: circuit.include(spice_library['2n2907']) circuit.BJT( nodes, nodelist[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, nodelist[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, nodelist[ind[5 * i + 4]] if ind[5 * i + 4] != 0 else circuit.gnd, '2n2907') elif ind[5 * i] == 6: circuit.include(spice_library['1N4148']) circuit.X( 'D{}'.format(nodes), '1N4148', nodelist[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, nodelist[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd) elif ind[5 * i] == 5: circuit.L( nodes, nodelist[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, nodelist[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, values.E12I[ind[5 * i + 1]]) elif ind[5 * i] == 0: continue else: continue nodes += 1 print(circuit)
def generate_and_test(self, gui, ind): circuit = Circuit('generated circuit') sys.stdout.write(' {:.1%}%\b\r'.format(self.GENCOUNTER / self.POPSIZE)) sys.stdout.flush() circuit.V('vcc', 'vcc', circuit.gnd, '5V') circuit.V('vdd', 'vdd', circuit.gnd, '-5V') circuit.Sinusoidal('input', 'vin', circuit.gnd, amplitude=2) nodes = 0 try: for i in range(self.N_NODES): if ind[5 * i] == 1: circuit.R( nodes, self.NODELIST[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, values.E12R[ind[5 * i + 1]]) elif ind[5 * i] == 2: circuit.C( nodes, self.NODELIST[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, values.E12C[ind[5 * i + 1]]) elif ind[5 * i] == 3: circuit.include(self.spice_library['2n2222a']) circuit.BJT( nodes, self.NODELIST[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 4]] if ind[5 * i + 4] != 0 else circuit.gnd, '2n2222a') elif ind[5 * i] == 4: circuit.include(self.spice_library['2n2907']) circuit.BJT( nodes, self.NODELIST[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 4]] if ind[5 * i + 4] != 0 else circuit.gnd, '2n2907') elif ind[5 * i] == 6: circuit.include(self.spice_library['1N4148']) circuit.X( 'D{}'.format(nodes), '1N4148', self.NODELIST[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd) elif ind[5 * i] == 5: circuit.L( nodes, self.NODELIST[ind[5 * i + 2]] if ind[5 * i + 2] != 0 else circuit.gnd, self.NODELIST[ind[5 * i + 3]] if ind[5 * i + 3] != 0 else circuit.gnd, values.E12I[ind[5 * i + 1]]) elif ind[5 * i] == 0: continue else: continue nodes += 1 simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.transient(start_time="2ms", step_time='1ms', end_time='40ms', max_time='40ms ') except: self.DEAD += 1 self.s['pop'][self.s['counter']] = [self.GEN, -1, self.GENCOUNTER] self.s['counter'] += 1 self.GENCOUNTER += 1 return (-1., ) result = 0 try: j = 0. for n, m in zip(analysis.nodes['vin'][1:-1], analysis.nodes['out'][1:-1]): j += self.toolbox.evaluator(n, m) result = (j / max([ len(analysis.nodes['out'][1:-1]), len(analysis.nodes['out'][1:-1]) ])) * (1 + 0.01 * (self.N_NODES - nodes)) if result > 0 and gui != None: gui.dc.update_data(result, analysis.nodes['out'][1:-1], analysis.nodes['vin'][1:-1]) self.s['pop'][self.s['counter']] = [ self.GEN, result, self.GENCOUNTER ] self.GENCOUNTER += 1 self.s['counter'] += 1 return (result if result > 0 else 0, ) except: self.s['pop'][self.s['counter']] = [ self.GEN, -0.5, self.GENCOUNTER ] self.s['counter'] += 1 self.GENCOUNTER += 1 return (-0.5, )
libraries_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'libraries') spice_library = SpiceLibrary(libraries_path) #################################################################################################### # #cm# relay.m4 period = 50@u_ms pulse_width = period / 2 circuit = Circuit('Relay') # circuit.V('digital', 'Vdigital', circuit.gnd, 5@u_V) circuit.Pulse('clock', 'clock', circuit.gnd, 0@u_V, 5@u_V, pulse_width, period, rise_time=5@u_ms, fall_time=5@u_ms) circuit.R('base', 'clock', 'base', 100@u_Ω) circuit.BJT(1, 'collector', 'base', circuit.gnd, 'bjt') # Q is mapped to BJT ! circuit.model('bjt', 'npn', bf=80, cjc=pico(5), rb=100) circuit.V('analog', 'VccAnalog', circuit.gnd, 8@u_V) circuit.R('relay', 'VccAnalog', 1, 50@u_Ω) circuit.L('relay', 1, 'collector', 100@u_mH) circuit.include(spice_library['1N5822']) # Schottky diode diode = circuit.X('D', '1N5822', 'collector', 'VccAnalog') # Fixme: subcircuit node # diode.minus.add_current_probe(circuit) #################################################################################################### figure = plt.figure(1, (20, 10)) simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.transient(step_time=period/1000, end_time=period*1.1)
from PySpice.Unit import * logger = Logging.setup_logging() libraries_path = find_libraries() spice_library = SpiceLibrary(libraries_path) circuit = Circuit('Transistor') circuit.V('power', 5, circuit.gnd, 15 @ u_V) source = circuit.SinusoidalVoltageSource('in', 'in', circuit.gnd, amplitude=.5 @ u_V, frequency=1 @ u_kHz) circuit.C(1, 'in', 2, 10 @ u_uF) circuit.R(1, 5, 2, 100 @ u_kΩ) circuit.R(2, 2, 0, 20 @ u_kΩ) circuit.R('C', 5, 4, 10 @ u_kΩ) circuit.BJT(1, 4, 2, 3, model='bjt') # Q is mapped to BJT ! circuit.model('bjt', 'npn', bf=80, cjc=pico(5), rb=100) circuit.R('E', 3, 0, 2 @ u_kΩ) circuit.C(2, 4, 'out', 10 @ u_uF) circuit.R('Load', 'out', 0, 1 @ u_MΩ) # .ac dec 5 10m 1G simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.transient(step_time=source.period / 200, end_time=source.period * 2)
#cm# ac-coupled-amplifier.m4 circuit = Circuit('Transistor') circuit.V('power', 5, circuit.gnd, 15 @ u_V) source = circuit.Sinusoidal('in', 'in', circuit.gnd, amplitude=.5 @ u_V, frequency=1 @ u_kHz) circuit.C(1, 'in', 2, 10 @ u_uF) circuit.R(1, 5, 2, 100 @ u_kΩ) circuit.R(2, 2, 0, 20 @ u_kΩ) circuit.R('C', 5, 4, 10 @ u_kΩ) circuit.BJT(1, 4, 2, 3, 'bjt') # Q is mapped to BJT ! circuit.model('bjt', 'npn', bf=80, cjc=pico(5), rb=100) circuit.R('E', 3, 0, 2 @ u_kΩ) circuit.C(2, 4, 'out', 10 @ u_uF) circuit.R('Load', 'out', 0, 1 @ u_MΩ) #################################################################################################### figure = plt.figure(1, (20, 10)) # .ac dec 5 10m 1G simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.transient(step_time=source.period / 200, end_time=source.period * 2)
def define_circuit(self): logger = Logging.setup_logging() circuit_lab = self.circuit circuit = Circuit(circuit_lab["name"]) # for complex circuit elements that requires SPICE library # libraries_path = find_libraries() python_file = os.path.abspath(sys.argv[0]) examples_root = parent_directory_of(python_file) libraries_path = os.path.join(examples_root, 'libraries') spice_library = SpiceLibrary(libraries_path) # return message message = "" # add all elements to the PySpice circuit for element in circuit_lab: if element == "V": for dc_voltage_source in circuit_lab["V"]: circuit.V( dc_voltage_source["id"], circuit.gnd if dc_voltage_source["node1"] == "gnd" else dc_voltage_source["node1"], circuit.gnd if dc_voltage_source["node2"] == "gnd" else dc_voltage_source["node2"], dc_voltage_source["value"] @ u_V) elif element == "VA": for ac_voltage_source in circuit_lab["VA"]: circuit.SinusoidalVoltageSource( ac_voltage_source["id"], circuit.gnd if ac_voltage_source["node1"] == "gnd" else ac_voltage_source["node1"], circuit.gnd if ac_voltage_source["node2"] == "gnd" else ac_voltage_source["node2"], amplitude=ac_voltage_source["amplitude"] @ u_V, frequency=ac_voltage_source["frequency"] @ u_Hz, offset=ac_voltage_source["offset"] @ u_V) elif element == "I": for dc_current_source in circuit_lab["I"]: circuit.I( dc_current_source["id"], circuit.gnd if dc_current_source["node1"] == "gnd" else dc_current_source["node1"], circuit.gnd if dc_current_source["node2"] == "gnd" else dc_current_source["node2"], dc_current_source["value"] @ u_A) elif element == "IA": for ac_current_source in circuit_lab["IA"]: circuit.SinusoidalCurrentSource( ac_current_source["id"], circuit.gnd if ac_current_source["node1"] == "gnd" else ac_current_source["node1"], circuit.gnd if ac_current_source["node2"] == "gnd" else ac_current_source["node2"], amplitude=ac_current_source["amplitude"] @ u_A, frequency=ac_current_source["frequency"] @ u_Hz, offset=ac_current_source["offset"] @ u_A) elif element == "R": for resistor in circuit_lab["R"]: circuit.R( resistor["id"], circuit.gnd if resistor["node1"] == "gnd" else resistor["node1"], circuit.gnd if resistor["node2"] == "gnd" else resistor["node2"], resistor["value"] @ u_Ω) elif element == "L": for inductor in circuit_lab["L"]: circuit.L( inductor["id"], circuit.gnd if inductor["node1"] == "gnd" else inductor["node1"], circuit.gnd if inductor["node2"] == "gnd" else inductor["node2"], inductor["value"] @ u_H) elif element == "C": for capacitor in circuit_lab["C"]: circuit.C( capacitor["id"], circuit.gnd if capacitor["node1"] == "gnd" else capacitor["node1"], circuit.gnd if capacitor["node2"] == "gnd" else capacitor["node2"], capacitor["value"] @ u_F) elif element == "D": for diode in circuit_lab["D"]: try: circuit.include(spice_library[diode["modelType"]]) circuit.X( diode["id"], diode["modelType"], circuit.gnd if diode["node1"] == "gnd" else diode["node1"], circuit.gnd if diode["node2"] == "gnd" else diode["node2"]) except KeyError as e: message += " " + str(e) elif element == "nBJT": for nBJT in circuit_lab["nBJT"]: try: circuit.include(spice_library[nBJT["modelType"]]) circuit.BJT(nBJT["id"], circuit.gnd if nBJT["node1"] == "gnd" else nBJT["node1"], circuit.gnd if nBJT["node2"] == "gnd" else nBJT["node2"], circuit.gnd if nBJT["node3"] == "gnd" else nBJT["node3"], model=nBJT["modelType"]) except KeyError as e: message += " " + str(e) elif element == "pBJT": for pBJT in circuit_lab["pBJT"]: try: circuit.include(spice_library[pBJT["modelType"]]) circuit.BJT(pBJT["id"], circuit.gnd if pBJT["node3"] == "gnd" else pBJT["node3"], circuit.gnd if pBJT["node2"] == "gnd" else pBJT["node2"], circuit.gnd if pBJT["node1"] == "gnd" else pBJT["node1"], model=pBJT["modelType"]) except KeyError as e: message += " " + str(e) elif element == "NMOS": for NMOS in circuit_lab["NMOS"]: try: circuit.include(spice_library[NMOS["modelType"]]) # nodes are: drain, gate, source, bulk circuit.MOSFET(NMOS["id"], circuit.gnd if NMOS["node4"] == "gnd" else NMOS["node4"], circuit.gnd if NMOS["node2"] == "gnd" else NMOS["node2"], circuit.gnd if NMOS["node3"] == "gnd" else NMOS["node3"], circuit.gnd if NMOS["node1"] == "gnd" else NMOS["node1"], model=NMOS["modelType"]) except KeyError as e: message += " " + str(e) elif element == "PMOS": for PMOS in circuit_lab["PMOS"]: try: circuit.include(spice_library[PMOS["modelType"]]) # nodes are: source, gate, drain, bulk circuit.MOSFET(PMOS["id"], circuit.gnd if PMOS["node1"] == "gnd" else PMOS["node1"], circuit.gnd if PMOS["node2"] == "gnd" else PMOS["node2"], circuit.gnd if PMOS["node3"] == "gnd" else PMOS["node3"], circuit.gnd if PMOS["node4"] == "gnd" else PMOS["node4"], model=PMOS["modelType"]) except KeyError as e: message += " " + str(e) # add ammeter as a 0 volt voltage source elif element == "AM": for ammeter in circuit_lab["AM"]: circuit.V( ammeter["id"], circuit.gnd if ammeter["node1"] == "gnd" else ammeter["node1"], circuit.gnd if ammeter["node2"] == "gnd" else ammeter["node2"], ammeter["value"] @ u_V) if not message: self.spice = circuit return message return "Undefined model type:" + message