# Zugriff auf serielle Schnittstelle Com Port



## chehilbi (18. Feb 2009)

Hallo Zusammen,

ich versuche gerade heraus zu finden, welche Möglichkeitn es in Java gibt, um auf einen Com Port zu zugreifen. 
Habe schon einiges gelesen, aber irgendwie komme ich nicht klar. Welche Möglichkeiten gibt es denn grundsätzlich ???

Stichtwort java com api oder über eine Art File Zugriff?? Wer kann mich bitte aufkären !!!

Habe gerade etwas gelesen von java communication??? Was haltet ihr davon ? Gibt es noch andere Möglickeiten?

Vielen Dank!


----------



## chehilbi (18. Feb 2009)

ich  habe mich jetzt noch ein wenig damit beschäftigt und muss sagen ich bin wirklich genervt wie wenig gute Seiten es im Internet über dieses Thema gibt. Nur Schrott. Kann nicht verstehen, warum es nicht gelingt solch ein Thema einfach zu beschreiben. Na ja ist immer das gleiche.

Nach meinen Informationen gibt es nun 2 Möglichkeiten. Entweder über Java Communication API von SUN oder über ein freies Projekt Namens rxtx. Leider unterstützt die Communciatio API von SUN keine Windows Systeme, was wirklich sehr schwach ist. 

Hat jemand mit rxtx schon Erfahrung gemacht. Die Webseite ist wirklich der letzte Mist. 

Oder gibt es noch andere Möglichkeiten!


----------



## Zed (18. Feb 2009)

Ich würde für diese Aufgabe eher auf C# gehen. Java taugt für sowas nicht. wenn du Java brauchst wäre JNI/JNA evtl. eine Alternative.


----------



## foobar (19. Feb 2009)

Mit rxtx funktioniert das wunderbar sowohl unter Windows als auch unter Linux. Die Com Api von Sun ist völlig veraltet und sollte nicht mehr verwendet werden.


----------



## Saxony (19. Feb 2009)

Hiho,

ich habe damals noch die Java Communication API verwendet - deswegen wundere ich mich wieso WinSysteme nicht unterstützt werden sollen, da ich alles komplett auf ner WinMaschine entwickelt habe! Dafür liegt der CommAPI doch extra eine Win32Com.dll bei.
Damit schicke ich Testanfragen direkt an einen AMD Élan SC520, generiere "Heartbeats" zwischen meiner Javaanwendung und dem Prozessor, lese den Speicher auf der Platine aus und schicke den seriell zu meiner Javaanwendung...

Ist also alles kein Problem -einfach nen kleines Protokoll erfinden und los gehts (z.B. [STX - Data - ETX]) . Literaturlage war bescheiden, weil nicht vorhanden. Es reicht aber sich die Beispiele anzuschauen.

bye Saxony


----------



## JuniorInformat. (14. Mrz 2011)

also wenn ihr damit schonmal gearbeitet habt schickt bitte mal ein code beispiel.
ich suche gerade vergeblich nach welchen die bei mir funken.


----------



## holgie (15. Mrz 2011)

Hallo,
untenstehend ist ein funktionierendes Beispiel welches "rot ein" an die serielle Schnittstelle sendet. Ich habe damit ein AVR-Board angesteuert und eine LED eingeschaltet. Das hat funktioniert. 
Daten lesen habe ich noch nicht getestet. Schau mal unter Serielle Schnittstelle unter Java - Mikrocontroller.net da ist das ganz gut erklärt.
Gruß
Holger



```
import java.io.*;
import java.util.*;
//import javax.comm.*;
import gnu.io.*;
/**
 * Class declaration
 *
 *
 * @author
 * @version 1.10, 08/04/00
 */
public class simplewrite {
    static Enumeration	      portList;
    @SuppressWarnings("restriction")
	static CommPortIdentifier portId;
    static String	      messageString = "rot ein\r";
    static SerialPort	      serialPort;
    static OutputStream       outputStream;
    static boolean	      outputBufferEmptyFlag = false;
    /**
     * Method declaration
     *
     *
     * @param args
     *
     * @see
     */
    public static void main(String[] args) {
	boolean portFound = false;
	String  defaultPort = "COM3";

	if (args.length > 0) {
	    defaultPort = args[0];
	} 

	portList = CommPortIdentifier.getPortIdentifiers();

	while (portList.hasMoreElements()) {
	    portId = (CommPortIdentifier) portList.nextElement();

	    if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

		if (portId.getName().equals(defaultPort)) {
		    System.out.println("Found port " + defaultPort);

		    portFound = true;

		    try {
			serialPort = 
			    (SerialPort) portId.open("SimpleWrite", 2000);
		    } catch (PortInUseException e) {
			System.out.println("Port in use.");

			continue;
		    } 

		    try {
			outputStream = serialPort.getOutputStream();
		    } catch (IOException e) {}

		    try {
			serialPort.setSerialPortParams(9600, 
						       SerialPort.DATABITS_8, 
						       SerialPort.STOPBITS_1, 
						       SerialPort.PARITY_NONE);
		    } catch (UnsupportedCommOperationException e) {}
	

		    try {
		    	serialPort.notifyOnOutputEmpty(true);
		    } catch (Exception e) {
			System.out.println("Error setting event notification");
			System.out.println(e.toString());
			System.exit(-1);
		    }
		    
		    
		    System.out.println(
		    	"Writing \""+messageString+"\" to "
			+serialPort.getName());

		    try {
			outputStream.write(messageString.getBytes());
		    } catch (IOException e) {}

		    try {
		       Thread.sleep(2000);  // Be sure data is xferred before closing
		    } catch (Exception e) {}
		    serialPort.close();
		    System.exit(1);
		} 
	    } 
	} 

	if (!portFound) {
	    System.out.println("port " + defaultPort + " not found.");
	} 
    } 


}
```


----------



## Ralph-Uwe (16. Mrz 2011)

Nabend

ich habe hier noch mal ein Beispiel für Datenübertragung von einem Rechner auf den anderen.
Von Prinzip sollte der Code funktionieren, habe aber leider z.Z. keine Möglichkeit einen 2. Rechner
anzuschließen und konnte die Funktion nicht prüfen. Der Code stammt aber aus einem Programm, mit dem 
ein Drucker von einem PC angesteuert wird und mit Steuerbefehlen antwortet.

Voraussetzung ist ein korrekt installierter RXTX Treiber.


```
/**
 * Autor : Ralph-Uwe
 * Email : [email]Pilula2010@gmx.de[/email]
 * 
 */


import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.TooManyListenersException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;



public class ComPort extends JFrame {
	private static final long serialVersionUID = -6008251315451848162L;
	private static SerialPort com1;
	private static String port = "COM1";
	private static CommPortIdentifier comPort = null;
	private static DataInputStream in;
	private static DataOutputStream out;
	private static JTextArea empfang = new JTextArea();
	private static JTextField senden = new JTextField(20);
	private static JButton absenden = new JButton("senden");
	
	public ComPort(){
	    /**
	     *  Port nummer abfragen   
	     */
		port = JOptionPane.showInputDialog("Bitte ComPort eingeben (Bsp.: COM1): ");
		
		/**
	     *  ComPort initialisieren 
	     */
	     try {
	     	comPort = CommPortIdentifier.getPortIdentifier(port); 
	        com1 = (SerialPort) comPort.open("Test", 5000);
	        com1.setSerialPortParams(38400, SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_EVEN);
	        com1.notifyOnDataAvailable(true);
	        com1.addEventListener( new CommListener());
	        in = new DataInputStream(com1.getInputStream());
	        out = new DataOutputStream(com1.getOutputStream());
	     } catch (UnsupportedCommOperationException e) {
	        e.printStackTrace();
	     } catch (TooManyListenersException e) {
	        e.printStackTrace();
	     } catch (NoSuchPortException e) {
	        e.printStackTrace();
	     } catch (IOException e) {
	        e.printStackTrace();
	     } catch (PortInUseException e) {
	        e.printStackTrace();
	     }

	     /**
	      * GUI einrichten
	      */
	     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	     setTitle("ComPort Test");
	     absenden.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				datenSenden(senden.getText());
			}
	     }); 
	     empfang.setColumns(30);
	     empfang.setRows(10);
	     JPanel panel = new JPanel();
	     panel.add(senden);
	     panel.add(absenden);
	     panel.add(empfang);
	     getContentPane().add(panel, BorderLayout.CENTER);
	     setSize(400,250);
	     setLocationRelativeTo(null);
	     setVisible(true);
	}
	
	public static class CommListener implements SerialPortEventListener{
	    public void serialEvent(SerialPortEvent event) {
	    switch (event.getEventType()) {
		    case SerialPortEvent.DATA_AVAILABLE: datenEmpfang();
		    default:
	    	}
	    }
	}
	
	private static void datenEmpfang(){
		try {
			 byte b = (byte) in.read();
			 System.out.println(b);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void datenSenden(String befehl){
		try {
			out.writeBytes(befehl);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new ComPort();
	}
}
[/Java]

Ich hoffe es hilft weiter !
```


----------



## HoaX (16. Mrz 2011)

Rxtx-Homepage aufrufen, "Usage" im Menü links anklicken und dann oben den ersten Link "Code Examples" und dann eines auswählen ... verdammt ist das alles so kompliziert und versteckt!

Edith: Sorry für den Sarkasmus, hatte übersehen dass der Ursprungspost von 2009 ist, da war noch die alte Homepage online, und die war wirklich ... nennen wir es "suboptimal".


----------



## xchrisx (11. Apr 2011)

Hallo zusammen,
Ich habe das Beispiel bei mir mal getestet (Windows 7).
Es "funktioniert" auch. Aber es dauert ca 1 min, bis das Programm einmal durchgelaufen ist.
Woran kann denn sowas liegen?

mfg
chris


----------



## Ralph-Uwe (11. Apr 2011)

Hi,

Welches Beispiel hast Du ausprobiert?

der CommPortIdentifier werkelt eine ganze weile rum.
Im ersten Beispiel von holgie werden alle Ports eingelesen.
In meinem Beispiel wird nur das eingegeben Port gesucht, geht etwas schneller. Bei mir ca. 20 sec


----------



## xchrisx (11. Apr 2011)

Hey,
Ich habe das Beispiel von holgie ausprobiert.
Ok Zeit habe ich jetzt nicht gestoppt, aber ich finde das schon extrem langsam. 
Ich will ja kein Glaubenskrieg(Diskussion) der Programmiersprachen auslösen. Aber unter C++ oder Pascal geht das def. schneller. 
Habe ich denn noch ne andere Möglichkeit unter Win 7 das schneller zum Laufen zu bekommen?


----------



## Ralph-Uwe (11. Apr 2011)

Hi,

eigendlich kein Problem, der CommPortIdentifier wir einmal
bei Programmstart aufgerufen. Danach vielleicht nur nochmal
um das Port zur Laufzeit zu wechseln.
Da man in der Regel seine Geräte nicht dauernd umsteckt
ist das als kein ernstes Problem.


----------



## xchrisx (11. Apr 2011)

Ja. Das ist nen Workaround. Ich werde mich morgen auf der Arbeit mal dran setzen. 
Vielen Dank erst mal.


----------

