การใช้งานขาสัญญาณ Analog ของ Arduino (PWM)
การใช้งานขา “สัญญาณอะนาล็อก” ใน Arduino (PWM) เป็นสัญญาณออก
หลังจากใช้งานขารับสัญญาณอนาล็อกมาแล้ว รอบนี้เรียนรู้เรื่องการใช้งานเป็นสัญญาณออกไปใช้งาน ก่อนอื่นต้องทำความเข้าใจเกี่ยวกับค่าพารามิเตอร์และคำสั่งเกี่ยวข้องก่อน
1) อนาล็อกอินพุต (ADC) คืออะไร
บอร์ด Arduino UNO ใช้ไมโครคอนโทรลเลอร์ ATmega328P ที่มีตัวแปลงสัญญาณอนาล็อกเป็นดิจิทัล (ADC) ความละเอียด 10 บิต ทำให้ค่าที่อ่านได้จาก analogRead()
อยู่ในช่วง 0 – 1023
ซึ่งสอดคล้องกับแรงดันอินพุตตั้งแต่ 0V ถึงแรงดันอ้างอิง (VREF) ของบอร์ด (โดยทั่วไปคือแรงดันทำงาน 5V บน UNO รุ่นคลาสสิก)
V = reading * Vref / 1023.0
พินที่ใช้ได้
A0–A5 คือขาอนาล็อกอินพุตบน UNO และยังใช้งานเป็นดิจิทัล D14–D19 ได้เมื่อจำเป็น
แรงดันอ้างอิง (Analog Reference)
DEFAULT
= Vcc ของบอร์ด (เช่น ~5V)INTERNAL
≈ 1.1V (บน AVR บางรุ่น)EXTERNAL
ใช้แรงดันภายนอกที่ขา AREF (อย่าลืมตั้งanalogReference(EXTERNAL)
ก่อนอ่านค่า)
ความเร็ว/อัตราสุ่ม
การแปลงหนึ่งครั้งใช้เวลาประมาณ 13 คล็อกของ ADC; ค่าปริยายทำให้ได้ราว ๆ 9–10 kSPS บน CPU 16MHz
อิมพีแดนซ์ของแหล่งสัญญาณ
แนะนำให้แหล่งสัญญาณมีอิมพีแดนซ์ ≤ 10 kΩ เพื่อให้ตัวเก็บตัวอย่างของ ADC ชาร์จได้เต็มในเวลาที่กำหนด
ตัวอย่างโค้ด: อ่านแรงดันที่ A0
// อ่านแรงดันอนาล็อกที่ A0 และพิมพ์เป็นโวลต์
const int pinAnalog = A0;
const float Vref = 5.0; // หากใช้ analogReference(DEFAULT) บน UNO
void setup() {
Serial.begin(9600);
analogReference(DEFAULT); // INTERNAL หรือ EXTERNAL ก็ได้ตามการใช้งาน
}
void loop() {
int raw = analogRead(pinAnalog); // 0..1023
float voltage = raw * Vref / 1023.0; // โวลต์ประมาณค่า
Serial.print("ADC="); Serial.print(raw);
Serial.print(" V="); Serial.println(voltage, 3);
delay(200);
}
2) “อนาล็อกเอาต์พุต” ของ Arduino: PWM
Arduino UNO ไม่มี DAC จริง ๆ เอาต์พุตอนาล็อกจึงสร้างด้วยเทคนิค PWM (Pulse-Width Modulation) คือการสลับสัญญาณดิจิทัล ON/OFF ที่ความถี่คงที่ แล้วปรับ “สัดส่วนเวลาที่เป็น ON” (duty cycle) ให้ได้ค่าเฉลี่ยเทียบเท่าแรงดันอนาล็อก
ความถี่ PWM โดยปริยาย
- ประมาณ 490 Hz: ขา 3, 9, 10, 11
- ประมาณ 980 Hz: ขา 5, 6
ช่วงค่า
analogWrite(pin, value)
โดย value
= 0..255 (8 บิต) → 0%..100% duty cycle
แรงดันเฉลี่ยที่โหลดเห็น
Vavg ≈ duty × Vcc
(เช่น duty 60% บน 5V → ~3V เฉลี่ย)
ตัวอย่างโค้ด: หรี่ไฟ LED ด้วย PWM
// ค่อยๆ เพิ่ม/ลดความสว่าง LED ที่ขา 9 (PWM)
const int ledPWM = 9;
void setup() {
pinMode(ledPWM, OUTPUT);
}
void loop() {
for (int v = 0; v <= 255; v++) { // fade in
analogWrite(ledPWM, v);
delay(8);
}
for (int v = 255; v >= 0; v--) { // fade out
analogWrite(ledPWM, v);
delay(8);
}
}
3) เคล็ดลับการใช้งานให้แม่นยำ
- ต้องกำหนด
analogReference()
ให้ตรงกับการต่อวงจรจริง (DEFAULT/INTERNAL/EXTERNAL) - ถ้าใช้ AREF ภายนอก ให้ตั้ง
EXTERNAL
ก่อนเรียกanalogRead()
และอย่าป้อนไฟเกินสเปก - หากแหล่งสัญญาณมีอิมพีแดนซ์สูง ควรใช้บัฟเฟอร์ (op-amp โหมดตามค่า) หรือใส่ตัวเก็บลัดริปเปิลตามคู่มือ
- จำไว้ว่าค่า PWM = “ค่าเฉลี่ยเชิงเวลา” ถ้าต้องการแรงดัน DC เนียน ๆ ให้ผ่านตัวกรอง RC หรือใช้ DAC ภายนอก

1. พื้นฐานของ analogWrite() และ PWM