ESPAsyncWebServer สร้างเว็บเพจแผนภูมิแสดงค่าเซนเซอร์
แสดงผลการค่าอุณหภูมิจากเซนเซอร์ DHT11 และนำค่าที่อ่านได้จากเซนเซอร์มาเขียนลงแผนภูมิเส้น ในการสร้างแผนภูมิ เราจะใช้ไลบรารี ChartJS สร้างแผนภูมิได้แก่ อุณหภูมิ ช่วงเวลาหนึ่ง แผนภูมิแสดงจุดข้อมูลสูงสุด 20 จุด และการอ่านใหม่จะถูกเพิ่มทุกๆ 10 วินาที ซึ่งสามารถแก้ไขช่วงเวลาในการเพิ่มข้อมูลและจุดในการแสดงผลข้อมูลได้ < สร้างหน้าเว็บเพจ แผนภูมิแสดงค่าเซนเซอร์ ด้วย ESPAsyncWebServer >
- รายละเอียดพื้นฐานของ — บอร์ด ESP32 คืออะไร พร้อมจุดเด่นและวิธีเริ่มต้นใช้งาน
- เพิ่งเริ่มต้นกับ ESP32? ไม่แน่ใจว่าไลบรารี WiFi มีฟังก์ชันอะไรให้ใช้บ้าง — คลิกอ่าน ESP32 WiFi Library Functions เพิ่มเติมได้เลย
- เรียนรู้วิธีใช้ — ESP32 ESPAsyncWebServer Guide เทคนิคการสร้างเว็บเซิร์ฟเวอร์แบบ Asynchronous พร้อมโค้ดตัวอย่างครบ
เตรียมความพร้อม
- เราจะโปรแกรมบอร์ด ESP32 โดยใช้ Arduino IDE ดังนั้นคุณต้องติดตั้งโปรแกรมเสริมของ ESP32 ให้เรียบร้อยก่อน
- ในการสร้างเว็บเซิร์ฟเวอร์แบบอะซิงโครนัส จำเป็นต้องติดตั้งไลบรารีต่อไปนี้
บอร์ด ESP32 ต้องติดตั้งไลบรารี ESPAsyncWebServer และ AsyncTCP
ติดตั้งไลบรารีใน Arduino IDE ไปที่ Sketch > Include Library > Add .zip Library และ เลือกไลบรารีที่จะติดตั้ง - การอ่านค่าจากเซ็นเซอร์ DHT คุณต้องติดตั้งไลบรารี DHT-sensor-library ติดตั้งไลบรารีใน Arduino IDE ไปที่ Sketch > Include Library > Add .zip Library และ เลือกไลบรารีที่จะติดตั้ง
อยากเริ่มใช้งาน Arduino, ESP32 ไม่ยากอย่างที่คิด ลองดูวิธีดาวน์โหลดและติดตั้ง Arduino IDE ใน Arduino IDE Download & Install
การต่อวงจร DHT + ESP32

การจัดระเบียบไฟล์
ในการสร้างเว็บเซิร์ฟเวอร์ในตัวบทเรียนนี้ จะมีไฟล์ 3 ไฟล์ คือ
- ไฟล์ Arduino sketch
- ไฟล์ index.h
- ไฟล์ style.h

หลักการทำงาน
- ESP32 อ่านค่า Temp/Hum จาก DHT Sensor
- ESPAsyncWebServer เปิด WebSocket รอเชื่อมต่อจาก Browser
- หน้าเว็บใช้ Chart.js วาดกราฟเส้น (Line Chart)
- ทุก 2 วินาที ESP32 จะส่งค่าใหม่ให้ Browser → กราฟอัปเดตอัตโนมัติ
ไฟล์ HTML
สร้างไฟล์ index.h โดยมีข้อมูลดังนี้
const char index_html[] PROGMEM = R"rawliteral(
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"></script>
<title> Deva DIY </title>
</head>
<body>
<div class="chartMenu">
<p>โครงงาน ESP สถานีอากาศ</p>
</div>
<div class="chartCard">
<div class="chartBox">
<canvas id="myChart" style="height:55vh; width:80vw" ></canvas>
</div>
<div class="sensorBox">
<p>
<i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="dht-labels">อุณหภูมิ เซลเซียส</span>
<span id="temperature" style="color:red">%VALUE_INPUT1%</span>
<sup class="units">°C</sup>
</p>
</div>
</div>
<script>
const ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'อุณหภูมิ',
data: [],
borderWidth: 1,
}]
},
options: {
responsive: true,
scales: {
x: {
type: 'time', // ตั้งค่า type เป็น 'time'
time: {
unit: 'minute',
displayFormats: {
second: 'hh:mm'
}
},
title: {
display: true,
text: 'เวลา'
}
},
y: {
title: {
display: true,
text: 'องศาเซลเซียส (°C)'
},
ticks: {
stepSize: 0.2
}
}
}
}
});
setInterval(function addData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//อัพเดทเวลาในแกน X
let date = new Date().getTime();
chart.data.labels.push(date);
// เพิ่มข้อมูลใหม่ลงใน datasets ของ chart เมื่อเซอเวอร์ตอบกลับ
newDataT = parseFloat(this.responseText);
chart.data.datasets[0].data.push(newDataT);
// เพิ่มข้อมูลใหม่ลงใน id=temperature หน้า html นี้ เมื่อเซอเวอร์ตอบกลับ
document.getElementById("temperature").innerHTML = this.responseText;
// ลบข้อมูลใน array data เมื่อเกิน 20 ค่า
if (chart.data.datasets[0].data.length > 20) {
chart.data.datasets[0].data.shift();
chart.data.labels.shift();
}
// อัพเดท chart
chart.update();
}
};
xhttp.open("GET", "/temperature", true);
xhttp.send();
}, 10000);
</script>
</body>
</html>
)rawliteral";
ไฟล์ style.css
สร้างไฟล์ style.h โดยมีข้อมูลดังนี้
const char style_css[] PROGMEM = R"rawliteral(
body {
margin: 0;
padding: 0;
font-family: sans-serif;
background: rgba(75, 192, 192, 0.2);
}
.chartMenu {
width: 100vw;
height: 60px;
background: #1A1A1A;
color: rgba(75, 192, 192, 1);
}
.chartMenu p {
padding: 10px;
font-size: 30px;
text-align: center;
}
.chartCard {
width: 100%;
display: block;
justify-content: center;
}
.chartBox {
width: 90%;
padding: 20px;
margin: 10px auto;
align-items: center;
border-radius: 20px;
border: solid 3px rgba(75, 192, 192, 1);
background: white;
}
.sensorBox {
width: 70%;
padding: 5px 15px;
margin: 10px auto;
text-align: center;
border-radius: 20px;
border: solid 3px rgba(75, 192, 192, 1);
background: white;
}
.sensorBox p {
font-size: 42px;
}
.units {
font-size: 16px;
}
.dht-labels{
font-size: 20px;
vertical-align: middle;
padding-bottom: 15px;
}
)rawliteral";
ไฟล์ Arduino sketch
ในส่วนของ Arduino sketch งานที่ทำคือการจัดการทำคำขอที่ได้รับมาในที่นีคือ root URL และ \temperature เราก็จะจัดส่งข้อมูลที่เกี่ยวข้องกลับไป
/*
Deva DIY
https//devadiy.com
ตัวอย่างการสร้างเว็บ แสดงค่าเซนเซอร์ และ แสดงกราฟ
*/
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <DHT.h>
#include "index.h"
#include "style.h"
// สร้าง AsyncWebServer object พอร์ต 80
AsyncWebServer server(80);
// ชนิดเซนเซอร์ DHT
#define DHTTYPE DHT11
// พินที่ต่อกับ เซนเซอร์ DHT
#define DHTPIN 4
// เริ่มต้นเซ็นเซอร์ DHT
DHT dht(DHTPIN, DHTTYPE);
//ตัวแปรบันทึกค่า ssid รหัสผ่านจากแบบฟอร์ม WiFi manager
const char* ssid = "your ssid";
const char* password = "your pass";
void WiFi_init() {
unsigned long pastTime = 0;
unsigned long nowTime = 0;
unsigned long timeOut = 10000;
// ตั้งค่า esp32 WiFi Mode : Station
WiFi.mode(WIFI_STA);
// เชื่อมต่อเครื่อข่าย WiFi ด้วย ssid, password
WiFi.begin(ssid, password);
// ตรวจสอบการเชื่อมต่อ WiFi ถ้าใช้เวลาเชื่อมต่อเกิน timeOut ให้หยุดการเชื่อมต่อ
pastTime = millis();
while ((WiFi.status() != WL_CONNECTED) && (nowTime <= timeOut )) {
Serial.print("Connecting to "); Serial.println(ssid);
delay(500);
nowTime = millis() - pastTime;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Local ESP32 IP: ");
Serial.println(WiFi.localIP());
Serial.print("RSSI: ");
Serial.println(WiFi.RSSI());
}
else {
Serial.print("Unable connect to Wi-Fi " + String(ssid));
WiFi.disconnect();
}
}
// วัดค่าอุณหภูมิในอากาศ
String readTemperatureDHT() {
// อ่านค่าอุณหภูมิเซลเซียส
float t = dht.readTemperature();
if (isnan(t)) {
Serial.println("Failed to read Temperature from DHT sensor!");
return "";
}
else {
Serial.println(t);
return String(t);
}
}
// Replaces placeholder with DHT values
String processor(const String& var) {
if (var == "VALUE_INPUT1") {
return (readTemperatureDHT());
}
return String();
}
void setup() {
Serial.begin(115200);
dht.begin();
WiFi_init();
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html, processor);
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/css", style_css);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/plain", readTemperatureDHT().c_str());
});
// Start server
server.begin();
}
void loop() {
}
ดาวน์โหลดโค้ดที่นี้
กรุณา เข้าสู่ระบบ เพื่อดาวน์โหลด
ผลลัพธ์
- Dashboard แสดงกราฟ Temperature และ Humidity อัปเดตทุก 2 วินาที
- ไม่ต้องใช้ Cloud → ทำงานแบบ Local WiFi ได้เลย
- เหมาะกับโปรเจกต์ Smart Farm, IoT, งานวิจัย

❓ FAQ (10 คำถามที่พบบ่อย)
ใช้ DHT11 แทน DHT22 ได้ไหม?
ได้ แต่ความแม่นยำต่ำกว่า และช่วงการวัดแคบกว่า
สามารถปรับให้ส่งค่าเร็วกว่า 2 วินาทีได้ไหม?
ได้ แค่แก้ delay(2000) แต่แนะนำไม่น้อยกว่า 1 วินาที
ถ้า WiFi หลุดจะเป็นอย่างไร?
WebSocket จะตัดการเชื่อมต่อ → ต้อง reconnect ใหม่
สามารถเพิ่มเซนเซอร์มากกว่า 1 ตัวได้ไหม?
ได้ โดยเพิ่ม object JSON เช่น {“temp1″:..,”temp2”:..}
ต้องใช้ Library Chart.js เท่านั้นหรือไม่?
ไม่จำเป็น อาจใช้ Google Chart หรือ ECharts ก็ได้
สามารถบันทึกค่าเป็นไฟล์ได้ไหม?
ได้ ถ้าเพิ่ม SD Card หรือ SPIFFS ลงไปในโค้ด
ใช้ ESP8266 ได้หรือไม่?
ได้ แต่ต้องปรับโค้ดเล็กน้อย และทรัพยากรน้อยกว่า ESP32
สามารถดูผ่านมือถือได้ไหม?
ได้ เพียงแค่ต่อ WiFi เดียวกับ ESP32 แล้วเปิด Browser
รองรับ HTTPS หรือเปล่า?
ESPAsyncWebServer รองรับ แต่การตั้งค่ายุ่งยากกว่านี้
เหมาะกับงานจริงไหม?
เหมาะกับงานขนาดเล็ก-กลาง ถ้าข้อมูลเยอะควรใช้ Server ภายนอก






