Diode I/V equation¶
It is common to ignore the "$-1$" in the Shockley diode equation, but this introduces an error.
Let's create some intuition on when this approximation error is significant or not.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
#plt.style.use('seaborn-bright')
mpl.rcParams['figure.figsize'] = (15.0, 8.0)
mpl.rcParams['font.size'] = 24
mpl.rcParams['lines.linewidth'] = 5
mpl.rcParams['lines.markersize'] = 5
\begin{align} i_D &= I_S \left[ \exp \left( \dfrac{v_D}{V_T} \right) - 1 \right] \\ &\approx I_S \exp \left( \dfrac{v_D}{V_T} \right) \end{align}
Plot both the full equation and the approximation.
kB = 1.380649e-23 # J/K
q = 1.602176634e-19 # C
n = 1.8 # typical 1N4148
def id(vd, Is=1e-9, T=300):
VT = kB * T / q
return Is * (np.exp(vd / (n*VT)) - 1)
def id_approx(vd, Is=1e-9, T=300):
VT = kB * T / q
return Is * np.exp(vd / (n*VT))
def plotlin_idvd(v, nvt=5):
plt.close('all')
ax1 = plt.subplot()
ax1.plot(v, 1000*id_approx(v), '-', label='approx')
ax1.plot(v, 1000*id(v), 'o', label='exact')
r = plt.xlim([0, v.max()])
plt.ylabel('$I_D$ (mA)')
plt.xlabel('$V_D$ (V)')
#plt.suptitle('$i_D$ vs. $v_D$', y=1.05, size='x-large')
plt.legend(loc='upper left')
plt.grid(axis='y')
VT = kB * 300 / q
ax2 = ax1.twiny()
vts = np.arange(0, int(v.max() / VT) + 1, nvt)
ax2.set_xticks(VT * vts)
ax2.set_xticklabels(vts)
ax2.set_xlabel(r'$n\times V_T$')
ax2.grid(True)
ax2.set_xlim(r)
plotlin_idvd(np.linspace(1e-3, 0.8, 100), nvt=10); plt.show()
A linear-y plot isn't so helpful.
Plot with a logarithmic vertical scale to see the exponential current better:
def plot_idvd(v, nvt=5):
plt.close('all')
ax1 = plt.subplot()
plt.semilogy(v, id_approx(v), '-', label='approx')
plt.semilogy(v, id(v), 'o', label='exact')
plt.ylabel('$I_D$ (A)')
plt.xlabel('$V_D$ (V)')
#plt.suptitle('$I_D$ vs. $V_D$', y=1.05, size='x-large')
plt.legend(loc='best')
r = plt.xlim([0, v.max()])
plt.grid(axis='y')
VT = kB*300/q
ax2 = ax1.twiny()
vts = np.arange(0, int(v.max()/VT)+1, nvt)
ax2.set_xticks(VT*vts)
ax2.set_xticklabels(vts)
ax2.set_xlabel(r'$n\times V_T$')
ax2.grid(True)
ax2.set_xlim(r)
plot_idvd(np.linspace(1e-3, 0.8, 100), nvt=10); plt.show()
Zoom in to near $V_D = 0$
v = np.linspace(0, 0.1, 100); plot_idvd(v, nvt=1); plt.show()
$\rightarrow$ using the approximation is plenty good:
\begin{equation} i_D \approx \begin{cases} I_S \exp \left( \dfrac{v_D}{V_T} \right) & v_D > 0 \\ -I_S & v_D < 0 \end{cases} \end{equation}
... unless $|v_D|$ is small.
Q: When is the approximation different from the exact equation by more than 1%?
Q: When is the approximation different from the exact equation by more than 10%?
\begin{align} i_D &= I_S \left[ \exp \left( \dfrac{v_D}{V_T} \right) - 1 \right] \\ & \\ &\approx I_S \exp \left( \dfrac{v_D}{V_T} \right) \end{align}
Relative change review¶
\begin{align} \dfrac{x - \textit{ref}}{\textit{ref}} = \dfrac{x}{\textit{ref}} - 1&\\ &\times 100\text{ for percent}\nonumber\\ &\times 10^6\text{ for PPM}\nonumber \end{align}
Helpful conversion $\rightarrow\; 1\% = 10\,000\,\mathrm{PPM}$
Diode temperature coefficient¶
kB = 1.380649e-23 # J/K
q = 1.602176634e-19 # C
Eg = 1.12 * q # J
n = 1.8 # typical 1N4148
Isref = 1e-9
Tref = 300
C = Isref / (Tref**4 * np.exp(-Eg/(n*kB*Tref)))
print('C: ', C)
def IS(T=Tref, n=n):
return C * T**4 * np.exp(-Eg / (n*kB*T))
def vd(Id, T=Tref, n=n):
VT = kB * T / q
return VT * np.log(Id/IS(T, n))
C: 3.5025815397654624e-09
def plotlin_vdT(temp):
plt.close('all')
ax1 = plt.subplot()
ax1.plot(temp, vd(1e-3, temp, n), '-', label='$v_D$')
r = plt.xlim([temp.min(), temp.max()])
plt.title('$v_D$ vs. temp, at constant current')
plt.ylabel('$v_D$ (V)')
plt.xlabel('Temp (K)')
#plt.suptitle('$i_D$ vs. $v_D$', y=1.05, size='x-large')
plt.legend(loc='upper right')
plt.grid()
temp = np.arange(100, 500); plotlin_vdT(temp)
def plotlin_dvdT(temp):
plt.close('all')
ax1 = plt.subplot()
ax1.plot(temp[:-1], 1e3*np.diff(vd(1e-3, temp)), '-', label='$v_D$')
r = plt.xlim([temp.min(), temp.max()])
plt.title('Temperature coefficient')
plt.ylabel('$\dfrac{d\,v_D}{dT}$ (mV/K)')
plt.xlabel('Temp (K)')
#plt.suptitle('$i_D$ vs. $v_D$', y=1.05, size='x-large')
plt.legend(loc='upper right')
plt.grid()
temp = np.arange(-40+273, 100+273); plotlin_dvdT(temp)