Diode Circuit Analysis
From Wikimization
(Difference between revisions)
Line 1: | Line 1: | ||
[[Image:Diode.jpg|850px]] | [[Image:Diode.jpg|850px]] | ||
+ | [[Image:Cyclic.jpg|850px]] | ||
<pre> | <pre> | ||
function [vl Cdmax Cdmin Cdmed] = diodeMap(vi, Rs, Rl, verbose, fundfreq, Fs, precision) %from Convex Optimization & Euclidean Distance Geometry | function [vl Cdmax Cdmin Cdmed] = diodeMap(vi, Rs, Rl, verbose, fundfreq, Fs, precision) %from Convex Optimization & Euclidean Distance Geometry |
Current revision
function [vl Cdmax Cdmin Cdmed] = diodeMap(vi, Rs, Rl, verbose, fundfreq, Fs, precision) %from Convex Optimization & Euclidean Distance Geometry mp.Digits(precision); %Advanpix MCT k = 1.380649e-23; %boltzmann constant % https://www.nist.gov/si-redefinition/kelvin-boltzmann-constant T = 298; %temperature kelvin %Neudeck p.5 q = 1.602176634e-19; %electron charge %NIST is = 76.9e-12; %circuitlab diodeInduced eta = 1.45; %circuitlab diodeInduced tau = 4.32e-6; %transport time. max exponent (observed) e-4. Increasing capacitance observes more nonlinearity in vL FFT. Rd = 0.042; %diode internal resistance nVt = eta*k*T/q; %[V] thermal voltage for particular diode characterized by eta isR = is*(Rs*Rl/(Rs + Rl) + Rd); dvd = 1000*randn(size(vi)); %perturbation of derivative proves that iteration converges to same median capacitance for i=1:5 %3 iterations will introduce randomness into mean impedance calculation Lw = exp((isR + vi*Rl/(Rl + Rs))/nVt)*isR.*(1 + tau*dvd/nVt)/nVt; vd = isR - nVt*Lambert_W(Lw) + vi*Rl/(Rl + Rs); dvd = [vd(2)-vd(end); vd(3:end)-vd(1:end-2); vd(1)-vd(end-1)]/2; %approximate the derivative first time around, otherwise dvd becomes near 0. Assumes periodicity. if verbose Cd = tau*is*exp(vd/nVt)/nVt; Cdmed = median(Cd); disp([num2eng(Cdmed,false,false,false,16) ' farad']); end end if verbose Cdmax = max(Cd); Cdmin = min(Cd); figure(20); plot(0:numel(Cd)-1, Cd); title('Cd over time'); xlabel('sample number'); ylabel('Farad'); set(get(gca,'ylabel'),'rotation',0); drawnow else Cd = tau*is*exp(vd/nVt)/nVt; end iC = Cd.*dvd*Fs; %diffusion capacitor current. Normalization by Fs makes current independent of sample rate id = is*(exp(vd/nVt) - 1); %ideal Shockley equation. This is already independent of Fs. vl = (id + iC)*Rd + vd; if verbose figure(21); plot(0:numel(iC)-1, iC); title('Cd current'); xlabel('sample number'); ylabel('Amp'); set(get(gca,'ylabel'),'rotation',0); figure(22); plot(0:numel(id)-1, id); title('diode current'); xlabel('sample number'); ylabel('Amp'); set(get(gca,'ylabel'),'rotation',0); idx = find(iC ~= 0); disp(['mean capacitor impedance = ' num2str(orosumvec(vd(idx)./iC(idx),1)/numel(idx),'%3.4e')]) % disp(['mean capacitor |impedance| = ' num2str(orosumvec(abs(vd(idx)./iC(idx)),1)/numel(idx),'%3.4e')]) t = median(vd./iC); if t < 0, spc=[]; else spc=' '; end disp(['median capacitor impedance =' spc num2str(t)]) %median impedance is always far smaller than mean despite mp.Digits precision medcapimp = median(abs(vd./iC)); disp(['median capacitor |impedance| = ' num2str(medcapimp,'%3.4e')]) disp(['empirical constant c = ' num2str(medcapimp*(2*pi*fundfreq*Cdmed),'%3.15e')]) figure(23); histogram(Cd,50,'Normalization','probability'); %for book illustration % histogram(Cd,round(3.25*48000)); %for counting smallest diffusion capacitors title('histogram C_d'); xlabel('bin'); ylabel('relative count'); %set(get(gca,'ylabel'),'rotation',0); drawnow end end % https://www.mathworks.com/matlabcentral/fileexchange/43419-the-lambert-w-function function w = Lambert_W(x,branch) % Lambert_W Functional inverse of x = w*exp(w). % w = Lambert_W(x), same as Lambert_W(x,0) % w = Lambert_W(x,0) Primary or upper branch, W_0(x) % w = Lambert_W(x,-1) Lower branch, W_{-1}(x) % % See: http://blogs.mathworks.com/cleve/2013/09/02/the-lambert-w-function/ % Effective starting guess if nargin < 2 || branch ~= -1 w = ones(size(x)); % Start above -1 else w = -2*ones(size(x)); % Start below -1 end v = inf*w; % Halley's method c = 0; limit = 100; while any(abs(w - v)./abs(w) > 1e-15) && c < limit %changed magic tolerance. Was 1e-8. -JonD v = w; e = exp(w); f = w.*e - x; % Iterate, to make this quantity zero w = w - f./((e.*(w+1) - (w+2).*f./(2*w + 2))); c = c + 1; end if c >= limit disp('%%%%%%%%%%%%%%%%%%%%%% Warning: Lambert limit reached %%%%%%%%%%%%%%%%%%%%%') end end