jSerialCommを利用したシリアル通信サンプル

# はじめに

先日、"[Javaのシリアル通信ライブラリRXTXの課題と代替調査](https://qiita.com/kyosho/items/fc0c40458385c7d98232)"で紹介した"[jSerialComm](http://fazecast.github.io/jSerialComm/)"のサンプルを紹介します。
実際は"[jSerialComm](http://fazecast.github.io/jSerialComm/)"を利用している"[Netty-Transport-jSerialComm](https://github.com/Ziver/Netty-Transport-jSerialComm)"を直接利用します。

# サンプル
## maven
pom.xmlにnetty-transport-jserialcommを追加します。

```xml:pom.xml
...
	<dependencies>
		<!-- https://mvnrepository.com/artifact/se.koc/netty-transport-jserialcomm -->
		<dependency>
			<groupId>se.koc</groupId>
			<artifactId>netty-transport-jserialcomm</artifactId>
			<version>1.0.0</version>
		</dependency>
	</dependencies>
...
```

## Javaソース
今回は単純にCOM5に接続して、テキストを受信し続けるサンプルを作成しています。
COM5には、手持ちのMONOWireless社のTWE-Lite-USBを利用しました。

```java:JSerialCommClient.java
package net.kyosho.serial.jsc;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.jsc.JSerialCommDeviceAddress;
import io.netty.channel.jsc.JSerialCommChannel;
import io.netty.channel.jsc.JSerialCommChannelConfig.Paritybit;
import io.netty.channel.jsc.JSerialCommChannelConfig.Stopbits;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * Sends one message to a serial device
 */
public final class JSerialCommClient {

	static final String PORT = System.getProperty("port", "COM5");

	public static void main(String[] args) throws Exception {
		EventLoopGroup group = new OioEventLoopGroup();
		try {
			Bootstrap b = new Bootstrap();
			b.group(group).channel(JSerialCommChannel.class).handler(new ChannelInitializer<JSerialCommChannel>() {
				@Override
				public void initChannel(JSerialCommChannel ch) throws Exception {
					ch.config().setBaudrate(115200).setParitybit(Paritybit.NONE).setStopbits(Stopbits.STOPBITS_1);
					ch.pipeline().addLast(new LineBasedFrameDecoder(32768), new StringEncoder(), new StringDecoder(),
							new JSerialCommClientHandler());
				}
			});

			ChannelFuture f = b.connect(new JSerialCommDeviceAddress(PORT)).sync();

			f.channel().closeFuture().sync();
		} finally {
			group.shutdownGracefully();
		}
	}
}
```

```java:JSerialCommClientHandler.java
package net.kyosho.serial.jsc;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class JSerialCommClientHandler extends SimpleChannelInboundHandler<String> {

	@Override
	public void channelActive(ChannelHandlerContext ctx) {
		ctx.writeAndFlush("AT\n");
	}

	@Override
	public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
		if ("OK".equals(msg)) {
			System.out.println("Serial port responded to AT");
		} else {
			System.out.println("Serial port responded with not-OK: " + msg);
		}
//		ctx.close();
	}
}
```

## 実行結果
実行すると以下の出力が得られます。
とりあえず、TWE-Lite-USBは1秒間隔でカウンタを出力しているのが読み取れています。

```text:output
Serial port responded with not-OK: ::ts=3760
Serial port responded with not-OK: ::ts=3761
Serial port responded with not-OK: ::ts=3762
Serial port responded with not-OK: ::ts=3763
Serial port responded with not-OK: ::ts=3764
```

# 評価

"[Netty-Transport-jSerialComm](https://github.com/Ziver/Netty-Transport-jSerialComm)"をpom.xmlに追加するだけでよいため、purejavacommよりも使いやすいですね。
(purejavacommもnetty-transportを整備してくれると同じ使い勝手になりますね)
nettyの本家サイトにリンクもついてますし、迷ったらjSerialCommとnetty-transport-jserialcommを使うと良いのではないでしょうか。