zur navigation

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<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() > 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:
			}
		}
	}
}