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


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

โจทย์

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

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

แนวปฏิบัติ

การควบคุมพลังงานที่ส่งออกไปยังอุปกรณ์ที่ต้องการควบคุม เช่น ความแรงมอร์เตอร์ ความสว่างของไฟ 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

 

การสร้างคลื่นเพื่อเร่ง/หรี่อุปกรณ์โดยใช้หลัก PWM

PWM

 

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

  • ให้นักศึกษาลองกำหนดคาบที่เหมาะสม โดยคาบยิ่งสั้นการควบคุมก็จะยิ่งเรียบ ในการทดลองนี้น่าจะใช้คาบระหว่าง 1-10 ms
  • วิธีสร้างลูกคลื่น PWM วิธีหนึ่งคือการใช้ Timer Interrupt ช่วย ตามแนวคิดต่อไปนี้
  1. ให้กำหนดก่อนว่าอยากจะสร้างลูกคลื่นกี่ขนาด ในรูปข้างต้นขนาดลูกคลื่น (หรือความกว้าง pulse) จะมี 6 ระดับตามเส้นประ คือตั้งแต่ 0 (ไม่มีคลื่นเลย) จนถึง 5 (ความกว้าง pulse เท่ากับคาบของ PWM)
  2. ตั้งค่า Timer ให้คาบของ Interrupt (Interrupt Period) มีค่าเท่ากับความกว้างของ pulse ที่เล็กที่สุด (ระยะเวลาระหว่างเส้นประในรูป) เช่นในตัวอย่างข้างต้น ถ้าคาบของ PWM (PWM Period) = 10 ms ค่า Interrupt Period ก็จะกว้าง = 10/5 = 2 ms (ข้อสังเกต! คาบของ Timer Interrupt เป็นคนละตัวกับคาบของ PWM)
  3. สร้างตัวแปรไว้สองตัว คือ
    1. PWM_Level จะเก็บค่าความกว้าง pulse ที่ต้องการ โดยจากตัวอย่างข้างต้น ค่า PWM_Level จะอยู่ระหว่าง 0-5 โดย 0 หมายถึงไม่มี pulse เลยเป็น low ตลอด และ 5 คือเป็น high ตลอด ส่วนในรูปตัวอย่างข้างบนค่า PWM_Level จะเท่ากับ 3
    2. Interrupt_Counter มีค่าเริ่มต้นเป็น 0 และจะเพิ่มค่าทุกครั้งที่เกิด Timer Interrupt ถ้า interrupt ครบ 6 ครั้ง ค่านี้จะถูก set กลับไปเป็น 0
  • ทุกครั้งที่เกิด Interrupt ให้ทำการตรวจสอบดังนี้
  1. ถ้าเป็น Interrupt ครั้งแรกของ PWM Period ให้ Output High ยกเว้นถ้า PWM_Level ถูกตั้งไว้เป็น 0
  2. สำหรับ Interrupt ครั้งต่อๆ ไป ให้เช็คดูว่า Interrupt_Counter มีค่าเท่ากับ PWM_Level หรือไม่ ถ้าเท่าแสดงว่าต้อง Output Low ยกเว้นถ้า PWM_Level ถูกตั้งไว้เป็น 5
  3. วนทำเช่นนี้เป็นเรื่อยๆ

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

Int_timer1() {
   counter++;
   if (counter == 5) { counter = 0;} 
   If (counter == 0) { output_high();}  // beginning of a new period
   If (counter ==duty) {output_low();}  
}

Main () {
   Counter = 0;
   Duty = 3;
   While(1);
}