[JAVA] Kann ich RXTX nicht verwenden? Gibt es eine Alternative?

Serielle Kommunikation nach langer Abwesenheit

Nach langer Zeit entschied ich mich, Java für die serielle Kommunikation zu verwenden, also habe ich viel recherchiert. Es ist schon eine Weile her, dass ich Programme in Java geschrieben habe, und in der Vergangenheit gab es nur RXTX für die serielle Java-Kommunikation, aber jetzt gibt es Artikel wie Nachfolger oder Alternativen in der Suche. Unten finden Sie die drei wichtigsten Artikel einer Google-Suche nach "Java Serial Communication".

  1. Verwenden wir die serielle Kommunikation mit Java http://web.sfc.wide.ad.jp/~tinaba/tutorials/serial-j/index.html
  2. Probleme und alternative Forschung der Java Serial Communication Library RXTX https://qiita.com/kyosho/items/fc0c40458385c7d98232
  3. Software Engineering / Serielle Java-Kommunikation <https://www.torutk.com/projects/swe/wiki/Java%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB % E9% 80% 9A% E4% BF% A1> Das erste ist die Verwendung von RXTX, und das nächste und das nächste sind Vorschläge für alternative Bibliotheken.

Com0com als Vorarbeit

Installieren Sie den Nullmodem-Emulator (https://sourceforge.net/projects/com0com/) als COM-Port für den Monitor. Es gibt viele Artikel, die möglicherweise nicht unter Windows 10 (64 Bit) installiert werden können, aber hier (Windows 10 Home 64 Bit) konnte ich sie problemlos installieren. Die Entwicklungsumgebung war übrigens "Eclipse 2020 (Windows 64bit Version)" von Pleiades All In One und "Full Edition" von "Platform", und nur JDT wurde zusätzlich installiert. Der bekannte "Tera Term" wird für das COM-Monitor-Terminal verwendet.

Können Sie ersetzen

Hier habe ich die folgenden vier Tests versucht, aber in meiner Umgebung (Windows 10 Home) konnte ich nicht "Zeichen mit PrintWriter usw. ausgeben (senden)" und "Zeicheneingabe vom Terminal mit Ereignis empfangen (Ereignisempfang)". Es war nur RXTX. Aber keine ist perfekt. Ich habe den Umfrageempfang nicht ausprobiert.

  1. RXTX [http://fizzed.com/oss/rxtx-for-java]
  2. jSerialComm [http://fazecast.github.io/jSerialComm/]
  3. jpurejavacomm [http://www.sparetimelabs.com/purejavacomm/purejavacomm.php]
  4. jssc [https://github.com/scream3r/java-simple-serial-connector]

Probieren Sie RXTX zum ersten Mal seit einiger Zeit aus

Ich habe "mfz-rxtx-2.2-20081207-win-x64.zip" von der oben gezeigten Seite mitgebracht. Sie werden gebeten, die DLL in lib \ ext unter bin oder jar abzulegen, aber openjdk11 hat keinen Ordner mit dem Namen lib / ext. Daher wurde jar der Bibliothek durch "Externes Archiv hinzufügen" im Eclipse-Erstellungspfad hinzugefügt. Die DLL hat jre / bin unter dem Eclipse-Ordner, also habe ich sie dort abgelegt. Die import-Anweisung wird weggelassen, aber die Klassendeklaration, die Schnittstelle und die Hauptfunktion (fügen Sie die throw-Anweisung hinzu, da try / catch problematisch ist) lauten wie folgt. Es ist ungefähr das gleiche, wenn man andere benutzt.

public class RXTXtest implements SerialPortEventListener {
	public static void main(String[] args) throws Exception {
		new RXTXtest();
	}
	...(Unterlassung)
}

Der Konstruktor und der erste Prozess sind wie folgt. Eine Liste der COM-Ports, auf die über die Aufzählung zugegriffen werden kann, wird angezeigt. Es kann problemlos angezeigt werden.

	String name;
	SerialPort port;
	RXTXtest() throws Exception {
		name=this.getClass().getSimpleName();
		Enumeration<CommPortIdentifier> ids=CommPortIdentifier.getPortIdentifiers();
		while(ids.hasMoreElements()) {
			CommPortIdentifier id=(CommPortIdentifier)ids.nextElement();
			System.out.println(id.getName());
		}
	...Unterlassung
	}

Als ich den COM-Port tatsächlich öffnete und versuchte, mit PrintWriter (Sendefunktion) zu schreiben, trat ein schwerwiegender Fehler auf. "COM7 & COM8" ist bei com0com gekoppelt. Wenn Sie mit Tera Term und "not" eine Verbindung zur "COM8" -Seite herstellen, tritt kein Fehler auf. Wenn Sie jedoch eine Verbindung herstellen und überwachen, wird ein FATAL ERROR angezeigt. Es war okay bis vor Flush (), aber wenn Flush (), wird es FATAL.

		CommPortIdentifier id=CommPortIdentifier.getPortIdentifier("COM7");
		SerialPort port=(SerialPort) id.open(name, 2000);
		port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
		port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
		port.addEventListener(this);
		PrintWriter pw=new PrintWriter(port.getOutputStream());
		pw.println(name+": "+"Tested!");
		pw.flush();

Der vollständige Text von FATAL ERROR dient als Referenz. Was soll ich so machen?

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000180004465, pid=4480, tid=4852
#
# JRE version: OpenJDK Runtime Environment (11.0.7+10) (build 11.0.7+10)
# Java VM: OpenJDK 64-Bit Server VM (11.0.7+10, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [rxtxSerial.dll+0x4465]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\akira\Documents\workspace\SerialTesting1\hs_err_pid4480.log
#
# If you would like to submit a bug report, please visit:
#   https://github.com/AdoptOpenJDK/openjdk-support/issues
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Versuchen Sie es mit jSerialComm

Ich habe "jSerialComm-2.6.2.jar" über die Schaltfläche "jar" oben in http://fazecast.github.io/jSerialComm/ abgerufen. Dies ist auch im Erstellungspfad unter "Externes Archiv hinzufügen" enthalten. Der Bereich um den Konstruktor ist wie folgt. Da die Schnittstelle während der Verarbeitung nach der Beispielquelle geschrieben wurde, wird sie zu Beginn nicht deklariert.

public class JSerialCommTest {
	public static void main(String[] args) throws Exception {
		new JSerialCommTest();
	}
	...Unterlassung
}

Die Liste der verfügbaren Ports wird in einem Array angezeigt. Intuitiv aber nicht klug. Außerdem werden die speziellen Paarports "CNCA0" und "CNCB0" von com0com aufgelistet, die ausgeblendet werden sollten (sie wurden in RXTX nicht angezeigt).

	SerialPort port;
	String name;
	JSerialCommTest() throws Exception {
		name=this.getClass().getSimpleName();
		SerialPort[] ports=SerialPort.getCommPorts();
		for(int i=0;i<ports.length;i++) System.out.println(ports[i].getSystemPortName());
		...Unterlassung
	}

Ich konnte problemlos öffnen und ausgeben. Es kann zumindest einseitig übertragen werden (auf RXTX spuckt pw.flush () FATAL).

		port=SerialPort.getCommPort("COM7");
		port.setComPortParameters(9600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
		port.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
		port.openPort();
		PrintWriter pw=new PrintWriter(port.getOutputStream());
		pw.println(name+": Tested!");
		pw.flush();

Das Problem ist die Empfangsseite. Wenn Sie ein Ereignis überwachen, während Sie auf die Eingabe in einer Endlosschleife warten (siehe unten), tritt eine Ausnahme auf oder es erfolgt keine Antwort. Die Ausnahme betraf TimeOut, konnte sie jedoch aufgrund mangelnder Fähigkeiten nicht gut lösen.

		port.addDataListener(new SerialPortDataListener() {
			public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; }
			public void serialEvent(SerialPortEvent event) {
				if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) return;
				byte[] newData = new byte[port.bytesAvailable()];
				int numRead = port.readBytes(newData, newData.length);
				pw.println("Read " + numRead + " bytes.");
			}
		});
		while(true) {}

Versuchen Sie es mit jpurejavacomm

Der alte Mann ist schon müde. Als nächstes verwenden wir jpurejavacomm. Ich habe "purejavacomm-1.0.3.jar" aus dem bin-Ordner von https://github.com/nyholku/purejavacomm mitgebracht. Es scheint, dass dies alleine nicht funktionieren wird, also brauchte ich auch "jna.jar". Es befindet sich hier im Ordner dist https://github.com/java-native-access/jna. Die Klassendefinition ist fast dieselbe wie bei den anderen. Auch hier ist die Schnittstelle anonym und wird während der Verarbeitung geschrieben, sodass keine Geräte vorhanden sind.

public class JPureJavaCommTest  {
	public static void main(String[] args) throws Exception {
		new JPureJavaCommTest();
	}
	...Unterlassung
}

Die verfügbaren Ports für die Konstruktorliste wurden normal ausgeführt. Bisher gibt es kein Problem mit einer Bibliothek.

	SerialPort port;
	String name;
	JPureJavaCommTest() throws Exception {
		name=this.getClass().getSimpleName();
		Enumeration<CommPortIdentifier> e=CommPortIdentifier.getPortIdentifiers();
		while(e.hasMoreElements()) {
			CommPortIdentifier id=(CommPortIdentifier)e.nextElement();
			System.out.println(id.getName());
		}
		...Unterlassung
	}

Vom Öffnen des Ports bis zur Überprüfung der Sendefunktion endete es ohne Probleme. RXTX hat nicht funktioniert, aber jSerialComm war bisher gut.

		CommPortIdentifier id=CommPortIdentifier.getPortIdentifier("COM7");
		port=(SerialPort)id.open(name,2000);
		port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
		port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
	
		PrintWriter pw=new PrintWriter(port.getOutputStream());
		pw.println(name+": Tested!");
		pw.flush();

Nun, es gibt keine Reaktion, wenn es darum geht, Ereignisse zu empfangen. Keine Fehler oder Ausnahmen. Anscheinend stimmt etwas nicht?

		port.notifyOnDataAvailable(true);
		port.addEventListener(new SerialPortEventListener() {
			public void serialEvent(SerialPortEvent arg0) {
				pw.println(name+": SerialEvent!");
			}});
		while(true) {}

Ich werde jssc versuchen

es ist jetzt vorbei. Sie können seriell senden, aber nicht mit Java empfangen !! Aber möchten Sie am Ende jssc ausprobieren? Ich habe "jssc-2.9.2.jar" von hier https://github.com/java-native/jssc/releases gelöscht, aber als ich es eine Weile versuchte, sah es wie NG aus, also das vorherige " Ich habe "jssc-2.9.1.jar" verwendet (weil ein Ausländer geschrieben hat, dass es sich um einen Fehler handelt, der in der vorherigen Version nicht aufgetreten ist, ist es nicht ein Fehler?). An diesem Punkt bin ich in der Stimmung aufzugeben. Darüber hinaus sind auch "native-lib-loader-2.3.4.jar", "slf4j-api-1.7.30.jar" und "slf4j-simple-1.7.30.jar" erforderlich. Was ist Maven? Ich weiß es nicht ... Die Klassendefinition lautet wie folgt. Aus irgendeinem Grund kann "new SerialPortEventListener ()" während der Verarbeitung nicht ausgeführt werden (gibt es einen Konstruktor?). Daher wird die Schnittstelle mit der Anweisung implements hinzugefügt.

public class JSSCtest  implements SerialPortEventListener {
	public static void main(String[] args) throws Exception {
		new JSSCtest();
	}
	...Unterlassung
}

Sie können auch die Ports auflisten, die normal verwendet werden können. Nun, ich könnte sogar RXTX machen. Dies gibt ein String [] -Array anstelle von Enumuration zurück. Es passt nicht zu meinem Geschmack, ist aber einfach. Hier werden jedoch auch "CNCA0" und "CNCB0" aufgelistet, die ausgeblendet werden sollen (diese werden nicht im Geräte-Manager angezeigt). Es ist sinnvoll, line.separator auf das Zeichen ls hier zu setzen.

	SerialPort port;
	String ls;
	JSSCtest() throws Exception {
		ls=System.getProperty("line.separator");
		String[] ports = SerialPortList.getPortNames();
		for(int i = 0; i < ports.length; i++) {
		   System.out.println(ports[i]);
		}
		...Unterlassung
	}

Sie können Ports problemlos öffnen und senden, aber aus irgendeinem Grund können Sie OutputStream nicht erhalten und müssen eine Methode wie writeString verwenden. Ich habe das Zeichen ls verwendet, weil ich die Zeile nicht gut unterbrechen konnte (der Inhalt ist System.geyProperty ("line.separator")), aber Sie können es so einstellen, dass \ n auf der Tera Term-Seite empfangen werden kann.

		port=new SerialPort("COM7");
		port.openPort();
		port.setParams(SerialPort.BAUDRATE_9600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
		port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
		port.writeString("JSSC Test!"+ls);

		port.addEventListener(this);
		while(true) {}

In Bezug auf den Empfang des Problems könnte das Ereignis abschließend eintreten, aber die zu empfangenden Inhalte sind nicht klar.

	public void serialEvent(SerialPortEvent arg0) {
		try {
			byte[] bs=port.readBytes();
			System.out.println(bs);
		} catch (SerialPortException e) {
			e.printStackTrace();
		}
	}

Wenn Sie "aaabb" manuell aus dem Tera-Begriff eingeben, wird Folgendes zurückgegeben. Es ist leicht zu verstehen mit einem Charakter und einem Ereignis, aber was ist das?

[B@1df7e046
[B@19c87720
[B@5ccaea7d
[B@4f8bbf28
[B@6d5c934f

Fazit

  1. RXTX gibt FATAL ERROR aus. Es tut mir Leid. Es wird nicht mehr gewartet und ist eingelagert!
  2. jSerialComm ist instabil. Keine Antwort oder Ausnahmen. Möchtest du härter arbeiten?
  3. jpurejavacomm reagiert nicht auf den Empfang von Ereignissen. Ist es schlecht zu benutzen?
  4. jssc kann möglicherweise etwas dagegen tun. Es ist notwendig, die empfangenen Inhalte zu überprüfen.

Recommended Posts

Kann ich RXTX nicht verwenden? Gibt es eine Alternative?
Wie man Maven benutzt, das ich nicht mehr hören kann
Gibt es eine Instanz, auch wenn der Konstruktor ausfällt?
Ich habe versucht, das Problem mit der Ruby-Karaoke-Maschine zu lösen (es gibt ein Beispiel für die Antwort).
Ich habe versucht, das Problem mit dem Ruby-Bonusgetränk zu lösen (es gibt ein Beispiel für die Antwort).