• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Paul A. Bristow 2016
2 // Copyright John Z. Maddock 2016
3 
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or
6 //  copy at http ://www.boost.org/LICENSE_1_0.txt).
7 
8 /*! brief Example of using Lambert W function to compute current through a diode connected transistor with preset series resistance.
9   \details T. C. Banwell and A. Jayakumar,
10   Exact analytical solution of current flow through diode with series resistance,
11   Electron Letters, 36(4):291-2 (2000)
12   DOI:  doi.org/10.1049/el:20000301
13 
14   The current through a diode connected NPN bipolar junction transistor (BJT)
15   type 2N2222 (See https://en.wikipedia.org/wiki/2N2222 and
16   https://www.fairchildsemi.com/datasheets/PN/PN2222.pdf Datasheet)
17   was measured, for a voltage between 0.3 to 1 volt, see Fig 2 for a log plot,
18   showing a knee visible at about 0.6 V.
19 
20   The transistor parameter isat was estimated to be 25 fA and the ideality factor = 1.0.
21   The intrinsic emitter resistance re was estimated from the rsat = 0 data to be 0.3 ohm.
22 
23   The solid curves in Figure 2 are calculated using equation 5 with rsat included with re.
24 
25   http://www3.imperial.ac.uk/pls/portallive/docs/1/7292572.PDF
26 */
27 
28 #include <boost/math/special_functions/lambert_w.hpp>
29 using boost::math::lambert_w0;
30 
31 #include <iostream>
32 // using std::cout;
33 // using std::endl;
34 #include <exception>
35 #include <stdexcept>
36 #include <string>
37 #include <array>
38 #include <vector>
39 
40 /*!
41 Compute thermal voltage as a function of temperature,
42 about 25 mV at room temperature.
43 https://en.wikipedia.org/wiki/Boltzmann_constant#Role_in_semiconductor_physics:_the_thermal_voltage
44 
45 \param temperature Temperature (degrees centigrade).
46 */
v_thermal(double temperature)47 const double v_thermal(double temperature)
48 {
49   constexpr const double boltzmann_k = 1.38e-23; // joules/kelvin.
50   const double charge_q = 1.6021766208e-19; // Charge of an electron (columb).
51   double temp =+ 273; // Degrees C to K.
52   return boltzmann_k * temp / charge_q;
53 } // v_thermal
54 
55 /*!
56 Banwell & Jayakumar, equation 2
57 */
i(double isat,double vd,double vt,double nu)58 double i(double isat, double vd, double vt, double nu)
59 {
60   double i = isat * (exp(vd / (nu * vt)) - 1);
61   return i;
62 } //
63 
64 /*!
65 
66 Banwell & Jayakumar, Equation 4.
67 i current flow = isat
68 v voltage source.
69 isat reverse saturation current in equation 4.
70 (might implement equation 4 instead of simpler equation 5?).
71 vd voltage drop = v - i* rs  (equation 1).
72 vt  thermal voltage, 0.0257025 = 25 mV.
73 nu junction ideality factor (default = unity), also known as the emission coefficient.
74 re intrinsic emitter resistance, estimated to be 0.3 ohm from low current.
75 rsat reverse saturation current
76 
77 \param v Voltage V to compute current I(V).
78 \param vt Thermal voltage, for example 0.0257025 = 25 mV, computed from boltzmann_k * temp / charge_q;
79 \param rsat Resistance in series with the diode.
80 \param re Intrinsic emitter resistance (estimated to be 0.3 ohm from the Rs = 0 data)
81 \param isat Reverse saturation current (See equation 2).
82 \param nu Ideality factor (default = unity).
83 
84 \returns I amp as function of V volt.
85 
86 */
iv(double v,double vt,double rsat,double re,double isat,double nu=1.)87 double iv(double v, double vt, double rsat, double re, double isat, double nu = 1.)
88 {
89   // V thermal 0.0257025 = 25 mV
90   // was double i = (nu * vt/r) * lambert_w((i0 * r) / (nu * vt)); equ 5.
91 
92   rsat = rsat + re;
93   double i = nu * vt / rsat;
94   std::cout << "nu * vt / rsat = " << i << std::endl; // 0.000103223
95 
96   double x = isat * rsat / (nu * vt);
97   std::cout << "isat * rsat / (nu * vt) = " << x << std::endl;
98 
99   double eterm = (v + isat * rsat) / (nu * vt);
100   std::cout << "(v + isat * rsat) / (nu * vt) = " << eterm << std::endl;
101 
102   double e = exp(eterm);
103   std::cout << "exp(eterm) = " << e << std::endl;
104 
105   double w0 = lambert_w0(x * e);
106   std::cout << "w0 = " << w0 << std::endl;
107   return i * w0 - isat;
108 
109 } // double iv
110 
111 std::array<double, 5> rss = {0., 2.18, 10., 51., 249};  // series resistance (ohm).
112 std::array<double, 8> vds = { 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 };  // Diode voltage.
113 
main()114 int main()
115 {
116   try
117   {
118     std::cout << "Lambert W diode current example." << std::endl;
119 
120     //[lambert_w_diode_example_1
121     double x = 0.01;
122     //std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.00990147
123 
124     double nu = 1.0;                  // Assumed ideal.
125     double vt = v_thermal(25);        // v thermal, Shockley equation, expect about 25 mV at room temperature.
126     double boltzmann_k = 1.38e-23;    // joules/kelvin
127     double temp = 273 + 25;
128     double charge_q = 1.6e-19;        // column
129     vt = boltzmann_k * temp / charge_q;
130     std::cout << "V thermal "
131        << vt << std::endl;            // V thermal 0.0257025 = 25 mV
132     double rsat = 0.;
133     double isat = 25.e-15;            //  25 fA;
134     std::cout << "Isat = " << isat << std::endl;
135 
136     double re = 0.3;  // Estimated from slope of straight section of graph (equation 6).
137 
138     double v = 0.9;
139     double icalc = iv(v, vt, 249., re, isat);
140 
141     std::cout << "voltage = " << v << ", current = " << icalc << ", " << log(icalc) << std::endl; // voltage = 0.9, current = 0.00108485, -6.82631
142  //] [/lambert_w_diode_example_1]
143   }
144   catch (std::exception& ex)
145   {
146     std::cout << ex.what() << std::endl;
147   }
148 }  // int main()
149 
150 /*
151    Output:
152 //[lambert_w_output_1
153    Lambert W diode current example.
154    V thermal 0.0257025
155    Isat = 2.5e-14
156    nu * vt / rsat = 0.000103099
157    isat * rsat / (nu * vt) = 2.42486e-10
158    (v + isat * rsat) / (nu * vt) = 35.016
159    exp(eterm) = 1.61167e+15
160    w0 = 10.5225
161    voltage = 0.9, current = 0.00108485, -6.82631
162 
163 //] [/lambert_w_output_1]
164 */
165 
166