A/DModul seriell auslesen

  • Themenstarter Themenstarter vitra
  • Beginndatum Beginndatum
V

vitra

Hallo,

Ich hab hier ein A/DModul mit 16 Eingangskanäle. Diese möchte nacheinander Auslesen und in eine Exceldatei schrieben. Das schreiben in eine Exceldatei funktioniert super genauso wie die Oberfläche zum Bedienen. Vom Hersteller diese Modul gibts nur ein fertiges Delphi-Programm und dieses liest die richtigen Werte ein. Jetzt habe ich versucht das DelphiProgramm nachzuprogrammieren jedoch funktioniert das Überhaupt nicht. Das Modul wird per USB an den PC angeschlossen und der mitgelieferte Treiber macht daraus einen virtuellen COM-Port.
Zum Auslesen von diesem benutze ich die RxTx-Bilbiothek.
Mein Java-Code(Auschnitt):
Code:
public class USBModul extends Thread
{
    //Variablen
    private Exceldatei Tabelle;
    private String Filename;
    private String Sheetname;
    private long Zeitintervall;
    private long StartZeit;
    private long LaufZeit;
    private long SchlafZeit;
    private double LF1;
    private double LF2;
    private double Temp1;
    private double Temp2;
    private double Strom;
    private long Digitalwert;
    private GUI GUI;
    private String portName;

    private CommPortIdentifier serialPortId;
    private SerialPort serialPort;
    private Boolean serialPortGeoeffnet = false;
    private int Zeit = 1;


    //Konstruktor
    public USBModul(String Datei,String Mappe,long Zeit,String Port,GUI Oberflaeche)
    {
        //Variablen sichern
        Filename=Datei;
        Sheetname=Mappe;
        Zeitintervall=Zeit;
        Tabelle = new Exceldatei(Filename,Sheetname);
        portName=Port;
        GUI=Oberflaeche;
        //COM-Port initialisieren
        initCOMPort();
    }
    public void run()
    {
        //Ausgabe schreiben
        GUI.schreibeAusgabe("Starten der Messung");
        //Läuft bis er unterbrochen wird
        while(!isInterrupted())
        {
            StartZeit = System.currentTimeMillis();
           //Werte einlesen vom Modul
           //Kanal 1 auslesen
                // A/D-Kanal auswählen
                setzenUSBOutput(1);
                // hole Analogwert
                Digitalwert = auslesenUSBAD();
                // Digital zu Strom umrechnen
                Strom = ((65536-Digitalwert) * 25)  / 65536;
                //Leitfähigkeit ausrechnen
                LF1 = Digitalwert;
            //Kanal 2 auslesen
                // A/D-Kanal auswählen
                setzenUSBOutput(2);
                // hole Analogwert
                Digitalwert = auslesenUSBAD();
                // Digital zu Strom umrechnen
                Strom = ((65536-Digitalwert) * 25)  / 65536;
                //Leitfähigkeit ausrechnen
                Temp1 = Digitalwert;
            //Kanal 3 auslesen
                // A/D-Kanal auswählen
                setzenUSBOutput(3);
                // hole Analogwert
                Digitalwert = auslesenUSBAD();
                // Digital zu Strom umrechnen
                Strom = ((65536-Digitalwert) * 25) / 65536;
                //Leitfähigkeit ausrechnen
                LF2 = Digitalwert;
            //Kanal 4 auslesen
                // A/D-Kanal auswählen
                setzenUSBOutput(4);
                // hole Analogwert
                Digitalwert = auslesenUSBAD();
                // Digital zu Strom umrechnen
                Strom = ((65536-Digitalwert) * 25)  / 65536;
                //Leitfähigkeit ausrechnen
                Temp2 = Digitalwert;
            //Tabelle mit Werten füllen
           Tabelle.schreibeWerte(LF1,Temp1,LF2,Temp2);
            //Werte auf Ausgabe schreiben
            GUI.schreibeAusgabe(String.format("%s %s\nLF1:%.3f  Temp.1:%.3f\nLF2:%.3f  Temp.2:%.3f\ndLF:%.3f",
                 Tabelle.aktuellesDatum(),Tabelle.aktuelleZeit(),LF1,Temp1,LF2,Temp2,LF2-LF1));

            LaufZeit = System.currentTimeMillis()- StartZeit;
            SchlafZeit=Zeitintervall-(LaufZeit/1000);
            if(SchlafZeit < 0) SchlafZeit=0;

            try
            {    //Zeit zum Abwarten
                Thread.sleep(SchlafZeit);
            }
            catch(InterruptedException Exc)
            {
                interrupt();
                break;
            }
        }
        //wenn thread beendet wird Ausgabe schreiben und Datei abschliessen
        GUI.schreibeAusgabe("Excel-Datei gespeichert");
        Tabelle.abschlussDatei();
        //Port schliessen
        schliesseSerialPort();
    }

    private void initCOMPort()
    {
        //HashSet Ports = getAvailableSerialPorts();
        if (oeffneSerialPort(portName) != true)
            return;
        if(serialPortGeoeffnet)
        {
                //Port-Werte brauchen nicht gesetzt werden

                //Modul E/A freigeben
                this.freigebenVModul(serialPort);
        }
       try
       {Thread.sleep(1000);}
       catch(InterruptedException e1) {}
    }
    private boolean oeffneSerialPort(String portName)
    {
		Boolean foundPort = false;
                CommPortIdentifier Port;

                //Prüfen ob Port geöffnet ist
		if (serialPortGeoeffnet != false)
                {
			System.out.println("Serialport bereits geöffnet");
			return false;
		}              
		System.out.println("Öffne Serialport");
                //Port suchen
                HashSet Ports=getAvailableSerialPorts();
                Iterator i = Ports.iterator();
		while(i.hasNext())
                {
                        Port =(CommPortIdentifier)i.next();
			if (portName.contentEquals(Port.getName()))
                        {
                                serialPortId=Port;
				foundPort = true;
				break;
			}
		}
		if (foundPort != true)
                {
			System.out.println("Serialport nicht gefunden: " + portName);
			return false;
		}

                // Port öffnen

                try
                {serialPort = (SerialPort) serialPortId.open("TeKo", 1000);} 
                catch (PortInUseException e2)
                {System.out.println("Port belegt");}
		serialPortGeoeffnet = true;
		return true;
	}

    private void schliesseSerialPort()
    {
		if ( serialPortGeoeffnet == true)
                {
			System.out.println("Schließe Serialport");
			serialPort.close();
			serialPortGeoeffnet = false;
		} else
                {System.out.println("Serialport bereits geschlossen");}
    }
    
    private void freigebenVModul(SerialPort Port)
    {
                //VModul E/A freigeben
                
                //EscapeCommFunction(hcomm,CLRBREAK); // TXD = 0
                Port.notifyOnCTS(true);
                Port.notifyOnDSR(true);
                Port.notifyOnOutputEmpty(true);
                Port.notifyOnBreakInterrupt(false);
                Port.setDTR(false);
                Port.setRTS(false);
                try
                {Thread.sleep(10*Zeit);}
                catch(InterruptedException e3)
                {System.out.println("Schlafen geht nicht.");}
                for ( int n = 0; n < 7; n++)
                {
                Port.setDTR(false);
                Port.setRTS(true);
                try
                {Thread.sleep(10*Zeit);}
                catch(InterruptedException e4)
                {System.out.println("Schlafen geht nicht.");}
                Port.setDTR(false);
                Port.setRTS(false);
                }
                try
                {Thread.sleep(10*Zeit);}
                catch(InterruptedException e5)
                {System.out.println("Schlafen geht nicht.");}
        }

    private void setzenUSBOutput(int Kanal)
    {
        serialPort.setRTS(true);
        try
        {Thread.sleep(2*Zeit);}
        catch(InterruptedException e6)
        {System.out.println("Schlafen geht nicht.");}

        if ((Kanal & 1)==1)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 2)==2)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 4)==4)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 8)==8)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 16)==16)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 32)==32)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 64)==64)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        if ((Kanal & 128)==128)
            setzenDTR();
        else ruecksetzenDTR();
        clockusb();
        try
        {Thread.sleep(2*Zeit);}
        catch(InterruptedException e7)
        {System.out.println("Schlafen geht nicht.");}
        serialPort.setRTS(false);	// Übergabe wenn low
        try
        {Thread.sleep(2*Zeit);}
        catch(InterruptedException e14)
        {System.out.println("Schlafen geht nicht.");}
    }

    private void clockusb()
    {
        String b = "";
        OutputStream out;

        try {
        out = serialPort.getOutputStream();
        out.write(b.getBytes());
        out.flush();
        out.close();
	} 
        catch (IOException e8)
        {
            System.out.println("Es konnte nichts rausgeschrieben werden.");
        }

        try // delay min. 7 ms
        {Thread.sleep(16*Zeit);}
        catch(InterruptedException e9)
        {System.out.println("Schlafen geht nicht.");}
    }

    private void setzenDTR()
    {
        serialPort.setDTR(true);
        try
        {Thread.sleep(1*Zeit);}
        catch(InterruptedException e10)
        {System.out.println("Schlafen geht nicht.");}
    }

    private void ruecksetzenDTR()
    {
        serialPort.setDTR(false);
        try
        {Thread.sleep(1*Zeit);}
        catch(InterruptedException e11)
        {System.out.println("Schlafen geht nicht.");}
    }

    // lesen des A/D-Eingang
    private long auslesenUSBAD()
    {
        long	value;
        int zahl;
        value = 0;
        zahl = 1;
        // Latch den Messwert in 16bit Speicher vom Modul
        this.setzenDTR();
        this.ruecksetzenDTR();
        serialPort.setRTS(true);
        serialPort.setRTS(false);
        // jetzt A/D-Wert von Latch-Register seriell einscannen
        for ( int i = 0; i < 16;)
        {
            try
            {Thread.sleep(5*Zeit);}
            catch(InterruptedException e13)
            {System.out.println("Schlafen geht nicht.");}

            if (!serialPort.isCTS())
                value += zahl;

            try
            {Thread.sleep(5*Zeit);}
            catch(InterruptedException e18)
            {System.out.println("Schlafen geht nicht.");}
            clockusb();
            zahl <<= 1;
            i++;
        }
        return value;  // Digitalwert zurückgeben
    }
}
Der Delphi-Code den ich versucht habe umzuschreiben
Code:
//======================================================================
// Liefert Ergebnis von Handshake-Signalen der ser.COM zurück
function GetInCount(hcomm : Thandle):DWORD;
var   com_status     : DWORD;
begin
 Result := 0;
	if hcomm <> INVALID_HANDLE_VALUE then
        begin
         GetCommModemStatus(hcomm,com_status);
         Result := com_status
        end;
end;

//======================================================================
// RS232 bit-operationen  (USB über virtuellen COM-Port)
procedure vm_freeall(hcomm : Thandle); // Modul freigeben für RS232
var n : byte;
begin
EscapeCommFunction(hcomm,CLRBREAK); // TXD = 0
EscapeCommFunction(hcomm,CLRDTR);   // DTR = 0
EscapeCommFunction(hcomm,CLRRTS);   // RTS = 0
sleep(10);
For n := 0 to 7 do
begin
EscapeCommFunction(hcomm,CLRDTR);   // DTR = 0
EscapeCommFunction(hcomm,SETRTS);   // RTS = 1
sleep(10);
EscapeCommFunction(hcomm,CLRDTR);   // DTR = 0
EscapeCommFunction(hcomm,CLRRTS);   // RTS = 0
end;
end;

procedure clock(hcomm : Thandle);
var       dwCharsWritten : DWORD;
begin
WriteFile(hcomm, PChar('')^, 1, dwCharsWritten, nil);
sleep(16);                                      // delay min. 6 ms 
end;

procedure clockusb(hcomm : Thandle);
var       dwCharsWritten : DWORD;
begin
WriteFile(hcomm, PChar('')^, 1, dwCharsWritten, nil);
sleep(16);                                      // delay
end;

procedure set_data(hcomm : Thandle);
begin
EscapeCommFunction(hcomm,SETDTR);             // DTR auf HIGH setzen
sleep(2);                                      // delay
end;

procedure res_data(hcomm : Thandle);
begin
EscapeCommFunction(hcomm,CLRDTR);             // DTR auf LOW setzen
sleep(2);                                      // delay
end;
// lesen der Eingänge
function get_vmadbyte(hcomm : Thandle):word;stdcall;export;
var zahl      : word;
    i         : byte;
    value     : word;
    inp_comstat : word;
begin
value := 0;
zahl := 1;
// Latch Messwert in 16bit Speicher (ISP1032)
EscapeCommFunction(hcomm,SETDTR);
sleep (1);
EscapeCommFunction(hcomm,CLRDTR);
for i := 0 to 15 do
 begin
sleep (3);
 inp_comstat := GetInCount(hcomm);
 if (inp_comstat AND 16 = 16) then value := value + zahl;
 clock(hcomm);
 zahl := zahl shl 1;
 end;
get_vmadbyte := word(value);
end;
//======================================================================
function getok_vm2(hcomm:Thandle):word;stdcall;export;
var       ok1, ok2, ok3, ok4, ok_all : byte;
          inp_comstat                : Dword;
begin
// TEST 1 : SW3
EscapeCommFunction(hcomm,CLRRTS);             // (Freigabe) WR=0
EscapeCommFunction(hcomm,CLRDTR);             // DTR DIN=0
sleep(5);
inp_comstat := GetInCount(hcomm);                  // byte COM-STATUS ID lesen
if (inp_comstat AND 32 <> 32) then ok1 := 1 else ok1 := 0;
// TEST2 : SW4
EscapeCommFunction(hcomm,SETRTS);             // (Freigabe) WR=1
EscapeCommFunction(hcomm,CLRDTR);             // DTR DIN=0
sleep(5);
inp_comstat := GetInCount(hcomm);                  // byte COM-STATUS ID lesen
if (inp_comstat AND 32 = 32) then ok2 := 1 else ok2 := 0;
// TEST3 : VCC
EscapeCommFunction(hcomm,SETRTS);             // (Freigabe) WR=1
EscapeCommFunction(hcomm,SETDTR);             // DTR DIN=1
sleep(5);
inp_comstat := GetInCount(hcomm);                  // byte COM-STATUS ID lesen
if (inp_comstat AND 32 = 32) then ok3 := 1 else ok3 := 0;
// TEST4 : DATA
EscapeCommFunction(hcomm,CLRRTS);             // (Freigabe) WR=0
EscapeCommFunction(hcomm,SETDTR);             // DTR DIN=1
sleep(5);
inp_comstat := GetInCount(hcomm);                  // byte COM-STATUS ID lesen
if (inp_comstat AND 32 = 32) then ok4 := 1 else ok4 := 0;
ok_all := (ok1*1) + (ok2*2) + (ok3*4) + (ok4*8);
if (ok_all <> 15) then
begin
MessageDlg('COM-Problem oder Modul ist nicht betriebsbereit !', mtInformation, [mbOk], 0);
end;
getok_vm2 := ok_all;
end;

//======================================================================
// Übergabe A/D-Kanal-Auswahl
procedure set_usbmux(hcomm : Thandle; x_word : word);stdcall;export;
begin
EscapeCommFunction(hcomm,SETRTS);             // auf HIGH für Send Data
sleep(2);
if ((x_word AND 1)=1) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 2)=2) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 4)=4) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 8)=8) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 16)=16) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 32)=32) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 64)=64) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
if ((x_word AND 128)=128) then set_data(hcomm) else res_data(hcomm);
clockusb(hcomm);
sleep(2);
EscapeCommFunction(hcomm,CLRRTS);              // Übergabe wenn low
sleep(2);
end;


// lesen der Eingänge
function get_usbad(hcomm : Thandle):word;stdcall;export;
var zahl      : word;
    i         : byte;
    value     : word;
    inp_comstat : word;
begin
value := 0;
zahl := 1;
EscapeCommFunction(hcomm,SETDTR);
EscapeCommFunction(hcomm,CLRDTR);
EscapeCommFunction(hcomm,SETRTS);
EscapeCommFunction(hcomm,CLRRTS);
for i := 0 to 15 do
 begin
 sleep(3);                                      // delay
 inp_comstat := GetInCount(hcomm);
 if (inp_comstat AND 16 = 16) then value := value + zahl;
 sleep(3);                                      // delay
 clockusb(hcomm);
 zahl := zahl shl 1;
 end;
get_usbad := word(value);
end;

Kann jemand mal schauen ob Da irgendein Fehler gemacht habe? Wenn jemand keinen finde, gibt es eine Möglichkeit das ich diesen Delphi-Code irgendwie extern über Java aufrufe? Ich hab irgendwas von JNA und JNI gelesen bloss da kenn ich mich nicht so aus wie ich da was machen muss. Außerdem wäre direkt programmieren performanter oder?
Danke im Vorraus für die Hilfe


vitra
 
Zurück