我的ESP32實做書籍:https://youyouyou.pixnet.net/blog/post/121105860
博客來網址:https://www.books.com.tw/products/0010901195


ESP內建的WiFi上網,我們就可以將收集到的資料存入雲端資料庫,方便立即查看即時狀況,而且有長期的資料後就可以進行後續分析與比較,也能在發生異常時發出Mail, Line等通知管理者,達到立即處理的功能,這樣才算真正發揮IoT裝置的功能。

本章要介紹如何將DHT11的溫濕度等資料上傳到自己建立的資料庫,若讀者沒有網路伺服器可以建立MySQL,則可跳過本章,直接閱讀下一章「ESP32 資料庫存取ThingSpeak圖表製作」,不需要自己建立資料庫,畢竟資料庫伺服器的管理維護問題之外,還有網路連線IP、DDNS、NAT、虛擬伺服器、連接埠轉送等網路相關的知識,再加上SQL資料庫的維護與語法也是一個很大的議題。不過自己建立資料庫的好處則是資料儲存、使用、及後續管理與查詢都是由自己掌控,相對更加自由,這也是很多進階玩家選擇這樣作法的原因。

另外要說明的則是本篇介紹的方法是讓ESP32與MySQL直接建立連接,而不是更正式的三層式(Three Tier)作法,也就是讓ESP32透過HTTP Post或Get傳資料到AP Server,而AP Server再存入資料庫中的間接連線方式。

為了快速讓讀者能完成練習,本章分成以下幾個部份說明

一、環境設定:安裝MySQL及workbench

二、線路佈置:連接ESP32及DHT11

三、程式開發:在Arduino IDE中撰寫程式


一、環境設定

本章使用MySQL最大的好處是,他是免費的,執行效能也不差,另外就是workbench,這是懶人的福音,如果你跟我一樣,對cmd界面不熟悉,你一定要安裝workbench,他提供你完整的MySQL圖形界面操作模式,真心推薦。

1.安裝MySQL伺服器,安裝方式網路非常多介紹,請自行google,或參考這篇: https://jerrynest.io/windows-mysql-installer/ ,下載的網址: https://dev.mysql.com/downloads/installer/ ,題外話,如果你想用cluster版,可參考本人本篇文章: http://youyouyou.pixnet.net/blog/post/119326123

2.安裝workbench,下載網址: https://www.mysql.com/products/workbench/ 

3.將workbench連線到mysql資料庫

workbench安裝完畢後,我們就可以透過workbench進入資料庫,以進行設定,包括建立新的資料庫欄位以及開放讓IoT可連入更新資料,讓Arduino可以WiFi遠端更新資料庫,

3.1 Workbench連線

一般Workbench安裝完畢都會建立一個連線是直接連線到本機端MySQL,名稱是127.0.0.1直接打開即可。

3.2 建立新資料庫

點選左上方的Create new schema圖示,以建立資料庫,將存放DHT11傳入的溫濕度資料。
image

資料庫名稱可自己取名,但不可用中文,例如筆者將新的資料庫取名為「tempandhumd」,代表收取的是溫度及濕度,完成名稱輸入後Collation依照預設值Server Default即可,最後按右下角的Apply即會看到完成的視窗。
image

再來建立資料表,在剛建好的資料庫前方+號點開,在table上按右鍵,選擇Create Table,建立資料表。
image 

建立的資料表名稱為「datalog」,欄位除了溫度、濕度之外,可用自動編號當作主鍵,最後在給一個更新時間,因此有四個欄位設定如下
1. id:整數,(代表自動編號欄位)

2. temp:整數(代表溫度欄位)
3. humd:整數(代表溼度欄位)
4. updatetime:timestamp(代表資料時間欄位),並給予預設值:CURRENT_TIMESTAMP,目的是這樣當資料新增時,直接給插入資料的時間。
然有四個欄位,但實際上我們僅須給temp跟humd即可,id與updatetime都是sql資料庫直接給值得。這樣比較簡單。

image

4. 修改MySQL遠端連線設定

因為安全考量,預設MySQL只允許本機登入而不能外部連入,但是我們的Arduino IoT裝置是屬於外部裝置,因此必須將使用者開放外部登入,這裡必須說明,這樣的作法是有安全性問題的,只建議自己建立伺服器來測試,不要拿公司或學校的伺服器來測試。
修改root使用者由原本的localhost改為%,代表該使用者可以從網路上任何地點連進資料庫來進行修改。 完成後按下方的Apply即可存檔。
image

5. 修改認證方式

因為後續有網友反應資料傳遞失敗,錯誤訊息是「Client does not support authentication protocol requested by server」,經查詢是因為MySQL 8.0的認證方式已經升級,但目前Arduino的MySQL函式庫並未升級,目前的方式,暫時將MySQL的連線認證方式降級,作法為開啟MySQL Command視窗,並輸入以下指令。
ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'SQLpassword';
這裡的SQLpassword代表你root的密碼。
image

二、線路佈置

本部份連接DHT11及ESP32,本請參考前篇:ESP32 溫濕度顯示器(DHT11+1602 LCD)

三、程式開發

本部份則是在Aruino IDE中撰寫程式,如何將資料上傳MySQL,我們將直接使用MySQL的library進行上傳,並說明注意事項。

1. 匯入MySQL Library

安裝"MySQL connector arduino" by Dr. Charles Bell,依照下圖開啟管理函式庫功能。

搜尋關鍵字MySQL ,即可找到所需的library,點選右側的Install安裝按鈕把他安裝起來。
image

2. 連線測試

接下來就可以先測試將值傳入過程是否正常,先使用以下程式進行測試,其中溫度及濕度是直接鍵入,目的在測試網路連線是否正常。要修改的部份包括無線網路的SSID及密碼,還有SQL資料庫的IP位址及帳號密碼,這裡有一個地方要注意的是server_addr是用「,」做區隔,而不是傳統的「.」做區隔。


//MySQL連線測試,手動寫入一個溫度及濕度資料做測試
#include <WiFi.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

const char ssid[]     = "SSID";// change to your WIFI SSID
const char password[] = "SSIDPassword";// change to your WIFI Password
IPAddress server_addr(192,168,1,107);// change to you server ip, note its form split by "," not "."
int MYSQLPort =3306;   //mysql port default is 3306
char user[] = "root";// Your MySQL user login username(default is root),and note to change MYSQL user root can access from local to internet(%)
char pass[] = "SQLpassword";// Your MYSQL password

WiFiClient client;            
MySQL_Connection conn((Client *)&client);

void setup() {
  Serial.begin(115200);
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);  
  //try to connect to WIFI 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  //try to connect to mysql server
  if (conn.connect(server_addr, 3306, user, pass)) {
     delay(1000);
  }
  else{
    Serial.println("Connection failed.");
  }
  delay(2000);  
  //insert, change database name and values by string and char[]
  char INSERT_SQL[] = "INSERT INTO tempandhumd.datalog (temp,humd) VALUES ('35','60')";//傳入的值固定為溫度,濕度為35,60
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);  
  cur_mem->execute(INSERT_SQL);//execute SQL
  delete cur_mem;
  conn.close();                  // close the connection
  Serial.println("Data Saved.");
}

void loop() {
//do nothing
}


若上傳成功,在資料庫內就會出現剛剛上傳的資料
image
image

3. DHT11測試

依據「第九篇 ESP32 溫濕度顯示器(DHT11+1602 LCD)」的方式,將DHT11腳位訊號的腳位接在GPIO 14的位置(麵包板左側8),接下來程式改為每10秒讀取DHT11一次,並上傳資料庫,完成上傳後就立即斷線資料庫,等候下一個Loop。


#include <WiFi.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <SimpleDHT.h>

const char ssid[]     = "SSID";// change to your WIFI SSID
const char password[] = "SSIDPassword";// change to your WIFI Password

IPAddress server_addr(192,168,1,17); // change to you server ip, note its form split by "," not "."
int MYSQLPort = 3306; //mysql port default is 3306
char user[] = "root";// Your MySQL user login username(default is root),and note to change MYSQL user root can access from local to internet(%)
char pass[] = "SQLpassword";// Your MYSQL password

WiFiClient client;
MySQL_Connection conn((Client *)&client);

int pinDHT11 = 14;
SimpleDHT11 dht11(pinDHT11);
void setup() {
  Serial.begin(115200);
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  //try to connect to WIFI
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  //try to connect to mysql server
  if (conn.connect(server_addr, 3306, user, pass)) {
    delay(1000);
  }
  else {
    Serial.println("Connection failed.");
  }
  delay(2000);

}

void loop() {
  //讀取DHT11
  byte temperature = 0;
  byte humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    Serial.print("Read DHT11 failed, err="); Serial.println(err); delay(1000);
    return;
  }
  Serial.print("Sample OK: ");
  Serial.print((int)temperature); Serial.print(" *C, ");
  Serial.print((int)humidity); Serial.println(" H");

  //將溫濕度加入SQL字串
  String INSERT_SQL = "INSERT INTO test.loj (t,h) VALUES ('" + String((int)temperature) + "','" + String((int)humidity) + "')";
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  cur_mem->execute(INSERT_SQL.c_str());//execute SQL
  delete cur_mem;
  conn.close();// close the connection
  Serial.println("Data Saved.");
  delay(10000);
}


查看序列視窗,可以發現上傳正常,查看資料庫,也可以發現資料都已經存入資料庫了。
image

 

arrow
arrow
    創作者介紹
    創作者 夜市 小霸王 的頭像
    夜市 小霸王

    夜市小霸王

    夜市 小霸王 發表在 痞客邦 留言(9) 人氣()