Diodenkennlinie mit Sourcemeter und Matlab aufnehmen

Loading

Dieses Mal gibt es hier keinen Bericht über die Restauration oder die Vorstellung eines alten Gerätes. Im Rahmen meiner beruflichen Tätigkeit muss ich immer wieder Messaufbauten realisieren und diese nach Möglichkeit automatisieren, um die Messzeiten zu minimieren. Auch die Datenauswertung und das Postprocessing möchte ich immer gerne automatisieren. Dafür gibt es sehr viele unterschiedliche Lösungsansätze. Der Grundansatz ist aber immer gleich. Ein, oder mehrere Messgeräte sind über eine Schnittstelle mit einem Rechner oder Controller verbunden. Auf dem Rechner oder Controller läuft eine Software, die das Messgerät steuert und die gemessenen Daten an den Rechner zurücksendet. Auf dem Rechner werden die Daten dann gespeichert, den Anforderungen entsprechend aufbereitet und ausgegeben.

Die Schnittstellen zwischen Rechner und Messtechnik können je nach Ausstattung des Messgerätes dabei RS232, GPIP, IEEE1394, USB oder LAN sein. Bei vielen Geräten wird der einfache SCPI-Befehlssatz im ASCII Code zum Befehle senden und empfangen über das entsprechende Protokoll der gewählten Schnittstelle verwendet. Die Software am Rechner oder Controller muss in der Lage sein die Hardware anzusprechen und schon kann eine Datenkommunikation hergestellt werden. Als Software oder Skriptsprache kann hier beispielsweise NI-LabVIEW, Matlab, C-Code, C++ Code, C#, Python, etc. verwendet werden. Und die Rechner- oder Controllerhardware kann ein Windows, Mac, oder LinuxPC sein, aber auch ein einfacher Arduino, RaspberryPi, oder ein programmierter Mikro-Controller, der eine der benötigten Schnittstelleninterfaces besitzt.

Bei meiner Arbeit wird das gerne mit Matworks Matlab gemacht (bzw. ich mache es gerne mit Matlab, weil ich Programme und Skripten lieber tippe als sie zu zeichnen 😀 ), einer skriptorientierten Software. Im konkreten Beispiel habe ich ein SOURCEMETER des Herstellers Keithley, das Keithley2400 über die RS232 Schnittstelle an einem WIN10 PC mit Matlab 2017b angesteuert. Das Sourcemeter hat die Aufgabe eine Diodenkennlinie aufzunehmen. Das Sourcemeter ist imstande einen Strom zu sourcen, also eine steuerbare Stromquelle zu sein und gleichzeitig den gesourcten Strom und die an den Klemmen anliegende Spannung zu messen. Umgekehrt wiederum kann es auch als steuerbare Spannungsquelle eingesetzt werden, die Spannung an den Klemmen und den Strom durch den DUT (Device Under Test) messen.  Und das geht in allen vier Quadranten, also Stromquelle oder -Senke, oder Spannungsquelle oder -Senke sein.

Genau das benötigte ich in diesem supereinfachen Beispiel um die Kennlinie eines PN-Überganges aufzunehmen und zwar vom Diffusionsbereich bis in den Durchlassbereich und natürlich auch wenn der PN-Übergang unter Photonenbeschuss steht 🙂

Die folgenden beiden Matlab-Skripten ermöglichen diese einfache Kennlinienaufnahme. Der Messaufbau selbst besteht lediglich aus einer, an die Klemmen des K2400 angeschlossenen Diode (in diesem Fall eine Photozelle). Dabei stellt das erste Skript eine gesteuerte Stromquelle dar und im zweiten Skript wird die Spannungsquelle durchgesteuert und jeweils die Daten aufgezeichnet und zum Schluss als Plot dargestellt.

 Matlab Code stromgetrieben:

% IV Logger PN Kennlinie
% 2.05.2019 ingmarsretro
% der supereasysimple-code
% drive current and measure voltage
% with sourcemter über RS232 

 serialObject = serial('COM4','BaudRate',19200, 'DataBits',8);   

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Sourcemeter 2400 setup                             %
    % serial config: 8N1, 19200, termchar CR+LF          %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
    fopen(serialObject)
    s.InputBufferSize = 6000;
    fprintf(serialObject,'*RST');
    
    mincurr = -15E-3;  % maximaler negativer strom (load an der Zelle) 
    maxcurr = 10E-4;   % maximaler positiver strom 
    step = 1E-5;       % schrittweite
    

    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % Messgeraet einstellen  %
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % SOURCING ->  CURRENT
    %
    %fprintf(serialObject,':INIT:CONT OFF;:ABOR');
    fprintf(serialObject,':FORM:DATA ASCII');
    fprintf(serialObject,':SOUR:FUNC CURR');
    fprintf(serialObject,':SOUR:CURR:MODE FIX');
    fprintf(serialObject,':SOUR:CURR:RANG 10E-2'); % -> 000.000mA
    fprintf(serialObject,':SOUR:CURR:LEV 0.0'); % -> Starteinstellung 0 A
    
    % MEASUREMENT -> Spannung 
    fprintf(serialObject,':SENS:FUNC "VOLT:DC"');
    fprintf(serialObject,':SENS:VOLT:PROT 8');     % -> compliance 8V
    fprintf(serialObject,':SENS:VOLT:RANG 10E-1'); % -> 0.00000 V
    fprintf(serialObject,':TRIG:COUN 1');
    
    %fprintf(serialObject,':CONF:VOLT:DC');
    
    fprintf(serialObject,':OUTP ON');

        %% Messen und Daten abholen
    count = 1; 
    v(1)=0; i(1)=0;  %init der arrays 
   
       for curr = mincurr:step:maxcurr
           
          strom=num2str(curr);
          command = strcat(':SOUR:CURR:LEV ',{' '},strom);
          fprintf(serialObject,char(command));
         

          fprintf(serialObject,':READ?');
          data=fscanf(serialObject);  % gesamten buffer des device einlesen
          c = strsplit(data,',');          % gelesenen string nach ',' in zellen zerlegen
          i(count) = str2num(cell2mat(c(2)));                 % stromzelle 
          v(count) = str2num(cell2mat(c(1)));                 % spannungszelle
        

        count = count +1;
       end
   
    
    figure(1);
    plot(v,i);
    grid on; hold on;
    xlabel('voltage [V]'); ylabel('current [A]')
    title('IV - Kennlinie ');
    
    %% instrument in local mode schalten
    fprintf(serialObject,':OUTP OFF');
    fprintf(serialObject,'SYSTEM:LOCAL');
    fclose(serialObject);

 

Matlab Code spannungsgetrieben:

% IV Logger PN Kennlinie
% 3.05.2019 ingmarsretro
% der supereasysimple-code
% drive current and measure voltage
% wit sourcemter über RS232 

 serialObject = serial('COM4','BaudRate',19200, 'DataBits',8);   

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Sourcemeter 2400 setup                             %
    % serial config: 8N1, 19200, termchar CR+LF          %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
    fopen(serialObject)
    s.InputBufferSize = 6000;
    fprintf(serialObject,'*RST');
    
    minvolt = -1;      % maximale negative spannung  
    maxvolt = 0.5;       % maximale positive spannung
    
    %mincurr = -20E-3;  % maximaler negativer strom (load an der Zelle) 
    %maxcurr = 10E-4;   % maximaler positiver strom 
    
    step = 1E-2;       % schrittweite
    
    % 
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % Messgeraet einstellen  %
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % SOURCING ->  VOLTAGE
    %
    %fprintf(serialObject,':INIT:CONT OFF;:ABOR');
    fprintf(serialObject,':FORM:DATA ASCII');
    fprintf(serialObject,':SOUR:FUNC VOLT');
    fprintf(serialObject,':SOUR:VOLT:MODE FIX');
    fprintf(serialObject,':SOUR:VOLT:RANG 10E-0');    % -> 00.0000 V
    fprintf(serialObject,':SOUR:VOLT:LEV 0.0');       % -> Starteinstellung 0 V
    
    % MEASUREMENT -> CURRENT 
    fprintf(serialObject,':SENS:FUNC "CURR:DC"');
    fprintf(serialObject,':SENS:CURR:PROT 40E-3');     % -> compliance 10.0000 mA
    fprintf(serialObject,':SENS:CURR:RANG 10E-2');     % -> 0.00000 mA  (muss kleiner als complience sein)
    fprintf(serialObject,':TRIG:COUN 1');
    
    %fprintf(serialObject,':CONF:VOLT:DC');
    
    fprintf(serialObject,':OUTP ON');


        %% Messen und Daten abholen
    count = 1; 
    v(1)=0; i(1)=0;  %init der arrays 
   
       for volt = minvolt:step:maxvolt
           
          spannung=num2str(volt);
          command = strcat(':SOUR:VOLT:LEV ',{' '},spannung);
          fprintf(serialObject,char(command));
           


          fprintf(serialObject,':READ?');
          data=fscanf(serialObject);  % gesamten buffer des device einlesen
          c = strsplit(data,',');          % gelesenen string nach ',' in zellen zerlegen
          i(count) = str2num(cell2mat(c(2)));                 % stromzelle 
          v(count) = str2num(cell2mat(c(1)));                 % spannungszelle
        
        

        count = count +1;
       end
   
    
    figure(1);
    plot(v,i);
    grid on; hold on;
    xlabel('voltage [V]'); ylabel('current [A]')
    title('IV - Kennlinie ');
    
    %% instrument in local mode schalten
    fprintf(serialObject,':OUTP OFF');
    fprintf(serialObject,'SYSTEM:LOCAL');
    fclose(serialObject);

 

Das Ergebnis der beiden Skripten ist der folgende Kennlinienverlauf: