\[ \definecolor{mycolor}{rgb}{0.3,0.7,0.7} \newcommand{\units}[1]{ { \color{mycolor} #1 } } \newcommand{\unitunit}[]{ \text{unit} } \newcommand{\unitm}[]{ \text{m} } \newcommand{\unitnm}[]{ \text{nm} } \newcommand{\unitcm}[]{ \text{cm} } \newcommand{\unitkg}[]{ \text{kg} } \newcommand{\unitsec}[]{ \text{s} } \newcommand{\unitsr}[]{ \text{sr} } \newcommand{\unitcd}[]{ \text{cd} } \newcommand{\unitlm}[]{ \text{lm} } \newcommand{\unitlx}[]{ \text{lx} } \newcommand{\unitnit}[]{ \text{nit} } \newcommand{\unitC}[]{ \text{C} } \newcommand{\unitW}[]{ \text{W} } \newcommand{\unitkW}[]{ \text{kW} } \newcommand{\unitJ}[]{ \text{J} } \newcommand{\unitK}[]{ \text{K} } \newcommand{\unitN}[]{ \text{N} } \newcommand{\unitspercent}[]{ \units{ \% } } \newcommand{\unitsaccel}[]{ \units{ \unitm \cdot \unitsec^{-2} } } \newcommand{\unitsE}[]{ \units{ \unitW / \unitm^2 } } \newcommand{\unitsL}[]{ \units{ \unitW/(\unitsr\cdot\unitm^2) } } \newcommand{\unitsnit}[]{ \units{ \unitnit } } \newcommand{\unitsm}[]{ \units{ \unitm } } \newcommand{\unitsnm}[]{ \units{ \unitnm } } \newcommand{\unitsAU}[]{ \units{ \text{AU} } } \newcommand{\unitsA}[]{ \units{ \text{A} } } \newcommand{\unitsmA}[]{ \units{ \text{mA} } } \newcommand{\unitsW}[]{ \units{ \text{W} } } \newcommand{\unitsmW}[]{ \units{ \text{mW} } } \newcommand{\unitsHz}[]{ \units{ \text{Hz} } } \newcommand{\unitsTHz}[]{ \units{ \text{THz} } } \newcommand{\unitsJ}[]{ \units{ \text{J} } } \newcommand{\unitsN}[]{ \units{ \text{N} } } \newcommand{\unitsOmega}[]{ \units{ \text{Ω} } } \newcommand{\unitsV}[]{ \units{ \text{V} } } \newcommand{\unitsdeg}[]{ \units{ \deg } } \newcommand{\unitsDegC}[]{ \units{ \deg\text{C} } } \]

Diode Model Fit

This tool fits a V–I (voltage vs. current) dataset[1] to the Shockley diode equation:

\[ I_D = \left( \exp\!\left(\frac{V_D}{n V_T}\right) - 1 \right) I_S,\hspace{1cm}\text{where } V_T = \frac{k_B}{q_p} T \]

Here, \(V_D\) and \(I_D\) are the voltage and current across the diode. The diode parameters are the 'ideality factor'[2] \(n\) (commonly called the 'emission coefficient'[3]) and the reverse-bias 'saturation current' \(I_S\). Finally, \(V_T\) is the 'thermal voltage', a function of the Boltzmann constant \(k_B := 1.380\,649 \times 10^{-23}~\units{\unitJ/\unitK}\), the elementary charge \(q_p := 1.602\,176\,634 \times 10^{-19}~\units{\unitC}\), and (absolute) temperature \(T\) in \(\units{\unitK}\).

SPICE's model (as well as our model here) adds some sophistication to the \(V_D\) term, accounting for a series-resistance \(R_S\) inside the diode. Any current flowing in the diode over this resistance creates its own voltage drop (by Ohm's Law). Thus, the total forward voltage \(V_F\) across the diode should be:

\[ V_F = R_S I_D + V_D \]

Substituting that into the previous equation, we get:

\begin{align*} I_D &= \left( \exp\!\left(\frac{V_F-R_S I_D}{n V_T}\right) - 1 \right) I_S \\ &= \frac{n V_T}{R_S} Q - I_S, \hspace{1cm}\text{where } Q := W\!\left( \exp\!\left(\frac{ R_S I_S + V_F }{n V_T}\right) \frac{R_S}{n V_T} I_S \right) \end{align*}

(Note that in the first line \(I_D\) is on both the left and right, so simplifying this form has required \(W\), the Lambert \(W\) function.)

The inverse[4] of this function is also useful:

\[ V_F = \ln\!\left( \frac{I_D}{I_S} + 1 \right) n V_T + R_S I_D \]

As are the partials / gradient with respect to the parameters:

\begin{alignat*}{2} &\frac{\partial V_F}{\partial I_S} = \frac{-n I_D V_T}{(I_D+I_S)\,I_S}, \hspace{1cm} &&\frac{\partial I_D}{\partial I_S} = \left(\frac{n V_T}{R_S I_S} Q - 1\right) / (1+Q) \\ &\frac{\partial V_F}{\partial R_S} = I_D, \hspace{1cm} &&\frac{\partial I_D}{\partial R_S} = \left( \frac{I_S}{R_S} - \frac{n V_T}{R_S^2} Q \right) Q / (1+Q) \\ &\frac{\partial V_F}{\partial n} = \ln\!\left( \frac{I_D}{I_S} + 1 \right) V_T, \hspace{1cm} &&\frac{\partial I_D}{\partial n} = \left( \frac{V_T}{R_S} Q - \frac{I_S}{n} - \frac{V_F}{n R_S} \right) Q / (1+Q) \end{alignat*}

Diode Model Calculator

This is just a simple calculator to evaluate the above equations. Set the diode parameters and temperature in the first table, then change either \(V_F\) or \(I_D\) in the second table to see the other one update.

\(I_S\) \(\unitsA\)
\(R_S\) \(\unitsOmega\)
\(n\)
\(T_C\) \(\unitsDegC\)
\(V_T\) \(\unitsV\)
\(V_F\) \(\unitsV\)
\(I_D\) \(\unitsA\)

Diode Model Curve-Fit

Fitting data to this model is useful because we need accurate models in order to accurately predict how diodes (including LEDs and laser diodes) perform.

The following calculator (not linked to the first one!) allows you to fit the diode model to data.


Data Input

More data points generally results in a more accurate fit.

Data format is a list of lines, where each line is a pair of voltage (in volts) and current (in amps). Some datasheets swap the order around[5], so be careful (you can select which one you have, below). SI prefixes / units are not necessary. Scientific notation with e notation, comments with #, and blank lines are supported. See example data.

Note that diodes are temperature-dependent. Although the model is calculated from data at some measurement temperature, the model generalizes to any temperature, in theory. Most simulators assume a certain fixed temperature[6]; in the likely case this is different from the measurement temperature, the model will produce different values from the datasheet. This is expected and correct.


[7]  [8]

Measured at temperature \(\unitsDegC\)


Curve-Fit Result

\(I_S\) \(\unitsA\)
\(R_S\) \(\unitsOmega\)
\(n\)

( so it has the same characteristics, but at temperature \(\unitsDegC\).)

  [9]     

Plot model at temperature \(\unitsDegC\)

 
 
 
 

Notes

This calculator is inspired by the diode-fitting calculator here. I wrote my own version because that one had some issues[10].

The curve-fitting is based on the simple but effective Gauss–Newton algorithm. (It was originally based on a 3rd-party solver using the more advanced Levenberg–Marquardt algorithm, but I had to implement my own because this failed to converge for some inputs.) Stability is really a big concern with this problem, because the value of \(I_S\) especially can be absolutely tiny. This leads to an ill-conditioned Jacobian.

I tried a lot of things, like rescaling and constraining the parameters (didn't help) and taking the log of the current (didn't even work). The single biggest thing that helped with convergence is taking the logarithm of \(I_S\) and \(R_S\) (so i.e., the solver solves for \(\vecinline{\ln{I_S},\ln{R_S},n}\), not \(\vecinline{I_S,R_S,n}\))[11]. Other things I think are a good idea are solving with the \(V_F(I_D)\) instead of \(I_D(V_F)\) model[12] (it's faster and more stable), and computing the Jacobian terms in closed-form. Constraining the step size also seemed to be necessary in some cases.

If this model fails to converge to a reasonable result for a particular diode (in the supported use-case, forward-bias for an actual part), please contact me (links on main page) with the part number and dataset, and I will investigate and try to fix. Thank you!