【物聯網相關】利用單晶片與虛擬主機發送email~

Document
網路上看到了一篇文章,內容說明了如何經由email傳送感測器獲得的資料到你的手機上。 我認為如果你是對物務聯網(IoT)有興趣的人,這個技巧是必須要學習的。因為物聯網的目的就是要讓各種東西都可以相互連結並且遠端控制,所以我認為完成型態的物聯網應該是要與網際網路做整合的。 而這篇文章提供的方式簡單而且不需要太多設備就可以完成,是非常適合入門的第一步~

在開始之前,先要說明一下整個系統的架構
基本上要讓手機收到email 要先有一個可以發送email的系統,而這裡就使用網路上提供的免費web hosting(虛擬主機), 有了發送email的地方後,需要有可以上網的工具才有辦法把資料傳到這個地方。這時候可以使用ESP8266或是NodeMCU等等的單晶片將資料連上網去傳送。 如此一來,我們就可以使用各種不同的感測器去擷取資料,然後把擷取到的資料透過單晶片與虛擬主機傳送出去。

本篇我們會使用的工具是NodeMCU與BME280(大氣壓力感測器)
先將原文網址付上,這篇基本上就是解說原文的內容
https://randomnerdtutorials.com/esp32-esp8266-send-email-notification/

整體架構說明:


上面的圖顯示了這個專案的整體架構,將BME280接收到的資料(大氣壓力,溫度與濕度)經由NodeMCU連接上wifi傳送到網路上的虛擬主機再由虛擬主機將數據發email到個人的信箱

準備工具:

  • 單晶片NodeMCU
  • 大氣壓力感測器BME280 (購買3.3V的)
  • 申請虛擬主機:這篇是使用【000webhost】 若有自己習慣的也可以使用
  • 可以連上網際網路的wifi,並且知道帳號與密碼

設定虛擬主機:

原文中有推薦2個虛擬主機: 原文的步驟畫面是擷取第一個Bluehost的畫面去做的,所以如果想照著原文一步一步去做,那可以跟著他用Bluehost。缺點是他要收費XD, 不過收費也代表著穩定性一定會比免費的好,這個大家可以自己評估。
這篇我們用000webhost來作為虛擬主機來發送email。 000webhost是一個歷史滿久的虛擬主機,各種功能都很齊全,是很好用的虛擬主機。如果只是剛開始入門接觸這類的東西我會建議先使用免費的資源來做測試,畢竟這裡會使用到的功能就是寄送email而已。 當然,如果你自己想要試試看別的虛擬主機也是沒問題的。 可以參考以下的網址,他有列出一些常用的虛擬主機,基本上規格上看到control panel是CPanel的都可以用本篇的方法來操作
https://www.webhostingsecretrevealed.net/blog/web-hosting-guides/free-hosting-sites/

以下說明操作步驟:
000webhost官網:https://www.000webhost.com/

先申請帳號登入

熟悉虛擬主機操作的人可以跳過這一步,直接從步驟四開始(或是步驟二,看你自己對虛擬主機的熟悉程度而決定)


登入首頁後,按下右上角的SIGN IN


下方可以看到有Sign up 的選項,按下此選項


看到此畫面後,填上email與設定密碼後,按下SIGN UP


看到此畫面代表你註冊的信箱已經收到一封認證用的email,此時到你剛剛註冊的email裡找到驗證信,並且按下認證的連結就可以啟動擬申請的虛擬主機。


認證完成後會看到這樣的畫面。 然後後續你會看到網站跳出幾個問及要你去回答,因為我們目前只是要先做測試性質的專案,我們先全部跳過,全部選擇skip




以上三個步驟,全部選擇右下角的skip跳過


最後會看到虛擬主機的主頁,在右上方可以看到 【+create new site】


這裡可以直接按下【create】,讓系統自動產生就好


完成後,可以看到你申請的虛擬主機在運作了。 點進去後,就可以做各種設定了!

設定好主機後,要將PHP程式碼放在上面,但是我們要找到對的位置放上去。我們要在【file/public_html】這個資資料夾裡面放入PHP檔。 檔案名稱使用【email-notification.php】。 如果想照著這篇操作,建議不要去修改檔案名稱,如果修改的話相關的網址也會需要修改。

找到file這個位置

點進去虛擬主機後,左手邊可以看到許多的功能列。 按下Tool-->File Manager 在按下畫面中間的Upload Files


要在public_html這個資料夾下建立一個PHP檔案

按下upload Files 後,選擇public_html這個資料夾,按下右上方的新增檔案的小圖示


PHP檔案名稱取名為【email-notification.php】

如下圖所示,將檔名取名為【email-notification.php】 建議不要修改檔名

按下create後會看到如下畫面,選擇檔案,按下編輯鈕


按下編輯鈕後會開啟檔案,看到編輯畫面


將下面的程式碼複製貼上到剛剛的檔案

<?php

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-send-email-notification/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Receiver Email Address (where to send email notification)
$email_address = "YourEmailAddress@example.com";

// Keep this API Key value to be compatible with the ESP code provided in the project page. If you change this value, the ESP sketch needs to match
$api_key_value = "tPmAT5Ab3j7F9";

$api_key = $value1 = $value2 = $value3 = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $api_key = test_input($_POST["api_key"]);
    if($api_key == $api_key_value) {
        $value1 = test_input($_POST["value1"]);
        $value2 = test_input($_POST["value2"]);
        $value3 = test_input($_POST["value3"]);
        
        // Email message
        $email_msg = "Temperature: " . $value1 . "ºC\nHumidity: " . $value2 . "%\nPressure: " . $value3 . "hPa";
        
        // Use wordwrap() if lines are longer than 70 characters
        $email_msg = wordwrap($email_msg, 70);
        
        // Uncomment the next if statement to set a threshold 
        // ($value1 = temperature, $value2 = humidity, $value3 = pressure)
        /*if($value1 < 24.0){
            echo "Temperature below threshold, don't send email";
            exit;
        }*/
        
        // send email with mail(receiver email address, email subject, email message)
        mail($email_address, "[NEW] ESP BME280 Readings", $email_msg);
        
        echo "Email sent";
    }
    else {
        echo "Wrong API Key provided.";
    }

}
else {
    echo "No data posted with HTTP POST.";
}

function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}





// Receiver Email Address (where to send email notification)
$email_address = "YourEmailAddress@example.com";


複製完後需要修改email位址:

將程式碼裡面的email改成你要送到的郵件地址。
// Receiver Email Address (where to send email notification)
$email_address = "YourEmailAddress@example.com";  
設定完之後可以測試一下是否正常,先找到剛剛文件的網址,按下你網站的名稱,會看到剛剛產生的檔案。


如果一切正常,按下檔案後可以看到以下畫面。另外,也可以看到網址列的網址,可以先將此網址記下來。



如果看到上面的畫面就代表虛擬主機上設定正常

硬體設定:NodeMCU & BME280

將NodeMCU跟BME280連接起來,參考以下的線路圖與表格來連接

表格:NodeMCU與BME280連接腳位說明
NodeMCUBME280
GPIO 5 SCK (SCL Pin)
GPIO 4 SDI (SDA pin)
3V3 VCC
GND GND
硬體連線好後,就要編寫程式碼 使用Arduino IDE編寫以下程式碼,上傳到NodeMCU上面。 開始之前要記得安裝以下3個東西到Arduino IDE裡面: 安裝完後將以下程式碼輸入Arduino IDE
 
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-send-email-notification/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#ifdef ESP32
  #include 
  #include 
#else
  #include 
  #include 
  #include 
#endif

#include 
#include 
#include 

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE with your Domain name with URL path or IP address with path
const char* serverName = "http://example.com/email-notification.php";

// Keep this API Key value to be compatible with the PHP code provided in the project page. 
// If you change the apiKeyValue value, the PHP file /email-notification.php also needs to have the same key 
String apiKeyValue = "tPmAT5Ab3j7F9";

/*#include 
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

Adafruit_BME280 bme;  // I2C
//Adafruit_BME280 bme(BME_CS);  // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);  // software SPI

void setup() {
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  // (you can also pass in a Wire library object like &Wire2)
  bool status = bme.begin(0x76);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
    while (1);
  }

  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    HTTPClient http;
    
    // Your Domain name with URL path or IP address with path
    http.begin(serverName);
    
    // Specify content-type header
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    // Prepare your HTTP POST request data
    String httpRequestData = "api_key=" + apiKeyValue + "&value1=" + String(bme.readTemperature())
                           + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);
    
    // You can comment the httpRequestData variable above
    // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
    //String httpRequestData = "api_key=tPmAT5Ab3j7F9&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = http.POST(httpRequestData);
     
    // If you need an HTTP request with a content type: application/json, use the following:
    //http.addHeader("Content-Type", "application/json");
    //int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
    
    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    http.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }

  // Use deep sleep to make the ESP send an email every X number of minutes/hours with low power consumption
  // ESP32 Deep Sleep Guide: https://RandomNerdTutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/
  // ESP8266 Deep Sleep Guide: https://RandomNerdTutorials.com/esp8266-deep-sleep-with-arduino-ide/
}

void loop() {

}




輸入完成後要先跟改幾個東西才可以使用

這裡要輸入wifi的帳號與密碼
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
將以下的網域修改成你申請的網域
以下的程式中,將http://example.com/email-notification.php修改成自己虛擬主機的網址(就是在測試虛擬主機時要你先記下的網址)
// REPLACE with your Domain name with URL path or IP address with path
const char* serverName = "http://example.com/email-notification.php";
跟改完成後儲存起來上傳到NodeMCU上

這裡有個地方要注意一下,我們在複製php檔案的網址時,複製到的網址是【https://】開頭的網址,他與【http://】開頭的網址是不一樣的。https是屬於加密的傳輸方式,而http是沒有加密的。但是https的加密傳送方式有點太複雜,這邊不需要處理到這部分,畢竟本篇算是一個測試性質的小專案而已。 因此,請去除https結尾的s,也就是說你的網址應該看起來會是http://......這樣子的形式

可以打開IDE的檢視視窗,如果一切正常應該可以看到如下的畫面

開啟Email收信

開啟你的email,你應該可以在你的email中收到由虛擬主機寄過來的數據了。如果需要再收到一次email,可以按下NodeMCU上的reset按鍵,如此一來就可以讓NodeMCU再執行一次程式。



操作到現在,相信各位已經可以收到email了。到這個階段,我們已經達到最重要的目的,那就是在email上收到通知 如果熟悉這個操作方式後,那麼各位也可以應用到各種不同的感測器上,去獲取相關數據再透過網路送到email裡面。

到目前為止已經做到可以在遠端獲取資料的功能,這對於想熟悉IoT的人來說已經完成了很重要的一步。目前在實際應用上大家可能會覺得上有一些限制,例如傳送時間與傳送條件上的設定。這些目前我們不在這篇做討論,這篇主要目的是讓各位了解如何運用單晶片配合感測器與網路的虛擬主機發送資料,如果各位可以先完成這一步就可以達到此篇的目的,其他方面的問題未來會再另外寫文章與各位分享~

以上~

留言

這個網誌中的熱門文章

【Arduino相關】 Arduino基礎介紹~ 腳位,PWM輸出,IDE...

【保險 】外幣收付非投資型商品考試隨筆整理~

【單晶片】單晶片/微控制器/MCU 是什麼?