จะเป็นยังไงถ้าเซนเซอร์ตัวเล็กๆ ไม่ได้ทำหน้าที่แค่ "แสดงตัวเลข" แต่สามารถ "ตีความสุขภาพ" ของคุณได้แบบเรียลไทม์?
ในโปรเจกต์นี้ เราจะพาทุกคนมาสร้างระบบติดตามสุขภาพอัจฉริยะ (Smart Health Monitoring System) ด้วยบอร์ด ESP32 ที่สามารถวัดอุณหภูมิร่างกาย อัตราการเต้นของหัวใจ และระดับออกซิเจนในเลือด (SpO2) ได้พร้อมกัน แถมยังนำข้อมูลทั้งหมดมารวมกันเพื่อวิเคราะห์หาความเสี่ยงต่างๆ เช่น ความเครียด, ความเสี่ยงเป็นไข้, หรือปัญหาทางระบบหายใจได้ด้วยครับ!
โปรเจกต์นี้ต่างจากการทำ Arduino ธรรมดาตรงที่เราไม่ได้อ่านค่าแค่อย่างเดียว แต่มันคือระบบ Full-Stack ที่เชื่อมต่อแบบครบวงจร: ESP32 → Cloud → Dashboard เหมาะมากๆ สำหรับนำไปประยุกต์ใช้ในการดูแลผู้สูงอายุ, ติดตามผู้ป่วยทางไกล, หรือทำเป็น Fitness Tracker ล้ำๆ ของตัวเองครับ
อุปกรณ์และซอฟต์แวร์ที่ต้องใช้ (Supplies)
ฮาร์ดแวร์ที่ใช้มีไม่เยอะครับ เน้นไปที่เซนเซอร์ทางการแพทย์ที่มีความแม่นยำสูง (และแน่นอนว่า ถ้าเพื่อนๆ กำลังหาบอร์ด ESP32, เซนเซอร์สุดล้ำ หรืออุปกรณ์อิเล็กทรอนิกส์คุณภาพเยี่ยม แวะไปช้อปได้ที่ Globalbyte เลยครับ ครบจบในที่เดียว!)
-
ESP32 Development Board (รุ่น 38-pin หรือรุ่นไหนก็ได้)
- เซนเซอร์วัดอุณหภูมิความแม่นยำสูง TMP117 (แบบ I2C ของ SparkFun หรือ Adafruit)
- โมดูลวัดชีพจรและออกซิเจนในเลือด MAX30102
- Breadboard, สายจัมเปอร์, สาย Micro USB และ Power Bank 5V
ฝั่งซอฟต์แวร์และคลาวด์ (ใช้ฟรีทั้งหมด):
- Arduino IDE (ลง ESP32 Board Support ไว้ด้วย) และไลบรารี:
SparkFun_MAX3010x, Adafruit TMP117, WiFiManager
-
Node.js v18+ สำหรับรัน Backend ในคอมพิวเตอร์
-
MongoDB Atlas สำหรับใช้ทำฐานข้อมูลคลาวด์ (ฟรีแพ็กเกจ M0)
-
Render.com สำหรับโฮสต์ Backend และ Dashboard (ฟรี)
-
GitHub Account สำหรับดึงโค้ดไป Deploy บน Render
Step 1: ภาพรวมสถาปัตยกรรมระบบ (How It All Fits Together)
ก่อนจะเริ่มต่อสาย เรามาดูภาพรวมกันก่อนครับ ข้อมูลทั้งหมดจะไหลไปในทิศทางเดียว คือ:
Sensors → ESP32 → Cloud Backend → Dashboard
โดยเซนเซอร์ทั้ง 2 ตัวจะใช้สาย I2C ร่วมกัน (SDA พิน 21, SCL พิน 22) จากนั้น ESP32 จะอ่านค่าและส่งข้อมูล (POST Request) เป็น JSON ไปที่ Node.js Backend ทุกๆ 5 วินาที ตัว Backend จะทำหน้าที่เซฟข้อมูลลงฐานข้อมูล MongoDB และมี "Sensor Fusion Engine" ที่คอยวิเคราะห์ความเสี่ยงสุขภาพ แล้วส่งข้อมูลไปแสดงผลสวยๆ บนหน้าเว็บ Dashboard ครับ
Step 2-3: การต่อวงจรและติดตั้งไลบรารี
เซนเซอร์ TMP117 และ MAX30102 ทำงานด้วยไฟ 3.3V และใช้อินเทอร์เฟซ I2C ทั้งคู่ เราสามารถต่อสายพ่วงกันได้เลย ใช้สายแค่ 4 เส้นเท่านั้นครับ:
- 3.3V → VCC ของเซนเซอร์ทั้งสอง
- GND → GND ของเซนเซอร์ทั้งสอง
- GPIO 21 → SDA (สายข้อมูล I2C)
- GPIO 22 → SCL (สายนาฬิกา I2C)
เซนเซอร์ 2 ตัวนี้มี Address ของ I2C ต่างกัน (0x48 และ 0x57) จึงไม่ตีกันแน่นอนครับ จากนั้นให้เปิดโปรแกรม Arduino IDE ไปที่เมนู Manage Libraries แล้วค้นหาติดตั้ง Adafruit TMP117, SparkFun MAX3010x, และ WiFiManager ให้เรียบร้อยครับ
Step 4-5: อัปโหลดโค้ด ESP32 และตั้งค่า WiFi
ก๊อปปี้โค้ดด้านล่างนี้ไปวางใน Arduino IDE ครับ สิ่งเดียวที่คุณต้องแก้คือตัวแปร serverURL ให้เปลี่ยนเป็น URL ของคุณเองหลังจากนำ Backend ไปฝากไว้บน Render แล้วครับ
#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"
#include <Adafruit_TMP117.h>
#include <WiFiManager.h>
String serverURL = "https://health-monitor-server-2pbh.onrender.com/data";
/* -------------------- OBJECTS -------------------- */
MAX30105 particleSensor;
Adafruit_TMP117 tmp117;
/* -------------------- MAX30102 VARIABLES -------------------- */
uint32_t irBuffer[100];
uint32_t redBuffer[100];
int32_t bufferLength = 100;
int32_t spo2;
int8_t validSPO2;
int32_t heartRate;
int8_t validHeartRate;
/* -------------------- TMP117 -------------------- */
float temperatureC = 0;
/* -------------------- TIMING -------------------- */
unsigned long lastSendTime = 0;
const unsigned long sendInterval = 5000;
void setup() {
Serial.begin(115200);
delay(1000);
/* ---------- WIFI ---------- */
WiFiManager wm;
bool res = wm.autoConnect("HealthMonitor-Setup");
if(!res) {
Serial.println("WiFi Failed");
ESP.restart();
}
Serial.println("WiFi Connected!");
Serial.println(WiFi.localIP());
/* ---------- I2C ---------- */
Wire.begin(21, 22);
/* ---------- TMP117 ---------- */
if (!tmp117.begin()) {
Serial.println("TMP117 not found");
while (1);
}
Serial.println("TMP117 initialized");
/* ---------- MAX30102 ---------- */
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
Serial.println(" MAX30102 not found");
while (1);
}
particleSensor.setup(60, 4, 2, 100, 411, 4096);
Serial.println(" MAX30102 initialized");
Serial.println(" Place finger on sensor");
}
void loop() {
/* ---------- COLLECT MAX30102 SAMPLES ---------- */
for (byte i = 0; i < bufferLength; i++) {
while (!particleSensor.available()) {
particleSensor.check();
}
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample();
}
/* ---------- CALCULATE HR & SPO2 ---------- */
maxim_heart_rate_and_oxygen_saturation(
irBuffer, bufferLength,
redBuffer,
&spo2, &validSPO2,
&heartRate, &validHeartRate
);
/* ---------- READ TMP117 ---------- */
sensors_event_t tempEvent;
tmp117.getEvent(&tempEvent);
temperatureC = tempEvent.temperature;
/* ---------- VALIDATED VALUES ---------- */
int finalHR = validHeartRate ? heartRate : -1;
int finalSpO2 = validSPO2 ? spo2 : -1;
Serial.print("Temp: ");
Serial.print(temperatureC, 2);
Serial.print(" °C | HR: ");
Serial.print(finalHR);
Serial.print(" | SpO2: ");
Serial.println(finalSpO2);
/* ---------- SEND TO DB EVERY 5s ---------- */
if (millis() - lastSendTime >= sendInterval && WiFi.status() == WL_CONNECTED) {
lastSendTime = millis();
HTTPClient http;
http.begin(serverURL);
http.addHeader("Content-Type", "application/json");
String jsonData = "{";
jsonData += "\"temperature\":" + String(temperatureC, 2) + ",";
jsonData += "\"heartRate\":" + String(finalHR) + ",";
jsonData += "\"spo2\":" + String(finalSpO2) + ",";
jsonData += "\"deviceId\":\"ESP32_01\"";
jsonData += "}";
int response = http.POST(jsonData);
Serial.print(" HTTP Response: ");
Serial.println(response);
http.end();
}
}
การตั้งค่า WiFi: ความเจ๋งของโปรเจกต์นี้คือเราใช้ไลบรารี WiFiManager ทำให้ไม่ต้องไปฮาร์ดโค้ดรหัสผ่าน WiFi ในโค้ดครับ พอเปิดบอร์ดปุ๊บ ให้ใช้มือถือเชื่อมต่อ WiFi ชื่อ HealthMonitor-Setup มันจะเด้งหน้าเว็บให้เราเลือก WiFi บ้านและใส่รหัสผ่านได้เลย สะดวกสุดๆ!
Step 6: สร้าง Backend (Node.js + MongoDB Atlas)
ถึงเวลาของระบบคลาวด์แล้วครับ เริ่มจากไปสมัคร MongoDB Atlas (ฟรี) เพื่อสร้างฐานข้อมูลสำหรับเก็บข้อมูลสุขภาพ และคัดลอก Connection String มาเก็บไว้ จากนั้นให้สร้างโครงสร้างไฟล์ Node.js ตามนี้ครับ:
const mongoose = require("mongoose");
const SensorSchema = new mongoose.Schema({
temperature: Number,
heartRate: Number,
spo2: Number,
deviceId: String,
time: { type: Date, default: Date.now }
});
module.exports = mongoose.model("SensorData", SensorSchema);
Sensor Fusion Engine (สมองของระบบ): ไฟล์ด้านล่างนี้คือตัวรับข้อมูลทั้ง 3 อย่างมาวิเคราะห์ร่วมกัน ถือเป็นไฮไลต์ของโปรเจกต์นี้เลยครับ
ส่วนไฟล์ routes/dashboard.js และ server.js จะทำหน้าที่รับ/ส่งข้อมูล API ครับ (สามารถดูโค้ดแบบเต็มๆ ใน Repository ได้เลย) เมื่อเตรียมไฟล์ครบแล้ว ให้อัปโหลดขึ้น GitHub แล้วนำไปผูกและสั่ง Deploy แบบฟรีๆ บน Render.com ได้เลยครับ สิ่งสำคัญคืออย่าลืมตั้งค่า Environment Variable MONGO_URI ให้เรียบร้อยด้วยนะครับ
Step 7: สร้าง Dashboard แสดงผล
ส่วนของหน้าเว็บ Dashboard เขียนด้วย HTML+CSS+JS ธรรมดาเลยครับ ไม่ต้องใช้ Framework ให้ยุ่งยาก หน้าเว็บนี้จะดึงข้อมูลผ่าน /api/dashboard ทุกๆ 3 วินาที เพื่อนำมาแสดงค่าอุณหภูมิ, ชีพจร, SpO2 และ "คำเตือนทางสุขภาพ" ที่คิดคำนวณมาจาก Sensor Fusion ของเราครับ

Step 8-9: ทดสอบการทำงาน และเจาะลึกการทำงานของเซนเซอร์
เมื่อแฟลชเฟิร์มแวร์และ Deploy Backend เสร็จแล้ว ก็เริ่มทดสอบได้เลยครับ! วางปลายนิ้วให้แน่นสนิทกับเซนเซอร์ MAX30102 (ด้านที่มีไฟแดง/อินฟราเรด) และอยู่นิ่งๆ ประมาณ 5-10 วินาที เพื่อให้เซนเซอร์อ่านค่าได้เสถียร (ถ้าค่าโชว์ -1 แปลว่านิ้วยังวางไม่สนิทนะ)
ค่ามาตรฐานขณะพักผ่อน (Expected readings at rest):
- อุณหภูมิร่างกาย: 36.0°C – 37.5°C (อุณหภูมิปลายนิ้วจะต่ำกว่าแกนกลางร่างกายนิดหน่อยครับ)
- อัตราการเต้นของหัวใจ: 60–100 BPM
- SpO2 (ออกซิเจนในเลือด): 95–100% (สำหรับคนสุขภาพปกติ)
- สถานะ Fusion: Normal (Risk score 0-1)
ทำไมถึงเลือกเซนเซอร์ 2 ตัวนี้?
TMP117 ไม่ใช่เซนเซอร์วัดอุณหภูมิบ้านๆ ทั่วไปนะครับ แต่มันมีความแม่นยำถึง ±0.1°C ซึ่งเป็นสเปกเดียวกับที่ใช้ในอุปกรณ์ทางการแพทย์เลย! (เทียบกับ DHT22 ที่คลาดเคลื่อน ±0.5°C ถือว่าคนละชั้น) ส่วน MAX30102 จะใช้หลักการยิงแสงสีแดงและแสงอินฟราเรดทะลุปลายนิ้วเรา เพื่อวัดการสะท้อนกลับของฮีโมโกลบินในเลือด ทำให้วัดค่าออกซิเจนและจังหวะชีพจรได้อย่างแม่นยำครับ
ไอเดียพัฒนาต่อยอด (Possible Improvements)
โปรเจกต์นี้วางรากฐานไว้ดีมาก สามารถอัปเกรดความล้ำต่อได้สบายๆ เลย เช่น:
- ต่อจอ OLED (SSD1306) เพิ่ม เพื่อให้ดูค่าได้โดยไม่ต้องเปิดมือถือ (I2C รองรับการต่อพ่วงอยู่แล้ว)
- ตั้งค่าบอท Telegram แจ้งเตือนอัตโนมัติหาก SpO2 ต่ำกว่า 94% หรือมีไข้สูงเกิน 38°C
- ปรับ Backend ให้รองรับบอร์ด ESP32 หลายๆ ตัว พร้อมกัน (สำหรับใช้งานในสถานพยาบาลหรือบ้านที่มีผู้สูงอายุหลายคน)
-
ออกแบบและ 3D Print เคสแบบสวมใส่ได้ (Wearable enclosure) (ถ้าใครอยากทำเคสแบบสวมข้อมือ หรือหนีบนิ้ว แนะนำให้ใช้เส้นพลาสติก 3D Print คุณภาพสูงจาก Globalbyte เลยครับ พิมพ์งานง่าย แข็งแรงทนทาน ใส่สบายแน่นอน!)
*คำเตือน: เนื้อหานี้เป็นการสรุปและเรียบเรียงจากบทความโปรเจกต์ต้นฉบับภาษาอังกฤษ โปรเจกต์นี้มีจุดประสงค์เพื่อการเรียนรู้และทดลอง
"ไม่ใช่เครื่องมือทางการแพทย์ที่ได้รับการรับรอง" หากมีปัญหาสุขภาพโปรดปรึกษาแพทย์ผู้เชี่ยวชาญ สามารถตรวจสอบข้อมูลและโค้ดเชิงลึกได้ที่
ต้นฉบับภาษาอังกฤษ