【雙A計畫】Part6:Arduino 傳兩筆資料到 Android 手機

大家久等了, 本篇文章告訴您如何在 Android 手機端接收兩筆 Arduino 的資料,這次是以 A0, A1 兩隻腳位來處理。本範例感謝嘉義高工張老師提供。 如果您要換成其他元件,例如數位感測器的話,做法是一樣的。請先看一下這個元件的資料範圍是多少。對於本範例的架構來說,最後就是透過藍牙傳一個陣列出去,因此重點在於您是否可先在 Serial Monitor 中看到正確的資料範圍。不過一般來說都會有讀值得範例程式,所以不用太擔心啦! 您可以擴充這個架構到 N 筆,但是筆數愈多,掉資料的機會也愈高。請自行斟酌喔!

雙A計畫文章總覽:

中文系列文章

English version

 

作者/攝影   曾吉弘
難度

★★★☆☆

材料表

【推薦套件】自學者的天堂|Arduino 入門到雲端基本套件包

下載

範例程式請點我下載(App Inventor中文學習網檔案庫)

請按照電路圖將電路接上,接了一個電位器(A0)與光敏電阻(A1)。當然啦,您也可以兩個腳位都用相同的元件,方便就好。為了不讓大家眼花,藍牙發射器另外獨立出來表示 (藍牙RX – Arduino D11, 藍牙TX – Arduino D10腳位)

未命名
A0:電位計。A1:光敏電阻
螢幕快照-2014-10-30-上午12.41.36
TX: Arduino D11, RX: Arduino D10

 

 

App Inventor 端程式

由於連線斷線的做法都是差不多的,在此把連線相關指令整理如下圖。請注意Clock timer 一開始是關閉的,我們會在連線成功之後才會將其啟動來發送藍牙指令,否則會一直跳出錯誤訊息(因為還沒連線啊!)
 
在 Clock.timer 事件中,首先發送一個數字49給Arduino,代表”我要發資料囉!” Arduino 則是先用 BluetoothClient.ReceiveText 指令,如果讀到’a’,就接續讀取後面兩筆資料,這就是 A0 腳位的數值。請注意在此之所以要判斷 text 變數之否小於0再加上 256,是由於Arduino 的 8 bit 整數範圍是 -127 ~ 128 的緣故。
 
 
反之如果App 收到字元 ‘b‘ 就是 A1 腳位。作法同上。
 
 
接著在Clock.timer 事件最後將這兩筆數值(value_A0value_A1) 顯示於 Textbox,並且用這兩筆數值來控制 Canvas 上面的小飛機移動,快點來玩雷電遊戲吧!
 
螢幕快照 2015-04-05 上午1.11.29
 
 
因為資料傳輸過程中難免會遺漏,因此我們都是先抓到火車頭(就是’a’ 與 ‘b’),確定這是一筆新的資料開頭之後,再去讀取數值,否則可能會發生數值亂跳的情形。另一方面,App Inventor 在藍牙傳輸的延遲狀況較明顯,請注意喔!
 
Arduino 端程式如下,我們把 A0 腳位的資料用 ‘a‘ 作為標頭,由於資料長度大於 1 byte ( 2的8次方),因此需要用到 2 bytes 才能把 A0 的數值範圍 (0~1023) 涵蓋進去,因此 Data[1]~Data[2] 就代表A0 腳位的資料,Data[4]~Data[5] 就是A1 腳位的資料:(Data [0] = ‘a’, Data[3] = ‘b’ 這兩個火車頭別忘記囉~)
 
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial I2CBT(10,11); // TX:10, RX:11
byte serialA;

void setup(){ 
  Serial.begin(9600);
  I2CBT.begin(9600);
}
 
void loop (){
    byte Data[6];
    byte cmmd[20];
    int insize;
    int x=analogRead(A0);//read sensor value
    int y=analogRead(A1);//read sensor value
    serialA=I2CBT.read();
    Data[0]='a';
    Data[1]=x/256;
    Data[2]=x%256;
    Data[3]='b';
    Data[4]=y/256;
    Data[5]=y%256;
     Serial.print(x);
     Serial.print(" , ");
     Serial.println(y);
 
     if (serialA == 49){
         for(int j=0;j<5;j++)
         I2CBT.write(Data[j]);
         serialA=0;
      }
  delay(100);
}
 

75 thoughts on “【雙A計畫】Part6:Arduino 傳兩筆資料到 Android 手機

  1. 杜同學 says:

    我藍芽連線後視窗會有一個Error515:Notconnected to bluetooth device.但是我有連上藍芽他卻一職跳出這個 有接收到值 但是 第二筆353都不會變

    • CAVEDU 阿吉 - 雜工 says:

      您好,資料傳送的過程中本來就容易遺失,無線傳輸(Wifi, BT)尤其明顯。您可以把兩筆資料組合成同一筆之後送出,犧牲精確度來換即時性。例如我可以把 0~ 1023 / 10 之後變成 0~100 左右的範圍再送出去,App Inventor 接到這個數字之後再 x 10 就好了

  2. 政昜 says:

    我想用arduino板子上的A0去接到紅外線測距的電路上,讓APP可以跑出測距的數值,請問APP INVENTOR跟arduino的程式要如何去做修改呢?

    • CAVEDU 阿吉 - 雜工 says:

      您好,接在 A0 的話,只要確認您所用的紅外線測距模組回傳數值範圍,如果是與電位計一樣介於 0~1023 之前的話,App Inventor 端程式完全不用修改。您可以先從 Serial Monitor 中看看紅外線測距數值是否正確,正確的話就可以直接發送

  3. DC says:

    我想請教,如果我是要傳在arduino裡計算好有小數點6碼的資料,arduino程式跟 ai2的程式該怎麼改,謝謝。

  4. 孟哲 says:

    我自己寫了一個Arduino 讀取電壓的程式 那我要怎麼把我讀到的值回傳至APP作顯示 這個值有小數點

  5. 水鏡窯 says:

    我找到問題點了,ARDUINO的程式有錯
    if (serialA == 49){
    for(int j=0;j這行錯了
    I2CBT.write(Data[j]);
    serialA=0;
    }

    是6不是5

  6. yuan says:

    為什麼在Serial Monitor有A0跟A1的數值再跑
    但是手機APP連接到藍芽後 螢幕中的數值卻沒有動靜

  7. Pikachu says:

    想請問一下,
    若我Arduino端要回傳至手機的是”溫溼度感測器”的數值,
    可直接使用此篇的程式碼(AI2跟Arduino)嗎?或是需要更改呢?

    感謝幫忙!

  8. siang says:

    請問如果我資料的”整數int”如果是小於256是不是就可以直接傳?
    數字如果大於256才要/256嗎?

  9. 呂明軒 says:

    不好意思沒事了~~~看到上面提供了範例檔
    另外想問 傳送讀取數位的資料一樣也是要
    Data[3]=’b’;
    Data[4]=y/256;
    Data[5]=y%256;
    這樣嗎?

  10. sheng says:

    請問一下我想把溫濕度感測器的值傳到手機的話,用上面的app程式碼和arduino的程式碼的話需要修改嗎?

  11. Kevin says:

    請問一下 按上面回復的 數值超過255 才需要拆封包處理
    可是溫溼度傳感器 的數值 好像沒有 大於255
    可是我在測試的時候 必須要/256 才會顯示正常數值

    另外 請問一下 %256 的用意是?

  12. 陳俞佑 says:

    想請問一下,這個程式可以接pluse sensor 和Neo 6M GPS嗎?因為一樣是兩筆資料透過HC-05回傳的,所以不知道這程式能不能用?

  13. 小草 says:

    想請教一下,如果我是想用Neo 6M GPS來和andriod手機資料的傳遞,想請問應該怎麼用才好,neo 6m gps的輸出腳位和這程式要怎麼修改啊,求教QAQ

    • CAVEDU 阿吉 - 雜工 says:

      概念差不多吧,先確定Arduino端可以正確讀取GPS data之後,再用本文程式傳出去就好,但您可能需要把資料格式做一些調整,例如都轉成整數後再發送出去,也要注意長度。本文的資料長度一筆可到 2 bytes

  14. eric says:

    我點下連接之後一直跳出
    invoke:no method named ‘addressandnames’ in class
    com.google.appinventor.components.rubtime.bluetoothserver

  15. Tai says:

    App Inventor 端程式:

    在 Clock.timer 事件中,則是先用 BluetoothClient.ReceiveText 指令,如果讀到’a’,就接續讀取後面兩筆資料,這就是 A0 腳位的數值。反之如果是 ‘b’ 就是 A1 腳位。
    螢幕快照 2015-04-05 上午1.11.20
    接著在Clock.timer 事件最後將這兩筆數值(value_A0, value_A1) 顯示於 Textbox,並且用這兩筆數值來控制 Canvas 上面的小飛機移動,快點來玩雷電遊戲吧!

    螢幕快照那邊沒辦法看

  16. Tai says:

    #include
    #include
    SoftwareSerial I2CBT(10,11); // TX:10, RX:11
    byte serialA;

    void setup(){
    Serial.begin(9600);
    I2CBT.begin(9600);//與藍牙發射器的鮑率為 9600
    }

    void loop (){
    byte Data[9];//此變數為封包
    byte cmmd[20];
    int insize;
    int x=analogRead(A0);//read sensor value 讀取感應器值
    int y=analogRead(A1);//read sensor value 讀取感應器值
    int z=analogRead(A2);//read sensor value 讀取感應器值
    serialA=I2CBT.read();//接收 Android 藍牙資料
    // 將感應器數值包成封包,由於類比腳位的值為0~1023,加上’a’,因此使用了三個Byte來傳送。

    // i 除以 256 以及對 256 取餘數就是以位元組(8 bits)為單位來拆封包噢!
    Data[0]=’a’;//確認碼
    Data[1]=x/256;
    Data[2]=x%256;
    Data[3]=’b’;//確認碼
    Data[4]=y/256;
    Data[5]=y%256;
    Data[6]=’c’;//確認碼
    Data[7]=z/256;
    Data[8]=z%256;
    Serial.print(x);//顯示感應器數值
    Serial.print(” , “);
    Serial.println(y);//顯示感應器數值
    Serial.print(” , “);
    Serial.println(z);//顯示感應器數值

    if (serialA == 49) //判斷從手機接收到的訊號是否為”49”
    {
    /* 傳送封包 */
    for(int j=0;j<8;j++)
    I2CBT.write(Data[j]);
    serialA=0;
    delay(1000);
    }
    //delay(100)
    }

    如果我要顯示A0,A1,A2 我這樣是否打對?

    for(int j=0;j<8;j++) 這行的 j<8正確還是 j<9

  17. Tai says:

    2015-04-05 01.15.40
    因為資料傳輸過程中難免會遺漏,因此我們都是先抓到火車頭(就是’a’ 與 ‘b’),確定這是一筆新的資料開頭之後,再去讀取數值,否則可能會發生數值亂跳的情形噢。另一方面,App Inventor 在藍牙傳輸的延遲狀況較明顯,請注意喔

    這邊也是 沒辦法看螢幕快照

  18. Tai says:

    App Inventor 端程式:

    在 Clock.timer 事件中,則是先用 BluetoothClient.ReceiveText 指令,如果讀到’a’,就接續讀取後面兩筆資料,這就是 A0 腳位的數值。反之如果是 ‘b’ 就是 A1 腳位。
    螢幕快照 2015-04-05 上午1.11.20

    2015-04-05 01.15.40
    因為資料傳輸過程中難免會遺漏,因此我們都是先抓到火車頭(就是’a’ 與 ‘b’),確定這是一筆新的資料開頭之後,再去讀取數值,否則可能會發生數值亂跳的情形噢。另一方面,App Inventor 在藍牙傳輸的延遲狀況較明顯,請注意喔

    都沒辦法看

  19. DD says:

    您好,我現在的專題是這樣:
    arduino端接按鈕,按下按鈕使得APP有圖片切換
    算是透過arduino控制APP
    請問有人做過類似的題目可以參考嗎?
    現在卡在不知道如何讓藍芽讀取字元(BT.read()不知道如何使用?會存取什麼資料?)
    謝謝老師幫忙!

    • CAVEDU 阿吉 - 雜工 says:

      3或4個職就繼續搭火車就好啦,但我們實際測試超過三個以上的值會明顯lag,例如以下:
      Data[0]='a';
          Data[1]=x/256; //sensor #1
          Data[2]=x%256; //sensor #1
          Data[3]='b';
          Data[4]=y/256; //sensor #2
          Data[5]=y%256; //sensor #2
      Data[6]='c';
          Data[7]=z/256; //sensor #3
          Data[8]=z%256; //sensor #3

  20. DODO says:

    老師您好,請問老師有Arduino透過RFID讀取Mifare白卡UID並同時傳UID資料給App inventor端的練習嗎? 或者能提供相關資料? 萬分感謝!!

  21. JOY says:

    想請問APP傳一樣的值過去給Arduino 為什麼Arduino收到的值會不一樣 要怎麼修正? 該從Arduino還是從APP修正?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *