สวัสดีครับนักศึกษาทุกคน ในบทที่แล้วเราเป็นฝ่าย “สั่งงาน” (Output) ให้ไฟติดไปแล้ว ในบทนี้เราจะเปลี่ยนมาเป็นฝ่าย “รับคำสั่ง” (Input) กันบ้างครับ
อุปกรณ์ Input พื้นฐานที่สุดคือ สวิตช์ปุ่มกด (Tactile Switch) ดูเหมือนจะง่ายแค่กดติด-ปล่อยดับ แต่ถ้านักศึกษาต่อวงจรไม่ถูกหลักทางไฟฟ้า จะเจอกับปรากฏการณ์ “ผีหลอก” คือไม่ได้กดปุ่ม แต่ไฟกระพริบเอง หรือค่าที่อ่านได้แกว่งไปมา บทความนี้จะมาไขความลับและวิธีแก้ปัญหานี้ด้วยฟังก์ชันพิเศษของ ESP32 ครับ

| ชื่อ | คำอธิบาย |
|---|---|
| 1.l / 1.r | การติดต่อครั้งแรก (ซ้าย / ขวา) |
| 2.l / 2.r | การติดต่อครั้งที่สอง (ซ้าย / ขวา) |
1. คำสั่งอ่านค่า Digital Input
ในการอ่านสถานะของขา Pin ว่ามีไฟเข้ามาหรือไม่ เราจะใช้คำสั่ง:
int buttonState = digitalRead(pin);
pin: หมายเลขขาที่ต้องการอ่าน- ค่าที่ได้คืนมา:
HIGH(1): มีไฟเข้า (ประมาณ 3.3V)LOW(0): ไม่มีไฟเข้า (0V / GND)
2. ปัญหา “สัญญาณลอย” (Floating State) คืออะไร?
สมมติเราต่อสวิตช์ระหว่างขา GPIO กับไฟบวก (3.3V)
- ตอนกดปุ่ม: ไฟ 3.3V ไหลเข้าขา ขามีสถานะเป็น HIGH (ชัดเจน)
- ตอนปล่อยปุ่ม: ขา GPIO ไม่ได้ต่อกับอะไรเลย ลอยอยู่กลางอากาศ (Open Circuit)
ในสภาวะที่ขาลอยอยู่นี้ ขาของ ESP32 จะทำตัวเหมือน “สายอากาศ” ที่คอยรับสัญญาณรบกวนรอบข้าง (Noise) ทำให้ค่าที่อ่านได้สลับไปมาระหว่าง HIGH กับ LOW มั่วไปหมด เราเรียกสภาวะนี้ว่า Floating ครับ
3. ทางแก้: ตัวต้านทาน Pull-up และ Pull-down
เพื่อไม่ให้ขาลอย เราต้อง “ดึง” (Pull) สัญญาณไว้ที่ระดับแรงดันใดแรงดันหนึ่งเสมอเมื่อไม่ได้กดปุ่ม
- Pull-down Resistor: ต่อตัวต้านทานลง GND
- ปกติ (ไม่กด): อ่านได้ LOW (เพราะถูกดึงลงดิน)
- กดปุ่ม (ต่อไฟ 3.3V): อ่านได้ HIGH
- Pull-up Resistor: ต่อตัวต้านทานขึ้นไฟ 3.3V
- ปกติ (ไม่กด): อ่านได้ HIGH (เพราะถูกดึงขึ้นไฟเลี้ยง)
- กดปุ่ม (ต่อลง GND): อ่านได้ LOW
4. ฟีเจอร์เด็ดของ ESP32: Internal Pull-up
ข่าวดีคือ! บอร์ด ESP32 มีตัวต้านทาน Pull-up ฝังมาให้ในตัวชิปเลย (Internal Pull-up) ทำให้เราไม่ต้องไปหาตัวต้านทานมาต่อเพิ่มให้รกวงจร เพียงแค่ตั้งค่าในโค้ดครับ
การต่อวงจรแบบ Internal Pull-up (นิยมใช้ที่สุด):
- ขาหนึ่งของสวิตช์ -> ต่อเข้าขา GPIO (เช่น GPIO 18)
- อีกขาของสวิตช์ -> ต่อลง GND (ไม่ต้องต่อไฟ 3.3V)
การเขียนโค้ด:
void setup() {
// ใช้โหมด INPUT_PULLUP เพื่อเปิดใช้ R ภายใน
pinMode(18, INPUT_PULLUP);
}
ข้อควรจำ (Active Low): เมื่อใช้
INPUT_PULLUPตรรกะจะกลับกันนะครับ
- ปล่อยปุ่ม: ได้ค่า HIGH (1)
- กดปุ่ม: ได้ค่า LOW (0) -> เพราะกระแสไหลลง Ground
5. ปฏิบัติการ: กดติด-ปล่อยดับ (ด้วย Internal Pull-up)
เราจะลองเขียนโปรแกรมรับค่าจากปุ่มกด (GPIO 18) เพื่อควบคุม LED (GPIO 23)
ผังวงจร:
- LED: ขาบวกต่อ GPIO 23, ขาลบต่อ R-220Ω ลง GND
- Button: ขาหนึ่งต่อ GPIO 18, อีกขาต่อ GND
โค้ดตัวอย่าง:
const int ledPin = 23;
const int buttonPin = 18;
void setup() {
Serial.begin(115200); // เปิด Serial Monitor ไว้ดูค่า
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // *สำคัญมาก*
}
void loop() {
int buttonState = digitalRead(buttonPin);
// แสดงผลค่าที่อ่านได้ทางหน้าจอคอมฯ
Serial.println(buttonState);
// ตรวจสอบเงื่อนไข (จำไว้ว่า กด = LOW)
if (buttonState == LOW) {
digitalWrite(ledPin, HIGH); // สั่งไฟติด
} else {
digitalWrite(ledPin, LOW); // สั่งไฟดับ
}
delay(50); // หน่วงเวลาเล็กน้อยเพื่อความเสถียร
}
6. ปัญหาของแถม: Switch Bouncing (สัญญาณกระเด้ง)
ในความเป็นจริง หน้าสัมผัสของสวิตช์เป็นโลหะ เมื่อมันกระทบกัน มันจะมีการ “สั่น” หรือ “กระเด้ง” (Bouncing) ในเสี้ยววินาที ทำให้ไมโครคอนโทรลเลอร์ที่ทำงานเร็วมาก อ่านค่าว่ามีการกด-ปล่อย-กด-ปล่อย หลายครั้งในการกดเพียงครั้งเดียว
ในบทความระดับสูง เราจะแก้ด้วยการเขียนโค้ด De-bouncing แบบจับเวลา แต่ในเบื้องต้นการใส่ delay(50); เล็กน้อยใน Loop ก็พอจะช่วยลดปัญหานี้ในการทดลองพื้นฐานได้ครับ
สรุปท้ายบท
วันนี้เราได้เรียนรู้เรื่อง Digital Input และเทคนิคการใช้ INPUT_PULLUP ซึ่งเป็นเทคนิคมาตรฐานที่นักพัฒนามืออาชีพใช้กัน เพื่อลดอุปกรณ์ภายนอกและทำให้วงจรเสถียรครับ
ภารกิจต่อไป: ตอนนี้เราเล่นกับอุปกรณ์ Digital (0 กับ 1) จนคล่องแล้ว ในบทความหน้า เราจะก้าวเข้าสู่โลกของ Analog กันบ้าง มาดูกันว่า ESP32 จะอ่านค่าแรงดันไฟฟ้าที่ “ไม่ใช่แค่ 0 หรือ 3.3V” ได้อย่างไร ในเรื่อง ADC (Analog to Digital Converter) ครับ
