在上一個實習中我們學會了如何使用手機透過藍牙控制Arduino上的LED,在這個實習中我們將再進一步來看看,如何透過藍牙讀取在Arduino上溫濕度感測器上的資訊。為了讓我們的實習內容有資料可以讀取,在這個範例中我們加上了一個DHT22溫濕度感測器的連接,如下圖所示:

上圖中間的那個綱狀的感測器DHT22,它共有4支接腳,面向我們的這一側左邊是5V電源接腳處,接著是資料接腳(在這個例子中,我們把它接到Arduino的D3接腳),然後是空的無用接腳,最右邊的是GND接地。以下是從另外一個角度的畫面:

先來看看成果影片:

以下是在Arduino端的程式碼:

#include <SoftwareSerial.h>
#include "DHT.h"
#define DHTPIN 3
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

#include <Wire.h>
 
int LED = 2;
SoftwareSerial BT(10,11); 
 
void setup() {
  BT.begin(38400);
  pinMode(LED, OUTPUT);    
  Serial.begin(9600);
  dht.begin();
}
 
void loop() {
  byte cmd[20];
  int strsize;
  while(true){
    if ((strsize=(BT.available()))>0){
      for (int i=0; i<strsize; i++){
        cmd[i]=char(BT.read());
      }
      Serial.println(cmd[0]);
    }
    if (cmd[0]=='a') {
      digitalWrite(LED, HIGH);
    } else if (cmd[0]=='b') {
      digitalWrite(LED, LOW);
    } else if (cmd[0]=='c') {
      float h = dht.readHumidity();
      float t = dht.readTemperature();
      char hum_buf[10], tem_buf[10];
      if (!isnan(h) && !isnan(t)) {
        dtostrf(h, 3, 2, hum_buf);
        dtostrf(t, 3, 2, tem_buf);
        for(int i=0; i<5; i++) {
          BT.write(hum_buf[i]);
        }
        for(int i=0; i<5; i++) {
          BT.write(tem_buf[i]);
        }
      }
      cmd[0]='d';
    }
  } 
  
}

上面的程式是從前一個實習中增加程式碼而來的。其中DHT這個類別是用來讀取溫濕度感測器數值用的,使用DHT dht(DHTPIN, DHTTYPE)建立dht這個實例變數之後,於setup()中執行dht.begin()函數初始化感測器的設定,然後在程式中就能夠以dht.readHumidity()讀取一個浮點數型態的濕度數值,以及使用dht.readTemperature()讀取溫度值,在這個例子中,我們分別把溫度及濕度放在浮點變數t和h中。

為了簡易示範起見,在讀取到溫濕度之後,我們把這兩個數值先以dtostrf()函數把它們轉換成字元型態,再透過BT.write()函數,逐一把字元寫到藍牙接收器,也就是手機中。

為了維持上一個實習中的功能,我們的Arduino還是會先讀取來自於手機的訊息,如果得到的是字元a,就把LED打開,和上一個例子一樣,如果得到的是字元b,就把LED關閉,如果是字元c的話,才是去讀取目前的溫濕度,再把資料依序寫回手機的APP中。

另外一方面,回到APP Inventor去修改之前的例子,這一次我們在手機的畫面中加上兩個顯示溫濕度的標籤,以及一個計時器,畫面如下所示:

元件清單如下所示:

此APP的重點是多了一個計時器,一開始的時候先讓它處在不是啟用的狀態,所以在屬性的地方要這樣設定:

並設定它的計時間隔為100,也就是當啟用之後,可以每0.1秒就觸發一次,相當於是每秒讀取10次資料。在Screen1初始化的事件中也要進行相關的設定:

如同上一個例子,在清單選擇器之前加上一個搜尋藍牙裝置的指令:

在選擇要連線的裝置之後,進行以下的相關設定:

上面就是在順利連線之後開啟計時器的功能,此時除了原有的兩個LED開關用的按鈕之外:

計時器每次觸發的時候會做以下的事情:

在程式中我們對Arduino發送字元’c’,如之前的Arduino程式中的操作,在收到’c’之後就會回傳各5個字元的溫濕度字串,因此在這裡就先檢查是否有可以收的字元,如果有的話,就分別接收濕度和溫度字元,然後放到我們在畫面中準備好的標籤中,如此就大功告成了。

如同示範影片所示的,在此APP中一樣可以開關LED,而且會每0.1秒就在手機的畫面上更新目前的溫濕度值。有也這些資料之後,同學們可以想想,那如何把這些資料儲存在手機中,或是直接上傳到ThingSpeak綱路中呢?

(1609)