在學會向 API 「問世界」之後,ESP32 亦可以變成「被問的一方」。 例如接上 DHT11 或 DHT22 感測器,量度溫度與濕度,再打包成 JSON 資料上傳到雲端,例如 Google Sheet。
先用 random 數據確認通路成功,再換成 溫濕度。
Sensor → ESP32 → HTTP POST → Google Apps Script → Google Sheet
ESP32 量度溫濕度,打包成 JSON 格式,透過 Google Apps Script (GAS) 做「橋樑」。 ESP32 就係向呢個 GAS 網址傳送 JSON,GAS 再幫你寫入 Sheet。
一個 Google 帳戶;一個新 Google Sheet(命名:ESP32_Data),
注意是下方這個頁面名稱必須為ESP32_Data,不是上方。
首行表頭:Timestamp | Device | Value | Extra(可先留空 Extra 俾之後溫濕度用)。

在該 Sheet 中:Extensions → Apps Script,將預設 Code.gs 全部改為以下:
231function doPost(e) {2 try {3 const sheet = SpreadsheetApp.getActive().getSheetByName('ESP32_Data');4 const raw = e && e.postData ? e.postData.contents : '{}';5 const data = JSON.parse(raw);6 // 可選:簡單 token 驗證(正式使用時)7 // if (data.token !== 'YOUR_TOKEN') return ContentService.createTextOutput('DENIED').setMimeType(ContentService.MimeType.TEXT);8
9
10 const now = new Date();11 const device = data.device || 'ESP32';12 const value = data.value;13 const extra = data.extra || '';14
15
16 sheet.appendRow([now, device, value, extra]);17 return ContentService.createTextOutput('OK').setMimeType(ContentService.MimeType.TEXT);18 } catch (err) {19 // 便於除錯:在 Apps Script 的 Executions 內可見20 console.error(err);21 return ContentService.createTextOutput('ERROR').setMimeType(ContentService.MimeType.TEXT);22 }23}Deploy → Manage deployments → New deployment
Type:Web app
Execute as:Me(由你寫入 Sheet)
Who has access:Anyone(Demo 階段)
允許權限後,取得 URL(以 /exec 結尾)。
提醒:每次改動程式後如需公開新版本,要 New deployment 或 Edit deployment 重新部署。
只需識睇幾句:Wi‑Fi 連線、指定 URL、POST JSON、Content-Type: application/json。
xxxxxxxxxx123
4
5const char* ssid = "YOUR_WIFI";6const char* pass = "YOUR_PASS";7const char* GAS_URL = "https://script.google.com/macros/s/XXXXXXXX/exec"; // 你的 /exec 連結8
9
10void setup() {11 Serial.begin(115200);12 WiFi.begin(ssid, pass);13 while (WiFi.status() != WL_CONNECTED) { delay(300); Serial.print('.');}14
15
16 HTTPClient http;17 http.begin(GAS_URL);18 http.addHeader("Content-Type", "application/json");19
20
21 String payload = String("{\"device\":\"ESP32_A1\", \"value\":") + String(random(20, 41)) + "}";22 // 20–40 隨機整數23 int code = http.POST(payload);24 Serial.printf("HTTP %d", code);25 Serial.println(payload);26 Serial.println(http.getString());27 http.end();28}29
30
31void loop() {}記得不要將你的密碼和GAS_URL給AI。
達標畫面:Sheet 會多一行,Value 欄出現 20–40 之間的數字,Timestamp 自動填入。
節奏:先單發一次(
loop()空置)。確認成功後,再改成每 10s 上報一次。
只替換 payload 組裝 部分;其餘(Wi‑Fi、URL、POST)保持不變。
要點:
使用 DHT 或 SHT31 等模組;示例以 DHT11:
需要行庫:DHT sensor library(by Adafruit)、Adafruit Unified Sensor。
提示:您是否應該先開一個新的對話/開一個新的獨立檔案,先測試一下感測器?
231234DHT dht(DHTPIN, DHTTYPE);5
6
7void setup(){ 8 Serial.begin(115200); 9 /* 省略 Wi‑Fi 連線與 http.begin(...) */ 10 dht.begin(); 11 sendOnce();12}13
14void loop() {}15
16void sendOnce(){17 float t = dht.readTemperature();18 float h = dht.readHumidity();19 // 只換呢句:把 random 換成 JSON(可放更多欄位入 Extra)20 String payload = String("{\"device\":\"ESP32_A1\", \"value\":" ) + String(t, 1) +21 ", \"extra\": \"humi=" + String(h, 1) + "%\"}";22 // 然後照舊 http.POST(payload)23}Sheet 欄位含義:
Value = 溫度,Extra = "humi=65.3%"。之後你亦可改為同時寫兩欄,或把Value換成 JSON string 由 GAS 拆開。
先在setup()最下方,加一行sendOnce(),避免程式有bug都濫發。
如果測試後沒有問題,請你告知AIjf 將sendOnce()放在loop()之中,每10秒上傳一次(正式場景 5–60 秒)。
| 項目 | 建議 | 原因 |
|---|---|---|
| 上傳間隔 | ≥ 10 秒(教學示範),正式場景 5–60 秒 | Apps Script 執行配額&Sheet 刷新成本 |
| 連線失敗重試 | 指數退避(1s→2s→4s,上限 60s) | 避免無限 POST 轟炸 |
| 內容大小 | 盡量 < 5KB | JSON 過大會觸發限制 |
| 權限 | Demo 用 Anyone,正式請加 token 驗證 | 防止被外部濫用 |
| 📄 Row 數上限 | 約 50000 | 太多會令 Sheet 緩慢 |
任務 A:Random 通路測試
將製作好的 GAS_URL 貼入程式。
找出兩句關鍵語句:http.addHeader("Content-Type", "application/json")、http.POST(payload)。
觀察 Sheet 是否新增一行數據。
任務 B:換成溫濕度
只替換 payload 組裝;device、value、extra 三欄保持格式。
在 Serial Monitor 顯示送出前的 payload,又回傳了甚麼。
Sheet 能否正確顯示?若否,回看 payload 是否為合法 JSON。
| 現象 | 可能原因 | 處理 |
|---|---|---|
HTTP 405 | 用了 GET 或 URL 非 /exec | 改用 POST;確認 /exec 連結 |
HTTP 401/403 | Web App 權限不對 | 部署時選 Anyone(Demo),或改為 token 驗證 |
GAS 執行紀錄有 TypeError: e.postData is undefined | 未設 Content-Type: application/json | 在 ESP32 端加 http.addHeader(...) |
| Sheet 無法寫入 | Sheet 名稱不符 / 欄位太多公式 | 確認 ESP32_Data;把寫入列放在不含公式的工作表 |
✅ ESP32 以前係「問問題」:問天氣、問時間。 ✅ 而家佢開始「答問題」:告訴世界「我量到咩數據」。
你有沒有發現,其實你不知不覺中,已在建立一個資料庫,下一步,你會怎樣運用這個資料庫?