PWM (مدلاسیون پهنای پالس) یک تکنیک مدلاسیون است که در آن با ثابت نگه داشتن فرکانس، پهنای پالس تغییر میکند.
از طریق تکنیک PWM، میتوان توان تحویل داده شده به بار را با استفاده از خاموش یا روشن کردن سیگنال کنترل کرد.
سیگنالهای PWM را میتوان برای کاربردهایی همچون کنترل سرعت موتورهای DC، تغییر شدت نور LED، کنترل سروو موتور و … به کار برد.
گیف زیر کاربرد PWM در کنترل شدت نور یک LED را به نمایش میگذارد.
PWM رزبریپای
رزبریپای دارای دو کانال PWM، یعنی PWM0 و PWM1 میباشد.
پینهای PWM برای دو کانال روی هدر پین P1 چهل پینه به صورت شرح زیر است.
پین GPIO |
PWM0/PWM1 |
GPIO12 |
PWM0 |
GPIO18 |
PWM0 |
GPIO13 |
PWM1 |
GPIO19 |
PWM1 |
پینهای PWM روی پین هدر ۴۰ پینه رزبریپای در شکل زیر نشان داده شده است.
پینهای PWM در رزبریپای با زیر سیستم صوتی مشترک هستند. بنابراین در هر لحظه یا خروجی صوتی و یا خروجی PWM را میتوانیم داشته باشیم.
دیاگرام اتصالات
در اینجا، میخواهیم با استفاده از رزبریپای سیگنال PWM ایجاد کنیم. این خروجی PWM به یک LED وصل است که تغییر در شدت نور را نشان میدهد.
اجازه دهید با استفاده از زبان پایتون و زبان C موج PWM تولید کنیم.
تولید PWM با استفاده از پایتون
PWM تولید شده به وسیلهی پایتون روی رزبریپای یک PWM نرمافزاری میباشد. این PWM داراری رزولوشن زمانی یک میکروثانیه میباشد که از PWM نرمافزاری تولید شده در زبان C (کتابخانه WiringPi) بهتر است.
برنامه پایتون
''' Control the Brightness of LED using PWM on Raspberry Pi http://www.electronicwings.com ''' import RPi.GPIO as GPIO from time import sleep ledpin = 12 # PWM pin connected to LED GPIO.setwarnings(False) #disable warnings GPIO.setmode(GPIO.BOARD) #set pin numbering system GPIO.setup(ledpin,GPIO.OUT) pi_pwm = GPIO.PWM(ledpin,1000) #create PWM instance with frequency pi_pwm.start(0) #start PWM of required Duty Cycle while True: for duty in range(0,101,1): pi_pwm.ChangeDutyCycle(duty) #provide duty cycle in the range 0-100 sleep(0.01) sleep(0.5) for duty in range(100,-1,-1): pi_pwm.ChangeDutyCycle(duty) sleep(0.01) sleep(0.5)
توابع PWM در پایتون
ایجاد شی PWM
یک شی از کلاس PWM، که بخشی از کتابخانهی RPi.GPIO است تولید کنید. در اینجا، ما شیای به نام pi_pwm ایجاد کردهایم. میتوان هر نام دلخواه دیگری را به شی اختصاص داد.
مثلا pi_pwm = GPIO.PWM (Pin no., frequency) که در آن:
.Pin no: شماره پین PWM است که موج PWM روی آن تولید میشود.
Frequency: فرکانس PWM میباشد.
اکنون، میتوان توابع PWM از کتابخانهی RPi.GPIO را با استفاده از شی PWM فراخوانی کرد.
نکته: سیگنال PWMای که در اینجا ایجاد میشود PWM نرمافزاری است و میتوان آن را روی هر پین GPIO تولید کرد.
Start(Duty Cycle): برای شروع تولید PWM با یک Duty Cycle مشخص به کار میرود.
ChangeDutyCycle(Duty Cycle): این تابع برای تغییر Duty Cycle سیگنال استفاده میشود. باید مقدار Duty Cycle را در محدوده ۰ تا ۱۰۰ وارد کنیم.
ChangeFrequency(frequency): این تابع برای تغییر فرکانس (هرتز) PWM استفاده میشود. از این تابع در برنامهی بالا استفاده نشده است. اما میتوان از آن برای تغییر فرکانس بهره برد.
()Stop: این تابع تولید سیگنال PWM را متوقف میکند.
تولید سیگنال PWM با استفاده از زبان C
PWM سختافزاری
PWM روی رزبریپای را میتوان با برنامهی زبان C نیز تولید کرد. در اینجا، از کتابخانهی WiringPi برای تولید سیگنال PWM روی رزبریپای بهره میگیریم. این کتابخانه امکان دسترسی به PWM سختافزاری روی رزبریپای را فراهم میکند.
برنامه C
/* Change the Intensity of LED using PWM on Raspberry Pi http://www.electronicwings.com */ #include <wiringPi.h> #include <stdio.h> #include <stdlib.h> const int PWM_pin = 1; /* GPIO 1 as per WiringPi, GPIO18 as per BCM */ int main (void) { int intensity ; if (wiringPiSetup () == -1) exit (1) ; pinMode (PWM_pin, PWM_OUTPUT) ; /* set PWM pin as output */ while (1) { for (intensity = 0 ; intensity < 1024 ; ++intensity) { pwmWrite (PWM_pin, intensity) ; /* provide PWM value for duty cycle */ delay (1) ; } delay(1); for (intensity = 1023 ; intensity >= 0 ; --intensity) { pwmWrite (PWM_pin, intensity) ; delay (1) ; } delay(1); } }
توابع PWM در زبان WiringPi) C)
تابع pwmWrite (PWM pin, PWM value)
در این تابع:
PWM pin: شماره پین PWM روی چیپ، که قرار است سیگنال در آن تولید شود.
PWM Value: مقداری که برای تولید PWM باید در رجیستر PWM نوشته شود. این مقدار در رنج «۰ – ۱۰۲۳» میباشد.
میتوان سیگنال PWM روی رزبریپای را با استفاده از تابع ()analogWrite، شبیه تابع آردوینو تولید کرد. اما برای استفاده از این تابع باید چند ماژول دیگر نیز ضمیمه کنیم.
تابع pwmSetClock (divisor)
این تابع برای تعیین مقسم کلاک PWM استفاده میشود.
تابع pwmSetMode (mode)
Mode: تولید PWM در دو حالت انجام میگیرد، حالت Balanced و حالت Mark:Space
با استفاده از پارامتر فوق میتوان یکی از این دو حالت را به صورت PWM_MODE_BAL و PWM_MODE_MS انتخاب کرد. حالت پیشفرض در رزبریپای حالت Balancded میباشد.
تابع pwmSetRange (range)
این تابع برای تعیین محدودهی تولید PWM در رجیستر تولید PWM به کار میرود. رنج پیشفرض ۱۰۲۴ میباشد.
PWM نرمافزاری با استفاده از زبان c
با استفاده از کتابخانه PWM نرمافزاری WiringPi، میتوان سیگنال PWM را روی هر پین GPIO رزبریپای تولید کرد.
در اینجا، ما شدت نور LED را با استفاده از PWM نرمافزاری روی رزبریپای تغییر میدهیم.
برنامه
/* Control Intensity of LED using PWM on Raspberry pi http://www.electronicwings.com
Tr2Persian: Melec.ir */ #include <wiringPi.h> /* include wiringPi library */ #include <stdio.h> #include <softPwm.h> /* include header file for software PWM */ int main(){ int PWM_pin = 1; /* GPIO1 as per WiringPi,GPIO18 as per BCM */ int intensity; wiringPiSetup(); /* initialize wiringPi setup */ pinMode(PWM_pin,OUTPUT); /* set GPIO as output */ softPwmCreate(PWM_pin,1,100); /* set PWM channel along with range*/ while (1) { for (intensity = 0; intensity < 101; intensity++) { softPwmWrite (PWM_pin, intensity); /* change the value of PWM */ delay (10) ; } delay(1); for (intensity = 100; intensity >= 0; intensity--) { softPwmWrite (PWM_pin, intensity); delay (10); } delay(1); } }
توابع به کار رفته
برای تولید PWM نرم افزاری با کتابخانهی WiringPi، باید هدر فایل softPwm.h را ضمیمه کنیم.
تابع softPwmCreate (Pin no., initial value, PWM Range)
این تابع برای تولید PWM نرمافزاری کنترل شده به کار میرود. میتوان PWM نرمافزاری را روی هر پین GPIO ایجاد کرد.
Pin no: شماره پین GPIO که میخواهیم روی آن PWM تولید کنیم.
Initial value: یک مقدار آغازین که در محدودهی PWM است مشخص میکند.
PWM range: میتوان یک رنج، یعنی رنج فرکانسی برای PWM تعیین کرد. این مقادیر برای تولید PWM با Duty Cycle متغیر مفید است.
نکته: مینیمم مقدار پهنای پالس برابر ۱۰۰ میکروثانیه است تا مصرف CPU کمینه باقی بماند. برای کمترین پهنای پالس، محدوده PWM پیشنهادی ۱۰۰ میباشد که فرکانس ۱۰۰ هرتز را نتیجه میدهد. اگر رنج PWM را کاهش دهیم، آنگاه فرکانس بالاتر با رزولوشن کمتر خواهیم داشت. یا میتوان رنج PWM را افزایش داد، و فرکانس پایینتر با رزولوشن بهتر به دست آورد.
تابع softPwmWrite(Pin no., value)
این تابع برای تغییر مقدار PWM روی پین PWM استفاده میشود.
Pin ni: پین GPIO که میخواهیم PWM روی آن تولید شود.
Value: مقدار PWM
PWM سختافزاری یا PWM نرمافزاری
هروقت نیاز داشته باشیم که تعداد بیشتری PWM تولید کنیم و کاربرد مد نظر ما تحمل پایینی نسبت به خطای رزولوشن زمانی داشته باشد، آنگاه از PWM نرمافزاری استفاده میکنیم.
اما اگر کاربرد مد نظر ما PWM با رزولوشن زمانی بالا نیاز داشته باشد، آنگاه باید از PWM سختافزاری استفاده کنیم.
- منبع: ترجمه از سایت electronicwings.com
امیدواریم این آموزش براتون مفید واقع شده باشه.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.