Quantcast
Channel: TM's Workspace »ライブラリ
Viewing all articles
Browse latest Browse all 10

Java Communications API メモ

$
0
0

 ちょっと忙しかったので、久しぶりの更新。
 最新、計測器制御用にRS-232C通信を使ったプログラムを書く機会があり、かなり久しぶり(10年振りくらい?)にJava Communications APIを使いました。
 備忘録としてメモを残しておきます。

  • Java Communications API3.0から、Windows用のバイナリが配布されなくなったようです。このため、互換ライブラリのRXTXライブラリを使用しました。
  • とりあえず、以下のSerialPortCommクラスとSerialPortParameterクラスを書いて、通信を処理しました。
  • ■SerialPortComm.java

import gnu.io.CommPortIdentifier;
import gnu.io.CommPortOwnershipListener;
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.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TooManyListenersException;
import javax.swing.JOptionPane;

public class SerialPortComm implements CommPortOwnershipListener{
	private DataInputStream is;
	private DataOutputStream os;
	private PrintStream ps;
	private boolean owned=false;
	private SerialPortParameter parameter;
	private CommPortIdentifier port_id;
	private SerialPort port;
	private int TIMEOUT=10000;

	public SerialPortComm(SerialPortParameter parameter,PrintStream ps){
		this.parameter=parameter;
		this.ps=ps;
	}

	public void open() throws IOException{
		try {
			port_id=CommPortIdentifier.getPortIdentifier(
				parameter.getPortName());
		} catch (NoSuchPortException e) {
			throw new IOException(e.getMessage());
		}
		port_id.addPortOwnershipListener(this);
		try {
			String name="RS232C_"+Long.toString(
			System.currentTimeMillis());
			port = (SerialPort)port_id.open(name, TIMEOUT);
		} catch (PortInUseException e) {
			throw new IOException(e.getMessage());
		}
  		try {
  			port.setSerialPortParams(
  					parameter.getBaudRate(),
					parameter.getDatabits(),
					parameter.getStopbits(),
					parameter.getParity());
  		} catch (UnsupportedCommOperationException e) {
  			throw new IOException("Unsupported parameter");
  		}
  		try {
  			port.setFlowControlMode(
  					parameter.getFlowControlIn() |
					parameter.getFlowControlOut());
  		} catch (UnsupportedCommOperationException e) {
  			throw new IOException("Unsupported flow control");
  		}
		try {
			os=new DataOutputStream(port.getOutputStream());
			is=new DataInputStream(port.getInputStream());
		} catch (IOException e) {
			port.close();
			throw new IOException("Error opening i/o streams");
		}
		port.setRTS(parameter.isRTS());
		port.setDTR(parameter.isDTR());
		port.notifyOnDataAvailable(true);
		port.notifyOnBreakInterrupt(true);
		try {
		    port.enableReceiveTimeout(TIMEOUT);
		} catch (UnsupportedCommOperationException e) {
 			throw new IOException("Unsupported parameter");
		}
		try{
			port.addEventListener(new SerialReader());
		}catch(TooManyListenersException e){
			throw new IOException(e.getMessage());
		}
	}

	public void close(){
		try{
			is.close();
			os.close();
			port.close();
			ps.println("An close succeeded.");
			port_id.removePortOwnershipListener(this);
		}catch(IOException e){
			e.printStackTrace();
		}
	}

	public void ownershipChange(int arg0) {
		switch(arg0){
		case CommPortOwnershipListener.PORT_OWNED:
			ps.println("An open succeeded.");
			owned=true;
			break;
		case CommPortOwnershipListener.PORT_UNOWNED:
			owned=false;
			break;
		case CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED:
			if(owned){
				if(JOptionPane.showConfirmDialog(null,
					"I've been asked to give up the port, shold I?",
					"Port Conflict("+port.getName()+")",
					JOptionPane.OK_CANCEL_OPTION)==0){
					close();
				}
			}else{
				ps.println("Somebody else has the port.");
			}
		}
	}

	public byte[] getDataBlock(String mes){
		byte[] ret=new byte[36];
		for(int i=0;i<ret.length;i++)ret[i]=0x1A;
		ret[0]=0x02;
		ret[1]=0x01;
		ret[2]=~0x01;
		byte[] m=mes.getBytes();
		int ck=0;
		for(int i=0;i<m.length;i++){
			ret[i+3]=m[i];
		}
		for(int i=0;i<32;i++){
			ck +=ret[i+3];
		}
		ret[35]=(byte)(ck & 0x0000ff);
		return ret;
	}

	public synchronized void send(String mes){
		try{
			byte[] b=getDataBlock(mes);
			os.write(b,0,b.length);
			ps.println("#User> "+mes);
		}catch(IOException e){
			e.printStackTrace();
		}
	}

	public void sendNAK(){
		try{
			os.write(0x15);
			ps.println("#User> NAK");
		}catch(IOException e){}
	}

	public void sendACK(){
		try{
			os.write(0x06);
			ps.println("#User> ACK");
		}catch(IOException e){}
	}

	public void sendEOT(){
		try{
			os.write(0x04);
			ps.println("#User> EOT");
		}catch(IOException e){}
	}

	public void sendCAN(){
		try{
			os.write(0x18);
			ps.println("#User> CAN");
		}catch(IOException e){}
	}

	private class SerialReader implements SerialPortEventListener{
		@Override
		public void serialEvent(SerialPortEvent arg0) {
			byte[] buffer = new byte[256];
			if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
				try{
					is.read(buffer);
					for(Reciever r : list)r.reciever(buffer,r);
					System.out.println(
						"#DEV > "+Integer.toHexString(buffer[0]));
				}catch(Exception e){e.printStackTrace();}
			}
		}
	}
}

■SerialPortParameter.java

import gnu.io.SerialPort;

public class SerialPortParameter {
	private String portName;
	private int baudRate;
	private int flowControlIn;
	private int flowControlOut;
	private int databits;
	private int stopbits;
	private int parity;
	private boolean isRTS=true;
	private boolean isDTR=true;
	private char[] delimiter;
	private static char[] CR="\r".toCharArray();
	private static char[] LF="\n".toCharArray();
	private static char[] CRLF="\r\n".toCharArray();
	public static String DELIMITER_CR="CR";
	public static String DELIMITER_LF="LF";
	public static String DELIMITER_CRLF="CRLF";

	public SerialPortParameter(){
		portName="COM1";
		baudRate=9600;
		flowControlIn=SerialPort.FLOWCONTROL_NONE;
		flowControlOut=SerialPort.FLOWCONTROL_NONE;
		databits=SerialPort.DATABITS_5;
		stopbits=SerialPort.STOPBITS_1;
		parity=SerialPort.PARITY_NONE;
		delimiter=CRLF;
	}

	public int getBaudRate() {
		return baudRate;
	}

	public void setBaudRate(int baudRate) {
		this.baudRate = baudRate;
	}

	public int getDatabits() {
		return databits;
	}

	public void setDatabits(int databits) {
		this.databits = databits;
	}

	public int getFlowControlIn() {
		return flowControlIn;
	}

	public void setFlowControlIn(int flowControlIn) {
		this.flowControlIn = flowControlIn;
	}

	public int getFlowControlOut() {
		return flowControlOut;
	}

	public void setFlowControlOut(int flowControlOut) {
		this.flowControlOut = flowControlOut;
	}

	public int getParity() {
		return parity;
	}

	public void setParity(int parity) {
		this.parity = parity;
	}

	public String getPortName() {
		return portName;
	}

	public void setPortName(String portName) {
		this.portName = portName;
	}

	public int getStopbits() {
		return stopbits;
	}

	public void setStopbits(int stopbits) {
		this.stopbits = stopbits;
	}

	public String getDelimiterType() {
		if(delimiter==CR){
			return DELIMITER_CR;
		}else if(delimiter==LF){
			return DELIMITER_LF;
		}else{
			return DELIMITER_CRLF;
		}
	}

	public void setDelimiterType(String str) {
		if(str.equals("CR")){
			delimiter=CR;
		}else{
			delimiter=CRLF;
		}
	}

	public char[] getDelimiter() {
		return delimiter;
	}

	public boolean isRTS() {
		return isRTS;
	}

	public void setRTS(boolean isRTS) {
		this.isRTS = isRTS;
	}

	public boolean isDTR() {
		return isDTR;
	}

	public void setDTR(boolean isDTR) {
		this.isDTR = isDTR;
	}

}

Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles