,

物聯網開發筆記 (二) ESP32 實作

開發物聯網,採用 ESP32 進行實作

物聯網開發筆記 (二) ESP32 實作
Photo by Jorge Ramirez / Unsplash

💡
開發上採用 VSCode + PlatformIO 以 C++ 撰寫

定義所需資訊

為了日後方便擴充 Sensor 放置點,除了定義相關連線資訊外,再而外定義一組設備名稱

// WiFi Info
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";

// Device Info
const char* DEVICE_NAME = "YOUR_CUSTOM_DEVICE_ID_OR_NAME";
const int DEVICE_WIFI_CONNECT_TIME_OUT = 15;

// Firebase Info
const char FIREBASE_PRIVATE_KEY[] PROGMEM = "YOUR_PROJECT_PRIVATE_KEY";
const char* FIREBASE_PROJECT_ID = "YOUR_PROJECT_ID";
const char* FIREBASE_CLIENT_EMAIL = "YOUR_CLIENT_EMAIL";
const char* FIREBASE_PROJECT_LOCATION = "YOUR_PROJECT_LOCATION";
const char GOOGLE_CA[] PROGMEM = "GOOGLE DOMAIN ROOT CA";
main.c

接著撰寫 WiFi 連線 function

#include <WiFi.h>

void connectToWiFi() {
  // 設定 WiFi 模式
  WiFi.mode(WIFI_STA);
  // 設定名稱
  WiFi.setHostname(DEVICE_NAME);
  // Connect
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  int connectTime = 0;
  
  // 等待 WiFi 連線中並輸出資訊
  Serial.print("WiFi 正在連線中.");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    // 如果超過 15 秒就重開機
    if (connectTime > DEVICE_WIFI_CONNECT_TIME_OUT) {
      ESP.restart();
    } else {
      connectTime++;
    }
    delay(1000);
  }

  Serial.printf("\nWiFi連線成功\n");
}
main.c

定義連線伺服器 function

#include <Firebase_ESP_Client.h>
#include <addons/TokenHelper.h>

// Firebase Variable
FirebaseData data;
FirebaseConfig config;
FirebaseAuth auth;

void connectToServer() {
  auth.user.email = "User email";
  auth.user.password = "User Password";
  
  config.cert.data = GOOGLE_CA;
  config.service_account.data.client_email = FIREBASE_CLIENT_EMAIL;
  config.service_account.data.project_id = FIREBASE_PROJECT_ID;
  config.service_account.data.private_key = FIREBASE_PRIVATE_KEY;
  config.token_status_callback = tokenStatusCallback;

  data.setCert(GOOGLE_CA);
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
}
main.c

定義上傳資料 function

void uploadData() {
  // 設定 HTTP POST 參數
  FirebaseJson payload;
  payload.set("deviceId", DEVICE_NAME);
  // 直接從腳位抓直帶入
  payload.set("moisture", analogRead(A0);

  if (Firebase.functions.callFunction(&data, 
                                FIREBASE_ID, 
                  FIREBASE_PROJECT_LOCATION, 
                             "FunctionName", 
                               payload.raw())) {
    // 解析伺服器回傳 json logic
    int nextUploadSec = 1800;
    // 設定深度睡眠喚醒時間
    esp_sleep_enable_timer_wakeup(nextUploadSec * 1000000L);
    Serial.printf("喚醒秒數 %u\n", nextUploadSec);
    delay(100);
    // 進入深度睡眠
    esp_deep_sleep_start();
  }
}
main.c

其他 function

bool taskCompleted = false;

void setup() {
  Serial.begin(115200);
  connectToWiFi();
  connectToServer();
}

void loop() {
  if (Firebase.ready() && !taskCompleted) {
    uploadData();
    taskCompleted = true;
  }
}
main.c