[TH] MicroPython : PWM

บทความนี้กล่าวถึงการใช้ PWM หรือ Pulse Width Modulation ที่เป็นโมดูลภายใต้คลาส machine ของ MicroPython เพื่อใช้งานกับ esp8266 และ esp32 พร้อมตัวอย่างการใช้ PWM ในการหรี่ความสว่างของหลอดแอลอีดี และการสร้างความถี่เสียงด้วย PWM ซึ่งสามารถนำไปประยุกต์ใช้ได้ต่อไป

PWM

การใช้งาน PWM ของ MicroPython ต้องเรียกใช้คลาส PWM ที่อยู่ในคลาส machine ดังภาพที่ 1 ซึ่งจะพบว่ามีคำสั่งให้ใช้งาน 4 คำสั่ง คือ init() deinit() freq() และ duty()

ภาพที่ 1 คลาสของ PWM

หลักการของ PWM คือกำหนดอัตราของการเป็นค่าสถานะ 1 และ 0 ของคลื่น 1 ลูก ดังภาพที่ 2 ถ้าต้องการให้ลูกคลื่นมีแต่ค่า 1 ต้องกำหนดให้สัดส่วนของค่าดิวตี้เป้น 100% หรือ 1023 และถ้าต้องการค่าดิวตี้เป็น 0% หรือค่า 0 ซึ่งทำให้ลูกคลื่นมีค่าสถานะดิจิทัลเป็น 0

ภาพที่ 2 ค่าดิวตี้

ด้วยหลักการนี้ทำให้ผู้ใช้งานไมโครคอนโทรลเลอร์ที่ไม่มี DAC (Digital to Analog Convertor) หรือตัวแปลงสัญญาณดิจิทัลเป็นอแนาล็อกสามารถกำหนดระดับแรงดันของขาที่ใช้เป็น PWM ได้ด้วยการกำหนดค่าดิวตี้ เช่น ปกติสามารถส่งแรงดันได้ 3.3v ถ้าต้องการให้เหลือครึ่งหนึ่ง หรือ 1.65V ให้กำหนดค่าดิวตี้เป็น 512 หรือ 50% และถ้าต้องการให้แรงดันเหลือ 1.0V จะต้องกำหนดค่าดิวตี้เป็น 310 ดังนั้น สมการหาค่าดิวตี้จึงเป็นดังนี้

ค่าดิวตี้ = 1023*(ค่าแรงดัน/3.3)

เมื่อนำมาเขียนเป็นฟังก์ชันภาษาไพธอนสามารถเขียนได้ดังนี้ ซึ่งตัวอย่างผลลัพธ์เป็นดังภาพที่ 3

def findDutyValue( volt ):
    return int(volt/3.3*1023.0)
print(findDutyValue(0.0))
print(findDutyValue(1.0))
print(findDutyValue(1.65))
print(findDutyValue(2.0))
print(findDutyValue(3.3))
ภาพที่ 3 ตัวอย่างผลลัพธ์ของการคำนวณหาค่าดิวตี้จากแรงดันที่กำหนด

ขาของ esp8266

ขาที่ทำหน้าที่ PWM ของไมโครคอนโทรลเลอร์ esp8266 ได้แก่

  • 0
  • 2
  • 4
  • 5
  • 12
  • 13
  • 14
  • 15

ข้อจำกัดของการใช้ PWM ของ esp8266 คือรองรับความถี่ของการทำงานในย่าน 1Hz ถึง 1kHz และค่าดิวตี้จะต้องอยู่ในช่วง 10 บิต หรือ 0 ถึง 1023

ขาของ esp32

ขาที่ทำหน้าที่ PWM ของไมโครคอนโทรลเลอร์ตระกูล esp32 สามารถใช้ได้กับทุกขาที่เปิดให้ใช้งาน โดยการกำหนดค่าดิวตี้อยู่ในค่า 0 ถึง 1023 และความถี่ที่สามารถกำหนดได้อยู่ในย่าน 1Hz ถึง 40MHz ซึ่งสูงกว่า esp8266 วึ่งค่าความถี่ที่ถูกกำหนดเอาไว้เป็นค่าเบื้องต้นคือ 5kHz และค่าดิวตี้เป็น 50% หรือ 512

นอกจากนี้ตัว esp32 รองรับการสร้าง PWM ได้ 16 ช่องสัญญาณ (channels) โดยมี 8 ช่องสัญญาณที่มีค่าความถี่แตกต่างกันได้ แต่อีก 8 ช่องสัญญาณจะต้องมีค่าความถี่เดียวกัน

การใช้งาน

การสร้างวัตถุ PWM มีรูปแบบการสร้างดังนี้

วัตถุ = machine.PWM( machine.Pin( หมายเลขขา ) )

การกำหนดค่าความถี่ของพัลซ์ มีรูปแบบดังนี้

วัตถุ.freq( ค่าความถี่ )

การกำหนดค่าดิวตี้ (Duty) หรือค่าช่วงเวลาที่เป็นระดับแรงดันดิจิทัล 1 ต้องมีค่าอยู่ในช่วง 0 ถึง 1023 ดังรูปแบบการใช้ต่อไปนี้

วัตถุ.duty( ค่าดิวตี้ )

และเมื่อใช้งานเสร็จผู้เขียนโปรแกรมควรยกเลิกการทำงานโดยใช้คำสั่ง deinit() ดังนี้

วัตถุ.deinit()

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

วัตถุ = machine.PWM( machine.Pin( หมายเลขขา ), freq=ค่าความถี่, duty=ค่าดิวตี้ )

ตัวอย่างโปรแกรม

ตัวอย่างโปรแกรมที่ยกมามีด้วยกัน 3 ตัวอย่างคือ หรี่หลอดแอลอีดี และสร้างความถี่เสียงดังต่อไปนี้

หรี่หลอดแอลอีดี

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

#fade LED
from machine import Pin,PWM
import time

led = PWM(Pin(2))
led.freq(50)
led.duty(1023)
for i in range(0,1023):
    #print(i)
    led.duty(1023-i)
    time.sleep_ms(1)
for i in range(0,1024):
    #print(i)
    led.duty(i)
    time.sleep_ms(1)
led.deinit()
led = Pin(2)
led.value(0)

สร้างความถี่เสียง

ตัวอย่างโปรแกรมสำหรับการสร้างความถี่เสียงโดยใช้ลำโพงต่อ – ของลำโพงเข้ากับขา GPIO13 และต่อ Vcc เข้ากับ + ของลำโพง

import time
from machine import Pin,PWM
spk = PWM(Pin(13))
spk.duty(0)
for i in range(100,1000,200):
    spk.freq(i)
    time.sleep_ms(20)
spk.duty(1023)
spk.deinit()
spk = Pin(13)
spk.value(1)

เมื่อนำส่วนของการทำงานมาเขียนเป็นฟังก์ชัน​beep() สามารถเขียนได้ดังนี้

def beep(f,d=512):
    spk = PWM(Pin(13),freq=f, duty=d)
    spk.init()
    time.sleep_ms(50)
    spk.deinit()

สรุป

จากบทความนี้จะพบว่าการใช้งาน PWM กับไมโครคอนโทรลเลอร์ esp8266 จะต้องเลือกขาใช้งานให้ถูกต้อง และย่านความถี่ต้องอยู่ในช่วง 1Hz ถึง 1kHz ขณะที่ esp32 รองรับการใช้งานทุกขาที่สูงสุด 16 ช่องสัญญาณ และมีความถี่อยู่ในย่าน 1Hz ถึง 40MHz ซึ่งการนำ PWM ไปประยุกต์ใช้สามารถกระทำได้หลากหลายอย่าง เช่น การนำไปควบคุมความเร็วของมอเตอร์ไฟฟ้า การควบคุมการหมุนของเซอร์โวมอเตอร์ การสร้างความถี่เสียง การควบคุมความสว่างของหลอดแอลอีดี หรือการสั่งระดับ ความสว่างของ TFT ด้วยการส่งพัลซ์์ไปที่ขา BL ของโมดูล TFT เป็นต้น สุดท้ายขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดต้องการพูดคุยสามารถคอมเมนท์ได้เลยครับ

แหล่งอ้างอิง

  1. MicroPython : esp8266 : Tutorial : Pulse Width Modulation
  2. MicroPython : esp32 : Tutorial : Pulse Width Modulation

(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-09-28, 2021-12-08