質問編集履歴

16 解決案の検討

kt.tk.co

kt.tk.co score 25

2016/11/22 03:55  投稿

シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようです。
そのためAndroidでデータを受け取り画面に表示すると、センサの値の途中で途切れた中途半端な状態で表示されてしまいます。
(Arduinoから1ビットずつ値を送っているため、Arduinoが送られてきたシリアル通信を読み込むタイミングによってセンサの値の途中で表示してしまっているものと考えています)
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける。
(送る値を、「ランダム,0,0,0,0,0,0,0,0,0,0,0¥n」にした場合)
(一番最初をランダムな値、それ以外は0で、すべてカンマ区切り。最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
(上の写真の順番は時系列に添っていませんが、更新される度に前の値の続きから表示されるので、データの欠損などはなさそうです。)
対処療法としてAndroid側にてカンマ区切りで分離しようと考えていますが、処理が複雑になってしまいうまく実装できていない状態です。(カンマ区切りに分割した後、必要な箇所は変数に代入して、¥nより後の値は次のデータ取得時に持ち越す。 といった処理がうまくできていないです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。(シリアル通信ではない?)
そういった処理を最初からできたら根本から解決できるかと考え調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothの通信時に、Arduinoで読み取ったセンサの値(アナログ値の0~1024)を複数個まとめて、Androidに送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
[このサイトより](http://d.hatena.ne.jp/kougaku-navi/20140501/p1)
「1回のSerial.write()で送れるデータは1バイト、すなわち数値として表現できる範囲は0~255です。」
とあることから、センサごとに値を送るのは難しいのかもしれません。
現在試行錯誤の真っ最中です。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つだけに減らしたコードを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
---
---
カンマ区切りでの通信
---
どうしても場当たり的な例外の処理が多く、無駄にコンピューターリソースを使っています。
このような処理の要らないシリアル通信での送受信方法を知ることが最優先事項です。
```Java
   //前回以降の残りのデータを入れる文字列型の変数
   String leftover = "";
   //カンマ区切りを分離して、表示する関数
   public void DataSplit(String msgStr){
       boolean StartFlag = false;
       boolean EndFlag = false;
       //配列の添字用にセンサ番号をカウントする
       int counter = 0;
       //前回以降の残りのデータと、今回のデータを繋げる
       msgStr = leftover + msgStr;
       //シリアル通信から送られてくるデータを分割する
       String[] SplitData = msgStr.split(",", 0);
       //取得したデータの数だけ繰り返す
       for (int i=0; i<SplitData.length; i++){
           //終了フラグが立っていなければ
           if (!EndFlag){
               //前回までにスタートがあれば
               if (StartFlag){
                   //スタート以降にエンドがあるなら
                   if (SplitData[i].equals("E")){
                       EndFlag = true;
                       //Eがあれば一度空にして、残ったものだけを引き次ぐ
                       leftover = "";
                   }else{
                       // 「null以外」 かつ 「空欄ではない」 なら (,区切りが先頭または最後に来ていると、残りデータとの結合時に,,となってしまう可能性があるため)
                       if(SplitData[i].trim() != null && !SplitData[i].trim().equals("")){
                           //センサーデータの配列に入れる
                           SensorData[counter] = SplitData[i]; //スタートの次からデータ配列に入れ始める
                           counter++;//カウンターを増やす
                       }
                   }
               //今がスタートであれば
               }else if (SplitData[i].equals("S")){
                   StartFlag = true;
               }
           }else{
               //カンマ区切りの最後の数値 かつ 文字の一番最後にカンマがない
               if (i == SplitData.length - 1 && msgStr.charAt(msgStr.length()-1) !=',' ){
                   //最後なら、一番最後に,を入れない!
                   //終了フラグが立っていれば、一つずつ残りデータに入れていく
                   leftover = leftover + "," +SplitData[i]; //前後にカンマを入れる。カンマは連続しても問題ない(カンマ区切りで抽出したものが空白になるため除外できる)が、カンマ無しで数値が繋がると問題なため。
               }else{
                   //終了フラグが立っていれば、一つずつ残りデータに入れていく
                   leftover = leftover + "," +SplitData[i] + ","; //前後にカンマを入れる。カンマは連続しても問題ない(カンマ区切りで抽出したものが空白になるため除外できる)が、カンマ無しで数値が繋がると問題なため。
               }
           }
       }
       //エンドがあれば、センサのデータ配列に入れ、あまりを繰り越す
       if (EndFlag){
           //出力文字を定義
           String OutputString = "";
           //出力用にセンサーの文字を結合する
           for (int i=0; i<12; i++){
               OutputString = OutputString +"センサ " + String.valueOf(i) + " = " + SensorData[i] + "\n";
           }
           //画面に出力する
           Message valueMsg = new Message();
           valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
           valueMsg.obj = OutputString; //Arduinoから取得したメッセージを代入
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       }else{//エンドがなければ、何もせずにシリアル通信のデータを繰り越す
           //Eがない場合はそのまま引き継ぐため代入。
           leftover = msgStr;
       }
   }
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

15 編集22

kt.tk.co

kt.tk.co score 25

2016/11/21 22:40  投稿

シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサの値の中途半端なタイミングで受け取ってしまいます。
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようです。
そのためAndroidでデータを受け取り画面に表示すると、センサの値の途中で途切れた中途半端な状態で表示されてしまいます。
(Arduinoから1ビットずつ値を送っているため、Arduinoが送られてきたシリアル通信を読み込むタイミングによってセンサの値の途中で表示してしまっているものと考えています)
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
1. Arduinoから12個の値をシリアル通信で送り続ける。
(送る値を、「ランダム,0,0,0,0,0,0,0,0,0,0,0¥n」にした場合)
(一番最初をランダムな値、それ以外は0で、すべてカンマ区切り。最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
(上の写真の順番は時系列に添っていませんが、更新される度に前の値の続きから表示されるので、データの欠損などはなさそうです。)
対処療法としてAndroid側にてカンマ区切りで分離しようと考えていますが、処理が複雑になってしまいうまく実装できていない状態です。(カンマ区切りに分割した後、必要な箇所は変数に代入して、¥nより後の値は次のデータ取得時に持ち越す。 といった処理がうまくできていないです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。(シリアル通信ではない?)
そういった処理を最初からできたら根本から解決できるかと考え調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
**Bluetoothの通信時に、Arduinoで読み取ったセンサの値(アナログ値の0~1024)を複数個まとめて、Androidに送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
[このサイトより](http://d.hatena.ne.jp/kougaku-navi/20140501/p1)
「1回のSerial.write()で送れるデータは1バイト、すなわち数値として表現できる範囲は0~255です。」
とあることから、センサごとに値を送るのは難しいのかもしれません。
現在試行錯誤の真っ最中です。  
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つだけに減らしたコードを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
---
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

14 変更2

kt.tk.co

kt.tk.co score 25

2016/11/21 22:28  投稿

シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサの値の中途半端なタイミングで受け取ってしまいます。
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
[このサイトより](http://d.hatena.ne.jp/kougaku-navi/20140501/p1)
「1回のSerial.write()で送れるデータは1バイト、すなわち数値として表現できる範囲は0~255です。」
とあることから、センサごとに値を送るのは難しいのかもしれません。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つだけに減らしたコードを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
 
---
---
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

13 変更

kt.tk.co

kt.tk.co score 25

2016/11/21 22:26  投稿

シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサの値の中途半端なタイミングで受け取ってしまいます。
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
[このサイトより](http://d.hatena.ne.jp/kougaku-navi/20140501/p1)
「1回のSerial.write()で送れるデータは1バイト、すなわち数値として表現できる範囲は0~255です。」
とあることから、センサごとに値を送るのは難しいのかもしれません。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つとしてまとめたものを載せました。)
■Bluetooth接続時のコード(簡略化のため、センサを2つだけに減らしたコードを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
---
---
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

12 画像の訂正

kt.tk.co

kt.tk.co score 25

2016/11/21 22:22  投稿

シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサの値の中途半端なタイミングで受け取ってしまいます。
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
 
[このサイトより](http://d.hatena.ne.jp/kougaku-navi/20140501/p1)  
「1回のSerial.write()で送れるデータは1バイト、すなわち数値として表現できる範囲は0~255です。」  
とあることから、センサごとに値を送るのは難しいのかもしれません。  
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
---
---
現在、
Serial.write(buf, len)
で実行できないか試しております。
---
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

11

kt.tk.co

kt.tk.co score 25

2016/11/21 11:59  投稿

シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサの値の中途半端なタイミングで受け取ってしまいます。
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
```
---
---
現在、
Serial.write(buf, len)
で実行できないか試しております。
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

10 タイトルの変更

kt.tk.co

kt.tk.co score 25

2016/11/21 11:48  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
シリアル通信で複数のセンサの値を送るには? Arduino→Android Bluetooth接続時
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
ArduinoからAndroidにBluetooth接続で複数センサの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
そこで次に、Arduinoから**複数のセンサの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサの値の中途半端なタイミングで受け取ってしまいます。
・例 センサ12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサごとにArduinoからデータを送ってもらい、Androidでセンサごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

9 解説の追加

kt.tk.co

kt.tk.co score 25

2016/11/21 11:47  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
■Bluetooth接続時のコード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
Bluetoothで無線化をする前は、USBホストケーブルでセンサの値を送っていました。
処理は問題なく、Androidでセンサごとにデータを受け取ることができておりました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

8 段落

kt.tk.co

kt.tk.co score 25

2016/11/21 11:46  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
■Bluetooth接続時のコード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
以下にコードを記載します。
■USBホストケーブル接続時のコード
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

7 誤字

kt.tk.co

kt.tk.co score 25

2016/11/21 11:44  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
●考え
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。
```Arduino
acc.write(&pack, sizeof(Pack));
```
しかし、Arduinoの上のコマンドUSBホストケーブルでの接続時でしか実行できないようでした。
しかし、Arduinoのacc.writeコマンドはUSBホストケーブルでの接続時でしか実行できないようでした。
そのため、シリアル通信で同様の送信方法がないかと探しております。
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

6 疑問点の更新

kt.tk.co

kt.tk.co score 25

2016/11/21 11:44  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
●問題
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
●質問内容
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
 
●考え  
Bluetooth時にも、USBホストケーブルと同様の「Arduinoからの送信処理」を行えば実現できそうと考えていました。  
```Arduino  
acc.write(&pack, sizeof(Pack));  
```  
しかし、Arduinoの上のコマンドUSBホストケーブルでの接続時でしか実行できないようでした。  
そのため、シリアル通信で同様の送信方法がないかと探しております。  
 
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
その際には次のコードで上手く動作していたのですが、
Arduinoの次のコマンドは実行できず、USBホストケーブル接続時にしか使用できないようでした。
```Arduino
acc.write(&pack, sizeof(Pack));
```
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

5 段落の変更

kt.tk.co

kt.tk.co score 25

2016/11/21 11:38  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●問題・質問内容
●手段
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
 
●問題  
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
 
●質問内容  
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
その際には次のコードで上手く動作していたのですが、
Arduinoの次のコマンドは実行できず、USBホストケーブル接続時にしか使用できないようでした。
```Arduino
acc.write(&pack, sizeof(Pack));
```
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

4 文章の修正m

kt.tk.co

kt.tk.co score 25

2016/11/21 11:37  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●問題・質問内容
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を「500±ランダム,0,0,0,~,0,0¥n」にした場合)
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を、一番「500±ランダム,0,0,0,~,0,0¥n」にした場合) ←(一番最初をランダムな値、それ以外は0の","区切りで計12個、最後に¥n)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
その際には次のコードで上手く動作していたのですが、
Arduinoの次のコマンドは実行できず、USBホストケーブル接続時にしか使用できないようでした。
```Arduino
acc.write(&pack, sizeof(Pack));
```
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

3 文章の修正

kt.tk.co

kt.tk.co score 25

2016/11/21 11:35  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●問題・質問内容
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから複数のセンサーの値をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
そこで次に、Arduinoから**複数のセンサーの値**をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を「500±ランダム,0,0,0,~,0,0¥n」にした場合)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
その際には次のコードで上手く動作していたのですが、
Arduinoの次のコマンドは実行できず、USBホストケーブル接続時にしか使用できないようでした。
```Arduino
acc.write(&pack, sizeof(Pack));
```
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

2 更新 文字

kt.tk.co

kt.tk.co score 25

2016/11/21 11:34  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●問題・質問内容
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て問題なく同じものを動作させることができました。
複数のセンサーの値をシリアル通信で送り、Androidでセンサごとに変数へ値を入れたいです。
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまうようです。
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て、全く同じコードで問題なく動作させることができました。
そこで次に、Arduinoから複数のセンサーの値をシリアル通信で送り、Androidで受信してセンサごとの変数へ代入を行いたいです。
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまいます。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を「500±ランダム,0,0,0,~,0,0¥n」にした場合)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。
(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
そもそも、USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
その際には次のコードで上手く動作していたのですが、
Arduinoの次のコマンドは実行できず、USBホストケーブル接続時にしか使用できないようでした。
```Arduino
acc.write(&pack, sizeof(Pack));
```
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

1 更新

kt.tk.co

kt.tk.co score 25

2016/11/21 11:32  投稿

AndroidとArduino間 Bluetooth接続時のシリアル通信 複数のセンサーのデータを送るには?
■目的・課題
--
●目的
ArduinoからAndroidに複数センサーの値を送りたいと考えております。
ArduinoからAndroidにBluetooth接続で複数センサーの値を送りたいと考えております。
イメージ
![イメージ](f7935266563451fe8868ea56ae888908.png)
●問題・質問内容
ArduinoとAndroidのBluetooth接続は[参考サイト](https://sites.google.com/a/gclue.jp/fab-zang-docs/sumafo-lian-xie/02-arduino-android)を見て問題なく同じものを動作させることができました。
複数のセンサーの値をシリアル通信で送り、Androidでセンサごとに変数へ値を入れたいです。
ただし、調べたところシリアル通信は「データを1ビットずつ連続的に送受信する通信方式」のようで、Androidでデータを受け取るとセンサーの値の中途半端なタイミングで受け取ってしまうようです。
・例 センサー12個の場合
1. Arduinoから12個の値をシリアル通信で送り続ける(送る値を「500±ランダム,0,0,0,~,0,0¥n」にした場合)
2. Androidに表示される値は次のようになります。
![イメージ説明](ee0488a6bfbc42ce76e9029e5d47e426.jpeg)
![イメージ説明](af756a943b315ab3f261f7edb205db68.jpeg)
![イメージ説明](dea3def2310e3f9628db68bdf63bfeee.jpeg)
![イメージ説明](888bcda556b4aa6ccd5e7bdf9e66cfd1.jpeg)
このように、取得のタイミングがずれてしまうため、”,”区切りで分離しようとしても処理が上手く行えていない状態です。(上の写真の順番は時系列に添っていませんが、更新される度に前の画面の続きからデータが表示されるので、データの欠損などはなさそうです。)
USBホストケーブルで行っていたとき(下にまとめました)には、センサーごとにArduinoからデータを送ってもらい、Androidでセンサーごとの変数へ代入できていました。
そういった処理を最初からできると思い調べていますが、なかなか良い方法が分からずに困っています。
**Bluetoothのシリアル通信時に、複数センサの値を送る適切な方法をお教えいただけますと幸いです。**
回路
![イメージ説明](005cb458cbd1b1f7e4e22015f34e4dc4.jpeg)
コード(簡略化のため、センサを2つとしてまとめたものを載せました。)
Arduinoの送信部分
```C
//文字を送るために、文字のバッファを定義
char buff[255];
////////////
//初期設定//
////////////
void setup(){
 // arduinoのシリアルモニタ用
 Serial.begin(19200);
 
 // Bluetooth用のシリアルのポートを設定
 Serial1.begin(9600);
 
}
void loop(){
 //バッファに値を代入
 sprintf(buff, "%d,%d\n",analogRead(0),analogRead(1));
 //Arduinoにセンサの値を送る
 Serial1.write(buff);
}
```
Andrroidの受信部分
```Java
   
      InputStream mmInStream = null;
       Message valueMsg = new Message(); //メッセージを入れる変数
       valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
       valueMsg.obj = "connecting..."; //ステータスに書き込むテキストを指定
       mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
       try{
           // 取得したデバイス名を使ってBluetoothでSocket接続
           mSocket = mDevice.createRfcommSocketToServiceRecord(MY_UUID);
           mSocket.connect();
           mmInStream = mSocket.getInputStream();
           mmOutputStream = mSocket.getOutputStream();
           // InputStreamのバッファを格納
           byte[] buffer = new byte[1024];
           // 取得したバッファのサイズを格納
           int bytes;
           valueMsg = new Message();
           valueMsg.what = VIEW_STATUS; //メッセージがステータスである とする
           valueMsg.obj = "connected."; //ステータスに書き込むテキストを指定
           mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
           //接続中である とする
           connectFlg = true;
           //フラグが立っていれば、Arduinoからシリアル通信のデータを読み込み
           while(isRunning){
               // InputStreamの読み込み
               bytes = mmInStream.read(buffer); //シリアル通信で送られてきたデータサイズを取得
               Log.i(TAG,"bytes="+bytes); //データサイズをログに書き出し
               // String型に変換
               String readMsg = new String(buffer, 0, bytes); //データそのもの,?,データサイズ
               // 「null以外」 かつ 「空欄ではない」 なら表示
               if(readMsg.trim() != null && !readMsg.trim().equals("")){
                    Log.i(TAG,"value="+readMsg.trim());
                    valueMsg = new Message();
                    valueMsg.what = VIEW_INPUT; //メッセージがシリアル通信のINPUTである とする
                    valueMsg.obj = readMsg; //Arduinoから取得したメッセージを代入
                    mHandler.sendMessage(valueMsg); //テキスト書き換え関数を実行する
               }
               else{
                  // Log.i(TAG,"value=nodata");
               }
          }
       }catch(Exception e){
       }
```
---
---
■USBホストケーブルでの通信
--
Bluetoothで無線化をする前は、USBホストケーブルでセンサーの値を送っていました。
![イメージ説明](5734849d509c8df21b7c5ee19b2dd032.png)
その際には次のコードで上手く動作していたのですが、
Arduinoの次のコマンドは実行できず、USBホストケーブル接続時にしか使用できないようでした。
```Arduino
acc.write(&pack, sizeof(Pack));
```
以下にコードを記載します。
Arduinoの送信部分
```C
//AndroidのUSBアクセサリ接続
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
// AndroidAccessoryオブジェクト作成
AndroidAccessory acc("MyManufacturer",        // 製造者名
                    "MyModel",                    // モデル名
                    "テスト",  // 説明文
                    "1.0",                        // バージョン名
                    "http://android.com",         // URL
                    "0000000012345678");          // シリアル番号
// Andloidにデータを送るためのパッケージを定義
struct Pack {
 long sensor1;  /* 4バイト */
 long sensor2;  /* 4バイト */
};
struct Pack pack;
////////////
//初期設定//
////////////
void setup()
{
 Serial.begin(9600);
 
 acc.powerOn(); //USB Host機能を有効にする。(Androidの通信用)
}
void loop(){
 //装置(Android)に接続していたら
 if (acc.isConnected()) {
   //メッセージ生成 (packの中に送りたいメッセージを詰め込む)
   pack.sensor1 = analogRead(0);
   pack.sensor2 = analogRead(1);
   //データをAndroidに送る
   acc.write(&pack, sizeof(Pack));
 }
}
```
Andrroidの受信部分
```Java
       //センサの値を入れる変数
       int SensorVal[] = new int[2];
       //受信データを入れる変数
       byte [] buffer = new byte[100000];//受信した全てのデータ
       //初めは必ず読み取りに行く
       int ret = 0; //受信データの長さ「ret」を定義する
       // Arduinoから受信
       try {
           //入力ストリームの読み込み
           ret = mInputStream.read(buffer);
       } catch (IOException e) {
           e.printStackTrace();
       }
       //取得したデータを、センサごとに分ける。
       byte[] arr = new byte[ret];
       System.arraycopy(buffer,0,arr,0,ret);
       ByteBuffer byteBuffer = ByteBuffer.wrap(arr);
       byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
   //得られた値を変数に入れる
       SensorVal[0] = byteBuffer.getInt();      // 4バイト
       SensorVal[1] = byteBuffer.getInt();      // 4バイト
```
  • Android

    7762 questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Bluetooth

    297 questions

    Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

  • シリアルポート

    64 questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

  • Arduino

    753 questions

    Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る