我的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傳入的溫濕度資料。
資料庫名稱可自己取名,但不可用中文,例如筆者將新的資料庫取名為「tempandhumd」,代表收取的是溫度及濕度,完成名稱輸入後Collation依照預設值Server Default即可,最後按右下角的Apply即會看到完成的視窗。
再來建立資料表,在剛建好的資料庫前方+號點開,在table上按右鍵,選擇Create Table,建立資料表。
建立的資料表名稱為「datalog」,欄位除了溫度、濕度之外,可用自動編號當作主鍵,最後在給一個更新時間,因此有四個欄位設定如下
1. id:整數,(代表自動編號欄位)
2. temp:整數(代表溫度欄位)
3. humd:整數(代表溼度欄位)
4. updatetime:timestamp(代表資料時間欄位),並給予預設值:CURRENT_TIMESTAMP,目的是這樣當資料新增時,直接給插入資料的時間。
然有四個欄位,但實際上我們僅須給temp跟humd即可,id與updatetime都是sql資料庫直接給值得。這樣比較簡單。
4. 修改MySQL遠端連線設定
因為安全考量,預設MySQL只允許本機登入而不能外部連入,但是我們的Arduino IoT裝置是屬於外部裝置,因此必須將使用者開放外部登入,這裡必須說明,這樣的作法是有安全性問題的,只建議自己建立伺服器來測試,不要拿公司或學校的伺服器來測試。
修改root使用者由原本的localhost改為%,代表該使用者可以從網路上任何地點連進資料庫來進行修改。 完成後按下方的Apply即可存檔。
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的密碼。
二、線路佈置
本部份連接DHT11及ESP32,本請參考前篇:ESP32 溫濕度顯示器(DHT11+1602 LCD)
三、程式開發
本部份則是在Aruino IDE中撰寫程式,如何將資料上傳MySQL,我們將直接使用MySQL的library進行上傳,並說明注意事項。
1. 匯入MySQL Library
安裝"MySQL connector arduino" by Dr. Charles Bell,依照下圖開啟管理函式庫功能。
搜尋關鍵字MySQL ,即可找到所需的library,點選右側的Install安裝按鈕把他安裝起來。
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
}
若上傳成功,在資料庫內就會出現剛剛上傳的資料
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);
}
查看序列視窗,可以發現上傳正常,查看資料庫,也可以發現資料都已經存入資料庫了。

我是用的板子是Arduino uno wifi, wifi的功能直接整合在板子裡面,不須再接ESP32 請問以下這段程式碼的WiFiClient需要修改嗎? WiFiClient client; MySQL_Connection conn((Client *)&client); 因為現在把程式寫進去板子後會出現: ERROR:class requires connected server 網路上關於arduino uno wifi板子的資訊較少 所以來這裡請教 不好意思打擾 謝謝
你的問題不是WIFI也不是板子,SQL連不上
請問板子是用SIM800L 是否也可以?
如何可以知道SQL Database的IP?
就是你電腦的IP阿
請問游老師 我在下載與安裝My Sql時,有這個問題 就是下載後安裝時My Sql的安裝程式會出現沒有任何Package可以安裝 請問我該如何接下去!!?? 謝謝!!
可能要節圖我才知道
老師您好 我正在照著本章操作 但是我會出現跟一樓一樣的問題 於是我請我朋友用電腦連線 但得到以下結果 ERROR 2003 (HY000): Can't connect to MySQL server on 'ip:3306' (10060) 我幾乎把網上的做法都做了一次但是都沒成功 希望能幫我指點迷津 PS.目前做過 port 開白名單 關防火牆 去system32裡面的host改東西
14:53:13.597 -> Sample OK: Disconnected. 14:53:13.878 -> Data Saved. 15:03:14.894 -> Sample OK: ERROR: Class requires connected server. 15:03:14.894 -> Data Saved. 請問 第二次都會顯示斷線 是因為第一次寫入後 conn.close();// close the connection斷開的關係嗎
存完後,一定要斷開,不然連線會爆
invalid conversion from 'const char*' to 'char*' [-fpermissive] 請問為甚麼會這樣?
意思是你的格式不對,把本來const char*的宣告改成char*應該就可以了
不好意思再問個問題 執行到這行的時候 if (conn.connect(server_addr, 3306, user, pass)) 監控視窗會有跳這個訊息出來,ˊ這要怎麼解決 CUT HERE FOR EXCEPTION DECODER --------------- Exception (28): epc1=0x40203380 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000049 depc=0x00000000
這個不清楚了喔
請問出現以下這個要如何處裡 ...trying... ERROR: Timeout waiting for client. ERROR: Timeout waiting for client. Error: -1 = Connection failed. ERROR: Timeout waiting for client. Data Saved.