สวัสดีครับนักศึกษาทุกคน ในบทที่แล้วเราเรียนรู้เรื่องสัญญาณ Digital ที่มีแค่ “เปิด” กับ “ปิด” (0 กับ 1) กันไปแล้ว แต่ในโลกความเป็นจริง สิ่งรอบตัวเราไม่ได้มีแค่ 2 สถานะครับ เช่น แสงแดดไม่ได้มีแค่ “มืด/สว่าง” แต่มันค่อยๆ สว่างขึ้น, อุณหภูมิค่อยๆ เปลี่ยนแปลง ค่าที่มีความต่อเนื่องเหล่านี้เราเรียกว่า สัญญาณอนาล็อก (Analog Signal)

บอร์ด ESP32 ซึ่งเป็นอุปกรณ์ดิจิทัล จะอ่านค่าเหล่านี้ได้อย่างไร? คำตอบคือต้องใช้ตัวช่วยที่เรียกว่า ADC (Analog-to-Digital Converter) เพื่อแปลงค่าแรงดันไฟฟ้าให้กลายเป็นตัวเลขที่คอมพิวเตอร์เข้าใจครับ


1. ความละเอียดของ ADC: Arduino vs ESP32

นี่คือจุดเด่นที่ทำให้ ESP32 เหนือกว่าบอร์ดรุ่นเก่าครับ

  • Arduino Uno: มี ADC ความละเอียด 10-bit
    • แปลงค่าไฟ 0-5V เป็นตัวเลข 0 – 1,023 (มี 1,024 ระดับ)
  • ESP32: มี ADC ความละเอียด 12-bit
    • แปลงค่าไฟ 0-3.3V เป็นตัวเลข 0 – 4,095 (มี 4,096 ระดับ)

แปลว่าอะไร? แปลว่า ESP32 สามารถอ่านค่าความเปลี่ยนแปลงได้ละเอียดกว่ามาก เหมาะสำหรับงานเซนเซอร์ที่ต้องการความแม่นยำสูงครับ


2. ข้อควรระวังระดับ “ดอกจันตัวโตๆ” (ADC2 vs WiFi)

เรื่องนี้สำคัญมากและมักทำให้นักศึกษาตกม้าตายเวลาทำโปรเจกต์จบครับ! ESP32 มีชุดแปลงสัญญาณ ADC อยู่ 2 ชุด คือ ADC1 และ ADC2

  • ADC1: (GPIO 32 – 39) -> ใช้งานได้ปกติ แนะนำให้ใช้ขากลุ่มนี้เป็นหลัก
  • ADC2: (GPIO 0, 2, 4, 12-15, 25-27) -> ห้ามใช้เมื่อเปิด WiFi!

จำไว้เลยครับ: เนื่องจากวงจร WiFi ในชิป ESP32 จะแย่งใช้ทรัพยากรของ ADC2 ทำให้เมื่อเราเชื่อมต่อเน็ต ขาพวกนี้จะอ่านค่าไม่ได้หรือค่าเพี้ยน ดังนั้นถ้าจะต่อเซนเซอร์ ให้เลือกใช้ขา GPIO 32, 33, 34, 35, 36, 39 ก่อนเสมอครับ


3. ปฏิบัติการ: อ่านค่าจากตัวต้านทานปรับค่าได้ (Potentiometer)

ชื่อคำอธิบาย
GNDกราวด์
SIGเอาต์พุต เชื่อมต่อกับขาอินพุตแบบอนาล็อก
VCCแรงดันไฟฟ้าแหล่งจ่าย

เราจะทดลองอ่านค่าแรงดันไฟฟ้าที่เปลี่ยนไปจากการหมุน “วอลุ่ม” (Potentiometer) ซึ่งหลักการนี้เหมือนกับการอ่านค่าเซนเซอร์แสง (LDR) หรือเซนเซอร์วัดความชื้นในดินแบบ Analog ทุกประการ

อุปกรณ์:

  1. บอร์ด ESP32
  2. ตัวต้านทานปรับค่าได้ (Potentiometer) ค่า 10kΩ หรือ 100kΩ

การต่อวงจร: ตัวต้านทานปรับค่าได้จะมี 3 ขา:

  1. ขาซ้าย: ต่อเข้า 3.3V
  2. ขากลาง (ขาปัด): ต่อเข้า GPIO 34 (เป็นขา Input-only ที่ปลอดภัยและอยู่ในกลุ่ม ADC1)
  3. ขาขวา: ต่อเข้า GND

4. เขียนโค้ดอ่านค่า (Analog Read)

ใช้คำสั่ง analogRead(pin) เพื่ออ่านค่าครับ

C++
const int potPin = 34; // ขาที่ต่อกับขากลางของ VR

void setup() {
  Serial.begin(115200); // เปิดการสื่อสาร Serial ความเร็ว 115200
  delay(1000); // รอระบบเสถียรนิดนึง
}

void loop() {
  // อ่านค่า Analog (จะได้ค่าช่วง 0 - 4095)
  int sensorValue = analogRead(potPin);
  
  // แปลงค่ากลับเป็นแรงดันไฟฟ้า (Voltage) เพื่อให้ดูง่ายขึ้น
  // สูตร: (ค่าที่อ่านได้ * แรงดันสูงสุด) / 4095
  float voltage = sensorValue * (3.3 / 4095.0);

  // แสดงผลทางหน้าจอ
  Serial.print("ADC Value: ");
  Serial.print(sensorValue);
  Serial.print(" | Voltage: ");
  Serial.print(voltage);
  Serial.println(" V");

  delay(500); // อ่านค่าทุกๆ ครึ่งวินาที
}

วิธีดูผลลัพธ์:

  1. Upload โค้ดลงบอร์ด
  2. เปิด Serial Monitor (ไอคอนแว่นขยายมุมขวาบน)
  3. ปรับ Baud Rate เป็น 115200 (ถ้าไม่ตรง ภาษาจะขึ้นเป็นต่างดาว)
  4. ลองหมุนวอลุ่มดู จะเห็นตัวเลขเปลี่ยนแปลงตามการหมุน

5. ความจริงที่โหดร้าย (Non-linearity)

ถ้านักศึกษาลองวัดไฟจริงๆ เทียบกับค่าที่โชว์ อาจจะเห็นว่าช่วง 0V หรือช่วง 3.3V ค่ามันอาจจะไม่ขยับ หรือขยับไม่ตรงเป๊ะๆ

  • นี่คือธรรมชาติของ ESP32 ครับ ADC ของมัน “ไม่เป็นเชิงเส้น (Non-linear)” โดยเฉพาะช่วงหัวและท้าย (0.1V แรก และ 3.2V ท้าย)
  • วิธีแก้ในงานจริง: เรามักจะใช้การเขียนโค้ดชดเชยค่า (Calibration) หรือหลีกเลี่ยงการใช้ช่วงแรงดันสุดขอบครับ แต่สำหรับการเรียนรู้เบื้องต้น ค่าที่ได้ถือว่าเพียงพอต่อการใช้งานครับ

สรุปท้ายบท

วันนี้เราได้เรียนรู้วิธีการอ่านค่า Analog ซึ่งเป็นพื้นฐานสำคัญของระบบ IoT Sensor ทั้งหลาย และที่สำคัญคือได้รู้ข้อจำกัดเรื่อง ADC2 กับ WiFi ซึ่งเป็นความรู้ระดับ “Pro Tip” ที่จะช่วยให้นักศึกษาไม่ปวดหัวในอนาคต

ภารกิจต่อไป: เมื่อเรารับค่า Analog ได้แล้ว (Input) เราจะส่งค่า Analog ออกไปบ้างได้ไหม? (Output) เพื่อทำไฟหรี่ หรือควบคุมความเร็วมอเตอร์ ในบทความหน้าเราจะมารู้จักกับเทคนิคที่เรียกว่า PWM (Pulse Width Modulation) กันครับ