ESP32 + DHT11 溫濕度資料自動寫入 Google 雲端試算表
NodeMCU-32S 透過 WiFi,每 60 秒讀取 DHT11 模組版溫濕度數值,以 HTTP GET 方式寫入 Google 試算表,免費實現雲端資料記錄,不需要任何伺服器或付費服務。
本篇教學示範如何利用 NodeMCU-32S 讀取 DHT11 溫濕度感測器數值,並透過 WiFi 自動將資料寫入 Google 試算表,實現免費的雲端資料記錄。完成後可在任何裝置上即時查看歷史數據,適合環境監控、溫室管理、實驗室記錄等應用場景。
硬體規格
| 元件 | 規格 | 數量 |
|---|---|---|
| NodeMCU-32S | ESP32 雙核心,內建 WiFi/BT | 1 |
| DHT11 模組版 | 溫度精度 ±2°C,濕度精度 ±5%RH,藍色 PCB 3 腳 | 1 |
| 杜邦線 | 3 條 | |
| 麵包板 | 標準 400 孔(選用) | 1 |



接線說明
| DHT11 模組腳位 | 接至 NodeMCU-32S |
|---|---|
| VCC(或 +) | 3.3V |
| DATA(或 OUT / S) | GPIO4 |
| GND(或 -) | GND |

前置作業:Google 試算表設定
STEP 1:建立試算表
- 開啟 Google Sheets,點「空白試算表」
- 將試算表命名為
ESP32_溫濕度記錄 - 在第一列填入標題:
| A1 | B1 | C1 |
|---|---|---|
| 時間戳記 | 溫度(°C) | 濕度(%) |

STEP 2:建立 Apps Script
- 點選上方選單「擴充功能 → Apps Script」

- 刪除預設程式碼,貼入以下內容:
function doGet(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// 讀取 URL 參數
var temp = e.parameter.temp || "";
var humi = e.parameter.humi || "";
// 台灣時區時間戳記
var tz = "Asia/Taipei";
var now = Utilities.formatDate(new Date(), tz, "yyyy/MM/dd HH:mm:ss");
// 寫入一列
sheet.appendRow([now, temp, humi]);
return ContentService.createTextOutput("OK");
}
- 點右上角「儲存」(專案命名為
DHT11Logger)

STEP 3:部署為網路應用程式
- 點「部署 → 新增部署」

- 類型選「網路應用程式」

- 設定如下:
| 項目 | 設定值 |
|---|---|
| 執行身分 | 我(帳號擁有者) |
| 誰可以存取 | 所有人 |

- 點「部署」,複製產生的 Web App URL(格式如
https://script.google.com/macros/s/AKfyc.../exec),之後會填入 ESP32 程式碼。

注意!! 這過程可能會出現警告是因為你的 Apps Script 是自己寫的未經 Google 審核的應用程式,Google 預設會顯示這個警告保護使用者。

點左下角的 Advanced,會展開隱藏選項:

然後點 「Go to DHT11Logger (unsafe)」
接著按「Allow」完成授權。
提醒: 日後若修改 Apps Script 程式碼,請選「管理部署 → 編輯現有部署版本」更新,不要建立新部署,否則 URL 會改變。
Arduino 程式碼
必要函式庫
在 Arduino IDE 的「函式庫管理員」中搜尋並安裝:
DHT sensor library(作者:Adafruit)Adafruit Unified Sensor(安裝 DHT 函式庫時通常會一起提示安裝)
完整程式碼
/*
* 【傑善創工】NodeMCU-32S + DHT11 模組版 → Google 試算表
* 教學文章:https://blog.jmaker.com.tw/
*
* 接線(模組版,3腳,不需加電阻):
* DHT11 VCC → 3.3V
* DHT11 DATA → GPIO4
* DHT11 GND → GND
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
// ===== 請修改以下設定 =====
const char* WIFI_SSID = "你的WiFi名稱";
const char* WIFI_PASSWORD = "你的WiFi密碼";
const String GAS_URL = "https://script.google.com/macros/s/你的Script_ID/exec";
// ==========================
#define DHT_PIN 4
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);
// 傳送間隔(毫秒),建議最短 30 秒,避免超過 Google 每日 20,000 次限制
const unsigned long SEND_INTERVAL = 60000; // 60 秒
unsigned long lastSendTime = 0;
void setup() {
Serial.begin(115200);
Serial.println("\n=============================");
Serial.println(" 傑善創工 DHT11 資料記錄器");
Serial.println("=============================");
dht.begin();
// 連接 WiFi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("連接 WiFi 中");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi 連線成功!IP:");
Serial.println(WiFi.localIP());
Serial.println("開始每 60 秒記錄一次...\n");
}
void loop() {
unsigned long now = millis();
if (now - lastSendTime >= SEND_INTERVAL) {
lastSendTime = now;
readAndSend();
}
}
void readAndSend() {
// 讀取感測器數值
float temp = dht.readTemperature();
float humi = dht.readHumidity();
// 檢查讀取是否成功
if (isnan(temp) || isnan(humi)) {
Serial.println("[錯誤] DHT11 讀取失敗!請檢查接線。");
return;
}
Serial.printf("[感測器] 溫度:%.1f°C 濕度:%.1f%%\n", temp, humi);
// 檢查 WiFi 狀態
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[警告] WiFi 未連線,嘗試重新連線...");
WiFi.reconnect();
delay(3000);
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[錯誤] WiFi 重連失敗,略過本次傳送。");
return;
}
}
// 組合 GET 請求 URL
String url = GAS_URL
+ "?temp=" + String(temp, 1)
+ "&humi=" + String(humi, 1);
// 發送 HTTP GET 請求
HTTPClient http;
http.begin(url);
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); // 必要!GAS 會做 302 重定向
http.setTimeout(10000); // 10 秒逾時
int httpCode = http.GET();
String response = http.getString();
http.end();
if (httpCode == 200) {
Serial.printf("[成功] 資料已寫入 Google 試算表(HTTP %d)\n\n", httpCode);
} else {
Serial.printf("[失敗] HTTP 狀態碼:%d | 回應:%s\n\n", httpCode, response.c_str());
}
}
接下來就可以把程式上傳到ESP32囉。若是第一次使用ESP32,建議先看一下我們的入門教學哦!

實測與驗證
上傳程式後,開啟序列監控器(鮑率 115200),正常運作時會看到:
=============================
傑善創工 DHT11 資料記錄器
=============================
連接 WiFi 中.....
WiFi 連線成功!IP:192.168.1.xxx
開始每 60 秒記錄一次...
[感測器] 溫度:26.0°C 濕度:62.0%
[成功] 資料已寫入 Google 試算表(HTTP 200)
[感測器] 溫度:26.0°C 濕度:63.0%
[成功] 資料已寫入 Google 試算表(HTTP 200)
同時切換到 Google 試算表,重新整理後就能看到資料依時間自動累積。


常見問題排查
問題 1:序列監控器顯示 HTTP 302 或 -1 程式碼中需加入 http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS),GAS Web App 一定會先做一次 302 重定向,不加這行就無法正常傳送。
問題 2:HTTP 200 但試算表沒有資料 回到 Apps Script 確認部署設定「誰可以存取」是否設為「所有人」,且記得要重新部署而不是只儲存程式碼。
問題 3:DHT11 一直顯示讀取失敗 模組版通常不需要加電阻,若仍持續失敗,可嘗試改用 GPIO2 或 GPIO5 測試,或換一條訊號線。
問題 4:每次修改 Apps Script 後 URL 變了 應選「管理部署 → 編輯現有部署版本」更新,不要新增部署,URL 就不會改變。
問題 5:WiFi 斷線後資料中斷 程式碼已內建重連機制,若仍持續斷線,可考慮在 readAndSend() 最後加入 delay(500) 後呼叫 ESP.restart() 定時重啟。
Google Apps Script 使用限制說明
Google Apps Script 每日有請求次數上限,使用免費 Gmail 帳號時為 20,000 次/天。
| 傳送頻率 | 每日請求次數 | 狀態 |
|---|---|---|
| 每 10 秒 | 8,640 次 | 安全 |
| 每 30 秒 | 2,880 次 | 安全 |
| 每 60 秒 | 1,440 次 | 非常安全 |
| 每 5 分鐘 | 288 次 | 綽綽有餘 |
建議傳送間隔設定在 30 秒以上,本教學預設 60 秒,兼顧資料粒度與額度使用。
進階應用方向
- Google 試算表圖表化:選取溫濕度欄位,插入折線圖,即可即時視覺化趨勢
- 多感測器同時記錄:修改 URL 參數加入
sensor_id欄位,區分不同裝置來源 - 超過閾值 Email 通知:在 Apps Script 中加入條件判斷,溫度超過設定值時自動發送 Gmail



