بله، میتوانید منطق تولید موج SPWM را برای اجرا روی Raspberry Pi Pico تطبیق دهید و بهجای رسم نمودار گرافیکی، پالسهای PWM واقعی را به یک پین GPIO ارسال کنید.
اما یک نکته مهم: کتابخانههای NumPy و Matplotlib در محیط محدود MicroPython که روی Pico اجرا میشود، در دسترس نیستند. بنابراین، باید کد را با استفاده از توابع ریاضی داخلی پایتون (مثل math) و امکانات PWM داخلی Pico بازنویسی کنیم.
پیادهسازی SPWM در Raspberry Pi Pico (MicroPython)
برای این کار به یک پین خروجی و ماژولهای machine و math نیاز داریم.
کد MicroPython
این کد را باید با استفاده از IDEهایی مانند Thonny به Raspberry Pi Pico خود منتقل کنید.
from machine import Pin, PWM
import math
import time
# --- تنظیمات پین و PWM ---
PWM_PIN = 0 # پین GPIO که میخواهید خروجی SPWM را ببینید (مثلاً GP0)
pwm_output = PWM(Pin(PWM_PIN))
# --- پارامترهای موج ---
# فرکانس موج حامل (Carrier Frequency - f_carrier)
# این فرکانس سوییچینگ PWM است و باید بالا باشد.
# هر چه بالاتر باشد، کیفیت بهتر و پالسها بهتری دارید، اما محدودیت سختافزاری دارد.
f_carrier = 20000 # 20 کیلوهرتز (معمولا بین 10 تا 50 کیلوهرتز خوب است)
pwm_output.freq(f_carrier)
# فرکانس موج مرجع سینوسی (Reference Sine Wave Frequency - f_ref)
f_ref = 50 # 50 هرتز (فرکانس خروجی نهایی)
# شاخص مدولاسیون (Amplitude Modulation Index - Ma)
Ma = 0.8 # بین 0 (خروجی DC صفر) و 1 (حداکثر دامنه)
# --- متغیرهای زمانبندی و حلقهها ---
period_ref = 1 / f_ref # زمان یک سیکل کامل موج سینوسی
num_samples_per_cycle = 50 # تعداد نقاطی که یک سیکل سینوسی را تشکیل میدهند (دقت کنترل)
# زمان گام برای هر نمونه (چقدر باید بین بهروزرسانیهای PWM منتظر بمانیم)
# باید بسیار کوچک باشد تا SPWM واقعی باشد.
dt = period_ref / num_samples_per_cycle
# --- اجرای حلقه اصلی SPWM ---
print("شروع به تولید SPWM در پین GPIO", PWM_PIN, "...")
try:
current_time = 0.0
while True:
# 1. محاسبه زاویه سینوسی: 0 تا 2*pi
angle = 2 * math.pi * f_ref * current_time
# 2. محاسبه مقدار مرجع سینوسی (دامنه بین 0 تا Ma)
# موج سینوسی بین -1 تا 1 است. برای استفاده در Duty Cycle (که بین 0 تا 1 است)، باید آن را تغییر دهیم.
# sine_ref = (Ma * sin(angle) + Ma) / 2
# این مقدار بین 0 تا Ma خواهد بود که متناسب با Duty Cycle است.
sine_ref_scaled = (Ma * math.sin(angle) + Ma) / 2
# 3. تبدیل به مقدار Duty Cycle: 0 تا 65535 (16 بیتی)
# 65535 * sine_ref_scaled
duty_cycle = int(65535 * sine_ref_scaled)
# 4. اعمال Duty Cycle به پین PWM
# این بهطور خودکار PWM را با فرکانس f_carrier و Duty Cycle محاسبهشده تولید میکند.
pwm_output.duty_u16(duty_cycle)
# 5. بهروزرسانی زمان و تاخیر
current_time += dt
# اگر زمان از یک سیکل کامل گذشت، فاز را ریست میکنیم تا از سرگردانی اعداد ممیز شناور جلوگیری شود.
if current_time >= period_ref:
current_time = 0.0
time.sleep(dt) # تاخیر برای نگهداشتن Duty Cycle در این گام زمانی
except KeyboardInterrupt:
print("تولید SPWM متوقف شد.")
pwm_output.duty_u16(0) # خاموش کردن پالسها
pwm_output.deinit() # غیر فعال کردن PWM

توضیح تفاوتها و منطق SPWM در میکروکنترلر
تولید SPWM در یک میکروکنترلر مانند Pico با رویکرد نرمافزاری کامپیوتر متفاوت است:
- حذف موج حامل (Carrier Wave):
- در کامپیوتر، SPWM با مقایسه موج سینوسی و مثلثی تولید میشد.
- در میکروکنترلر، شما نیاز به تولید موج مثلثی ندارید. خود ماژول PWM سختافزاری در Pico، موج حامل را با فرکانس f_carrier تولید میکند.
- کاری که ما میکنیم این است که بهطور نرمافزاری، Duty Cycle پالس PWM را بهطور مداوم با توجه به دامنه لحظهای موج سینوسی تغییر میدهیم.
- تابع سینوسی در MicroPython:
- از
import mathوmath.sin(angle)استفاده میکنیم.
- از
- تبدیل دامنه به Duty Cycle:
- Duty Cycle (چرخه وظیفه) در Pico به صورت یک عدد ۱۶ بیتی از 0 تا 65535 تنظیم میشود.
- موج سینوسی عادی بین −1 تا +1 نوسان میکند.
- برای اعمال به Duty Cycle (که باید بین ۰ و ۱۰۰٪ باشد)، ابتدا آن را به بازه ۰ تا 2M_a و سپس به ۰ تا M_a میبریم و در نهایت به بازه ۰ تا ۶۵۵۳۵ مقیاسدهی میکنیم:Duty Cycle Value=int(65535×2Ma⋅sin(2πfreft)+Ma)
- M_a⋅sin(…): دامنه بین −M_a تا +M_a.
- +M_a: جابهجایی دامنه به بازه 0 تا 2M_a.
- /2: مقیاسدهی به بازه 0 تا M_a (که متناسب با Duty Cycle بین ۰ تا ۱۰۰٪ است).
- زمانبندی دقیق:
- متغیر
dt(گام زمانی) مشخص میکند که هر چند وقت یکبار باید Duty Cycle را با مقدار جدید سینوسی بهروز کنیم. مقدارnum_samples_per_cycle(تعداد نمونهها در هر سیکل 50Hz) دقت و همواری موج نهایی شما را تعیین میکند. time.sleep(dt)باعث میشود که Duty Cycle محاسبهشده، به مدتdt(چند میکرو یا میلیثانیه) ثابت بماند تا یکنواختی در SPWM حفظ شود.
- متغیر
با اتصال این پین به مدار یک اینورتر (H-Bridge) میتوانید برق DC را به برق AC سینوسی مدولهشده تبدیل کنید.
سایت آموزشی الکترونیک و کامپیوتر اوپن مقاله های آموزشی الکترونیک و کامپیوتر و فن آوری