ESP8266 กับการ connect HTTPS

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <DHT11.h>
#include <WiFiClientSecure.h> // ต้องเพิ่มตัวนี้

#ifndef STASSID
#define STASSID "XXXXXXXXXX"
#define STAPSK  "XXXXXXXXXX"
#endif

DHT11 dht11(D2);

int sensor_id = 1;
int location_id = 1;

void setup() {

  Serial.begin(115200);

  Serial.println();
  Serial.println();
  Serial.println();

  WiFi.begin(STASSID, STAPSK);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());

}

void loop() {
  int temperature = 0;
  int humidity = 0;

  int result = dht11.readTemperatureHumidity(temperature, humidity);

  if (result != 0) {
    temperature = -99999;
    humidity = 99999;
  }

  // wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {

    WiFiClientSecure client;
    HTTPClient http;
    client.setInsecure();
    Serial.print("[HTTP] begin...\n");
    // configure traged server and url
    http.begin(client, "https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX); //HTTP
    http.addHeader("Content-Type", "application/json");

    Serial.print("[HTTP] POST...\n");
    // start connection and send HTTP header and body
    String payload = "{\"sensor_t_m\":\"" + String(temperature) + "\", \"sensor_h_m\": \"" + String(humidity) + "\", \"sensor_id\":\"" + String(sensor_id) + "\", \"location_id\":\"" + String(location_id) + "\"}";
    int httpCode = http.POST(payload);
    //int httpCode = http.POST("{\"sensor_t_m\":\"" + temperature + "\", \"sensor_h_m\": \"" + humidity + "\"}");

    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTP] POST... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK) {
        const String& payload = http.getString();
        Serial.println("received payload:\n<<");
        Serial.println(payload);
        Serial.println(">>");
      } else {
        Serial.printf("[HTTP] POST... Not failed?, %s\n", http.errorToString(httpCode).c_str());
      }
    } else {
      Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  }

  delay(60000);
}

From GEMINI

สำหรับ WiFiClient ปกติ ไม่สามารถ เชื่อมต่อกับ https (SSL/TLS) ได้โดยตรงครับ เพราะมันถูกออกแบบมาเพื่อส่งข้อมูลแบบ Plain Text (HTTP) เท่านั้น

หากคุณพยายามใช้โค้ดที่คุณเขียนมาเพื่อต่อเข้ากับ URL ที่ขึ้นต้นด้วย https:// ตัว Library จะฟ้อง Error หรือเชื่อมต่อไม่สำเร็จครับ


วิธีแก้ไข: ต้องใช้ WiFiClientSecure

เพื่อให้เชื่อมต่อ HTTPS ได้ คุณต้องเปลี่ยนจากการใช้ WiFiClient มาเป็น WiFiClientSecure แทน และต้องมีการจัดการเรื่องความปลอดภัย (Certificate) เพิ่มเติมครับ

1. วิธีที่ง่ายที่สุด (แต่ปลอดภัยน้อยกว่า)

หากคุณแค่ต้องการดึงข้อมูลและไม่ซีเรียสเรื่องการตรวจสอบตัวตนของ Server (ป้องกันการโดนปลอมแปลง) ให้ใช้คำสั่ง setInsecure() ครับ

C++

#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h> // ต้องเพิ่มตัวนี้

WiFiClientSecure client; // เปลี่ยนจาก WiFiClient เป็น WiFiClientSecure
HTTPClient http;

void setup() {
    // ... การเชื่อมต่อ WiFi ...

    // สำคัญ: สั่งให้ข้ามการเช็คใบรับรอง (SSL Certificate)
    client.setInsecure(); 

    Serial.print("[HTTPS] begin...\n");
    
    // ใช้ client ตัวใหม่ใน http.begin
    if (http.begin(client, "https://XXXXXXXXXXXXXXXXXXXXXXXXXXXX")) {
        http.addHeader("Content-Type", "application/json");
        int httpCode = http.POST("{\"sensor\":\"data\"}");
        // ... จัดการคำตอบที่ได้รับ ...
    }
}

2. วิธีที่ถูกต้องตามมาตรฐาน (ปลอดภัยสูง)

ในกรณีที่คุณต้องการความปลอดภัยจริงๆ คุณต้องระบุ Root CA Certificate หรือ Fingerprint ของ Server ลงไปด้วย เพื่อให้ Arduino มั่นใจว่ากำลังคุยกับ Server ตัวจริง ไม่ใช่ Hacker ที่ดักกลางทาง (Man-in-the-Middle)


ข้อสังเกตเพิ่มเติม

  1. IP Address กับ HTTPS: ปกติแล้วการรัน HTTPS บน IP ตรงๆ (192.168.1.166) มักจะเจอปัญหาเรื่อง Self-signed Certificate หากคุณทำระบบเอง อย่าลืมใช้ client.setInsecure() เพื่อให้มันยอมรับการเชื่อมต่อครับ
  2. RAM: การใช้ HTTPS กินทรัพยากรเครื่อง (RAM) มากกว่า HTTP ปกติพอสมควร ถ้าคุณใช้ ESP8266 อาจจะต้องระวังเรื่อง Memory เป็นพิเศษ แต่ถ้าเป็น ESP32 สบายมากครับ