株式会社インデペンデンスシステムズ横浜

システム開発エンジニアの西田五郎が運営しております。Raspberry Pi や Arduino その他新規開発案件のご依頼をお待ちしております。

Android

温度管理システム的なものを作ってみる(その3)Androidでの温度取得

投稿日:2014年7月6日 更新日:

screenshotshare_20140706_185023「温度管理システム的なものを作ってみる」の3回目です。前回はArduinoで温度データを取得する内容についてでした。今回はそのArduinoから温度データを取得するスマホ(Android)のアプリについてです。ここでのスクリーンショットはそのアプリの画面です。AndroidでArduinoとのシリアル通信を行うためのドライバは以下からのエントリで書きました。ここでもこのドライバ、ライブラリを使います。

AndroidでUSBシリアル通信(その1)ハードウェア・ソフトウェア構成等
ここでは上記のシリーズからの応用的な展開としてAndroidアプリでのArduinoから温度データを取得する通信処理について書きたいと思います。

通信といいましても、Android側からTという文字を送信してArduinoから送信される温度データを受信するだけのシンプルな送受信です。これをボタンをタッチしたら実行するという処理を実装します。

実際のプログラムの説明に入る前にですが、今回の「温度管理システム」という中ではAndroidアプリは取得した温度データをCloudへ送信するという機能もあります。(スクリーンショットの登録実行ボタンでの処理です。)この部分はCloudのプログラムについて書いた後に書きます。

それではプログラムについてですが、以下のエントリで書いた内容が基本になります。
AndroidでUSBシリアル通信(その4)ライブラリサンプルの内容

最初に認識したドライバ(ここではArduinoとのUSBケーブルのドライバ)を使って通信をします。ドライバは種類を意識しないで UsbSerialDriver クラスを使います。このクラスのopen()、close()、write()あたりを使います。実際は、SerialInputOutputManagerクラスを使ってスレッドで送受信を行います。listenerを定義して、データを受信した際の処理を実装します。やはり説明より実際に見て頂いた方がいいでしょうか。以下がこのあたりの処理です。ここでは1回の処理ごとにオープン、クローズで完結しています。

ソース全体は以下からダウンロード出来ます。位置情報の取得やCloudへの登録処理も含まれています。
(※念のためですが一切動作保証はしておりません。サンプルプログラムのレベルです。)
ソースファイル一式(USB Serialライブラリは含まれていません。)

インスタンス変数

//通信関連
private UsbSerialDriver usb = null;
private SerialInputOutputManager serialIoManager;
private final ExecutorService executor = Executors.newSingleThreadExecutor();

//受信データ関連
private int responseCounter;    //レスポンスの現在位置の読み込み用
private byte[] response;
private final int buflen = 100; //とりあえず

listenerの定義

/**
* シリアル入出力 Listener
*/
private final SerialInputOutputManager.Listener mListener =
    new SerialInputOutputManager.Listener() {

	@Override
	public void onRunError(Exception e) {
		tvMsg.setText("通信エラーが発生しました。" + e.getMessage());

		try {
		usb.close();
		} catch (IOException e1) {
		}
		serialIoManager.stop();
	}

	public void onNewData(final byte[] data) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				updateReceivedData(data);
			}
		});
	}
};

ドライバ取得

/**
* ドライバの取得
*/
private void getUsbDriver(){
	UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
	List<UsbSerialDriver> drvs = new ArrayList<UsbSerialDriver>();

	if(manager.getDeviceList().size() == 0){
	    return;
	}

    //ドライバを取得する
    //最初のドライバを利用する
    for (UsbDevice device : manager.getDeviceList().values()) {
        List<UsbSerialDriver> drivers =
                    UsbSerialProber.probeSingleDevice(manager, device);

        if (!drivers.isEmpty()) {
        	for (UsbSerialDriver driver : drivers) {
                    drvs.add(driver);
        	}
        }
    }
    usb = drvs.get(0);
}

通信開始処理

/**
* 温度データの取得
*/
private void getTempData(){
	try{
		if(usb == null){
			getUsbDriver();
		}
	}
	catch(Exception e){
		tvMsg.setText("ケーブルを再度接続して下さい。");
		btnGetTemp.setEnabled(false);
		return;
	}

	if (usb == null) {
		tvMsg.setText("ケーブルが認識出来ません。");
		return;
	}

	//接続の開始
	try{
		response = null;
		response = new byte[buflen];

		usb.open();
		usb.setParameters(9600, 8, UsbSerialDriver.STOPBITS_1, UsbSerialDriver.PARITY_NONE);

		serialIoManager = new SerialInputOutputManager(usb, mListener);
		executor.submit(serialIoManager);

		try {
			String cmd = "t";
			usb.write(cmd.getBytes(), 10000);

		} catch (Exception e) {
			tvMsg.setText("送信処理でエラーが発生しました。" + e.getMessage());

			serialIoManager.stop();
			serialIoManager = null;

			try {
				usb.close();
				usb = null;
			} catch (IOException ex) {
			}
		}
	}
	catch(IOException e){
		tvMsg.setText("送信処理で入出力エラーが発生しました。" + e.getMessage());
	}
}

データ受信時の処理

/**
* シリアル通信の受信時の処理
* @param data
*/
private void updateReceivedData(byte[] data) {

	//tvMsg.setText("受信した。");

	//受信データ取得
	boolean bCR = false;
	for(int i=0; i<data.length; i++){
		response[responseCounter] = data[i];
		responseCounter++;

		if(data[i] == '\n'){
			bCR = true;
		}
	}

	if(bCR)
	{
		try {
			String value = new String(response, "US-ASCII");
			//tvMsg.setText(value);
			tvTemp.setText(getString(R.string.label_temp) + value);

			temperature = Double.parseDouble(value);

			serialIoManager.stop();
			serialIoManager = null;

			try {
				usb.close();
				usb = null;

				tvMsg.setText("温度データを取得しました。");
				bTemp = true;
				} catch (IOException e1) {
				}

		} catch (UnsupportedEncodingException e) {
			//e.printStackTrace();
		}
	}
}

実際にArduinoを接続した状態で動作させた画面が以下です。(※ページ先頭のスクリーンショットと同じです。)この温度を取得するのボタンで温度の取得を実行します。

screenshotshare_20140706_185023

今回はここまでです。次回は、Cloud(Microsoft Azure)での処理についてです。Cloudでは温度データ、位置データを保存して表示します。




AdSense

AdSense

-Android

執筆者:

関連記事

温度管理システム的なものを作ってみる(その2)Arduinoでの温度取得からスマホへ送信

「温度管理システム的なものを作ってみる」の2回目です。前回は全体的な内容についてでした。今回はArduinoでの温度取得とスマホへの送信についてです。Arduinoは、Arduino UNOを使ってい …

AndroidでUSBシリアル通信(その2)ライブラリサンプルのArduinoスケッチ

AndroidでUSBシリアル通信の2回目です。前回はハードウェア構成、ソフトウェア構成等全体的な内容について書きました。今回はAndroidの通信相手となるArduinoのスケッチの動作確認を行って …

温度管理システム的なものを作ってみる(その1)システム概要

「温度管理システム的なものを作ってみる」の1回目です。AndroidでUSBシリアル通信の記事を書きました。(1回目はこちらから。)次は、その少し応用的な内容で書きたいと思いました。そこで、温度センサ …

AndroidでUSBシリアル通信(その4)ライブラリサンプルの内容

AndroidでUSBシリアル通信の4回目です。今回は、前回動作確認をしたライブラリサンプルの内容、つまり設定ファイルやプログラムの構成、プログラムの仕様等を見ます。 ライブライは以下です。より詳細は …

AndroidでUSBシリアル通信(その1)ハードウェア・ソフトウェア構成等

Androidスマートフォン、タブレットでUSBシリアル通信を行う方法についてです。AndroidでのUSBシリアル通信の方法は何通りかあると思いますが、今回はAndroidのUSBホスト機能とオープ …