# برنامه نویسی میکروکنترلر (MicroController) ها و MicroProcessor ها > برنامه نویسی سیستم های Embeded > گفتگو: PID?????

## mhmmdshirazi

این تاپیک رو برای این راه اندازی کردم که هم خودم یاد بگیرم هم تا اونجایی که ممکنه به کسایی که رباتیک دوست دارند کمک کنم!!!!!

راستش من یه مدته زیادی نیومدم و ببخشید بخواطر این من رو!!!!!


خب موضوع این پست پی ای دی کنترلر ها انواعشون نحوه ی عمل کردشون و کلا اینکه به چه دردی می خورن!!!!


شما یه وقتی می خواین یه موتور دی سی نه استپ موتور رو دقیقا یه دور بچرخونید یا 15 درجه فرض کنید موتورتون فید بک هم داشته باشه که یه پالس مربعیه!!
فرض کنید شما مدت زمان 15 درجه چرخیدن دقیق موتور رو تو شرایط فرضی می دونید!!!!! مثلا 1 ثانیه
خب حالا تو واقعیت که ان هزار تا مشکل هست مثل اصطکاک یا باری که رو موتوره حالا بحث اصلی میشه اینکه با اون فید بکی که می گیریم باید موتور رو با چند برابر نه لظوما بیشتر سرعت شرایط استاندارد بچرخونیم تا تو همون زمان و تحت هر شرایطی موتور همون کار رو بکنه!!!!!!!!


خب اینجاست که متوجه می شیم هر کی قوله هر چی که هست از PID استفاده می کنه مسه تقریبا همه تیمای اسمال سایز و تو صنعت تمام روبات های صنعتی حتی دقیق ترین چیز ها مثل ربات های عمل جراحی و و و..........


من خودم PI رو تا حدودی خیلی ساده تونستم راه اندازی کنم حالا دوست دارم اگه کسی می تونه کمک کنه و اگه کسی هم می خواد من تا اونجایی که می تونم و بلدم به اون کمک کنم!!!!

----------


## farzadsw

اگر درس کنترل خطی رو گذرانده باشید ، حتما با PID Controller آشنا شدید . 

PID یک کنترل کننده هست که از سه بخش تشکیل شده :


یک بخش ضریب عددی (P) ، انتگرالگیر(I) و یک مشتق گیر (D) .
هر کدام از این سه بخش دارای یک ضریب هستند(Kp,Ki,Kd ) . با تغییر این ضرایب پاسخ سیستم تغییر میکنه و با tune کردن مناسب این ضرایب میشه پاسخ مطلوب رو بدست آورد.

برای روشن شدن مطلب یه مثال میزنم . 
فرض کنید یک وسیله مشابه آسانسور (نه دقیقا خود آسانسور) در اختیار دارید که جسم رو جابه جا میکنه . ورودی که به این وسیله(سیستم) میدید ، شماره طبقه هست . به این ورودی رفنس هم میگن(تو شکل بالا set point). چرا میگن رفنس ؟ چون وقتی که قراره اتاق آسانسور از طبقه 0 به طبقه 1 بره ، دکمه طبقه 1 فشار داده میشه و رفرنس شما به طبقه 1 تغییر میکنه . ولی اتاق آسانسور در همون لحظه هنوز جا به جا نشده ولی بعد از یه مدت زمانی خودش به رفنس یا همون طبقه 1 ، میرسونه . به عبارت دیگه رفرنس چیزی هست که قراره سیستم به اون برسه (بعد یه زمانی) .
حالا تو این مثال وقتی از طبقه 0 به طبقه 1 میخوایم بریم ، رفنسمون رو از 0 به 1 تغییر دادیم  . به عبارت دیگه ورودی سیستممون رو از 0 به 1 تغییر دادیم .  در این حالت میگن ورودی پله (از 0 به 1) به سیستم (همون دستگاهمون) اعمال شده. 
حالا بحث اصلی اینه که این آسانسور چطوری و طی چه مدت زمانی به اون رفنس جدید میرسه؟  آروم آروم میره تا بعد از مدت نسبتا طولانی به طبقه1 میرسه با خیلی سریع میره بالا که طبقه رو رد میکنه دوباره یکم میاد پایین  ، بعد یکم میره بالا تا برسه به طبقه ؟ این رو در نظر داشته باشید که  جسم ما دارای جرم هست ، بنابراین دارای اینرسی هست و وقتی داره با سرعت مثلا 10 متر بر ثانیه میره بالا نمیتونه، به محظ رسیدن به طبقه ، متوقف بشه . و اگه فرمان توقف تو لحظه رسیدن به طبقه بهش داده بشه ، اون رو رد میکنه و متوقف میشه . بنابر این مجبوره باز یکم برگرده پایین و .... . 
به شکلهای زیر نگاه کنید :

تو این نمودار خط آبی رو به عنوان سرعت نوشته ولی شما همون موقعیت و مکان آسانسور در نظر بگیرید . همونطور که میبینید ، تو شکل اول خیلی طول میکشه تا به 1 برسه . تو شکل 2 کمتر طول میکشه . و تو شکل سوم سریع به 1 میرسه ولی اون رو رد میکنه و بر میگرده و بعد چندتا نوسان به 1 میرسه. این مقدار رد کردن 1 تو شکل سوم رو overshoot میگن . 
شاید به نظرتون شکل دوم از همه بهتره باشه ولی اگه ما برای پاسخ مطلوبمون یک بازه خطای قابل قبول در نظر بگیریم ، شکل سوم میتونه مناسب تر باشه . مثلا آسانسور 5 سانت بالا یا پیین طبقه باشه اهمیتی نداره برای همین وقتی آسانسور به محدوده طبقه سوم  و 5 سانت پایین یا بالاش رسید رو حالت مطلوب در نظر میگیریم.


پس تا حالا با مفاهیم ورودی پله و پاسخ سیستم به اون (پاسخ پله) و زمان رسیدن به پاسخ نهایی و overshoot آشنا شدید .
حالا برمیگیدیم به PID : با تغییر ضرایب PID (همون Kp , Ki, Kd) میشه نحوه پاسخ یک سیستم رو به ورودی پله تغییر داد . برای مثال تو شکلهای زیر میبینید که با تغییر ضرایب PID پاسخ سیستم به پله چطور تغییر میکنه :




تنظیمات این ضرایب برای هر سیستمی متفاوته و فرمول خاصی نداره ، یعنی تقریبا از طریق سعی و خطا PID رو tune میکنن .البته الگوریتمهای بسیاری با استفاده از منطق فازی ، ژنتیک و غیره وجود داره که ضرایب مناسب و بهینه رو در اختیار میگذارن .

----------


## mhmmdshirazi

> اگر درس کنترل خطی رو گذرانده باشید ، حتما با PID Controller آشنا شدید . 
> 
> PID یک کنترل کننده هست که از سه بخش تشکیل شده :
> 
> 
> یک بخش ضریب عددی (P) ، انتگرالگیر(I) و یک مشتق گیر (D) .
> هر کدام از این سه بخش دارای یک ضریب هستند(Kp,Ki,Kd ) . با تغییر این ضرایب پاسخ سیستم تغییر میکنه و با tune کردن مناسب این ضرایب میشه پاسخ مطلوب رو بدست آورد.
> 
> برای روشن شدن مطلب یه مثال میزنم . 
> ...



مرسی از راهنماییه کاملتون من هنوز دانشگاه نرفتم پس درس کنترل خطی رو پاس نکردم اگه میشه یکم در مورد نحوه مشتق و انتگرال گیری با c توضیح بدید!!!

----------


## farzadsw

عليرغم اينكه پردازنده ديجيتال هست ولي  مشتق و انتگرال تو اون با مفهومي كه تو حساب ديفرانسيل خونديد ، يكسانه . 
مثلا براي مشتق گرفتن ، اختلاف دومقدار خونده شده رو ، بر زمان فاصله بين اين قرائت ها تقسيم ميكنيد . براي انتگرال هم ، مقادير رو در زمانشون ضرب ميكنيد و اينا رو با هم جمع ميكنيد .

----------


## mhmmdshirazi

> عليرغم اينكه پردازنده ديجيتال هست ولي  مشتق و انتگرال تو اون با مفهومي كه تو حساب ديفرانسيل خونديد ، يكسانه . 
> مثلا براي مشتق گرفتن ، اختلاف دومقدار خونده شده رو ، بر زمان فاصله بين اين قرائت ها تقسيم ميكنيد . براي انتگرال هم ، مقادير رو در زمانشون ضرب ميكنيد و اينا رو با هم جمع ميكنيد .



مرسی من از همین راه عمل کردم تا حدودی جواب گرفتم ولی مشکل اصلیه من اینجاست که در نهایت من انتگرال رو می گیرم و به این شکل عمل می کنم (pi) ولی این برنامه اون طوری که باید عمل کنه عمل نمیکنه اشکال از کجاشه؟؟؟


///////////////////////////man ye error daram ke beyne -255 ta 255 e ke az jense khode pwm e va ye tabe vase ye motor ke intorie motor(pwm); ke pwm beyne + 255 , -255 mitune bashe + sa@ gard va manfi baraksesh!!!! va error barakse pwm motore yani + pad sa@ gard va manfi sa@ gard



int error=0,i=0,p=0;

void pi()
{
if(error>=-5&&error<=5)
{
i=0;
p=0;
}
else if(error>5)
{
i=i+(int)(dx)(error);
p=(int)(dp)(error);
}
else if(error<-5)
{
i=i-(int)(dx)(error);
p=-(int)(dp)(error);
}

if(error>5)
motor(pwm+i+p);
if(error<5)
motor(pwm-i-p);
}

----------


## aghasina

سلام . این dx,dp منظور چیه؟! مسافت طول و عرضه زمینه؟! میشه کامل توضیح بدی و بگی چجوری از نمودار زمان نسبت به زاویه استفاده میشه کرد .

----------


## Mehran.GH

این کد که نوشتی  را دقیق نمی دانم چه انتظار داری انجام دهد!  اما در ابتدای کد که اصلا error   را محاسبه نکردی که بعدش بخواهی اگر بین 5 و 5- بود یک کارایی بکند؟  (error صفر باقی می ماند)

مباحث پایه ای را دوستمون  farzadsw  توضیح داد و من چند نکته عملی اضافه می کنم 

در کنترلر آنالوگ خیلی ساده زمانی که بخواهی بدون ریاضیات یک کنترلر PID  درست کنی روش معمول این است که

در ابتدا با I=0,D=0  شروع می کنی و پارامتر P را در حدی زیاد می کنی که سیستم در حد *مرز* شروع به نوسان برسد

بعد پارامتر D را زیاد می کنی تا حدی که یک نوسان کوچولو رخ دهد

در آخر با پارامتر I  بازی می کنی تا نوسان از بین برود


تاثیر D  در یک کنترلر ساده این است که* سرعت* رسیدن به نقطه مورد نظرت را تعیین می کند (که در دنیای فیزیکی چنین المانی وجود ندارد ) و تاثیر I  هم این است که *دقت* رسیدن نقطه setpoint  مورد نظر را تعیین می کند( جبران خطاي ماندگار)   بنابراین در مواردی که سرعت رسیدن به نقطه موردنظر مهم نباشد PI  کنترلر کافی است.(یعنی اغلب موارد ساده)
مشکل D هم این است که در عمل اگر در محیط نویز شدید باشد D آن را تقویت می کند و در بعضی موارد کل حلقه کنترلر را از کار می اندازد ! 

در کنترلر دیجیتال هم اصول کار یکی است و برای تحقق PI  در حقیقت الگوریتم  زیر است

esum = esum + e
y = Kp * e + Ki * Ta * esum

e انحراف از نقطه هدف
esum  جمع  انحرافهای قبلی از نقطه هدف است .
Ta زمان نمونه برداری است برای تحقق انتگرالگیر (توضیحش کمی ریاضیات می خواد و چون نوشتی هنوز دانشگاه نرفتی توضیح نمی دم یک عدد 1 در ابتدا قرار بده تا بعد اگر عمکرد کنترلر مناسب نبود تغییر بدهی)

این موارد را برای این نوشتم که در نظر داشته باشی اولا چه کنترلری مناسب کارت است و بعد هم  وقتی پارامترهای کنترلر را تغییر می دهی چه خروجی را *می توانی انتظار داشته باشی* 


این کد را با انجام تغییرات مورد نیازت استفاده کن 

double esum=0;
double KP=xx;
double KI=xx;
double Ta=xx;
double y;

double PI_Berechnung (double x, double w)
{    
e =w-x;                                    

  if ((y < 1023)&&(y > 0))                 
    {                                      // (Anti-Windup)
      esum = esum + e;                      
    }
    y = (Kp*e)+(KI*Ta*esum); 
                                           
    
  if (y > 1023)                              
    {
      y = 1023;
    }
  if (y < 1)
    {
      y = 0;
    }
  return y;
}


پارامترهای کنترلر را چون از سیستمت اطلاعی ندارم خودت باید تکمیل کنی

نکته مهم استفاده از double است برای تعریف متغیرها چون اگر int تعریف کنی و در محاسبات مثلا 0.5  باشد سیستم به 0  گرد  می کند و در نتیجه کنترلر محاسبات درستی انجام نمی دهد.

anti-windup  هم در کد که نوشتم برای یک خروجی dac  مقادیر دیجیتال بین 0 تا 1023 دسیمال  است و ظاهرا در کاربرد که داری می توانی مستقیم 5 و 5- بدهی که آن را هم خودت تغییر بده.

ننوشتی از چه پروسسوری استفاده می کنی به هر حال اگر از میکروهای معمولی است که باید وقفه یک تایمر را  برای اجرای این تابع  صدا کنی    اگر هم از یک پروسسوری که لینوکس روش پورت شده مثل arm  یا cortex یا هرچی ...      استفاده می کنی که باید یک thread  تعریف کنی حقیقت یک پروسس موازی با برنامه اصلی تعریف می شود (مالتی پروسس) که  اگر لازم داشتی بعد  توضیح  می دهم.

البته در یک ربات واقعی سیستم  چند ورودی و چند خروجی دارد که ورودیها بر هم تاثیر دارند و بررسی این سیستم ها در کنترل به روش  State space  تعریف می شود که اگر لازم داشتی بعدا می توان صحبت کرد.

----------


## mhmmdshirazi

> این کد که نوشتی  را دقیق نمی دانم چه انتظار داری انجام دهد!  اما در ابتدای کد که اصلا error   را محاسبه نکردی که بعدش بخواهی اگر بین 5 و 5- بود یک کارایی بکند؟  (error صفر باقی می ماند)
> 
> مباحث پایه ای را دوستمون  farzadsw  توضیح داد و من چند نکته عملی اضافه می کنم 
> 
> در کنترلر آنالوگ خیلی ساده زمانی که بخواهی بدون ریاضیات یک کنترلر PID  درست کنی روش معمول این است که
> 
> در ابتدا با I=0,D=0  شروع می کنی و پارامتر P را در حدی زیاد می کنی که سیستم در حد *مرز* شروع به نوسان برسد
> 
> بعد پارامتر D را زیاد می کنی تا حدی که یک نوسان کوچولو رخ دهد
> ...


مرسی خیلی مفید بود!!!! من راستش با میکرو کنترلر اون هم avr می خوام این کارو بکنم مشکلیم تو استفاده از تابع هایی که باید هم زمان اجرا شن بدون مولتی پروسس ندارم!!!! ولی اگه توضیح بدی ممنون میشم!!!

----------


## mhossein72

خوب چرا از یه سیستم عامل مث uC استفاده نمی کنی؟

----------


## aghasina

مگه میشه uC  رو روی میکرو های عادی نصب کرد؟ باید ARM باشه تا بشه ازش استفاده کرد . محمد جواب سوال قبلیمو ندادیا !!!!

----------


## farzadsw

ucos  روی (تقریبا) همه پردازنده ها نصب میشه ، از جمله avr . 
غیر از اون RTOS رایگان و غیر رایگان زیاده . مثلا freertos
حالا اگر نمیخوای rtos استفاده کنی ، با تایمر ها می تونی چند تا پردازش رو همزمان انجام بدی.

----------


## kavehslt

بحث بسیار عالی و مفیدی بود ممنون

----------


## AMIR2640

با سلام

دوستان من میخوام یه کنترل گر pid طراحی کنم و ضرائبشو با فازی تنظیم کنم اگه میشه کمکم کنید چون فردا طهر باید تحویل استاد بدم
ممنون

----------


## robo87gh

دوستان سلام
لطف میکنید سخت افزار PID رو به همراه نرم افزار شرح بدید؟من یه نکات کلی از تئوری میدونم ولی تو عمل که سخت افزار و نرم افزاری استفاده می شه رو ندیدم. :ناراحت: 
قبلا از همکاری شما کمالل تشکر رو دارم. :تشویق:  :تشویق:  :تشویق:

----------


## farzadsw

سخت افزار یک کنترلر کاملا به خود سیستم شما بستگی داره . به طور کلی شما باید یک فیدبک از خروجی سیستم داشته باشید که در عمل توسط سنسور امکان پذیر میشه ( اگر سنسور آنالوگ هست باید توسط مدارات Instrument amplifier سیگنال رو تقویت کنید)  . بعد باید اطلاعات سنسور رو تحلیل کنید تا تو بازه مناسب قرار بگیره و سپس با مقدار ورودی مرجع (set point ) مقایسه کنید ؛ در واقع مقدار مرجع رو از نتیجه سنسور کم می کنید و تو یک متغیر قرار میدید ( این متغیر میشه مقدار خطا نسبت به مرجع) . 
بعد از بدست آوردن مقدار خطا ، اون رو توی کنترلر PID استفاده میکنیم . PID از سه بخش تشکیل شده : تناسبی ، مشتقی و انتگرالی . هر کدوم از این بخشها رو به صورت یک متغیر در نظر می گیریم و خروجی کنترلر رو می سازیم :
Co = kp*e + kd * de + ki*ie
که e همون مقدار خطاست ، de مشتق خطا ( تفاضل خطا در دو سیکل متوالی تقسیم بر زمان سیکل) و ie انتگرال خطا ( جمع خطا ها ی همه سیکلهای قبلی) . ضرایب kp , ki , kd رو هم که باید خودمون مشخص کنیم و در اکثر مواقع یک عدد ثابت هست (کنترل کلاسیک) .
در نهایت باید خروجی کنترلر (Co ) رو به سیستم اعمال کنیم که باز این خودش مدارات متناسب با سیستم رو لازم داره و در حقیقت یکجور DAC باید پیاده سازی بشه. 
یکی از ساده ترین سیستم ها موتور الکتریکی هست و برای این سیستم از سنسور تاکومتر یا شفت انکدر (کنترل موقعیت و سرعت) استفاده میشه و خروجی  توسط درایور موتور اعمال میشه . سیستم ها دیگه هم هر کدوم سخت افزار خودش رو می خواد.

----------


## elham...

سلام
مرسی از اطلاعات عالی و مفیدتون
من روی کنترل کوآد کار میکنم و قصد دارم از پی ای دی کنترولر استفاده کنم
ولی راستش نمی دونم  که تا چه اندازه باید وارده مطالب کنترل خطی بشم
اینکه  برای استفاده از پی آی دی باید تابع تبدیلی برای سیستممون در بیارم و وارده مطالبی مثله قطب ها و صفر های سیستم برای رسیدن به پاسخ مطلوب بشم یا که نه فقط با برسی خروجی سنسور ها (ژیروسکپ و اکسلرو ) پی ا دی رو پیاده کنم؟
خواهش می کنم منو راهنماییی کنید

----------


## farzadsw

اگر میخواد بغیر از کنترلر PID کنترلر دیگری هم بعدا استفاده و طراحی کنید باید مدل سیستم رو بدست بیارید ولی برای کنترل کننده PID مدل دقیق سیستم ضروری نیست .
 با توجه به اینکه مدل سیستم کوادروتور قبلا با دقتهای مختلف بارها محاسبه شده ، یه کلیتی از سیستم مشخصه . مثلا اینکه یک کنترل کننده PD روی زاویه (یا PI روی سرعت زاویه ای) میتونه سیستم رو پایدار کنه . تعیین ضرایب رو میشه از طریق سعی و خطا و آزمایش مشخص کرد (روش زیگلر نیکلز هم در واقع یجور سعی و خطا هست) . ولی اگه مدل به اندازه کافی دقیق از سیستمتون داشته باشید (که در آوردنش یکم سخته) می تونید با بررسی سیستم ضرایب مناسب رو طراحی کنید و روی سیستم بگذارید و اگه مدلتون دقیق باشه کار خواهد کرد .

----------


## sogolam

سلام 

من میخوام  درباره کنترل  pid  به بیسیک 
برنامه ای بنویسید

 ایا دستور  انتگرال داریم 

ممنون میشم راهنماییم کنید 

mojtaba_hp@ymail.com

----------

