% Digitek DT80000 Multimeter - Auswertung
%
% Stefan Heindel,               29.01.2010
%
% Zum Format: Das Multimeter wird mit einem Standard-RS232-Kabel an den PC
% angeschlossen. Die Schnittstelleneinstellungen sind 9600-8-N-1
% Wichtig: RTS (Ready to Send) muss per Software UNBEDINGT aktiviert
% werden, das braucht der Optokoppler im Meßgerät. Das Meßgerät schickt
% Echos für jedes Kommando. Ein "richtiges" Datenpaket sendet das
% Multimeter nur, wenn 0x89h gesendet wird. RS232 muss im Display angezeigt
% sein. Manchmal kommt es vor, dass es nicht funktioniert, dann das
% Meßgerät einfach nochmal aus- und anschalten.
%
%Aufbau des Byte-Blocks:
%
%Es werden insgesamt 12 Bytes empfangen, wenn 89h gesendet wird.
%
%1.Byte: Echo
%           0x89h             Echo des gesendeten Kommandos
%2.Byte: Modus                
%           [6..4]            Drehschalter-Position                
%           [2..0]            Modus, der mit "Select" ausgewählt wird.
%                             Für die meisten Drehschalterpositionen
%                             versch.
%3.Byte: Skalierung
%           [5..3]            Zehnerpotenz der Meßwerte, für die meisten
%                             Modi verschieden
%                             Für Frequenz-Ausgang: Bits 6:3 stellen die 
%                             einzelnen Stufen dar    
%4.Byte: Leer                 Platzhalter?! Funktion nicht geklärt.
%           0x81h             Scheint sich jedoch nicht zu ändern
%5.Byte:    [6]               Hat eine Funktion, aber welche?
%                             Wer die Antwort kennt kriegt ein Wassereis!
%           [4]               Vorzeichen:    0 = +       1 = -
%           [3]               Überlauf (O.L.)
%6.Byte:                      Höchstes Digit in ASCII
%7.Byte:                      ..
%8.Byte:                      ..
%9.Byte:                     ..
%10.Byte:                     Niedrigstes Digit in ASCII
%11.Byte:                     Checksumme(?) - Auch hier gibts wieder
%                             Wassereis!
%12.Byte: LineFeed
%           0x10h


function [a,b,c] = getMultimeterData(port)
    s = openDT80000(port);
    
    while(true)
        fwrite(s,hex2dec('89'));            % Zeichen senden

        try
            [raw,n] = fread(s,12,'char');
        catch
        end
        err = false;
        if (n ~= 12)
                err = true;
                disp('Kommunikationsfehler: Nicht genügend Zeichen empfangen')
            elseif(raw(1) ~= hex2dec('89'))
                err = true;
                disp('Kommunikationsfehler: Unerwartetes Startbyte empfangen')
        elseif(raw(12) ~= hex2dec('0A'))
                err = true;
                disp('Kommunikationsfehler: Kein korrektes LF empfangen')  
        end

        if (err == false)             % Prüfungen bestanden
           assignin('base','raw',raw)
            digits = str2num(char(raw(6:10)'));                             %Zahlen extrahieren
            
            mode  = bitshift(bitand(raw(2),bin2dec('01111000')),-3);        %[6..3] Extrahieren: Modus
            sub   = bitshift(bitand(raw(2),bin2dec('00000111')), 0);        %[3..1] Extrahieren: Submodus
            scale = bitshift(bitand(raw(3),bin2dec('00111000')),-3);        %[5..3] Extrahieren: Skalierung (Exponent)
            
            if (bitget(raw(5),5) == false)                                  %[4]    Extrahieren: Vorzeichenbit
                sign = 1;
            else
                sign = -1;
            end
            
            if (bitget(raw(5),4) == false)                                  %[4]    Extrahieren: Überlauf
                over = 1;
            else
                over = inf;
            end 
                       
            switch (mode)
                case 4,
                    name = 'Out';
                    unit = 'Hz';
                    pres = 1;                                               % Macht hier nicht so viel Sinn
                case 5,
                    name = 'A =';                   
                    unit = 'A';
                    pres = 1e-4;
                case 6,
                    name = 'mA';
                    unit = 'mA';
                    pres = 1e-3;
                case 7,                                                     % Fall 7 gibt es wohl nicht :)
                    name = '?';             
                    unit = '?';
                    pres = 1;
                case 8,
                    name = 'Temp';
                    unit = '°C';
                    pres = 1e-3;
                case 9,
                    name = 'Cap';
                    unit = 'µF';
                    pres = 1e-1;
                case 10,
                    name = 'Freq';
                    unit = 'Hz';
                    pres = 1e-3;
                case 11,
                    name = 'Diode';
                    unit = 'V';
                    pres = 1e-4;
                case 12,
                    name = 'Ohm';
                    unit = 'Ohm';
                    pres = 1e-2;
                case 13,
                    name = 'mV';
                    unit = 'mV';
                    pres = 1e-3;
                case 14,
                    name = 'V';
                    unit = 'V';
                    pres = 1e-4;
                case 15,
                    name = 'V ~';
                    unit = 'V';
                    pres = 1e-4;
            end
            
           value = sign * digits * pres * 10^scale * over;        
           
           text = sprintf('Wert: %f %s',value,unit);
           disp(text) 
        end
    end
end

function [s] = openDT80000(port)
    
    try
        fclose(s);
        clear s;
    catch
    end

    s = serial(port);
    set(s,'BaudRate',9600);
    set(s,'Terminator','LF');
    s.RequestToSend = 'on';
    fopen(s);
    assignin('base','s',s)
end
    
