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

大家久等了, 本篇文章告訴您如何在 Android 手機端接收兩筆 Arduino 的資料,這次是以 A0, A1 兩隻腳位來處理。本範例感謝嘉義高工張老師提供。

如果您要換成其他元件,例如數位感測器的話,做法是一樣的。請先看一下這個元件的資料範圍是多少。對於本範例的架構來說,最後就是透過藍牙傳一個陣列出去,因此重點在於您是否可先在 Serial Monitor 中看到正確的資料範圍。不過一般來說都會有讀值得範例程式,所以不用太擔心啦!

您可以擴充這個架構到 N 筆,但是筆數愈多,掉資料的機會也愈高。請自行斟酌喔!

[雙A計畫] 常見問題整理

[雙A計畫] 藍芽模組(HC05/06)常用指令教學

[雙A計劃] Part0:App Inventor 透過藍牙傳送訊號給 Arduino

[雙A計劃] Part2:App Inventor 經由藍牙控制 Arduino LED 漸明漸暗

[雙A計劃] Part3:Android 手機透過藍牙接收 Arduino 類比腳位狀態

[雙A計劃] Part4:App Inventor 藍牙遙控 Arduino 雙輪機器人

[雙A計劃] Part5:Paperduino 藍牙控制 LED 閃爍

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

[雙A計劃] Part7:Arduino超音波感測距離回傳數值給Android手機

[雙A計劃] Part8:Android 手機對 Arduino 同時進行資料收發

English version

Arduino LED Blink

Arduino LED PWM

Arduino LED Blink (Arduino 101 with BLE)

Arduino LED PWM (Arduino 101 with BLE)


在撰寫程式前我們先準備以下材料:範例程式請點我下載(App Inventor中文學習網檔案庫)

材料清單:

1 Android系統智慧型手機

2.Arduino相容開發板

3.藍牙收發接收器 (本系列使用JY-MCU04 or JY-MCU05)

4. 電位計

5. 光敏電阻

6. 1k~10k 歐姆電阻,用於光敏電阻

請按照電路圖將電路接上,接了一個電位器(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);
}

65 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

Tai 發表迴響 取消回覆

你的電子郵件位址並不會被公開。 必要欄位標記為 *