#include <SoftwareSerial.h>           //載入軟體串列埠函式庫
#include <DHT.h>                   //載入 DHT11 函式庫
#define DHTPIN 2                    //定義 DIO 腳 2 為 DHT11 輸入
#define DHTTYPE DHT11               //定義 DHT 型態為 DHT11
DHT dht(DHTPIN, DHTTYPE);          //初始化 DHT11 感測器
int LED=13;                         //宣告 DIO 腳 13 為 LED 輸出
String api_key="UTE44U6ATHUL4RJO";  //Thingspeak API Write Key
SoftwareSerial sSerial(10,11);        //設定軟體串列埠腳位 RX, TX為 DIO 腳 10, 11
void setup() {               
  pinMode(LED, OUTPUT);             //設定 DIO Pin 13 為 LED 輸出
  Serial.begin(9600);                //啟始硬體串列埠 (除錯用)
  sSerial.begin(9600);              //啟始軟體串列埠 (與 ESP8266 介接用)
  dht.begin();                      //啟始 DHT11 溫濕度感測器
  sSerial.println("AT+RST");        //軟體串列埠傳送 AT 指令重啟 ESP8266
  }
void loop() {
  float h=dht.readHumidity();         //讀取濕度
  float c=dht.readTemperature();      //讀取攝氏溫度
  float f=dht.readTemperature(true);  //讀取華氏溫度
  //有任何一個是 NAN 就不往下執行資料傳送
  if (isnan(h) || isnan(c) || isnan(f)) { 
    Serial.println("Failed to read from DHT sensor!");
    return;
    } 
  blink_led(1000,500); //進入資料傳送程序 : LED 閃爍一次   
  String param="&field1=" + (String)c + "&field2=" + (String)f +
               "&field3=" + (String)h; //製作參數字串
  //Serial.println(param); //輸出字串參數於監控視窗
  //與 Thingspeak 主機建立 TCP 連線
  String cmd="AT+CIPSTART=\"TCP\",\"184.106.153.149\",80";
  sSerial.println(cmd); //向 ESP8266 傳送 TCP 連線之 AT 指令
  //偵測 TCP 連線是否成功
  if (sSerial.find("Error")) {           
    Serial.println("AT+CIPSTART error!");
    return;  //連線失敗跳出目前迴圈 (不做後續傳送作業)
    }
  Serial.println(cmd);  //輸出 AT 指令於監控視窗
  //製作 GET 字串
  String GET="GET /update?api_key=" + api_key + param + "\r\n\r\n";
  Serial.println(GET);  //顯示 GET 字串內容於監控視窗 
  cmd="AT+CIPSEND=" + String(GET.length()); //傳送 GET 字串長度之 AT 指令
  sSerial.println(cmd);  //告知 ESP8266 即將傳送之 GET 字串長度
  Serial.println(cmd); //輸出 AT 指令於監控視窗
  //檢查 ESP8266 是否回應
  if (sSerial.find(">")) {  //若收到 ESP8266 的回應標頭結束字元
    sSerial.print(GET);  //向 ESP8266 傳送 GET 字串內容
    }
  else {  //沒有收到 ESP8266 回應
    sSerial.println("AT+CIPCLOSE");  //關閉 TCP 連線
    Serial.println("AT+CIPCLOSE");    //顯示連線關閉訊息於監控視窗
    }
  delay(16000);  //延遲 16 秒 (因 Thingspeak 每次更新須隔 15 秒)
  }
void blink_led(int on, int off) {  //LED 閃爍函式
  digitalWrite(LED, HIGH);
  delay(on);
  digitalWrite(LED, LOW);
  delay(off);
  }