zur navigation

19. September 2011 Veröffentlicht von Heinrich in : Technik , einen kommentar schreiben

H-TRONIC USB Datenerfassungssystem per JAVA (HB627)

H-TRONIC USB 12-Bit-Datenerfassungssystem Baustein (Quelle: Google)

H-TRONIC USB 12-Bit-Datenerfassungssystem Baustein (Quelle: Google)

H-TRONIC USB 12-Bit-Datenerfassungssystem (HB627) mit JAVA steuern

Update 18.03.2012: Absturzursache behoben (falls nicht alle Bytes empfangen wurden und die ArrayList nicht die erwartete Länge bekam). Der Code hier im Artikel wurde dementsprechend auch aktualisiert.

Mit dieser Platine kann man 8 verschiedene analoge Signale im Spannungsbereich von 0 bis 4095 mV messen. Dies tut die Karte im Grunde auch sehr zuverlässig, jedoch kann man sich, gerade als JAVA-Nutzer, an einigen Ecken der Lieferung ärgern. Dazu später mehr.

Das Prinzip

Wir senden eine Byte-Folge an die Karte (Befehl) und erhalten die aktuellen Spannungswerte als Antwort zurück. Laut Handbuch geht das 300x in der Sekunde, bei mir läuft die Karte allerdings erst bei höchstens 75 Abfragen in der Sekunde stabil, was aber (im Grunde)* immer noch sehr schnell ist.

Pro-Argumente

  • Messungen (im Grunde)* sehr genau
  • Arbeitet (im Grunde)* sehr schnell
  • Gute Verarbeitung

Contra-Argumente

  • (*) Nur unter ideal-Voraussetzungen: Wenn an einem Kontakt kein geschlossener Stromkreis mit einer gewissen Spannung anliegt, so bekommt man für diesen Kontakt einen „Zufallswert“ als Spannung geliefert. So muss man durch eine Messreihe unerwünschte Messergebnisse erfassen und rausfiltern. Das erhöht den Arbeitsaufwand für einen brauchbare Messreihe. Dieser Fehler der Karte ist besonders ärgerlich, wenn man (wie ich) eben messen will, ob ein Stromkreis geschlossen oder offen ist.
  • Kein Stecker mitgeliefert
  • Karte kann nicht Kaskadiert werden (mehrere in „Reihe“ schalten und über einen USB-Port steuern)
  • Handbuch / Dokumentation sehr mager
Mitgeliefertes Beispielprogramm: Liegt keine Spannung an, so erhalten wir willkürliche Spannungswerte. An Kontakt 8 liegt eine konstante Spannung an.

Mitgeliefertes Beispielprogramm: Liegt keine Spannung an, so erhalten wir willkürliche Spannungswerte. An Kontakt 8 liegt eine konstante Spannung an.

.

Anwendung der JAVA-Klasse

Die im folgenden beschriebene JAVA-Klasse braucht KEINE „Idealvoraussetzungen“ (wie unter Contra (*) beschrieben). Der Preis dafür ist lediglich, dass die Abfrage etwas länger dauert. Das Prinzip: Es werden mehrere Messungen (cfg: „newLaps“) unmittelbar hintereinander ausgeführt und verglichen: Sind stark schwankende Werte gemessen worden, so geht die Klasse davon aus, dass dort keine Spannung anliegt (es werden willkürliche Messwerte gesendet, ein Bug der Mess-Karte!). Bewegen sich die Schwankungen allerdings innerhalb eines bestimmten Intervalls (cfg: „newTolerance“), so wird diese Spannung als richtig bzw. zuverlässig interpretiert. Ferner kann man einstellen, welche Spannung mindestens anliegen muss, um als richtig gewertet zu werden. Die im unteren Beispiel verwendete Konfigurationseinstellung hat bei mir mit (wahrscheinlich)** 100%iger Genauigkeit die richtigen Messwerte geliefert.

(** Nach tausenden Messdurchläufen keine Abweichung der Messwerte von den realen Umständen)

Zunächst müssen wir bei Nutzung von Windows 7 die RXTXcomm.jar eingebunden haben. Wie das geht, könnt ihr im Artikel zur Relaiskarte nachlesen. Danach können wir die Klassen verwenden. Hier einen kleinen Crashkurs zu meiner Klasse:

public class Main {	
	public static void main (String args[]) {
 
		//VERBINDUNG AUFBAUEN
		HB627 hb627 = new HB627("COM19");
 
                //KLASSE KONFIGURIEREN
		//hb627.setCfg(newSleepTime, newLaps, newTolerance, newMinimumMV);
		//STANDARDEINSTELLUNGEN:
		//newLaps = 5; //Wieviele Messrunden soll eine Messung (ein Race) surchlaufen, bevor entschieden wird, ob der Port einen zuverlässigen Wert übermittelt hat? (je mehr, desto zuverlässiger); Wert = 1 setzen, wenn keine Messreihe vorgenommen werden soll, sondern im "klassischen" Sinne gemessen werden soll
		//newTolerance = 25; //in mV. Wie hoch darf die Durchschnitts-Differenz zwischen den Messrunden-Werten eines einzelnen Mess-Ports höchstens sein, um noch als zuverlässiges Ergebnis eingestuft zu werden.
		//newSleepTime = 16; //Wie lange soll nach jedem Kommando (nach jeder Runde [lap]) gewartet werden?
		//newMinimumMV = 1500; //Welchen Wert muss die Messung mindestens haben, um ÜBERHAUPT berücksichtigt zu werden?
 
                //ALLE PORTS GLEICHZEITIG LESEN / MESSEN
		//Wo liegt eine konstante Spannung an?
		boolean[] resultB = hb627.readAll();
 
	        //Wie hoch sind die anliegenden Spannungen? (vorher muss "readAll" oder "read" aufgerufen worden sein)
		int[] voltages = hb627.getVoltage();
 
                //Ergebnisse ausgeben	
			for (int j = 0; j<resultB.length;j++) {
				System.out.println(resultB[j]);
				System.out.println(voltages[j]);
			}
 
                 //PORTS EINZELN LESEN / MESSEN
                        boolean result = hb627.read(8);
			int[] voltages = hb627.getVoltage();
			System.out.println(result);
			System.out.println(voltages[0]);
 
                }
}

Der Quellcode der JAVA-Klasse

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.TooManyListenersException;
 
 
public class HB627 {
	private CommPortIdentifier commPortIdentifier; 
	private SerialPort serialPort;
	private OutputStream outputStream;
	private BufferedOutputStream out;
	private InputStream inputStream;
 
	private int cfg_laps;
	private int cfg_tolerance;
	private int sleepTime;
	private int mVschwelle;
 
	private int commando; //letztes durchgeführtes commando
	private int lap; //aktuelle runde im rennen (race) (jedes race liefert ein Messergebnis in form von true oder false zurück)
 
	private ArrayList<Integer> finalResults;
	private ArrayList<byte[]> respondResults;
	private boolean[] booleanResults;
 
 
	//KONSTRUKTOR: VERBINDUNG MIT EMPFAENGERKARTE HERSTELLEN (z.B. comName = "COM17" )
	HB627(String comName) {
 
		booleanResults = new boolean[8];
 
		cfg_laps = 4; //Wieviele Messrunden soll eine Messung (ein Race) surchlaufen, bevor entschieden wird, ob der Port einen zuverlässigen Wert übermittelt hat? (je mehr, desto zuverlässiger)
		cfg_tolerance = 20; //in mV. Wie hoch darf die Durchschnitts-Differenz zwischen den Messrunden-Werten eines einzelnen Mess-Ports höchstens sein, um noch als zuverlässiges Ergebnis eingestuft zu werden.
		sleepTime = 15; //Wie lange soll nach jedem Kommando (nach jeder Runde [lap]) gewartet werden?
		mVschwelle = 1500; //Welchen Wert muss die Messung mindestens haben, um ÜBERHAUPT berücksichtigt zu werden?
 
		finalResults = new ArrayList<Integer>();
		respondResults = new ArrayList<byte[]>();
 
 
		//COM-PORT-OPEN
		if (!Main.simulation) {
 
 
			try {
				commPortIdentifier = CommPortIdentifier.getPortIdentifier(comName);
				serialPort = (SerialPort) commPortIdentifier.open(comName,2000);
				serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
 
				outputStream = serialPort.getOutputStream();
				out = new BufferedOutputStream(outputStream);
 
				System.out.println("Connected to " + comName + "");
 
 
			 }
			 catch(Exception exc)
			 {
				 System.out.println("Fehler Outputstream :"+exc);			
			 }
 
			 //INPUT-STREAM
			 try {
				inputStream = serialPort.getInputStream();
 
				System.out.println("Inputstream open " + comName + "");
 
			 } catch (IOException exc) {
				System.out.println("Fehler Inputstream :"+exc);
			 }
			 try {
					serialPort.addEventListener(new serialPortEventListener());
					System.out.println("Add Eventlistener " + comName + "");
 
				} catch (TooManyListenersException e) {
					System.out.println("TooManyListenersException für Serialport");
				}
				serialPort.notifyOnDataAvailable(true);
		}	
	}
 
	void setCfg(int newSleepTime, int newLaps, int newTolerance, int newMinimumMV) {
		sleepTime = newSleepTime;
		cfg_laps = newLaps;
		cfg_tolerance = newTolerance;
		mVschwelle = newMinimumMV;
	}
 
	int getSleepTime() {
		return sleepTime;
	}
 
	//KOMMANDO-METHODE
	private void cmd(int third) {
		commando = third;
		lap++;
 
		//KOMMANDOS IN ARRAY SCHREIBEN
 
		//Datenpaket schnüren 
		byte[] sendData = new byte[3];
		sendData[0] = (byte) 99; //byte0_array[0];
		sendData[1] = (byte) 48; //cmd;
		sendData[2] = (byte) (48+third); //(cmd ^ sendData[0]);
 
 
		//DATEN SENDEN
		if (!Main.simulation) {
			try {
				out.write(sendData, 0, 3);
				out.flush();
 
				//System.out.println("Data send: First " + sendData[0] + "; second " + sendData[1] + "; third " + sendData[2] + " ");
			} catch (IOException e) {
				System.out.println("No data sended");
			}
 
			//WARTEN
			try {
				//System.out.println("wait " + sleepTime + "ms");
				Thread.sleep(sleepTime);
			} catch (InterruptedException e) {
				System.out.println("Sleeping failed");
			}
		}
	}
 
	//VERBINDUNG ZUR HB627-KARTE BEENDEN
	void close() {
		if (!Main.simulation) {
			serialPort.close();
			System.out.println("Connection closed");
		}
	}
 
	//EINGEHENDES SIGNAL AUS HIGH-BYTE UND LOW-BYTE UMRECHNEN
	int parseResponse(byte highByte, byte lowByte) {
		int intHB = 0;
		int intLB = 0;
 
		//In positive Zahlen parsen
		if (highByte < 0) {
			intHB = 256 + highByte;
		} else {
			intHB = highByte;
		}
 
		if (lowByte < 0) {
			intLB = 256 + lowByte;
		} else {
			intLB = lowByte;
		}
 
		//IN FERTGE ZAHL UMRECHNEN
		int result = (int) ((intHB*10) + intLB*0); //LOW-BYTE WIRD zZ IGNORIERT!
 
		return result;
	}
 
	//NEUES RENNEN / NEUE MESSUNG: GRUNDLAGE SCHAFFEN (Vergleichswerte zurücksetzen)
	private void newRace() {
		respondResults.clear();
		finalResults.clear();
		lap = 0;
 
		for (int i = 0;i<booleanResults.length; i++) {
			booleanResults[i] = false;
		}
 
	}
 
	//EINEN PORT LESEN/MESSEN
	boolean read(int port) {
		newRace();
 
		for (int i = 0; i<cfg_laps;i++) {
			cmd(port);
		}
 
		if (finalResults.size() > 0) {				
			//System.out.println("FR: " + finalResults.get(0));
 
			/*System.out.println(" ");
			for (int k = 0;k<finalResults.size();k++) {
				System.out.print(finalResults.get(k) + " ");
			}*/
 
			//hat der messwert die mindest-volt-schwelle erreicht?
 
			//if (finalResults.get(0) >= mVschwelle || true) {
 
				int durchschnitt = 0;
				int differenz = 0;
				int high;
 
				//durchschnitt ausrechnen
 
				System.out.println(finalResults.size()+" "+cfg_laps);
 
				if (finalResults.size() == (cfg_laps*8)) {
					for (int i = 0; i<cfg_laps;i++) {
						durchschnitt += finalResults.get((i*8));
					}
 
 
					durchschnitt = durchschnitt/cfg_laps;
 
					//Checken, ob höchstdifferenz eingehalten wird
					for (int i = 0; i<cfg_laps;i++) {
 
						high = (i*8);
						if (durchschnitt > finalResults.get(high)) {
							differenz += durchschnitt-finalResults.get(high);
						} else {
							differenz += finalResults.get(high)-durchschnitt;
						}
 
					}
 
					if ((differenz/cfg_laps) > cfg_tolerance ) {
						System.out.println("!tolerance: " + (differenz/cfg_laps));
						return false;
					} else {
						System.out.println("tolerance: " + (differenz/cfg_laps));
						booleanResults[0] = true;
						return true;
 
					}
				} else {
					System.out.println("Notice: (Array-Fehler)");
					return false;
				}
			} else {
				return false;
			}
		//} else {
		//	return false;
		//}		
	}
 
	//ALLE PORTS LESEN/MESSEN
	boolean[] readAll() {
		newRace();
 
 
		for (int i = 0; i<cfg_laps;i++) {
			cmd(9);
		}
 
		boolean[] result = {false,false,false,false,false,false,false,false}; 
		if (finalResults.size() > 0) {				
 
 
			/*System.out.println(" ");
			for (int k = 0;k<finalResults.size();k++) {
				System.out.print(finalResults.get(k) + " ");
			}*/
 
			for(int i = 0; i<8;i++) {
				//System.out.println("FR "+(i+1)+": " + finalResults.get(i));
 
				if(finalResults.get(i) > mVschwelle) {
 
					int durchschnitt = 0;
					int differenz = 0;
					int high;
 
					//durchschnitt ausrechnen
					for (int j = 0; j<cfg_laps;j++) {
						durchschnitt += finalResults.get((j*8)+i);
					}
					durchschnitt = durchschnitt/cfg_laps;
 
					//Checken, ob höchstdifferenz eingehalten wird
					for (int j = 0; j<cfg_laps;j++) {
						high = (j*8)+i;
 
						/*if (i==7) {
							System.out.println(durchschnitt + " dif " + finalResults.get(high));
						}*/
 
						if (durchschnitt > finalResults.get(high)) {
							differenz += durchschnitt-finalResults.get(high);
						} else {
							differenz += finalResults.get(high)-durchschnitt;
						}
 
					}
 
					if ((differenz/cfg_laps) > cfg_tolerance ) {
						//System.out.println("!tolerance: " + (differenz/cfg_laps));
						result[i] = false;
					} else {
						//System.out.println("tolerance: " + (differenz/cfg_laps));
						booleanResults[i] = true;
						result[i] = true;
					}
 
 
 
				}
			}
		}
 
		return result;
	}
 
	//MESSWERTE IN mV-Ausgeben
	int[] getVoltage() {
 
		int[] result = new int[8];
 
		for (int i = 0;i<8;i++) {
			if (booleanResults[i]) {
				result[i] = finalResults.get(i);
			} else {
				result[i] = 0;
			}
		}
 
		return result;
 
	}
 
	//DATEN EMPFANGEN & VERARBEITEN
	public void serialPortDataAvailable() {
		try {
			byte[] data = new byte[17];
 
 
 
			while(inputStream.available() > 0) {
 
				inputStream.read(data, 0, data.length);
				//System.out.println("[] "+data[0]+" "+data[1]+" "+data[2]+" "+data[3]+" "+data[4]+" "+data[5]+" "+data[6]+" "+data[7]+" "+data[8]+" "+data[9]+" "+data[10]+" "+data[11]+" "+data[12]+" "+data[13]+" "+data[14]+" "+data[15]+" "+data[16]+"");
 
				byte[] currentbytes = new byte[2];
				int currentvoltage;
 
				int fb;
				int sb;
 
				for (int i = 0;i<(data.length);i++) {
 
					fb = 2+(i*2)-1;
					sb = 2+(i*2);
 
					if (sb < 17) {
 
					if (commando == 9) {
						currentbytes[1] = data[sb];
						currentbytes[0] = data[fb];
 
					} else {
						currentbytes[0] = data[sb];
						currentbytes[1] = data[fb];
					}
 
					currentvoltage = this.parseResponse(currentbytes[0], currentbytes[1]);
 
					respondResults.add(currentbytes);
					finalResults.add(currentvoltage);
 
 
					//System.out.print(currentvoltage + "(" +fb+ "" +sb+ "): " + data[fb] + "/ " + data[sb] +" || ");
					}
				}
				//System.out.println(" ");
 
			}
		} catch (IOException e) {
			System.out.println("!!! Data could not be recieved !!!");
		}
	}
 
	class serialPortEventListener implements SerialPortEventListener {
		public void serialEvent(SerialPortEvent event) {
			switch (event.getEventType()) {
			case SerialPortEvent.DATA_AVAILABLE:
				serialPortDataAvailable();
				break;
			case SerialPortEvent.BI:
			case SerialPortEvent.CD:
			case SerialPortEvent.CTS:
			case SerialPortEvent.DSR:
			case SerialPortEvent.FE:
			case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
			case SerialPortEvent.PE:
			case SerialPortEvent.RI:
			default:
			}
		}
	}	
 
 
}

Bekannte / Mögliche Schwachstellen / Bugs in der Klasse

  • Ich habe nicht geprüft (da in meinem Anwendungsbereich unerheblich) ob die gemessenen Spannungswerte („getVoltage()“) den realen Spannungswerten entsprechen. Eventuell ergibt sich die tatsächliche Spannung erst nach durch die Differenz von 4095… oder auch nicht. Ausgeschlossen werden kann ist, dass „getVoltage()“ falsche ergebnisse liefert. Man muss diese eben nur richtig interpretieren können.
  • Die Umrechnung von High-Byte und Lowbyte (Antwort von der Empfängerkarte) ist möglicherweise unvollständig, jedoch ausreichend (für meine Zwecke). Für eine Umrechnung unter berücksichtigung des Low-Bytes fehlt mir bisher die korrekte Formel, die sich auch nicht aus dem Handbuch ergibt. Sobald ich in diesem Punkt weiter bin, werde ich das im Kommentarbereich ergänzen.

13. August 2011 Veröffentlicht von Heinrich in : Technik , 1 kommentar bisher

Conrad-Relaiskarte mit JAVA steuern

Conrad Relaiskarte

Conrad Relaiskarte (Quelle: Google)

 

Siehe auch: Conrad Relaiskarte Widerstand

Conrad-Relaiskarte mit JAVA ansteuern unter Windows 7 / USB-Schnittstelle

Kürzlich erwarb ich eine Relaiskarte von Conrad. Doch schnell stieß ich auf ein Problem: Ich möchte die Karte über JAVA ansteuern, jedoch gibt es keine Anleitung im Internet, die einem bei diesem Vorhaben konkret weiterhelfen. Nach einiger Recherche hier mein Ergebnis:

1. Um die Karte über USB anzusteuern, benötigt man zusätzlich zur Karte noch einen RS232-Converter (ca. 15 EUR).

2. Um eine Verbindung per JAVA unter Windows 7 herzustellen, braucht man die RXTXcomm-Bibliothek

3. Es muss eine passende Klasse programmiert werden, mit der man die Relaiskarte steuern kann.

1.: Die Hardwarevoraussetzungen

Im folgenden arbeite ich mit der Conrad-Relaiskarte. Möchte man diese per USB ansteuern (so wie hier beschrieben), so braucht man für die erste Karte einen RS232-Converter.

2.: Die RXTXcomm.jar für Windows 7

Mit der Standard-JAVA-Bibliothek ist es nicht möglich, die Karte anzusteuern. Man muss in sein Projekt noch folgende Bibliothek einbinden:

RXTXcomm (download)

RXTXcomm Installationsanweisung | Alternative Anleitung

3.: Die eigentliche Klasse

Im Handbuch der Relaiskarte ist von sogenannten Kommandos die Rede, mit denen man die einzelnen Relais ansteuern kann. Meine Klasse arbeitet wie folgt:

public class Main {
	public static void main (String args[]) {
 
		//VERBINDUNG AUFBAUEN
		CRelais cRelais = new CRelais("COM17");
 
		//RELAISKARTE-INITIIEREN
		cRelais.cmd(1, 1, 0 );
 
		//TEST: TOGGLE-BEFEHL MIT ALLEN KOMBINATIONEN HINTEREINANDER DURCHFÜHREN
		for (int i = 0; i&lt;255; i++) {
			cRelais.cmd(8, 1, i ); //(int) Math.pow(2, i));
		}
 
                //VERBINDUNG SCHLIE?EN
		cRelais.close();
	}
}

 

Wer sich mit dem Handbuch auseinandersetzt, der weiß auch, was die Zahlen im JAVA-Code bedeuten.

Hier der Quellcode CRelais-Klasse:

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
 
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;
 
public class CRelais {
	private CommPortIdentifier commPortIdentifier;
	private SerialPort serialPort;
	private OutputStream outputStream;
	private BufferedOutputStream out;
	private int sleepTime;
	private InputStream inputStream;
 
	//KONSTRUKTOR: VERBINDUNG MIT RELAISKARTE HERSTELLEN (z.B. comName = "COM17" )
	CRelais(String comName) {
 
		//comName = "COM17";
		sleepTime = 50; //SEND + RESPOND works until 14ms, but not lower. 50ms sounds healthy ;) 
 
		//COM-PORT-OPEN
		try {
			commPortIdentifier = CommPortIdentifier.getPortIdentifier(comName);
			serialPort = (SerialPort) commPortIdentifier.open(comName,2000);
			serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
 
			outputStream = serialPort.getOutputStream();
			out = new BufferedOutputStream(outputStream);
 
			System.out.println("Connected to " + comName + "");
 
		 }
		 catch(Exception exc)
		 {
			 System.out.println("Fehler Outputstream :"+exc);
		 }
 
		 //INPUT-STREAM
		 try {
			inputStream = serialPort.getInputStream();
 
			System.out.println("Inputstream open " + comName + "");
 
		 } catch (IOException exc) {
			System.out.println("Fehler Inputstream :"+exc);
		 }
		 try {
				serialPort.addEventListener(new serialPortEventListener());
			} catch (TooManyListenersException e) {
				System.out.println("TooManyListenersException für Serialport");
			}
			serialPort.notifyOnDataAvailable(true);
			try {
				serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
			} catch(UnsupportedCommOperationException e) {
				System.out.println("Konnte Schnittstellen-Paramter nicht setzen");
			}
	}
 
	//SETTER-METHODE FÜR SLEEPTIME (zweit, die gewartet wird, nachdem ein Kommando versendet wurde)
	void setSleepTime(int newTime) {
		sleepTime = newTime;
	}
 
	//KOMMANDO-METHODE
	void cmd(int cmd, int adress, int data) {
 
		//KOMMANDOS IN ARRAY SCHREIBEN
		byte[] sendData = new byte[4];
		sendData[0] = (byte) cmd;
		sendData[1] = (byte) adress;
		sendData[2] = (byte) data;
		sendData[3] = (byte) (cmd ^ adress ^ data);
 
		//DATEN SENDEN
		try {
			out.write(sendData, 0, 4);
			out.flush();
 
			System.out.println("Data send: cmd " + sendData[0] + "; adress " + sendData[1] + "; data " + sendData[2] + "; XOR " + sendData[3] + " ");
		} catch (IOException e) {
			System.out.println("No data sended");
		}
 
		//WARTEN
		try {
			Thread.sleep(sleepTime);
		} catch (InterruptedException e) {
			System.out.println("Sleeping failed");
		}
 
	}
 
	//VERBINDUNG ZUR RELAISKARTE BEENDEN
	void close() {
		serialPort.close();
		System.out.println("Connection closed");
	}
 
	public void serialPortDataAvailable() {
		try {
			byte[] data = new byte[4];
			while(inputStream.available() &gt; 0) {
 
				inputStream.read(data, 0, data.length);
 
				//XOR-CHECK
				if ((data[0] ^ data[1] ^ data[2]) == data[3]) {
					System.out.println("Data resp: TRUE ; " + data[0] + "; " + data[1] + "; " + data[2] + "; XOR " + data[3] + " ");
 
				} else {
					System.out.println("Data resp: !!! FALSE !!! ; " + data[0] + "; adress " + data[1] + "; " + data[2] + "; XOR " + data[3] + " ");
				}
 
			}
		} catch (IOException e) {
			System.out.println("!!! Data could not be recieved !!!");
		}
	}
 
	class serialPortEventListener implements SerialPortEventListener {
		public void serialEvent(SerialPortEvent event) {
			switch (event.getEventType()) {
			case SerialPortEvent.DATA_AVAILABLE:
				serialPortDataAvailable();
				break;
			case SerialPortEvent.BI:
			case SerialPortEvent.CD:
			case SerialPortEvent.CTS:
			case SerialPortEvent.DSR:
			case SerialPortEvent.FE:
			case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
			case SerialPortEvent.PE:
			case SerialPortEvent.RI:
			default:
			}
		}
	}
}