def PULSEV(self, channel, initial_value, pulsed_value, pulse_width, period, delay_time): frequency = (1 / u(period)) @ u_Hz offset = (pulsed_value / 2) + initial_value amplitude = pulsed_value duty_cycle = (u(pulse_width) / u(period)) * 100 self.set_channel(channel, 'pulse', amplitude, frequency, offset, duty_cycle)
def willMount(self, color='green'): """ V_min -- Minimal voltage that could be applied """ self.Power = u(self['I_load']) @ u_A self.V_j = u(self['V_drop']) @ u_V self.consumption(self.V_j) self.Z = (self.V_j * self.V_j) / self.P self.load(self.V - self.V_j)
def willMount(self, f_3db=500e3 @ u_Hz): """ f_3db -- Frequencies of interest are passed by the highpass filter C_in -- Blocking capacitor is chosen so that all frequencies of interest are passed by the highpass filter `C_(i\\n) >= 1 / (2 pi f_(3db) (R_s∥R_g))` """ self.V_split = self.V / 6 self.load(self.V) self.I_b = self.I_load self.R_out = (u(self.V_split) / u(self.I_b) * 100) @ u_Ohm
def willMount(self, R_in = 0 @ u_Ohm, R_out = 0 @ u_Ohm): """ R_in -- The input voltage and upper resistance might represent the output of an amplifier R_out -- The lower resistance might represent the input of the following stage """ self.load(self.V) # Find right values A = np.array([[u(self.V_out), u(self.V_out - self.V) ], [1, 1]]) B = np.array([[0], [u(self.V / self.I_load)]]) # + (1 * params_tolerance)))]]) X = np.linalg.inv(A) @ B self.R_in = X[0][0] @ u_Ohm - self.R_in self.R_out = X[1][0] @ u_Ohm - self.R_out
def set_channel(self, channel, waveform='sine', amplitude=5 @ u_V, frequency=100 @ u_Hz, offset=0 @ u_V, duty_cycle=50): print(channel, waveform, frequency, amplitude, offset, duty_cycle) channel = int(channel) self.device.setfrequency(channel, u(frequency)) self.device.setwaveform(channel, waveform) self.device.setamplitude(channel, u(amplitude)) self.device.setoffset(channel, u(offset)) self.device.setdutycycle(channel, duty_cycle)
def EXPV(self, channel, initial_value=0 @ u_V, pulsed_value=5 @ u_V, rise_delay_time=0 @ u_s, rise_time_constant=0.1 @ u_s, fall_delay_time=0.1 @ u_s, fall_time_constant=0.1 @ u_s): period = u(rise_time_constant) + u(fall_time_constant) frequency = (1 / period) @ u_Hz offset = initial_value amplitude = pulsed_value duty_cycle = (u(rise_time_constant) / period) * 100 self.set_channel(channel, 'exp-rize', amplitude, frequency, offset, duty_cycle)
def set_channel(self, channel, waveform='V', value=0 @ u_V, current=0 @ u_A): """ 200 ms time for channel setting """ channel = self.device.channels[0] channel.voltage = u(value) self.device.output.on()
def circuit(self): period = 1 / self.Frequency quant = period / 4 rate = self.V / quant self.tau = u(self.V / rate) current_sensing = Resistor()(self.R_load * 2) differetiator = Capacitor()((self.tau / current_sensing.value) @ u_F) self.input & self.v_ref & differetiator & self.output & current_sensing & self.gnd
def circuit(self): period = 1 / self.Frequency quant = period / 4 rate = self.V / quant self.tau = u(self.V / rate) discharger = Resistor()(self.R_load / 10) integrator = Capacitor()((self.tau / discharger.value) @ u_F) self.input & self.v_ref & discharger & self.output & integrator & self.gnd
def circuit(self): c = speed_of_light * (1 @ u_m) / (1 @ u_s) frequency = self.frequency #self.input.signal.frequency self.wave_length = c / frequency self.normalized_length = u(self.length / self.wave_length) self.element = self.part(impedance=self.Z, frequency=frequency, normalized_length=self.normalized_length) # ip, op -- positive line in Spice Transmmittion element self.input & (self.element['ip'] or self.element[1]) self.output & (self.element['op'] or self.element[2]) # in, on -- negative line, used for ground if self.element['in']: self.gnd += self.element['in', 'on']
def circuit(self): R = Resistor() self.R_c = self.V / 2 / self.I_quiescent self.R_e = self.R_load self.R_out = (0 @ u_V - self.V_inv) / (self.I_quiescent * 2) self.r_e = 0.026 @ u_V / self.I_quiescent self.G_diff = u(self.R_c / (2 * (self.r_e + self.R_e))) self.G_cm = u(-1 * self.R_c / (2 * self.R_out + self.R_e + self.r_e)) self.CMMR = u(self.R_out / (self.R_e + self.r_e)) amplifier = Bipolar(type='npn', common='emitter', follow='collector') # First amplifier INVERTING left = amplifier( collector=R(self.R_c), emitter=R(self.R_e) # Emitter resistore conected to bipolar ) right = amplifier(collector=R(self.R_c), emitter=R(self.R_e)) power = self.v_ref & left.v_ref & right.v_ref left_input = self.input & left & self.output_n right_input = self.input_n & right & self.output sink = left.gnd & right.gnd & R(self.R_out) & self.v_inv
def circuit(self, **kwargs): generator = Bipolar(type='npn', follow='emitter')() self.V_e = generator.V_je + randint(1, int(u(self.V) / 2)) @ u_V self.V_b = self.V_e + generator.V_je self.R_e = self.V_e / self.I_load generator.collector += self.output_n controller = Divider(type='resistive')(V=self.V, V_out=self.V_b, Load=self.I_load) controller.input += self.v_ref controller.gnd += self.gnd source = controller.output & generator & Resistor()( self.R_e) & self.gnd
def willMount(self): """ I_load -- That current puts the collector at `V_(ref)` V_je -- Base-emitter built-in potential V_e -- `V_e = 1V` selected for temperature stability and maximum voltage swing V_c -- `V_c = V_(ref) / 2` R_c -- `R_c = (V_(ref) - V_c) / I_(load)` R_in -- `1/R_(i\\n) = 1/R_s + 1/R_g + 1 / R_(i\\n(base))` R_e -- `R_e = V_e / I_(load)` R_in_base_dc -- `R_(i\\n(base),dc) = beta * R_e` R_in_base_ac -- `R_(i\\n(base),ac) = beta * (r_e + R_(load))` G_v -- Amplifier gain `G_v = v_(out) / v_(i\\n) = - g_m * R_c = -R_c/R_e` g_m -- The inverse of resistance is called conductance. An amplifier whose gain has units of conductance is called a transconductance amplifier. `g_m = i_(out)/v_(i\\n) = - G_v / R_c ` r_e -- Transresistance `r_e = V_T / I_e = ((kT) / q) / I_e = (0.0253 V) / I_e` """ self.props['follow'] = 'collector' self.props['common'] = 'emitter' self.V_c = self.V / 2 self.R_c = (self.V - self.V_c) / self.I_load self.V_e = 1.0 @ u_V # For temperature stability self.R_e = self.V_e / self.I_load # TODO: Make it temperature dependent self.r_e = 0.026 @ u_V / self.I_load self.G_v = -1 * u(self.R_c / (self.R_e + self.r_e)) self.R_3 = (-1 * self.R_c - self.r_e * self.G_v) / self.G_v self.g_m = self.G_v / self.R_c * -1 self.R_in_base_dc = self.Beta * self.R_e self.R_in_base_ac = self.Beta * (self.r_e + self.R_3) self.Power = (self.V_c - self.V_e) * self.I_load self.consumption(self.V_c)
def LoadLineQPoint(self, args, temperature=[25] @ u_Degree): """ The Q-point can be found by plotting the graph of the load line on the i-v characteristic for the diode. The intersection of the two curves represents the quiescent operating point, or Q-point, for the diode. """ voltage_sweep = slice(0, self.block.V, .1) data = self.characteristics(args, temperature, voltage_sweep) data[0]['Load_Line'] = u(self.block.I_load) data[len(data) - 1]['Load_Line'] = 0 return { 'x': { 'field': 'V_input', 'label': 'Volt', 'unit': 'V' }, 'y': { 'label': 'Current', 'unit': 'A', 'scale': 'sqrt', 'domain': [-1e-3, 1e-3] }, 'data': data }