ボタンを押すとAndroidのBluetooth機能を通じてBluetoothモジュールRN42に通信がなされ、その値をArduinoで読み取りLEDを光らせる。
こういったものを作っています。
このアプリ作成にあたってUnityからBluetoothを扱う方法を調べるうち、Unityにネイティブプラグインというものを加えAndroidの機能(ここではBluetooth)を使用する方法があると知りました。
さらに調べた結果、Android Studioを用いてJava Libraryを作成。ここにUnityから呼び出せる関数として機能をまとめておくことでBluetoothも使えると考えました。
そこで参考にしたのがこのページです。これはAndroid Studioで作成するアプリでBluetoothを使用するためのものですが、これをLibraryに関数としてまとめてしまえば、Unityから呼び出しても使用できる!
そう思っていたのですが・・・
次に、実際に作成したAndroid Libraryのソースを記します。
lang
1package com.hoge.bluetooth_plugin_library; 2 3import android.app.AlertDialog; 4import android.bluetooth.BluetoothAdapter; 5import android.bluetooth.BluetoothDevice; 6import android.bluetooth.BluetoothSocket; 7import android.content.Context; 8 9import java.io.IOException; 10import java.io.OutputStream; 11import java.util.Set; 12import java.util.UUID; 13 14 15public class BluetoothPlugin { 16 17 static private BluetoothAdapter mBTAdapter = null;// Bluetooth通信を行うために必要な情報を格納する 18 static private BluetoothDevice mBTDevice = null;// 実際に通信を行うデバイスの情報を格納する 19 static private BluetoothSocket mBTSocket = null;// ソケット情報を格納する 20 static private OutputStream mOutputStream = null;// 出力ストリーム 21 22 static private boolean connectFlg = false;// Connect確認用フラグ 23 static private String DEVICE_NAME = "RNBT-HOGE";// デバイス名 24 static private UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");// 通信規格がSPPであることを示す数字 25 26 // Bluetoothを使用するにあたっての初期設定 27 static public boolean BluetoothSetup(){ 28 29 // Bluetoothのデバイス名を取得 30 mBTAdapter = BluetoothAdapter.getDefaultAdapter(); 31 Set< BluetoothDevice > devices = mBTAdapter.getBondedDevices(); 32 for ( BluetoothDevice device : devices){ 33 if(device.getName().equals(DEVICE_NAME)){ 34 mBTDevice = device; 35 return true; 36 } 37 } 38 // 取得できなかった 39 return false; 40 } 41 42 // Bluetoothを使用して通信する 43 static public void BluetoothRun(){ 44 45 try{ 46 // 取得したデバイス名を使ってBluetoothでSocket接続 47 mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(MY_UUID); 48 mBTSocket.connect(); 49 mOutputStream = mBTSocket.getOutputStream(); 50 connectFlg = true; 51 }catch(Exception e){ 52 try{ 53 mBTSocket.close(); 54 }catch(Exception ee){} 55 56 connectFlg = false; 57 } 58 } 59 60 // Bluetoothを使用して出力する 61 static public void BluetoothSend(){ 62 63 // もしモジュールと接続できていれば 64 if(connectFlg) { 65 try { 66 mOutputStream.write("1".getBytes()); 67 } catch (IOException e) {} 68 } 69 } 70} 71
InputStreamはおそらく通信で送られてきた情報を扱う部分ですので、今回のような一方的な送信には使用しないと思い省いています。
次に、実際にUnityでこれらの関数を使用している部分を記します。
lang
1 2using UnityEngine; 3 4public class BluetoothPluginTest : MonoBehaviour 5{ 6 private AndroidJavaClass bluetoothPlugin; 7 8 private void Awake() 9 { 10 bluetoothPlugin = new AndroidJavaClass("com.hoge.bluetooth_plugin_library.BluetoothPlugin"); 11 12 // Bluetoothのセットアップを実行 13 if(bluetoothPlugin.CallStatic<bool>("BluetoothSetup")) 14 { 15 // Bluetoothの初期設定が完了 16 Debug.Log("Bluetoothの初期設定が完了しました。"); 17 } 18 else 19 { 20 // Bluetoothの初期設定が失敗 21 Debug.Log("Bluetoothの初期設定に失敗しました。"); 22 } 23 } 24 25 private void Update() 26 { 27 // Bluetoothの通信を更新 28 bluetoothPlugin.CallStatic("BluetoothRun"); 29 } 30 31 public void OnClick() 32 { 33 bluetoothPlugin.CallStatic("BluetoothSend"); 34 } 35 36} 37
また、Arduino Unoに書いたプログラムです。
C
1#include <SoftwareSerial.h> 2 3SoftwareSerial android(2,3); 4 5const int LED_PIN = 13; // デバッグ用LED 6byte data = 0; // Androidからのテキスト取得用 7bool flag = false; 8 9void setup(){ 10 // Bluetooth用のシリアルのポートを設定 11 android.begin(115200); 12 // arduinoのシリアルモニタ用 13 Serial.begin(19200); 14 // LEDピンの出力設定 15 pinMode(LED_PIN, OUTPUT); 16 17 Serial.write("init"); 18} 19 20void loop(){ 21 22 if(android.available()){ 23 data = android.read(); 24 Serial.println(data); 25 26 flag = true; 27 } 28 29 if(flag) 30 { 31 digitalWrite(LED_PIN, HIGH); 32 } 33} 34
何か情報が送られてきた時点でフラグを立て、13番のLEDを点灯させる、というプログラムにしたつもりです。
Unityから実機(Nexus7)でBuild And Runしてみると、「Made with Unity」が消えてから黒い画面のまま十数秒経ってゲーム画面が表示されます(おそらくこの間に接続されているのでしょうが、遅すぎですか?)。
ゲーム画面が表示されると同時にBluetoothモジュールの「Conect」ランプが光るので、一応接続はできているみたいです。画面からLogが見れるようにしているのですが、そこに
Blutoohの初期設定が完了しました。
と2回出ます(AwakeやStartは複数回呼ばれるらしい?)。やはり接続は成功しているみたいです。
しかしボタンを押してOnClick関数からデータを送信するBluetoothSend関数を呼び出しても、LEDには何の変化も見られません。シリアルモニタも確認しようとしたのですが、そもそもどのbpsの画面を見ていいかわからず、19200bpsの画面には「init」と書いてあるのを確認しました。しかし画面のボタンを押しても何の変化もなかったのでやはり送信はできていないと思います。
なお、この実行中非常にアプリが重いです。画面を横に傾けるのに6秒ほどかかり、ボタンを押しても反応が5秒ほど遅れます。
質問内容は次の通りです。
・全体としてこの方法での通信は可能でしょうか?
・データが送信できていない(あるいは、送信できていないと勘違いしているだけ?)理由を知りたいです。
・アプリが非常に重くなる理由を教えてください。素人の考えですが、データの送信にかかる時間が1/60秒より大きく、Unityの実行速度が早すぎて重くなっているということはないでしょうか?
以上です。少しでも手掛かりが欲しいので、一つだけでもお答えいただけると嬉しいです。ご不明な点があればお聞きください。
よろしくお願いします。
バージョン情報
Android Studio 3.2
Unity 2018.2.11f1
Arduino 1.8.5

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。