PWM (Pulse Width Modulation) [Arduino]

PWM หมายถึง Pulse Width Modulation เป็นเทคนิคที่ Arduino ใช้ในการควบคุมวงจร
และ เขียนค่าแบบอะนาล๊อก (Analog) ด้วยพอร์ตดิจิตัล (Digital) 
คือ โดยปกติแล้ว พอร์ตดิจิตัล จะสามารถมีได้แค่ 2 สถานะ คือ HIGH (5 โวล์ท) กับ LOW (0 โวล์ท)
เท่านั้น จึงทำให้สร้างค่าสัญญาณลอจิคได้เพียง เปิดหรือปิด (1 หรือ 0 , มีไฟหรือไม่มีไฟ) แค่นั้น
ซึ่งการใช้เทคนิค PWM นั้น จะเป็นการทำให้พอร์ตดิจิตัล สามารถเขียนค่าได้มากกว่า HIGH หรือ LOW
โดย ทำให้สามารถเขียนค่าเป็นแบบอะนาล๊อกได้ (อาจเป็น 0-255 หรือ 0-1023) โดยวิธีการนั้น
จะใช้การปรับสถานะของสัญญาณลอจิค HIGH / LOW สลับกันไปมาด้วยคาบเวลาหนึ่งๆ
โดยค่าที่ได้นั้นจะขึ้นอยู่กับ สัดส่วนเวลาของสัญญาณในช่วงเวลาที่มีสถานะเป็น HIGH
กับช่วงเวลาที่เป็น LOW โดย ช่วงเวลาทั้งหมดที่สัญญาณมีสถานะเป็น HIGH นั้นเราจะเรียกว่าเป็น

“ความกว้าง Pulse (Pulse Width)”

โดยสัญญาณพัลส์ เมื่อเทียบ % ของช่วงเวลาที่เป็น HIGH (หรือก็คือ % ของ Pulse Width)
กับ % ของคาบเวลา (Period) ของพัลส์ลูกนั้นๆ เราจะเรียกว่า Duty Cycle ครับ
เพื่อความเข้าใจสามารถดูได้จากตัวอย่างด้านล่างครับ
(คลิ๊กที่รูปภาพเพื่อดูภาพขนาดเต็ม)

การใช้งานใน Arduino

สำหรับการใช้งานใน Arduino นั้น ต้องรู้ก่อนว่า
บอร์ดของเรานั้นรองรับเทคนิค PWM ที่พอร์ตใดบ้าง 
ซึ่งจาก Datasheet ที่ผมรวมรวมมา จะเป็นดังนี้ครับ
 
Arduino Nano = พอร์ต 3 , 5 , 6 , 9 , 10 และ 11
Arduino UNO R3 = พอร์ต 3 , 5 , 6 , 9 , 10 และ 11
Arduino MEGA 2560 R3 = ตั้งแต่พอร์ต 2 ถึงพอร์ต 13
ส่วนใหญ่แล้ว การใช้ PWM ใน Arduino ที่สามารถพบเห็นได้บ่อยที่สุด
คือการนำไปใช้ในการ ควบคุมความเร็วมอเตอร์ ผ่านชุดไดรว์ (Motor Driver) เช่น L298N ครับ
L298N Dual H-Bridge Motor Driver

คำสั่งที่ใช้ใน Arduino

ในการใช้พอร์ตดิจิตัล สร้าง PWM เป็นค่าแบบอะนาล๊อก จะใช้คำสั่งนี้ครับ
analogWrite( หมายเลขขาที่เป็น PWM , ค่าที่ต้องการสร้าง เช่น 0-255 หรือ 0-1023);
 
เช่น ใน Arduino UNO ต้องการเขียนค่าอะนาล๊อคที่พอร์ต 10 
ด้วยค่าแบบอะนาล๊อกที่ 190 จะใช้คำสั่งแบบนี้ครับ
 
analogWrite( 10 , 190 );
 
ต้องการเขียนค่าอะนาล๊อคที่พอร์ต 5 ด้วยค่าแบบอะนาล๊อกที่ 255 จะใช้คำสั่ง…
 
analogWrite( 5 , 255 );
 
ตัวอย่างการใช้งานจริง ในการควบคุมมอเตอร์ด้วย L298N เช่นต้องการควบคุม
มอเตอร์ A ซึ่งตอนนี้กำลังหมุนไปด้านหน้า ให้มีความเร็วสูงสุด (255) จะใช้คำสั่งแบบนี้ครับ
 
void setup()
{
     pinMode(10,OUTPUT);    //ผมต่อขาควบคุมความเร็วมอเตอร์ A (ENA) ที่ขานี้ (รองรับ PWM)
     pinMode(9,OUTPUT);      // ขานี้เป็นสัญญาณลอจิคควบคุมทิศทางมอเตอร์ A
     pinMode(8,OUTPUT);      // ขานี้เป็นสัญญาณลอจิคควบคุมทิศทางมอเตอร์ A
}
void loop()
{
     analogWrite(10,255);   //คำสั่งสร้างค่าอะนาล๊อกที่พอร์ต 10 ด้วย PWM ด้วยค่า 255
                                            //ซึ่งเป็นค่าที่ใช้ในการควบคุมความเร็วของมอเตอร์ A (ด้วยความเร็วสูงสุด)
     digitalWrite(9,HIGH);   //คำสั่งสำหรับลอจิคควบคุมทิศทางมอเตอร์ A
     digitalWrite(8,LOW);   //คำสั่งสำหรับลอจิคควบคุมทิศทางมอเตอร์ A
}
สำหรับบทความเกี่ยวกับการใช้งานชุดควบคุมมอเตอร์ L298N สามารถไปดูได้ที่ลิ้งค์นี้นะครับ