How much does a diode's characteristics actually diviate from diode to diode? I measured a small number of diodes, and then recovered the SPICE DC parameters. Due to the limitations of my equipment, I only did this in the DC forward biased region. I'll also describe how to accurately recover the SPICE parameters using numerical methods.
Forward bias SPICE Diode Model at DC
SPICE models a diode using the Shockley diode equation with a series resistor. That is, I=Is(eVD−IRsnkbT−1)
- I [A] is the current through the diode.
- VD [V] is the voltage across the entire diode (i.e. voltage across diode junction and internal series resistance)
- Is [A] is the reverse biase saturation current/scale current.
- Rs [Ω] is the series resistance.
- n is the emission coefficient.
- kb [eVK] is Boltzmann's constant.
- T [K] is the absolute temperature of the junction.
Non-linear curve fitting (aside)
Re-arranging the model equation in the form of a root equation (note: it's not necessary to do this level of re-arrangement; simply moving I over to the right would have worked, too), 0=IRs+ln(IIs+1)nkbT−V
Implementation
The Jacobian matrix for our diode model is: Ji=[ln(I1Is,i+1)kbTI1−I1nikbTI1Is,i+I2s,iln(I2Is,i+1)kbTI2−I2nikbTI2Is,i+I2s,i⋮⋮⋮ln(ImIs,i+1)kbTIm−ImnikbTImIs,i+I2s,i]# Yes, I know. I'm lazy. from numpy import * from scipy.optimize import leastsq def diode_res(args, T, V, I): ''' Shockley diode equation with series resistor residual @param n emission coefficient [unitless] @param Rs series resistance [ohms] @param Is saturation current [A] @param T reference temperature [K] @param V voltage across diode [V] @param I current through diode [A] @return I*Rs+log(I/Is+1)*n*k*T-V ''' n, Rs, Is = args kb = 8.617332478e-5 return I*Rs+log(I/Is+1)*n*kb*T-V def jac_diode(args, T, V, I): ''' Jacobian of the diode equation. Independent vars: n, Rs, Is @param n emission coefficient [unitless] @param Rs series resistance [ohms] @param Is saturation current [A] @param T reference temperature [K] @param V voltage across diode [V] @param I current through diode [A] @return Jacobian matrix transposed ''' n,Rs,Is = args kb = 8.617332478e-5 res = zeros([3,len(V)]) res[0,:] = log(I/Is+1)*kb*T res[1,:] = I res[2,:] = -I/(I*Is+Is**2)*n*kb*T return res def diode_coeffs(V, I, T): ''' Find diode coefficients given V vs. I at a specified T. @param V @param I @param T in K @return n, Rs, Is ''' return leastsq(diode_res, array([1,0,1e-14]),args=(T,V,I), Dfun=jac_diode, col_deriv=True,xtol=1e-15)[0]
Experimental Setup
The setup couldn't be any easier:

The diodes tested were the 1N4148 made by Fairchild Semiconductor.
Data
The data was measured at T=19∘C±1∘C. Table 1 shows the measured currents at the various voltages for each diode tested. The measured lead resistance (using a 4-wire measurement with the power supply panel meter and multimeter) was 17.319Ω.
0.6V | 0.7V | 0.8V | 0.9V | 1V | 1.5V | 2V | 2.5V | 3V | |
Diode 1 | 0.52 | 2.31 | 5.58 | 9.82 | 14.46 | 39.8 | 66.5 | 93.8 | 121 |
Diode 2 | 0.56 | 2.43 | 5.75 | 9.98 | 14.58 | 39.7 | 66 | 93 | 119.8 |
Diode 3 | 0.54 | 2.4 | 5.7 | 9.91 | 14.54 | 39.8 | 66.1 | 93.3 | 120.3 |
Diode 4 | 0.49 | 2.27 | 5.54 | 9.75 | 14.38 | 39.98 | 66.1 | 93.3 | 120.3 |
Diode 5 | 0.54 | 2.38 | 5.69 | 9.95 | 14.6 | 40 | 66.7 | 94 | 121.1 |
Diode 6 | 0.57 | 2.46 | 5.8 | 10.06 | 14.7 | 40 | 66.5 | 39.7 | 120.8 |
Diode 7 | 0.52 | 2.32 | 5.61 | 9.85 | 14.5 | 39.9 | 66.4 | 93.6 | 120.9 |
Analysis
Figure 2 shows the reconstructed I-V curves, demonstrating that the technique appears to work.



n | Rs | Is | |
mean | 1.7875 | 0.636 Ω | 1.081 nA |
std. deviation | 0.022 | 0.0913 Ω | 0.1924 nA |
relative error (std.dev.mean) | 1.23% | 14.4% | 17.8% |
Conclusion
This test does provide a convenient rough bound on what should be relatively easy to achieve in practice. The parameters are certainly within an order of magnitude of each other. Unfortunately, it's hard to determine if most of the deviation errors in the diode model parameters are due to experimental setup or intrinsic to the diodes. Additionally, 7 test samples is hardly what could be called a statistically significant quantity. The test setup was quite limited because I lacked a second DMM to directly measure the diode voltage, instead relying on a fixed shunt resistance that was measured before-hand. Comparisons to the datasheet and manufacturer SPICE model had some sort of systematic error. This could have been associated with assuming the model parameters are constant vs. temperature, where in reality they could drift. There was significant self heating and getting an accurate junction temperature was not possible.
Which version of Python, numpy, and scipy are you using? The code you've posted errors with TypeError: 'numpy.float32' object cannot be interpreted as an integer (traceback is pointing to the line "return I*Rs+log(I/Is+1)*n*kb*T-V" in diode_res(), but seems to actually be something wrong with leastsq(), since I can call diode_res() just fine.
ReplyDeleteI tried with Python 3 and Python 2.7 and both of them work. I have SciPy 0.18.1, but I think at the time I wrote this it was SciPy 0.15.0?
Delete