Lab 5.1: เทคนิค Pulse Width Modulation (PWM)


Lab 5.1 – เทคนิค Pulse Width Modulation (PWM)

โจทย์

ให้นักศึกษาเขียนโปรแกรมควบคุมความสว่างของ LED

  • เมื่อเริ่มโปรแกรม LED จะดับอยู่
  • ทุกครั้งที่ผู้ใช้กดปุ่ม Run จะทำให้ LED ค่อยๆ สว่างขึ้น (มีอย่างน้อย 5 ระดับ)

แนะนำ PWM เบื้องต้น

การควบคุมพลังงานที่ส่งออกไปยังอุปกรณ์ที่ต้องการควบคุม เช่น ความแรงมอร์เตอร์ ความสว่างของไฟ LED โดยปกติหมายถึงการลดแรงดันที่ส่งออกไปยังมอร์เตอร์ แต่การลดแรงดันนั้นเป็นแนวทางที่ต้องใช้วงจรที่ซับซ้อนมีความยุ่งยากค่อนข้างมาก ดังนั้นโดยทั่วไปจึงนิยมใช้เทคนิคที่เรียกว่า Pulse Width Modulation (PWM) ซึ่งไม่ได้ลดแรงดัน หากแต่ใช้หลักการเปิด/ปิดมอร์เตอร์ด้วยความเร็วสูงๆ จนผลค่าเฉลี่ยของแรงดันที่ได้ออกมาเทียบเท่ากับการเปลียนแรงดันโดยตรง เทคนิคนี้ทำให้ไม่ต้องใช้วงจรซับซ้อน แต่การเขียนโปรแกรมจะยุ่งยากขึ้นบ้าง

PWM นั้นโดยทั่วไปจะมีการสร้างลูกคลื่นสี่เหลี่ยม (Square Wave) ออกมาโดยกำหนดคาบของสัญญาณ (Period) ให้สั้นๆ ซึ่งปกติคาบจะจะมีค่าไม่เกิน 33 ms (30 Hz) สำหรับการทดลองทั่วไป และอาจมีค่าน้อยถึง 0.01 ms (100KHz) หรือน้อยกว่าในงานอุตสาหกรรมบางชนิด หลักการสำคัญของ PWM คือการปรับเปลี่ยนความกว้างของลูกคลื่นในแต่ละคาบ โดยถ้าลูกคลื่นสั้นก็จะทำให้แรงดันเฉลี่ยที่ออกมามีค่าน้อย และถ้าลูกคลื่นยาวแรงดันเฉลี่ยก็จะมีค่ามากขึ้น จากรูปด้านล่าง V เฉลี่ย (เส้นสี่ส้ม) จะสูงหรือต่ำนั้นขึ้นอยู่กับความกว้างของลูกคลื่น ซึ่งความกว้างของลูกคลื่นนี้เรียกว่า pulse width หรือ Duty Cycle

Pulse width จะต้องน้อยกว่าค่าความยาวคาบเสมอ Duty Cycle จะมีหน่วยเป็น % ของความยาวคาบ เช่น ถ้าคาบ = 10ms และ Duty Cycle = 40% นั่นหมายความว่า Pulse width = 10ms * 0.4 = 4 ms เป็นต้น

PWM

 

Algorithm การสร้าง PWM โดยใช้ Timer Interrupt

PWM

ตัวแปรที่สำคัญมีดังนี้

  • PWM Period = คาบของสัญญาณคลื่นที่สร้างขึ้น
  • Interrupt Period = คาบของ Timer Interrupt ซึ่งจะเท่ากับความกว้างของลูกคลื่นที่เล็กที่สุด
  • Pulse Width = ค่าความกว้างของลูกคลื่นที่ต้องการ โดยในตัวอย่างแบ่งเป็น 6 ระดับ ตั้งแต่ 0-5
ข้อควรระวัง
PWM Period กับ Interrupt Period ไม่ใช่ค่าเดียวกัน การจะได้ลูกคลื่น PWM 1 ลูกจะเกิดจาก Interrupt หลายๆ ครั้ง ตามที่จะอธิบายต่อไป

 

  1. กำหนดความถี่ของสัญญาณ PWM ที่เหมาะสมสำหรับการขับ LED  – โดยความถี่ยิ่งสูงก็จะยิ่งทำให้ LED ที่แสดงผลเนียนเรียบ (ไม่กะพริบ) ซึ่งแลกด้วยภาระการทำงานของ CPU ที่หนักขึ้น โดยทั่วไป PWM สำหรับ LED ไม่ควรน้อยกว่า 30 Hz แต่ถ้าให้เนียนจริงๆ ก็จะเป็น 100 Hz ขึ้นไป
  2. ใช้ Timer Interrupt สร้าง PWM – ดังรายละเอียดต่อไปนี้
    1. Duty Cycle ต้องการกี่ระดับ – Algorithm นี้จะกำหนด Duty Cycle เป็นจำนวนระดับ เช่น ถ้ากำหนดว่า 5 ระดับ ก็เท่ากับบอกว่า Duty Cycle ที่จะใช้ได้คือ 0%, 25%, 50%, 75%, 100%
    2. ตั้งค่า Timer ให้คาบของ Interrupt (Interrupt Period) มีค่าเท่ากับความกว้างของ pulse ที่เล็กที่สุด (ระยะเวลาระหว่างเส้นประในรูป) เช่นในตัวอย่างข้างต้น ถ้าคาบของ PWM (PWM Period) = 10 ms
      ค่า Interrupt Period ก็จะกว้าง = 10/5 = 2 ms (ข้อสังเกต! คาบของ Timer Interrupt เป็นคนละตัวกับคาบของ PWM)
    3. สร้างตัวแปรไว้สองตัว คือ
      1. dutyCycle –  จะเก็บค่า duty ของสัญญาณ PWM เช่นถ้ากำหนดว่ามี 6 ระดับ (ดังใน diagram ข้างต้น) ค่าตัวแปรนี้เทียบกับ duty จะเป็นดังนี้
        • 0 = 0%
        • 1 = 20%
        • 2 = 40%
        • 3 = 60%
        • 4 = 80%
        • 5 = 100%
          ในภาพไดอะแกรมตัวอย่าง dutyCycle = 3 หรือ 60%
      2. interruptCounter – มีค่าเริ่มต้นเป็น 0 และจะเพิ่มค่าทุกครั้งที่เกิด Timer Interrupt ถ้า interrupt ครบ 6 ครั้ง ค่านี้จะถูก set กลับไปเป็น 0

ทุกครั้งที่เกิด Interrupt ให้ทำการตรวจสอบดังนี้

โครงสร้างคร่าวๆ ของโปรแกรมอาจเป็นดัง psudocode นี้

Int_timer1() {
   interruptCounter++;  // ติดตามว่านี่เป็น timer interrupt ครั้งที่เท่าใดในรอบ pwm period
   if (interruptCounter == 5) {  // ถ้า interrupt นี้เป็นครั้งสุดท้ายของรอบ pwm period
       interruptCounter = 0; }   // reset ค่าตัวนับสำหรับ pwm period รอบถัดไป
       if (dutyCycle > 0) {output_high(); }  // output high เพื่อเริ่มต้นคลื่น PWM ลูกใหม่ ยกเว้นถ้า duty =0
   }
   If (interruptCounter == dutyCycle) {output_low();}  // ถ้านับถึง dutyCycle ก็ output low เพื่อให้ได้ duty ตามระดับที่กำหนดไว้
}

Main () {
   interruptCounter = 0;
   dutyCycle = 3;
   While(1);
}

ดูตัวอย่างการทำงานในรูปแบบ Animation ได้ที่นี่

 

 

 

 

 

 

 

 

 

Click to view