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

雙A計畫不知不覺就來到第七篇了呢!這次我們將告訴您如何在 Android 手機端接收 Arduino端數位感測元件的數值,本範例使用的是超音波感測器讀取的距離數值。

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

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

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

       [雙A計劃] Part1:App Inventor 經由藍牙控制 Arduino LED 亮滅

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

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

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

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

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

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

本次範例App Inventor .aia範例檔下載請點我 

先來看看示範的影片吧!

 

 

在撰寫程式前我們先準備以下材料:

1 Android系統智慧型手機

2.Arduino相容開發板(本範例使用Arduino UNO)

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

4. 超音波感測器(本範例使用HC-SR04)

請先按照電路圖將電路接上,以下是超音波感測器與藍牙收發器接到Arduino的各個腳位

藍牙收發器:

GND → GND,  VCC → 5V,  TX → 11,  RX → 10

超音波感測器:

GND → GND,  VCC → 5V,  Trig → 8,  Echo → 9

Screen Shot 2015-06-06 at 9.00.05 PM

 


App Inventor 端程式:
本範例使用的App使用者介面如下:
Screen Shot 2015-06-06 at 11.43.32 AM
記得要將Clock元件的TimeInterval設定設短一點,每隔一段時間手機會去接收來自藍牙的訊息,為了避免漏接的情形,我們可以把這個間個時間改短一點,本範例使用100毫秒。
Screen Shot 2015-06-06 at 11.45.15 AM
接下來是 Blocks 頁面,全部程式碼如下圖,大致上可區分成四個區塊:
Screen Shot 2015-06-06 at 11.52.21 AM
區塊元件名稱功能
1.藍牙列表的設定when List_BT.BeforePicking在藍牙連線到裝置前,先將之前配對好的藍芽裝置匯入到準備連接的列表中
2.藍牙連線到裝置when List_BT.AfterPicking選好要連接的藍牙裝置後,將藍牙列表關閉、啟動計時器開始每隔一段時間讀值,並把斷線的按鈕設定為可執行
3.藍牙通訊(發送key與接收資料)when Clock1.Timer計時器啟動後,每隔一段時間(100ms)就會啟動一次,一開始我們會先發送一個key(=97)給Arduino,如果Arduino確任無誤的話也會發送一個key(=97)給手機,手機確認無誤後,會開始收兩個byte(1byte = 8 bits)的數值,因為Arduino端送出的數值是採用8bits的封包,所以在這邊要將它還原回來必須將它從8bits(2^8 = 256)轉回10進制,最後在除上100將單位轉成cm
4.斷線按鈕的設定when Btn_Disconnect.Click按下斷線後就會斷開藍牙通訊,並把按鈕配置回到一開始的狀態

Arduino端的程式設計:
接下來我們看到Arduino的程式碼,藉由計算超音波打到物體的收發時間間隔,再搭配上音速的計算公式,就可以算出距離,注意到本程式碼為了保留小數兩位,所以先乘上100,並化成整數再轉成兩個bytes的封包,Arduino在發送訊息之前,也會先確認是否收到手機端送來的key,確認無誤之後,就會將資料送出去,資料的前頭也會附上Arduino傳給手機端的key,一方面讓手機知道可以接收資料了,一方面也比較不會有封包漏接的情況,因為手機端每次收資料,都會將以收到的key開始做基準收兩個bytes。
程式碼如下:
#include <SoftwareSerial.h> //Arduino I2C library

const int trig =  8; //define Arduino pin
const int echo =  9;
const int TX   = 10;
const int RX   = 11;

const int delay_time = 1000; //delay 1000 ms for every measurment

SoftwareSerial BT(RX, TX); 
//set Bluetooth RX (-> pin TX of Bluetooth Module), TX (-> pin RX of Bluetooth Module)

void setup() {
	Serial.begin(9600); //set baud rate of Serial Monitor
	BT.begin(9600); //set baud rate of Bluetooth
	pinMode(trig, OUTPUT); //set trigger pin to OUTPUT (-> pin trig of Ultrasonic Sensor)
	pinMode(echo, INPUT); //set echo pin to INPUT (-> pin echo of Ultrasonic Sensor)
	Serial.println("Start!!!");
}

void loop() {
	float duration; //duration to record the time of every back and forth 
	float distance; 
	digitalWrite(trig, HIGH); //trigger sona for 1 ms
	delayMicroseconds(1000); 
	digitalWrite(trig, LOW);
	duration = pulseIn(echo, HIGH); 
	//use pulseIn() function to get the time of pin echo from HIGH to LOW, unit=microseconds
	distance = (duration / 2) * 0.034;
	//distance = ( half of time of back and forth )x( wave velocity(use 0.034 cm per microsecond) )
	
	Serial.print("Distance ="); //show result on Serial Monitor
	Serial.print(distance);
	Serial.println("cm");
	delay(delay_time);

	int sendData = (int) (distance * 100); //times 100 and convert disance to integer 
	byte packet[3]; 
	packet[0] = 97; //key send to phone
	packet[1] = sendData / 256; //divides sendData to two 1 byte packets
	packet[2] = sendData % 256;
	

	
	if(BT.available() > 0) //check BT is succeed
		if(BT.read() == 97) //check recieve key from phone
		{
			Serial.println("succeed!");
			for(int i = 0; i < 3; i++) 
				BT.write(packet[i]); //send packet to phone
		}


}
Arduino_Android_UltrasonicSensor

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

  1. 初學者 says:

    請問一下 : 有沒有可能 ….

    1. 點下手機 app 按鈕打開超音波接收 app 之後 , 藍芽自動連接上 , 而不需要再次去 點擊 connect 按鈕 ?

    2. 如果是懶人的話(像我這樣) , 有沒有可能設計成 : 手機一開機 , 就自動進入 app 的測量畫面 ?

    感謝回復 謝謝

    • CAVEDU 阿吉 - 雜工 says:

      您好, 當然可以的, 只要把藍牙連線的指令(bluetoothClient.connect)指令寫在 Screen1.Initialize 事件中就可以了. 但要注意您的arduino 要先開起來等候連線, 不然程式開啟時會試著連線一次, 沒連上就沒戲唱了

    • CAVEDU 阿吉 - 雜工 says:

      請參考本篇:http://blog.cavedu.com/programming-language/appinventor/appinventorandarduinowithbluetooth3/ 但您是用SR04嗎? 這類型的超音波感測器如果超過2公尺的話不是太準,建議只送出2m以內的數值這樣會比較簡單

  2. anthonCH says:

    你好,請問如果要將超音波之類的感測器從序列埠上讀取到的多筆數值,輸出成TXT檔可行嗎(週邊界面是超音波感測器->Arduino UNO改接USB->PC)?
    還有輸出指令的寫法是否是用void loop()迴圈裡用if else條件式去寫?

    • 許 鈺莨 says:

      你好,如果要將數值輸出成TXT檔是可行的,以下有幾種方法供你參考:
      1.使用teraterm免費軟體,在網路上搜尋teraterm Arduino關鍵字有很多教學,Arduino輸出指令是Serial.print(); 或 Serial.println();
      2.使用Arduino透過firmata協定,利用Python做輸出。建議參考書目:Python x Arduino物聯網整合開發實戰
      3.可以買SD卡模組,將檔案存入SD卡內。

      • anthonCH says:

        感謝你的回覆!
        方法一的部分我也有看到國外的玩家用類似Teraterm的免費軟體”Coolterm”來做ARDUINO的TXT輸出。
        只是方法二和方法三的是用Python的程式語言,比較符合我的需求。
        請問簡單來說使用方法二的話,是不是先將ARDUINO的程式上傳板子->Python再跟ARDUINO做連結->最後把ARDUINO的data存成TXT檔放到Python的資料夾裡面?

        • 許 鈺莨 says:

          你好,先說方法二,方法二只需要用到SD的函式庫即可,不需要用到Python。
          再來方法三,你說的沒錯,Arduino這端上傳完程式,然後Python這端要安裝pySerial套件跟Arduino COM port溝通,讀到的txt會存在執行的Python檔的同一個資料夾中。
          可以詳見:https://playground.arduino.cc/Interfacing/Python

    • CAVEDU 阿吉 - 雜工 says:

      可以的,但這樣就要走WIFI了,App Inventor端也要改成Web元件來與開發板互動,本篇教學就不適用囉 這篇提供您參考:https://medium.com/kidstronics/mit-app-inventor-2-meets-esp8266-03-kidserie-fa92cc8ae8a2

  3. Rxg says:

    我想請問下 我想將火焰感測器數值傳到手機app裡(利用藍芽的方式) 當偵測到火焰時蜂鳴器會叫 我可以參考哪一篇呢 我把您一~七篇教學文都參閱了 但還是不太會弄

  4. Aki says:

    老師您好
    如果要將這篇文章中的app跟常閉型震動感測器(sw-420)做應用的話應該如何修改呢?
    他是數位輸出的感測器
    我想要製作一個類似警報器的東西,當震動感測器感受到震動的時候就會透過藍牙傳送訊號給手機
    請問app及編碼的部分應該如何修改呢?
    謝謝老師

    • CAVEDU 阿吉 - 雜工 says:

      您好,請參考本系列Part 2,請把code中的analogread改為digitalRead即可。如果有偵測到震動(digitalRead() 結果為 1) 就送某個數字或字元給App Inventor,反之則送另一筆資料。架構都是一樣的,請先確認在Arduino端可以正確讀取感測器資料即可

      不過感測器都是輸入裝置才對喔

  5. 巫國華 says:

    如果改成用夏普PM2.5和DH22 使用藍芽HC06 傳送至手機 ARDUINO的程式碼怎麼寫? AI2的方面怎麼製作?

  6. Hsu says:

    您好,想做這個來做專題
    但我們運用的是 拿超音波來量身高的值。
    想請問 可以讀取 身高的值嗎, 我有這個來做測驗 發現距離一高的時候差距滿大的。

  7. 承德 says:

    您好,我們最近做專題遇到了一些問題想請教你們
    問題如下:我們因為需要所以用了兩台arduino,讓兩台以I2C連結(有線),其中master端想要加入藍芽,讓手機能夠傳一些數值給master的arduino做使用,但不知道會不會與I2C做衝突呢?

發表迴響

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