ข้ามไปยังเนื้อหา

วัด PWM

เมื่อจบบทเรียนนี้ คุณจะ

  1. วัดคาบเวลา (period) ความถี่ และ duty cycle ของ PWM จากรูปคลื่นได้
  2. เทียบ duty cycle ที่วัดได้กับค่าที่โปรแกรมสั่ง และอธิบายเมื่อไม่ตรงกัน
  • ตั้งออสซิลโลสโคปให้ภาพนิ่งได้ (บทเรียน ออสซิลโลสโคปเบื้องต้น) และใช้ logic analyzer วัดเวลาได้ (บทเรียน จับสัญญาณดิจิทัลครั้งแรก)
  • TESAIoT Dev Kit ที่ flash ตัวอย่าง QWA309 Header I/O Test ไว้ ออสซิลโลสโคปสองช่อง (หรือ logic analyzer) และมัลติมิเตอร์
  • ส่วนเสริมของแล็บใช้เฟิร์มแวร์ MicroPython ของหลักสูตร AIoT in Action ที่มีคำสั่ง led.brightness() ถ้าไม่มี ข้ามส่วนนั้นได้

หลักสูตร AIoT in Action มีตัวอย่าง 03_led_brightness.py ที่หรี่ LED ด้วย led.brightness(pct) แล้วอ่านค่ากลับด้วย led.duty() ในตัวอย่างนั้นมีการทดลองหนึ่งที่สั่ง on() แล้วตามด้วย toggle() หลอดดับไปแล้ว แต่ duty() ยังตอบเลขเดิม ความเห็นในโค้ดสรุปไว้ว่า “duty() = สิ่งที่สั่ง ไม่ใช่สิ่งที่วัด”

นี่คือคำถามของบทนี้ ตัวเลขที่โปรแกรมบอก กับสัญญาณที่ออกจากขาจริง ตรงกันไหม เราจะตอบด้วยเครื่องมือวัด ไม่ใช่ด้วยการเชื่อตัวเลขบนจอ

PWM (pulse-width modulation) คือสัญญาณสี่เหลี่ยมที่คาบเวลาคงที่ แต่ปรับสัดส่วนเวลาที่เป็น 1 ได้

25% 50% 75% period T duty D = t_high / T
PWM สามแถวมีคาบเวลาเท่ากัน ต่างกันที่สัดส่วนเวลาที่เป็น 1 ต่อหนึ่งคาบเวลา (duty cycle)
คาบเวลา T = เวลาจากขอบขาขึ้นถึงขอบขาขึ้นถัดไป
ความถี่ f = 1 / T
duty cycle D = t_high / T
แรงดันเฉลี่ย V_avg = D × V_high (เมื่อโหลดหรือวงจรกรองเฉลี่ยสัญญาณ)

ตัวอย่าง T = 2 ms, t_high = 0.5 ms บนขา 3.3 V

f = 1 / 2 ms = 500 Hz D = 0.5 / 2 = 25% V_avg = 0.25 × 3.3 V = 0.825 V

LED ที่ขับด้วย PWM ความถี่สูงพอ ตาคนเห็นเป็นความสว่างเฉลี่ย (โดยทั่วไปสูงกว่าราว 100 Hz ขึ้นไปคนส่วนใหญ่ไม่เห็นกะพริบ แต่กล้องมือถืออาจยังเห็นเป็นแถบ) มัลติมิเตอร์โหมดแรงดันไฟตรงก็อ่านค่าเฉลี่ยได้ ถ้าคาบเวลาสั้นกว่าเวลาเฉลี่ยของเครื่องมาก ถ้าความถี่ต่ำอย่าง 25 Hz ตัวเลขจะกระโดดไปมา

PWM จากตัวจับเวลา (timer) ของฮาร์ดแวร์ ตัวนับนับขึ้นด้วยสัญญาณนาฬิกาความถี่ f_clk ครบ N ครั้งก็เริ่มใหม่ ขาเป็น 1 ขณะที่ค่านับยังน้อยกว่าค่าเปรียบเทียบ (compare)

f_PWM = f_clk / N D = compare / N ความละเอียดของ duty = 1 / N

ตัวอย่าง f_clk = 1 MHz, N = 1000 ได้ PWM 1 kHz และ duty ปรับได้ละเอียด 0.1% ต่อขั้น ถ้าต้องการ 20 kHz จากนาฬิกา 100 MHz จะได้ N = 5000 ความละเอียด 0.02% รายละเอียดของรีจิสเตอร์ (ค่าที่ใส่คือ N หรือ N − 1) ต่างกันไปตามฮาร์ดแวร์ ใน PSoC บล็อกนี้ชื่อ TCPWM ให้ดูเอกสารของ PDL ประกอบ SDK ของ TESAIoT Dev Kit อธิบายว่าเส้นทางหรี่ไฟของ LED สี RGB ต่อขาเข้ากับสัญญาณของ TCPWM0 ส่วนหลักสูตร AIoT in Action อธิบายว่า LED ที่ไม่มีเส้นทาง PWM ของฮาร์ดแวร์ จะได้พัลส์สั้น ๆ ราว 12 ms แล้วดับ ไม่ค้างความสว่างไว้

PWM จากซอฟต์แวร์ โปรแกรมเขียนขาเป็น 1 หน่วงเวลา เขียนเป็น 0 หน่วงเวลา วนไป ปุ่ม PWM Out ของโปรแกรมทดสอบ header ทำแบบนี้ (เขียน P13.3 = 1, P13.4 = 0 หน่วง 20 ms แล้วสลับ ทำ 50 รอบ ตามโค้ดของตัวอย่าง) ข้อดีคือใช้ขาไหนก็ได้ ข้อเสียคือเวลาของคำสั่งอื่นและการขัดจังหวะ (interrupt) ปนเข้าไปในจังหวะ คาบเวลาจึงยาวกว่าที่ตั้งเล็กน้อยและแกว่งได้ (jitter) และ CPU ต้องไม่ไปทำอย่างอื่นระหว่างนั้น

คู่สัญญาณกลับเฟส (complementary) งานขับมอเตอร์ด้วยสะพาน H (H-bridge) ใช้สัญญาณสองเส้นที่กลับเฟสกัน สองเส้นนี้ ห้ามเป็น 1 พร้อมกัน ไม่อย่างนั้นทรานซิสเตอร์ด้านบนและด้านล่างจะนำไฟพร้อมกันและลัดวงจรแหล่งจ่าย (shoot-through) ระบบจริงจึงเว้น dead time ให้ทั้งสองเส้นเป็น 0 สั้น ๆ ก่อนสลับ

P13.3 P13.4 ≈ 40 ms (2 × 20 ms)
คู่สัญญาณกลับเฟส (complementary) จากปุ่ม PWM Out ของตัวทดสอบ header: เมื่อขาหนึ่งเป็น 1 อีกขาเป็น 0 และห้ามเป็น 1 พร้อมกัน (both-high fault)
สาเหตุ อาการ ตัวอย่าง
ความละเอียดของตัวนับ duty ถูกปัดเป็นขั้น N = 100 สั่ง 33.3% ได้จริง 33%
นับเกินหรือขาดหนึ่ง (off-by-one) คาบเวลาหรือ duty คลาดหนึ่งขั้นเสมอ ใส่ N แทน N − 1 ในรีจิสเตอร์
PWM จากซอฟต์แวร์ คาบเวลายาวกว่าที่ตั้ง และแกว่ง ตั้ง 40 ms วัดได้ 40.1 ms
ขั้วกลับ duty ที่วัดได้เป็น 100% ลบค่าที่สั่ง LED ต่อแบบ active-low สั่ง 20% หลอดติด 80% ของเวลา
ตัวเลขในโปรแกรมไม่ใช่การวัด โปรแกรมรายงานค่าที่สั่งครั้งล่าสุด duty() ยังตอบ 100 หลัง toggle() ดับหลอดแล้ว
ขาไม่ได้ต่อกับ PWM ของฮาร์ดแวร์ ได้พัลส์สั้นแล้วหยุด หรือไม่มีสัญญาณ LED ที่ไม่มีเส้นทาง PWM
วิธีวัด ความกว้างพัลส์เพี้ยนเมื่อขอบช้า วัดที่ระดับ 10% แทน 50% ของแรงดัน

วิธีวัดให้แม่น

  • วัดความกว้างพัลส์ที่ ระดับ 50% ของแรงดัน (เครื่องส่วนใหญ่ใช้ระดับนี้ในการวัดอัตโนมัติ)
  • วัดหลายคาบเวลาแล้วเฉลี่ย หรือใช้สถิติของเครื่อง (ค่าเฉลี่ย ต่ำสุด สูงสุด) ค่าต่ำสุดกับสูงสุดบอกได้ว่ามี jitter เท่าไร
  • ความละเอียดของเวลาต้องละเอียดกว่าความละเอียดของ duty ที่อยากตรวจ ถ้าอยากเห็นขั้น 0.1% ของ PWM 1 kHz (1 µs) ต้องวัดเวลาได้ละเอียดกว่า 1 µs

โจทย์ วัด PWM จากปุ่ม PWM Out แล้วเทียบกับที่โค้ดสั่ง (ครึ่งคาบเวลา 20 ms, 50 รอบ, P13.3 กับ P13.4 กลับเฟสกัน) ตัวเลขที่วัดได้ด้านล่างเป็นข้อมูลตัวอย่าง

  1. ค่าที่สั่ง t_high = 20 ms, T = 40 ms, f = 25 Hz, D = 50%
  2. ต่อ ช่อง 1 ที่ P13.3 ช่อง 2 ที่ P13.4 กราวด์ของโพรบทั้งสองที่ GND ตั้ง 10 ms/div, 1 V/div, trigger ขาขึ้นของช่อง 1 ที่ 1.65 V, mode Normal
  3. วัดช่อง 1 (เฉลี่ย 10 คาบเวลา) T = 40.10 ms, t_high = 20.05 ms
f = 1 / 40.10 ms = 24.94 Hz
D = 20.05 / 40.10 = 50.0%
คาบเวลายาวกว่าที่สั่ง 0.10 ms = 0.25%
  1. อธิบาย duty ตรงกับที่สั่ง แต่คาบเวลายาวขึ้นเล็กน้อยทั้งครึ่งบนและครึ่งล่าง เป็นลักษณะของ PWM จากซอฟต์แวร์ที่มีเวลาของคำสั่งเขียนขาและวนลูปปนเข้าไปในทุกครึ่งคาบเวลา
  2. ตรวจคู่กลับเฟส ซูมที่ขอบที่สองช่องสลับกัน ดูว่ามีช่วงที่ทั้งสองเส้นเป็น 1 พร้อมกันไหม ในโค้ดตัวอย่าง ขาหนึ่งถูกเขียนเป็น 1 ก่อนอีกขาถูกเขียนเป็น 0 เพียงคำสั่งเดียว ถ้าเครื่องของคุณละเอียดพอ อาจเห็นช่วงซ้อนกันสั้นมาก ๆ ที่ขอบหนึ่งทุกรอบ นี่คือเหตุผลที่ระบบจริงต้องออกแบบ dead time ด้วยฮาร์ดแวร์ ไม่ใช่พึ่งลำดับคำสั่ง
  3. นับรอบ ต้องได้ 50 พัลส์บนช่อง 1
  1. PWM มีคาบเวลา 2 ms ความกว้างพัลส์ 0.5 ms หาความถี่ duty และแรงดันเฉลี่ยบนขา 3.3 V
  2. PWM 20 kHz duty 30% หาคาบเวลาและความกว้างพัลส์
  3. ตัวจับเวลาใช้นาฬิกา 10 MHz ต้องการ PWM 10 kHz ต้องนับกี่ครั้งต่อหนึ่งคาบเวลา ค่าเปรียบเทียบสำหรับ duty 33% คือเท่าไร และ duty ละเอียดได้เท่าไร
  4. LED ต่อแบบ active-low (ขาเป็น 0 หลอดติด) โปรแกรมสั่ง duty ของขา 20% หลอดติดกี่เปอร์เซ็นต์ของเวลา
  5. PWM จากซอฟต์แวร์ตั้งคาบเวลา 40.0 ms วัดได้ 40.4 ms คลาดกี่เปอร์เซ็นต์ ความถี่จริงเป็นเท่าไร
  6. ตัวจับเวลามี N = 100 โปรแกรมสั่ง 12.34% ฮาร์ดแวร์น่าจะให้ duty จริงเท่าไร
  7. ขา 3.3 V ขับ PWM duty 40% มัลติมิเตอร์โหมดแรงดันไฟตรงควรอ่านได้ราวเท่าไร ถ้าความถี่สูงพอ
  1. f = 500 Hz, D = 25%, V_avg = 0.825 V
  2. T = 1 / 20 kHz = 50 µs ความกว้างพัลส์ = 0.30 × 50 µs = 15 µs
  3. N = 10 MHz / 10 kHz = 1000 ค่าเปรียบเทียบ = 330 ความละเอียด 1 / 1000 = 0.1%
  4. หลอดติดเมื่อขาเป็น 0 คือ 100% − 20% = 80% ของเวลา
  5. (40.4 − 40.0) / 40.0 = 1% ความถี่ = 1 / 40.4 ms = 24.75 Hz
  6. 12 ขั้นจาก 100 คือ 12% (ถ้าโค้ดปัดเศษทิ้ง) คลาดจากที่สั่ง 0.34 จุดเปอร์เซ็นต์
  7. 0.40 × 3.3 V = 1.32 V

ตอบคำถามใน quiz.yaml ให้ถูกอย่างน้อย 4 ใน 5 ข้อ

ส่วน A: PWM Out บน P13.3 และ P13.4 ทำตามตัวอย่างสมบูรณ์ด้วยข้อมูลจริงของคุณ ใช้ออสซิลโลสโคป (หรือ logic analyzer ที่ 100 kHz ถ้าไม่มีสโคป)

ส่วน B: PWM3 Out บน P15.2 และ P15.3 กดปุ่ม PWM3 Out โปรแกรมขับคู่สัญญาณกลับเฟสแบบเดียวกันบนขาที่ใช้ร่วมกับ ADC วัดแบบเดียวกัน แล้วเทียบกับส่วน A

ค่าที่สั่ง P13.3 P13.4 P15.2 P15.3
คาบเวลาเฉลี่ย 40 ms
ความถี่ 25 Hz
t_high 20 ms
duty 50%
jitter (T สูงสุด − ต่ำสุด) 0
มีช่วงที่เป็น 1 พร้อมกับคู่ของมันไหม ไม่มี

ส่วน C: มัลติมิเตอร์กับ PWM วัด P13.3 ด้วยโหมดแรงดันไฟตรงระหว่างที่ PWM Out วิ่ง จดตัวเลขที่เห็น แล้วอธิบายว่าทำไมมันแกว่งรอบราว 1.65 V แทนที่จะนิ่ง

ส่วนเสริม: PWM ของ LED (ถ้ามีเฟิร์มแวร์ MicroPython และมีจุดวัดที่เข้าถึงได้)

  1. เปิดแผนผังวงจรของบอร์ด หาว่าขาของ LED สี RGB หรือตัวต้านทานที่ต่อกับมันมีจุดที่วัดได้อย่างปลอดภัยไหม ถ้าไม่มี ให้หยุดตรงนี้ ห้ามจิ้มขาชิป
  2. ถ้ามี สั่ง led.brightness(10), led.brightness(50) และ led.brightness(90) ทีละค่า วัดความถี่และ duty ที่จุดนั้น
  3. อ่าน led.duty() ทุกครั้งแล้วเทียบกับที่วัดได้ อย่าลืมพิจารณาขั้ว (LED ติดตอนขาเป็น 1 หรือ 0) ก่อนสรุป

โมดูลถัดไปเริ่มที่ ต่อวงจรบนเบรดบอร์ด เราจะต่อวงจรที่ใหญ่ขึ้นให้ถูกตั้งแต่ครั้งแรก และตรวจด้วยเครื่องมือทั้งหมดที่ใช้เป็นแล้วก่อนเสียบไฟ

ตัวเลขใดในโปรแกรมของคุณเองที่รายงาน “สิ่งที่สั่ง” แต่คุณเคยอ่านมันเป็น “สิ่งที่เกิดขึ้นจริง” และคุณจะพิสูจน์มันด้วยเครื่องมือตัวไหน

คำถามทบทวน

ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย

  1. PWM มีคาบเวลา 2 ms และความกว้างพัลส์ 0.5 ms ความถี่และ duty cycle เป็นเท่าไร (เป้าหมายข้อ 1)

    1. 500 Hz และ 25%
    2. 2 kHz และ 25%
    3. 500 Hz และ 75%
    4. 250 Hz และ 50%
    ดูเฉลย

    คำตอบ: A. 500 Hz และ 25%

    f = 1 / 2 ms = 500 Hz และ D = 0.5 / 2 = 25%

  2. ขา 3.3 V ขับ PWM duty 40% ความถี่สูง ต่อวงจรกรองที่เฉลี่ยสัญญาณ จะได้แรงดันเฉลี่ยเท่าไร (เป้าหมายข้อ 1)

    1. 1.32 V
    2. 1.98 V
    3. 3.3 V
    4. 0.40 V
    ดูเฉลย

    คำตอบ: A. 1.32 V

    V_avg = D × V_high = 0.40 × 3.3 V = 1.32 V ส่วน 1.98 V คือกรณี duty 60%

  3. วิธีใดทำให้วัด duty cycle ของ PWM ได้แม่นที่สุด (เป้าหมายข้อ 1)

    1. วัดคาบเวลาเดียวที่ระดับ 10% ของแรงดัน
    2. วัดความกว้างพัลส์ที่ระดับ 50% ของแรงดัน และเฉลี่ยหลายคาบเวลา
    3. อ่านค่าจากฟังก์ชัน duty() ของโปรแกรม
    4. ใช้มัลติมิเตอร์โหมดความต่อเนื่อง
    ดูเฉลย

    คำตอบ: B. วัดความกว้างพัลส์ที่ระดับ 50% ของแรงดัน และเฉลี่ยหลายคาบเวลา

    ระดับ 50% ลดผลของขอบที่ช้า และการเฉลี่ยหลายคาบเวลาลดผลของความละเอียดเวลาและ jitter ค่าจากโปรแกรมคือค่าที่สั่ง ไม่ใช่ค่าที่วัด

  4. โปรแกรมสั่ง duty 30% แต่วัดที่ขาได้ 70% ทุกค่าที่ลองสั่ง ผลรวมของค่าที่สั่งกับค่าที่วัดได้เป็น 100% เสมอ สาเหตุที่น่าจะเป็นที่สุดคืออะไร (เป้าหมายข้อ 2)

    1. ความละเอียดของตัวนับไม่พอ
    2. ขั้วของสัญญาณกลับ เช่น ขาออกตั้งเป็น active-low หรือวัดขาที่เป็นคู่กลับเฟส
    3. ความถี่ของ PWM สูงเกินไป
    4. ออสซิลโลสโคปเสีย
    ดูเฉลย

    คำตอบ: B. ขั้วของสัญญาณกลับ เช่น ขาออกตั้งเป็น active-low หรือวัดขาที่เป็นคู่กลับเฟส

    D ที่วัดได้ = 100% − D ที่สั่ง คือรูปแบบของขั้วกลับ ความละเอียดของตัวนับทำให้คลาดเป็นขั้นเล็ก ๆ ไม่ได้กลับค่าทั้งหมด

  5. หลังสั่ง on() แล้ว toggle() หลอด LED ดับ แต่ duty() ยังตอบ 100 อธิบายได้อย่างไร (เป้าหมายข้อ 2)

    1. หลอดเสีย
    2. duty() รายงานค่าที่สั่งครั้งล่าสุด ไม่ได้วัดสถานะจริงของขา
    3. toggle() ไม่ทำงาน
    4. PWM ของฮาร์ดแวร์ยังทำงานอยู่ที่ 100%
    ดูเฉลย

    คำตอบ: B. duty() รายงานค่าที่สั่งครั้งล่าสุด ไม่ได้วัดสถานะจริงของขา

    ตัวอย่าง 03_led_brightness.py ของหลักสูตร AIoT in Action สาธิตเรื่องนี้ไว้ ตัวเลขในโปรแกรมคือสิ่งที่สั่ง การจะรู้ว่าขาทำอะไรจริงต้องวัดด้วยเครื่องมือ

อ้างอิงบทเรียนนี้

ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน

"วัด PWM" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0

ข้อความอ้างอิงภาษาอังกฤษ: "Measuring PWM" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0

ลิงก์บทเรียน: https://tesaiot.github.io/tesa-qualification-program/courses/electronics-and-instruments/m05-oscilloscope/l02-measuring-pwm/

วิธีอ้างอิง TESA ฉบับเต็ม

TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0

เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA