Java Microbit Serial data connect 〜シリアル通信〜

イントロダクション

ここ数日、マイクロビットでのデータ通信をやりたいと思い。。。色々と調べていました。Bluetoothで繋ごうと思ったけど、WenBluetooth APIは制限が多く面倒なので、シリアル通信をやって見てはどうだろうか?と思い調べて見たところヒット!右中間を抜けて2ベースヒットくらいの勢いです。

ちなみに、今までやったのは以下のリンクにあります。

  1. MicrobitでHttpリクエストを飛ばすためのメモ
  2. Microbitで遊ぶ〜ボタンを押す〜
  3. Microbitで遊ぶ〜シリアル通信をする〜

マイクロビットからシリアル通信でデータを飛ばす→PCで受信することを確認したので、今度は受信したデータをHTTPリクエストで送信することを考えます。

そしたらJavaの出番かね?

このように思いました。じゃ、早速調べます。。。

「Javaでシリアル通信を行う」を調べて、見つけたのはjavax.commパッケージを使用してttyの入力を受け取る方法です。

javax.commパッケージのダウンロード

上のリンクからJARファイルをダウンロード。

そして、javax.commの使い方(サンプル)を見て実装(写経)します。

いつものように、ビルドパスの設定を行います。

  1. プロジェクトを右クリック
  2. プロジェクトのプロパティを開く
  3. Java BuildPathを選択する

そしてAdd External Jarsを選択して、ダウンロードしてきたJarファイルを選択します。 ※comm-2.0.jarを選択


そして写経する。。。

 

package jp.zenryoku.app.microbit;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;

import javax.comm.CommDriver;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

/**
 * シリアル通信で送られてきたデータを受信します。
 * 使用する外部ライブラリ: javax.comm
 * 
 * @see http://www.java2s.com/Code/Jar/c/Downloadcomm20jar.htm
 * @author takunoji
 * 2018/12/05
 */
public class SerialReciever implements Runnable, SerialPortEventListener {
	/** シリアルポート(ID) */
	static CommPortIdentifier portId;
	/** 使用可能なポートのEnumeration */
	static Enumeration portList;
	/** 入力 */
	InputStream inputStream;
	/** シリアルポート */
	SerialPort serialPort;
	/** 受信するスレッド(Javaの起動スレッド) */
	Thread readThread;
	
	public static void main(String[] args) {
		// 初期化処理(必要な情報を集めます)
		initReciever(true);
		System.out.println("*** System Propertiees ***");
		System.out.println("java.home: " + System.getProperty("java.home"));
		System.out.println("**************************");
		// ポートが、あるか、ないか。。。
		boolean portFound = false;
		// デフォルトポート
		String defaultPort = "/dev/tty.usbmodemFA132";
		CommPortIdentifier.addPortName(defaultPort, CommPortIdentifier.PORT_SERIAL, null);
		if (args.length > 0) {
			// プログラム引数がある場合はこれをデフォルトポートにする
			defaultPort = args[0];
		}
		// ポートの取得
		portList = CommPortIdentifier.getPortIdentifiers();
		System.out.println("hasMoreElements: " + portList.hasMoreElements());
		while (portList.hasMoreElements()) {
			portId = (CommPortIdentifier) portList.nextElement();
			if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				String portName = portId.getName();
				System.out.println("portName: " + portName);
				if (defaultPort.equals(portName)) {
					System.out.println("PortFound: " + portName);
					portFound = true;
					SerialReciever recieve = new SerialReciever();
				}
			}
		}
		if (portFound == false) {
			System.out.println(defaultPort + " is not found...");
		}
		
	}

	/**
	 * コマンドを実行して必要な情報を集める
	 * @param isExecute プロパティの取得のみを行う場合はfalseに設定する
	 */
	public static void initReciever(boolean isExecute) {
		
		if (isExecute == false) {
			System.exit(0);
		}
	}
	public SerialReciever() {
		try {
		    serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
		} catch (PortInUseException e) {}

		try {
		    inputStream = serialPort.getInputStream();
		} catch (IOException e) {}

		try {
		    serialPort.addEventListener(this);
		} catch (TooManyListenersException e) {}

		serialPort.notifyOnDataAvailable(true);

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

		readThread = new Thread(this);

		readThread.start();
	    }

	    /**
	     * Method declaration
	     *
	     *
	     * @see
	     */
	    public void run() {
		try {
		    Thread.sleep(20000);
		} catch (InterruptedException e) {}
	    } 

	    /**
	     * Method declaration
	     *
	     *
	     * @param event
	     *
	     * @see
	     */
	    public void serialEvent(SerialPortEvent event) {
		switch (event.getEventType()) {

		case SerialPortEvent.BI:

		case SerialPortEvent.OE:

		case SerialPortEvent.FE:

		case SerialPortEvent.PE:

		case SerialPortEvent.CD:

		case SerialPortEvent.CTS:

		case SerialPortEvent.DSR:

		case SerialPortEvent.RI:

		case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
		    break;

		case SerialPortEvent.DATA_AVAILABLE:
		    byte[] readBuffer = new byte[20];

		    try {
			while (inputStream.available() > 0) {
			    int numBytes = inputStream.read(readBuffer);
			} 

			System.out.print(new String(readBuffer));
		    } catch (IOException e) {}

		    break;
		}
    } 

}

しかし、パソコンのOSに依存する実装しかできないため、シリアルポート通信を諦めるのでした。。。

よく考えてみれば、USBシリアルポートを使うんだもんなぁ。。。そりゃOSに依存するようなぁ(笑)