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