จะเจ๋งแค่ไหนถ้าบอร์ด Arduino ของคุณสามารถ "รับรู้" ถึงอุณหภูมิรอบตัวได้เหมือนกับผิวหนังของมนุษย์ และตอบสนองต่อมันได้?
ด้วยเซ็นเซอร์ตัวจิ๋วอย่าง LM35 เราสามารถทำแบบนั้นได้สบายๆ! ไอซี (IC) ตัวเล็กๆ นี้จะวัดอุณหภูมิรอบข้างและแปลงค่าออกมาเป็นแรงดันไฟฟ้าให้ Arduino อ่านค่าได้ทันที ในบทเรียนนี้เราจะมาทำความเข้าใจว่ามันทำงานอย่างไร และลงมือสร้างโปรเจกต์วัดอุณหภูมิห้องแบบสมาร์ทๆ ที่โชว์ผลบนหน้าจอ LCD และกดเปลี่ยนหน่วย (C/F) ได้ด้วยปุ่มกดกันครับ
อุปกรณ์ที่ต้องเตรียม (Supplies)
- บอร์ด Arduino UNO
- บอร์ดขยายพอร์ต (I/O Expansion Shield)
- เซ็นเซอร์วัดอุณหภูมิ LM35
- โมดูลปุ่มกด (Push button module)
- หน้าจอ I2C LCD Module
- สายจัมเปอร์ (Jumper wires)
- (อุปกรณ์ทั้งหมดอ้างอิงจากชุด DFRobot MindPlus Arduino Coding Kit)
คลิกเพื่อดูรูปภาพอุปกรณ์ชิ้นอื่นๆ (View More)
Step 2: ทำความรู้จักเซ็นเซอร์ LM35
LM35 ไม่ได้ทำงานแบบเปลี่ยนค่าความต้านทานตามความร้อนเหมือนพวก Thermistor แต่มันมีวงจรภายในที่แปลงอุณหภูมิให้กลายเป็น "แรงดันไฟฟ้า" ส่งออกมาตรงๆ เลย ทำให้ไมโครคอนโทรลเลอร์อ่านค่าได้ง่ายมาก
-
ช่วงการวัด: วัดได้ตั้งแต่ -55°C ถึง 150°C (เหลือเฟือสำหรับโปรเจกต์ในบ้าน)
-
จุดเด่น (Scale Factor): ทุกๆ อุณหภูมิที่เพิ่มขึ้น 1°C เซ็นเซอร์จะปล่อยแรงดันไฟเพิ่มขึ้น 10 มิลลิโวลต์ (10 mV) เสมอ! ความเป็นเส้นตรง (Linear) แบบนี้ทำให้เราเอาไปเขียนโค้ดคูณเลขธรรมดาๆ ก็ได้ค่าอุณหภูมิแล้ว ไม่ต้องพึ่งสมการซับซ้อนเลย
-
ความแม่นยำ: คลาดเคลื่อนแค่ราวๆ ±0.25°C (ที่อุณหภูมิห้อง) และไม่ต้องมานั่งตั้งค่าคาลิเบรตเอง เพราะโรงงานจัดการมาให้แล้ว
คลิกเพื่อดูรูปภาพของเซ็นเซอร์ LM35 (View More)
Step 3: ผู้สนับสนุนโปรเจกต์
อุปกรณ์ทั้งหมดในโปรเจกต์นี้มาจาก DFRobot ผู้จัดจำหน่ายฮาร์ดแวร์สำหรับสาย Maker ทั่วโลก โดยชุด MindPlus Arduino Coding Kit นี้เหมาะมากสำหรับมือใหม่ เพราะมีโมดูลและเซ็นเซอร์พื้นฐานมาให้ลองเล่นแบบครบเซ็ตครับ
Step 4: ลงมือต่อวงจร (Wiring)
ระบบนี้ทำงานง่ายมาก เมื่อเปิดเครื่อง หน้าจอจะโชว์อุณหภูมิเป็นหน่วยเซลเซียส (°C) ถ้าคุณกดปุ่ม มันจะสลับเป็นหน่วยฟาเรนไฮต์ (°F) ทันที ดูเป็นมืออาชีพสุดๆ เริ่มต่อสายตามนี้เลย:
- สวม I/O Expansion Shield ลงบนบอร์ด Arduino
- ต่อโมดูลปุ่มกดเข้ากับ Digital port 2
- ต่อสายสัญญาณ (Signal) ของ LM35 เข้าที่ Analog port A3 (เช็กสาย VCC และ GND ให้ถูกขั้วด้วย)
- ต่อจอ LCD เข้าช่อง I2C (SCL ไปที่ A5, SDA ไปที่ A4)
คลิกเพื่อดูรูปการต่อวงจรและภาพรวมโปรเจกต์ (View More)
Step 5: อธิบายโค้ด (พร้อมให้กดก๊อปปี้)
ในโค้ดนี้เราจะไม่ได้ใช้คำสั่ง delay() เลย! แต่เราจะใช้ฟังก์ชัน millis() เพื่อจับเวลาแทน (Non-blocking timing) ซึ่งเป็นทักษะการเขียนโค้ดแบบมือโปรที่ทำให้บอร์ดประมวลผลงานอื่นๆ พร้อมกันได้โดยไม่ค้าง
ทริคสำคัญในโค้ดนี้:
- Circular Buffer: เราจะอ่านค่าเซ็นเซอร์ 10 ครั้งแล้วเอามาหาค่าเฉลี่ย (Averaging) เพื่อให้ตัวเลขอุณหภูมินิ่งขึ้น ไม่แกว่งไปมา
- Debounce Logic: การดักจับการกดปุ่ม ป้องกันไม่ให้บอร์ดเข้าใจผิดว่าเรากดปุ่มรัวๆ เวลาที่หน้าสัมผัสของสวิตช์เด้ง
คลิกเพื่อดูและคัดลอกโค้ด C++ ทั้งหมด (View More)
#include <Wire.h>
#include <DFRobot_RGBLCD1602.h>
#define LM35_PIN A3
#define BUTTON_PIN 2
DFRobot_RGBLCD1602 lcd(0x60, 16, 2);
bool showCelsius = true;
// ---------- Button ----------
bool lastReading;
bool buttonState;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
// ---------- Startup lock ----------
unsigned long startTime;
// ---------- Averaging ----------
const int numSamples = 10;
int samples[numSamples];
int sampleIndex = 0;
long total = 0;
float smoothedTempC = 0;
unsigned long lastSampleTime = 0;
const unsigned long sampleInterval = 10;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
lcd.init();
lcd.display();
lcd.setColorWhite();
lcd.clear();
showCelsius = true;
lastReading = digitalRead(BUTTON_PIN);
buttonState = lastReading;
startTime = millis();
// Initialize sample buffer
for (int i = 0; i < numSamples; i++) {
samples[i] = analogRead(LM35_PIN);
total += samples[i];
}
}
void loop() {
unsigned long now = millis();
// ---------- Sample LM35 ----------
if (now - lastSampleTime >= sampleInterval) {
lastSampleTime = now;
total -= samples[sampleIndex];
samples[sampleIndex] = analogRead(LM35_PIN);
total += samples[sampleIndex];
sampleIndex = (sampleIndex + 1) % numSamples;
float avgReading = total / (float)numSamples;
float voltage = avgReading * (5.0 / 1023.0);
smoothedTempC = voltage * 100.0;
}
float tempF = (smoothedTempC * 9.0 / 5.0) + 32.0;
// ---------- Button (after startup) ----------
if (now - startTime > 1000) {
bool reading = digitalRead(BUTTON_PIN);
if (reading != lastReading) {
lastDebounceTime = now;
}
if ((now - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
showCelsius = !showCelsius;
}
}
}
lastReading = reading;
}
// ---------- LCD Update ----------
static unsigned long lastLCDUpdate = 0;
if (now - lastLCDUpdate >= 500) {
lastLCDUpdate = now;
lcd.setCursor(0, 0);
lcd.print(" "); // Clear line
lcd.setCursor(0, 0);
lcd.print("Temp: ");
if (showCelsius) {
lcd.print(smoothedTempC, 1);
lcd.print((char)223);
lcd.print("C");
} else {
lcd.print(tempF, 1);
lcd.print((char)223);
lcd.print("F");
}
Serial.print("Temp: ");
Serial.print(smoothedTempC);
Serial.print(" C | ");
Serial.print(tempF);
Serial.println(" F");
}
}
Step 6: สรุปผล
ในบทเรียนนี้ คุณไม่ได้แค่เสียบเซ็นเซอร์อ่านค่าอุณหภูมิทื่อๆ แต่คุณได้สร้าง ระบบสมาร์ท ที่รู้จักกรองข้อมูลให้นิ่งขึ้น (Filtering) จัดการอินพุตจากปุ่มกดได้อย่างถูกต้อง (Debounce) และสามารถให้ Arduino จัดการหลายๆ งานพร้อมกันโดยที่ระบบไม่ค้าง!

อยากลองทำระบบเซ็นเซอร์เป็นของตัวเองบ้างไหม?
คำเตือน: เนื้อหานี้เป็นการสรุปและเรียบเรียงจากบทความต้นฉบับภาษาอังกฤษ ข้อมูลฉบับภาษาไทยอาจมีความคลาดเคลื่อนบางประการจากการตีความหรือย่อเนื้อหา