I am trying to write a program in Python which can plot the I-V curves of a bipolar transistor with given device parameters Is, Vt, Va, and Beta. I also want to be able to, given the Q-point of the device, to compute the small signal parameters r_pi, ro, and transconductance.
I created a GUI using the libraries, PyQt4, matplotlib, and numpy. My problem is that my curves are not coming out as expected and I'm not sure why. I've provided my code for calculating the collector current, Ic. Does anyone know what I might be doing wrong? For the parameters I used the values:
Is = 10*10^-15, Beta = 100, Vt = 0.025, and Va = 100
I think maybe I might be use bad voltage values for Vbe and Vce, but I'm not sure.
Code:
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
import numpy as np
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
import random
Vbe = [0 for x in range(7)]
Vbc = [0 for x in range(7)]
class Window(QtGui.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
#### Create Widgets ####
self.plotButton = QtGui.QPushButton('Plot')
self.plotButton.setFixedWidth(100)
self.plotButton.setFixedHeight(30)
self.plotButton.clicked.connect(self.plot)
self.clearButton = QtGui.QPushButton('Clear Plot')
self.clearButton.setFixedWidth(100)
self.clearButton.setFixedHeight(30)
self.clearButton.clicked.connect(self.clear)
self.calculate = QtGui.QPushButton('r_pi, r_o, g_m')
self.calculate.setFixedWidth(120)
self.calculate.setFixedHeight(30)
self.calculate.clicked.connect(self.stuff)
self.param = QtGui.QLabel('<b>Enter Parameters:</b>')
self.param.setAlignment(QtCore.Qt.AlignLeft)
self.beta = QtGui.QLineEdit()
self.beta.setFixedWidth(70)
self.bLabel = QtGui.QLabel('Beta')
self.bLabel.setAlignment(QtCore.Qt.AlignRight)
self.Is = QtGui.QLineEdit()
self.Is.setFixedWidth(70)
self.IsLabel = QtGui.QLabel('I<sub>s</sub>')
self.IsLabel.setAlignment(QtCore.Qt.AlignRight)
self.Vt = QtGui.QLineEdit()
self.Vt.setFixedWidth(70)
self.VtLabel = QtGui.QLabel('V<sub>T</sub>')
self.VtLabel.setAlignment(QtCore.Qt.AlignRight)
self.Va = QtGui.QLineEdit()
self.Va.setFixedWidth(70)
self.VaLabel = QtGui.QLabel('V<sub>A</sub>')
self.VaLabel.setAlignment(QtCore.Qt.AlignRight)
self.VceEdit = QtGui.QLineEdit()
self.VceEdit.setFixedWidth(70)
self.VceEdit.setAlignment(QtCore.Qt.AlignLeft)
self.VceLabel = QtGui.QLabel('V<sub>CE</sub> (Q-Point)')
self.VceLabel.setAlignment(QtCore.Qt.AlignRight)
self.IcEdit = QtGui.QLineEdit()
self.IcEdit.setFixedWidth(70)
self.IcEdit.setAlignment(QtCore.Qt.AlignLeft)
self.IcLabel = QtGui.QLabel('I<sub>C</sub> (Q-Point)')
self.IcLabel.setAlignment(QtCore.Qt.AlignRight)
#### Set The Layout ####
layout = QtGui.QVBoxLayout()
layout.addWidget(self.canvas)
layout.addWidget(self.param)
layout2 = QtGui.QHBoxLayout()
layout2.addWidget(self.bLabel)
layout2.addWidget(self.beta)
layout2.addWidget(self.IsLabel)
layout2.addWidget(self.Is)
layout2.addWidget(self.VtLabel)
layout2.addWidget(self.Vt)
layout2.addWidget(self.VaLabel)
layout2.addWidget(self.Va)
layout2.addWidget(self.VceLabel)
layout2.addWidget(self.VceEdit)
layout2.addWidget(self.IcLabel)
layout2.addWidget(self.IcEdit)
layout.addLayout(layout2)
layout.addWidget(self.plotButton)
layout.addWidget(self.clearButton)
layout.addWidget(self.calculate)
self.setLayout(layout)
def clear(self):
plt.clf()
plt.cla()
print ('cleared')
def stuff(self):
self.qIc1 = str("%s" % self.IcEdit.text())
self.qVc1 = str("%s" % self.VceEdit.text())
def plot(self):
plt.cla()
self.betaVal = str("%s" % self.beta.text())
self.IsVal = str("%s" % self.Is.text())
self.VtVal = str("%s" % self.Vt.text())
self.VaVal = str("%s" % self.Va.text())
#### Compute Collector Current ####
data1, data2, data3 = [], [], []
Vbe1, Vbe2, Vbe3 = [], [], []
Vce1, Vce2, Vce3 = [], [], []
x1, x2, x3 = 6, 5, 4 #Vce
y1, y2, y3 = 5, 4, 2 #Vbe
for j in range(600):
x1, x2, x3 = x1 + 0.01, x2 + 0.01, x3 + 0.01
y1, y2, y3 = y1 + 0.01, y2 + 0.01, y3 + 0.01
Vce1.append(x1)
Vbe1.append(y1)
Vce2.append(x2)
Vbe2.append(y2)
Vbe3.append(x3)
Vce3.append(y3)
for i in range(600):
e1 = np.exp(Vbe1[i]/float(self.VtVal))
e2 = np.exp((Vbe1[i] - Vce1[i])/float(self.VtVal))
e3 = (float(self.IsVal)/float(self.betaVal))*(np.exp((Vbe1[i] - Vce1[i])/float(self.VtVal)) - 1)
e4 = (Vce1[i] + float(self.VaVal))/float(self.VaVal)
subtract = float(self.IsVal)*(e1 - e2) - e3
ic = subtract * e4
data1.append(ic)
e1 = np.exp(Vbe2[i]/float(self.VtVal))
e2 = np.exp((Vbe2[i] - Vce2[i])/float(self.VtVal))
e3 = (float(self.IsVal)/float(self.betaVal))*(np.exp((Vbe2[i] - Vce2[i])/float(self.VtVal)) - 1)
e4 = (Vce2[i] + float(self.VaVal))/float(self.VaVal)
subtract = float(self.IsVal)*(e1 - e2) - e3
#m1 = float(self.IsVal)*subtract
ic = subtract * e4
data2.append(ic)
e1 = np.exp(Vbe3[i]/float(self.VtVal))
e2 = np.exp((Vbe3[i] - Vce3[i])/float(self.VtVal))
e3 = (float(self.IsVal)/float(self.betaVal))*(np.exp((Vbe3[i] - Vce3[i])/float(self.VtVal)) - 1)
e4 = (Vce3[i] + float(self.VaVal))/float(self.VaVal)
subtract = float(self.IsVal)*(e1 - e2) - e3
#m1 = float(self.IsVal)*subtract
ic = subtract * e4
data3.append(ic)
self.ax = self.figure.add_subplot(111)
plt.xlabel('Vce')
plt.ylabel('Ic')
plt.title('BJT I-V Characteristics')
self.ax.plot(data1, 'r')
self.ax.plot(data2, 'b')
self.ax.plot(data3, 'g')
self.canvas.draw()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Window()
main.setWindowTitle('BJT I-V Curve Plotter')
main.resize(1000, 600)
main.show()
sys.exit(app.exec_())
My results:
https://drive.google.com/file/d/0B3fmw_rxjp4nYVVMR2x2RThXTXc/view?usp=sharing
what I would expect:
https://awrcorp.com/download/faq/english/examples/images%5Cbjt_amp_oppnt_bjt_iv_curves_graph.gif