اطلاعیه

Collapse
No announcement yet.

کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    #31
    پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

    نوشته اصلی توسط طراح
    زمانی در دانشگاه در کلاس کنترل کننده های صنعتی (که یک درس تئوری بود)، کنترل کننده PID و On-Off را بصورت عملی برای دانشجویان پیاده سازی می کردم. برای این کار در خروجی پورت موازی یک PWM ایجاد می شد که از طریق بافر، یک مقاومت آجری به عنوان مولد حرارت را گرم می کرد و این مقاومت با یک نوار چند سانتی متری آلومینیومی (برای ایجاد تاخیر) به یک LM35 متصل می شد و خروجی این سنسور هم از طریق اتصال ADC به پورت موازی برای محاسبات و رسم دما به کامپیوتر وارد می شد. در این حالت در مرحله اول، برنامه یک کنترلر قطع و وصل اجرا می شد که نشان می داد دما بصورت دقیق تثبیت نمی شود و دائما حول Set point نوسان می کند. اما با همین سخت افزار و اجرای نرم افزار PID و تنظیم صحیح ضرایب مشاهده می شد که دما بصورت بسیار تثبیت شده و نوسان نزدیک به صفر، مقدار Set point را دنبال می کند. در این شرایط امکان تغییر ضرایب PID و مشاهده تاثیر آن در عملکرد کنترلر قابل مشاهده بود.
    در مورد صورت مسئله جاری هم قبل از آنکه بخواهید تمام مراحل را با هم اجرا کنید و در یک مرحله یک کنترلر Auto tunning بسازید، در مرحله اول باید امکان تصحیح دستی ضرایب از طریق نرم افزار و سخت افزار مناسب فراهم شود و بعد از آنکه اصل اجرای کنترلر پیاده سازی شد، در گام بعد می توانید از دو روش Ziegler-Nichols که یکی از آنها در پست های قبل توضیح داده شد، استفاده کنید و سوال در این مورد تا زمانی که اصل اجرای کنترلر پیاده سازی نشود، چندان موضوعیتی ندارد. یک روش کم هزینه برای پیاده سازی هم همین تولید گرما بوسیله یک مقاومت و اتصال آن با یک هادی حرارت در فاصله دورتر به یک سنسور دماست. اگر در interfacing به PC تسلط داشته باشید، می توانید در مرحله اول برای درک هر چه بهتر عملکرد کنترلر از PC به عنوان کنترلر استفاده کنید و در گام بعد پروژه را روی میکروکنترلر پیاده سازی کنید. پروژه ها و نمونه کدهای زیادی هم برای AVR موجود است که با صرف وقت و بررسی خط به خط کدها می توانید در مورد عملکرد آنها تسلط پیدا کنید. از جمله این پروژه ها AVR221 است که لینک سورس پروژه و فایل PDF آن در زیر قرار داده می شود:

    www.atmel.com/Images/AVR221.zip

    www.atmel.com/Images/doc2558.pdf
    سلام به همگی
    خیلی ممنون از آقای کی نژاد برای مطلب مفیدی که گذاشتین
    من دارم از همین کد به کمک یه مقاومت آجری و یک ds18b20 سعی میکنم pid رو راه بندازم تا بعد از اینکه اکی گرفتم روی پروژه اصلیم استفاده کنم
    با توجه به اینکه وقتی هیتر گرم میشه و میخواد به دمای مورد نظر ما برسه یه تاخیر زمانی وجود داره...
    من این هیتر رو با pwm کنترل میکنم ...
    الان توی مرحله پیدا کردن kp مناسب برای رسیدن به اون نوسان منظم هستم . ولی فک میکنم جز kp مناسب timeinterval توی برنامه هم خیلی مهمه
    چون اگه این زمان خیلی کوتاه باشه (توی برنامه atmel پنج میلی ثانیه هست) برای کنترل دما فک کنم مناسب نیست .چون خیلی سریع عرض پالس من توی مد fast که ماکسیممش 1024 هست به 1024 میرسه...و وقتی که دما از setpoint رد میشه خیلی سریع عرض پالس به 0 میرسه...انگار on/off میشه ...
    حالا من timeinterval رو حدود 10 ثانیه کردم و با kp 4 که به هیتر فرصت بدم دمای خودشو بالا ببره....
    الان زمان پریود این نوسانات خیلی زیاد شد...یعنی اون موقع خیلی سریع نوسان میکرد ولی الان خیلی کند...ولی دیگه pwm به مقدار 1024 نمیرسه...الان به 300 میرسه شروع کنه به کم شدن...یعنی مثلا setpint من که 35 درجه است pwm مورد نظر باید یه مقداری بین 150 تا 300 باشه...
    فک کنم اگه کنترل دور موتور dc بود زمان پاسخگویی سیستم خیلی سریع بود.الان باید بشینم هی دما کم و زیاد بشه

    نمودار زمان ضرب در 10 کنین (هر یه خونش 10 ثانیه)
    سوال :
    حالا این kp همون Kc هست و این زمان پریود نوسان میشه Pc که با توجه به جدول زیگلرنیکولز مقدار kp ti tp بدست میاد
    و با توجه به اون فرمول زیر مقادیر برای تابع pid بدست میاد .



    میشه یکم راه نمایی کنید ؟تا اینجا درسته ؟ باید چه timeinterval ,KP انتخاب کنم ؟
    pc برحسب ثانیه هست دیگه ؟

    دیدگاه


      #32
      پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

      timeinterval رو بردم روی 20 ثانیه .kp=4
      setpoint 35 درجه هست . نتیجه :

      272 تا نمونه برداری و پدیت pid هست که 20 ثانیه طول کشیده و 90 دقیقه کل این پروسه بوده...

      بعد از 365 بار پدیت شدن و نمونه برداری . 120 دقیقه ...
      خب نظرتون چیه ؟kp , Pc چی میشه ؟ باید بازم kp دیگه ای امتحان کنم؟

      با توجه به این جدول مثلا کنترل P باید این kp فعلی استفاده شده که 4 هست رو در 0.5 ضرب کنم و توی کنترلرم از 2 استفاده کنم؟
      واسه pid چی؟
      جالا من توی نمونه واقعی دمای 100 تا 300 درجه میخوام کنترل کنم .فک کنم اینجوری خیلیییی طول میکشه پروسه...

      دیدگاه


        #33
        پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

        دوستان من از این کد استفاده کردم :

        http://www.atmel.com/Images/AVR221.zip

        و قسمت مقدار دهی به pwm رو هم اینکارو کردم :
        کد:
        
        void Set_Input(int16_t inputValue)
        {
         _OCR+=inputValue;
         if(_OCR >= 1020)
         {
        	 _OCR = 1020;
        	
         }
         else if(_OCR <= 0)
         {
        	
        	 _OCR = 0;
         }
         
         OCR1A = _OCR ;
        }
        فک کنم نوسان منظور نوسانی هست که به set point میل نکنه و Pc دوره تناوبش میشه...یه تناوب منظم
        ولی نمودار من به set point رسید ...
        ولی کد هایی که توی نت گشتم جوره دیگه ای بود...من اشتباه کردم ؟

        دیدگاه


          #34
          پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

          سلام
          خوبید؟
          مشکلتون چیه؟
          تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

          www.intelart.ir


          ساخت کنترلر دما PID فازي با AVR [آموزشی]

          دیدگاه


            #35
            پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

            نوشته اصلی توسط Mahdi.Faani
            سلام
            خوبید؟
            مشکلتون چیه؟
            سلم
            کارایی که کردمو تو این سه تا پست اخیر گذاشتم.سعی کردم یک هیتر کوچیک رو شبیه سازی کنم باpwm fast
            از کد اتمل استفاده کردم.که اقای کی نژاد گذاشته بودند
            قسمت خروجی pid رو با ocr قبلی اضافه کردم .نمودار خروجی دمارو هم گذاشتم.این نمودارا با kp برابر 4 امتحان کردم.نمودار اول pid با 10ثانیه تاخیر اپدیت میشد و دومی با 20 ثانیه تاخیر.نمیدونم زمان اپدیت مناسب چقدره....
            ولی من کدهای دیگه ای که توی اینترنت دیدم یکم فرق داشت...خروجیpidرو مستقیم ریختم توی ocrبعضیها
            من با kp 4 و timeinterval 20 ثانیه تقریبا به ست پوینتم رسیدم..نمودارش هست....ولی نه با pid کامل
            فک میکنم یه جای کار مشکل داره...
            وقتی ki kd رو اضافه میکنم کلا نمودار بهم میخوره...یکم گیج شدم

            دیدگاه


              #36
              پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

              نوشته اصلی توسط کیوان قاسمی
              سلم
              کارایی که کردمو تو این سه تا پست اخیر گذاشتم.سعی کردم یک هیتر کوچیک رو شبیه سازی کنم باpwm fast
              از کد اتمل استفاده کردم.که اقای کی نژاد گذاشته بودند
              قسمت خروجی pid رو با ocr قبلی اضافه کردم .نمودار خروجی دمارو هم گذاشتم.این نمودارا با kp برابر 4 امتحان کردم.نمودار اول pid با 10ثانیه تاخیر اپدیت میشد و دومی با 20 ثانیه تاخیر.نمیدونم زمان اپدیت مناسب چقدره....
              ولی من کدهای دیگه ای که توی اینترنت دیدم یکم فرق داشت...خروجیpidرو مستقیم ریختم توی ocrبعضیها
              من با kp 4 و timeinterval 20 ثانیه تقریبا به ست پوینتم رسیدم..نمودارش هست....ولی نه با pid کامل
              فک میکنم یه جای کار مشکل داره...
              وقتی ki kd رو اضافه میکنم کلا نمودار بهم میخوره...یکم گیج شدم
              10ثانیه؟؟؟؟ oo:
              ببینید باید فرکانس کاری PID حداقل 5 باشه.یعنی هر 200 میلی ثانیه یبار پردازش PID رو انجام بدید و فرکانس نمونه گیری هم حداقل باید 2برابر فرکانس کاری PID باشه.2 برابر که گفتم نتیجه یک قضیه هست به اسم قضیه نایکوئیست که در کنترل دیجیتال مطرح شده ولی در عمل شما باید فرکانس نمونه گیری رو حداقل 8 برابر فرکانس کاری PID در نظر بگیرید.یعنی حدودا هر 20 میلی ثانیه یبار نمونه بگیرید.در مورد اینکه ضرایب رو چجور تعیین کنید ، دارم تاپیک آموزش ساخت PID رو پدیت میکنم.به زودی اونجا مفصل توضیح میدم...
              موفق باشید
              تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

              www.intelart.ir


              ساخت کنترلر دما PID فازي با AVR [آموزشی]

              دیدگاه


                #37
                پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم&#1

                نوشته اصلی توسط Mahdi.Faani
                10ثانیه؟؟؟؟ oo:
                ببینید باید فرکانس کاری PID حداقل 5 باشه.یعنی هر 200 میلی ثانیه یبار پردازش PID رو انجام بدید و فرکانس نمونه گیری هم حداقل باید 2برابر فرکانس کاری PID باشه.2 برابر که گفتم نتیجه یک قضیه هست به اسم قضیه نایکوئیست که در کنترل دیجیتال مطرح شده ولی در عمل شما باید فرکانس نمونه گیری رو حداقل 8 برابر فرکانس کاری PID در نظر بگیرید.یعنی حدودا هر 20 میلی ثانیه یبار نمونه بگیرید.در مورد اینکه ضرایب رو چجور تعیین کنید ، دارم تاپیک آموزش ساخت PID رو پدیت میکنم.به زودی اونجا مفصل توضیح میدم...
                موفق باشید
                سلام
                من زمان پدیت PID رو طولانی در نظر گرفتم چون وقتی هیتر روشن میشد فقط حداقل 3 ثانیه در حالت فول پاور طول میکشید سنسور دما 1 درجه افزایش دما رو هس کنه ...و من فک میکردم اگه تند تند پدیت بشه فقط مقدار OCR سریع به ماکسیمم میرسه و توی نقطه SETPOINT هم سریع به 0 میل میکنه...من بهش فرصت دادم تا مثلا OCR مناسب رو برای دمای 35 درجه پیدا کنه،میخواستم اون لختی انتقال دما رو جبران کنم.....نمیدونم خب حتما این فرضیه ای که داشتم اشتباه بود. :mrgreen: :mrgreen:همه مثال ها درباره ی موتور DC هست که اونم خیلی سریع سرعتش تغییر میکنه... ولی یه مثلا عملی برای هیتر نبود
                امروز اومدم از یک کد ساده استفاده کردم اینجا میزارمش تا از ائل بررسی کنیم pid.h , pid.c :
                کد:
                
                #ifndef PID_V2_H_
                #define PID_V2_H_
                
                #include "../app_config.h"
                typedef struct
                {
                	float dState; // Last position input
                	float iState; // Integrator state
                	float iMax, iMin;
                	// Maximum and minimum allowable integrator state
                	float iGain, // integral gain
                	pGain, // proportional gain
                	dGain; // derivative gain
                } SPid;
                
                void pid_Init(float p_factor, float i_factor, float d_factor, float iMin, float iMax ,SPid *pid);
                
                float UpdatePID(float setPoint, float processValue, SPid * pid);
                
                
                
                #endif /* PID_V2_H_ */
                کد:
                #include "../app_config.h"
                #include "pid_v2.h"
                
                void pid_Init(float p_factor, float i_factor, float d_factor, float iMin, float iMax ,SPid *pid)
                // Set up PID controller parameters
                {
                	// Start values for PID controller
                	pid->dState = 0;
                	pid->iState = 0;
                	// Tuning constants for PID loop
                	pid->pGain = p_factor;
                	pid->iGain = i_factor;
                	pid->dGain = d_factor;
                	// Limits to avoid overflow
                	pid->iMax = iMax;
                	pid->iMin = iMin;
                }
                
                
                float UpdatePID(float setPoint, float processValue, SPid * pid)
                {
                	float error,ret,pTerm,dTerm, iTerm;
                	
                	error = setPoint - processValue;
                
                	pTerm = pid->pGain * error;
                	// calculate the proportional term
                	// calculate the integral state with appropriate limiting
                	pid->iState += error;
                	if (pid->iState > pid->iMax) pid->iState = pid->iMax;
                	else if (pid->iState<pid->iMin) pid->iState = pid->iMin;
                	iTerm = pid->iGain * pid->iState; // calculate the integral term
                	dTerm = pid->dGain * (processValue - pid->dState);
                	pid->dState = processValue ;
                	
                	ret = pTerm + iTerm - dTerm;
                	if(ret > pid->iMax)
                	{
                		ret = pid->iMax;
                	}
                	else if(ret < -pid->iMax)
                	{
                		ret = -pid->iMax;
                	}
                	return (int16_t)ret;
                }
                خب حالا خلاصه ای از main برنامه :
                کد:
                .
                .
                .
                
                #define K_P  6.00
                //! \xrefitem todo "Todo" "Todo list"
                #define K_I  0.00
                //! \xrefitem todo "Todo" "Todo list"
                #define K_D  0.00
                
                /*! \brief Flags for status information
                 */
                struct GLOBAL_FLAGS {
                 //! True when PID control loop should run one time
                 uint8_t pidTimer:1;
                 uint8_t tempTimer:1;
                } gFlags = {0, 0};
                
                //! Parameters for regulator
                SPid pidData;
                
                /*! \brief Sampling Time Interval
                 *
                 * Specify the desired PID sample time interval
                 * With a 8-bit counter (255 cylces to overflow), the time interval value is calculated as follows:
                 * TIME_INTERVAL = ( desired interval [sec] ) * ( frequency [Hz] ) / 255
                 */
                
                #define TIME_INTERVAL 10
                
                
                /*! \brief Init of PID controller demo
                 */
                void Init(void)
                {
                 pid_Init(K_P, K_I,K_D,0,1024, &pidData);
                
                 
                
                //زمان سرریز تامیر 2040 میلی ثانیه
                 TCCR0 = (1<<CS00) | (1<<CS01) ;//| (1<<CS02);
                 TIMSK = (1<<TOIE0);
                 TCNT0 = 0;
                }
                
                ISR(TIMER0_OVF_vect)
                {
                	static uint16_t i_20ms = 0 , i_200ms;
                	if(i_20ms < TIME_INTERVAL)
                		i_20ms++;
                	else
                	{
                		gFlags.tempTimer = 1;
                		i_20ms=0;
                	}
                	if(i_200ms < 10* TIME_INTERVAL)
                		i_200ms++;
                	else
                	{
                		gFlags.pidTimer = 1;
                		i_200ms=0;
                	}
                }
                
                void Set_Input(int16_t inputValue)
                {
                 _OCR+=inputValue;
                 if(_OCR >= 1020)
                 {
                	 _OCR = 1020;
                 }
                 else if(_OCR <= 0)
                 {
                	 _OCR = 0;
                 }
                 OCR1A = _OCR ;
                 
                 //OCR1A = inputValue;
                }
                .
                .
                .
                .
                
                int	main(void)
                {
                داخل یک LOOP :
                
                		// Run PID calculations once every PID timer timeout
                		if(gFlags.tempTimer)
                		{
                			measurementValue = Get_Measurement();
                			ftoa(measurementValue,2,temp);
                			sprintf(lcd,"T:%s OCR:%i ",temp, _OCR );
                			LCDWriteStringXY(0,0,lcd);
                			Debug(lcd);
                			Debug("\n");
                			gFlags.tempTimer=0;
                		}
                		if(gFlags.pidTimer)
                		{
                			referenceValue = Get_Reference();
                
                			inputValue = UpdatePID(referenceValue, measurementValue, &pidData);
                
                			Set_Input(inputValue);
                
                		 ftoa(_ref_Temp,2,temp);
                		 sprintf(lcd,"S:%s In:%i ",temp, inputValue);
                		 LCDWriteStringXY(0,1,lcd);
                		 
                		 
                			gFlags.pidTimer = 0;
                		}
                .
                .
                .
                		}
                خب کاری که کردم SETPIONT روی 35.5 درجه هست و KI KD صفر در نظر گرفتم KP رو هم 6، هر 200 میلی ثانیه PID پدیت میشه هر 20 میلی ثانیه هم دمارو از سنسور میخونم...
                نتیجه کار واسه نمودار دما : ( هر واحد زمان 200 میلی ثانیه )


                و نمودار تغییرات OCR برای تولید PWM :


                خب حالا یه نظر کارشناسی بدین لطفا من از این ابهام بیام بیرون .کم کم دارم به همون on/off ساده راضی میشم :sad:
                سوال :
                #در عمل شما باید فرکانس نمونه گیری رو حداقل 8 برابر فرکانس کاری PID در نظر بگیرید.یعنی حدودا هر 20 میلی ثانیه یبار نمونه بگیرید
                این واسه کشیدن نمودار دما هست ؟یعنی تغییرات دمارو دنبال کنیم دیگه؟

                دیدگاه


                  #38
                  پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

                  نوشته اصلی توسط کیوان قاسمی
                  سلام
                  من زمان پدیت PID رو طولانی در نظر گرفتم چون وقتی هیتر روشن میشد فقط حداقل 3 ثانیه در حالت فول پاور طول میکشید سنسور دما 1 درجه افزایش دما رو هس کنه ...و من فک میکردم اگه تند تند پدیت بشه فقط مقدار OCR سریع به ماکسیمم میرسه و توی نقطه SETPOINT هم سریع به 0 میل میکنه...من بهش فرصت دادم تا مثلا OCR مناسب رو برای دمای 35 درجه پیدا کنه،میخواستم اون لختی انتقال دما رو جبران کنم.....نمیدونم خب حتما این فرضیه ای که داشتم اشتباه بود. :mrgreen: :mrgreen:همه مثال ها درباره ی موتور DC هست که اونم خیلی سریع سرعتش تغییر میکنه... ولی یه مثلا عملی برای هیتر نبود
                  امروز اومدم از یک کد ساده استفاده کردم اینجا میزارمش تا از ائل بررسی کنیم pid.h , pid.c :
                  کد:
                  
                  #ifndef PID_V2_H_
                  #define PID_V2_H_
                  
                  #include "../app_config.h"
                  typedef struct
                  {
                  	float dState; // Last position input
                  	float iState; // Integrator state
                  	float iMax, iMin;
                  	// Maximum and minimum allowable integrator state
                  	float iGain, // integral gain
                  	pGain, // proportional gain
                  	dGain; // derivative gain
                  } SPid;
                  
                  void pid_Init(float p_factor, float i_factor, float d_factor, float iMin, float iMax ,SPid *pid);
                  
                  float UpdatePID(float setPoint, float processValue, SPid * pid);
                  
                  
                  
                  #endif /* PID_V2_H_ */
                  کد:
                  #include "../app_config.h"
                  #include "pid_v2.h"
                  
                  void pid_Init(float p_factor, float i_factor, float d_factor, float iMin, float iMax ,SPid *pid)
                  // Set up PID controller parameters
                  {
                  	// Start values for PID controller
                  	pid->dState = 0;
                  	pid->iState = 0;
                  	// Tuning constants for PID loop
                  	pid->pGain = p_factor;
                  	pid->iGain = i_factor;
                  	pid->dGain = d_factor;
                  	// Limits to avoid overflow
                  	pid->iMax = iMax;
                  	pid->iMin = iMin;
                  }
                  
                  
                  float UpdatePID(float setPoint, float processValue, SPid * pid)
                  {
                  	float error,ret,pTerm,dTerm, iTerm;
                  	
                  	error = setPoint - processValue;
                  
                  	pTerm = pid->pGain * error;
                  	// calculate the proportional term
                  	// calculate the integral state with appropriate limiting
                  	pid->iState += error;
                  	if (pid->iState > pid->iMax) pid->iState = pid->iMax;
                  	else if (pid->iState<pid->iMin) pid->iState = pid->iMin;
                  	iTerm = pid->iGain * pid->iState; // calculate the integral term
                  	dTerm = pid->dGain * (processValue - pid->dState);
                  	pid->dState = processValue ;
                  	
                  	ret = pTerm + iTerm - dTerm;
                  	if(ret > pid->iMax)
                  	{
                  		ret = pid->iMax;
                  	}
                  	else if(ret < -pid->iMax)
                  	{
                  		ret = -pid->iMax;
                  	}
                  	return (int16_t)ret;
                  }
                  خب حالا خلاصه ای از main برنامه :
                  کد:
                  .
                  .
                  .
                  
                  #define K_P  6.00
                  //! \xrefitem todo "Todo" "Todo list"
                  #define K_I  0.00
                  //! \xrefitem todo "Todo" "Todo list"
                  #define K_D  0.00
                  
                  /*! \brief Flags for status information
                   */
                  struct GLOBAL_FLAGS {
                   //! True when PID control loop should run one time
                   uint8_t pidTimer:1;
                   uint8_t tempTimer:1;
                  } gFlags = {0, 0};
                  
                  //! Parameters for regulator
                  SPid pidData;
                  
                  /*! \brief Sampling Time Interval
                   *
                   * Specify the desired PID sample time interval
                   * With a 8-bit counter (255 cylces to overflow), the time interval value is calculated as follows:
                   * TIME_INTERVAL = ( desired interval [sec] ) * ( frequency [Hz] ) / 255
                   */
                  
                  #define TIME_INTERVAL 10
                  
                  
                  /*! \brief Init of PID controller demo
                   */
                  void Init(void)
                  {
                   pid_Init(K_P, K_I,K_D,0,1024, &pidData);
                  
                   
                  
                  //زمان سرریز تامیر 2040 میلی ثانیه
                   TCCR0 = (1<<CS00) | (1<<CS01) ;//| (1<<CS02);
                   TIMSK = (1<<TOIE0);
                   TCNT0 = 0;
                  }
                  
                  ISR(TIMER0_OVF_vect)
                  {
                  	static uint16_t i_20ms = 0 , i_200ms;
                  	if(i_20ms < TIME_INTERVAL)
                  		i_20ms++;
                  	else
                  	{
                  		gFlags.tempTimer = 1;
                  		i_20ms=0;
                  	}
                  	if(i_200ms < 10* TIME_INTERVAL)
                  		i_200ms++;
                  	else
                  	{
                  		gFlags.pidTimer = 1;
                  		i_200ms=0;
                  	}
                  }
                  
                  void Set_Input(int16_t inputValue)
                  {
                   _OCR+=inputValue;
                   if(_OCR >= 1020)
                   {
                  	 _OCR = 1020;
                   }
                   else if(_OCR <= 0)
                   {
                  	 _OCR = 0;
                   }
                   OCR1A = _OCR ;
                   
                   //OCR1A = inputValue;
                  }
                  .
                  .
                  .
                  .
                  
                  int	main(void)
                  {
                  داخل یک LOOP :
                  
                  		// Run PID calculations once every PID timer timeout
                  		if(gFlags.tempTimer)
                  		{
                  			measurementValue = Get_Measurement();
                  			ftoa(measurementValue,2,temp);
                  			sprintf(lcd,"T:%s OCR:%i ",temp, _OCR );
                  			LCDWriteStringXY(0,0,lcd);
                  			Debug(lcd);
                  			Debug("\n");
                  			gFlags.tempTimer=0;
                  		}
                  		if(gFlags.pidTimer)
                  		{
                  			referenceValue = Get_Reference();
                  
                  			inputValue = UpdatePID(referenceValue, measurementValue, &pidData);
                  
                  			Set_Input(inputValue);
                  
                  		 ftoa(_ref_Temp,2,temp);
                  		 sprintf(lcd,"S:%s In:%i ",temp, inputValue);
                  		 LCDWriteStringXY(0,1,lcd);
                  		 
                  		 
                  			gFlags.pidTimer = 0;
                  		}
                  .
                  .
                  .
                  		}
                  خب کاری که کردم SETPIONT روی 35.5 درجه هست و KI KD صفر در نظر گرفتم KP رو هم 6، هر 200 میلی ثانیه PID پدیت میشه هر 20 میلی ثانیه هم دمارو از سنسور میخونم...
                  نتیجه کار واسه نمودار دما : ( هر واحد زمان 200 میلی ثانیه )


                  و نمودار تغییرات OCR برای تولید PWM :


                  خب حالا یه نظر کارشناسی بدین لطفا من از این ابهام بیام بیرون .کم کم دارم به همون on/off ساده راضی میشم :sad:
                  سوال :
                  #در عمل شما باید فرکانس نمونه گیری رو حداقل 8 برابر فرکانس کاری PID در نظر بگیرید.یعنی حدودا هر 20 میلی ثانیه یبار نمونه بگیرید
                  این واسه کشیدن نمودار دما هست ؟یعنی تغییرات دمارو دنبال کنیم دیگه؟
                  خواهش میکنم.لطف دارید
                  نه...نمودار مهم نیس.این که از خروجی سیستم نمونه بگیرید مهم هست.باید زمانبندی ها دقیق باشه.با تایمر زمانبندی ایجاد کنید و مثلا هر 25 نیلی ثانیه خروجی سنسور رو توی یه متغیر عمومی قرار بدید.بگذارید تا هر 25 میلی ثانیه از خروجی نمونه گرفته بشه.کاری به دیگر اجزای برنامه هم نداشته باشه.و هر 200 میلی ثانیه هم روتین PID رو پردازش کنه و از مقدار خروجی که حداکثر 25 میلی ثانیه قبل توی متغیر ذخیره شده استفاده کنه...
                  ببینید این کار با چیزی که در کنترل دیجیتال مطرح میشه کلا تفاوت داره.اونجا اگه 5 میلی ثانیه مقدار زمان پردازش PID رو تغییر بدید کلا تابع تبدیل کنترلر عوض میشه و باید ضرایب رو از نو تنظیم کنید.شما فعلا همین کار رو انجام بدید.ضرایب رو چاره ندارید جز اینکه آزمون و خطا استفاده کنید.نتیجه خیلی بهتر از حالت اول میشه ولی کار اصولی اینه که از متدهای مطرح شده در کنترل دیجیتال استفاده بشه که اونم کلی کار داره...اگه فعلا عجله ای ندارید میتونید صبر کنید توی تاپیک PID اونو هم قراره اضافه کنم.
                  اگه از آزمون و خطا زیاد استفاده کنید میتونید به 95 درصد حالت ایده آل در کنترل دیجیتال نزدیک بشید.این دیگه بسته به تلاش خودتون واسه تعیین ضرایب داره...
                  موفق باشید
                  تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                  www.intelart.ir


                  ساخت کنترلر دما PID فازي با AVR [آموزشی]

                  دیدگاه


                    #39
                    پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

                    نوشته اصلی توسط Mahdi.Faani
                    خواهش میکنم.لطف دارید
                    نه...نمودار مهم نیس.این که از خروجی سیستم نمونه بگیرید مهم هست.باید زمانبندی ها دقیق باشه.با تایمر زمانبندی ایجاد کنید و مثلا هر 25 نیلی ثانیه خروجی سنسور رو توی یه متغیر عمومی قرار بدید.بگذارید تا هر 25 میلی ثانیه از خروجی نمونه گرفته بشه.کاری به دیگر اجزای برنامه هم نداشته باشه.و هر 200 میلی ثانیه هم روتین PID رو پردازش کنه و از مقدار خروجی که حداکثر 25 میلی ثانیه قبل توی متغیر ذخیره شده استفاده کنه...
                    ببینید این کار با چیزی که در کنترل دیجیتال مطرح میشه کلا تفاوت داره.اونجا اگه 5 میلی ثانیه مقدار زمان پردازش PID رو تغییر بدید کلا تابع تبدیل کنترلر عوض میشه و باید ضرایب رو از نو تنظیم کنید.شما فعلا همین کار رو انجام بدید.ضرایب رو چاره ندارید جز اینکه آزمون و خطا استفاده کنید.نتیجه خیلی بهتر از حالت اول میشه ولی کار اصولی اینه که از متدهای مطرح شده در کنترل دیجیتال استفاده بشه که اونم کلی کار داره...اگه فعلا عجله ای ندارید میتونید صبر کنید توی تاپیک PID اونو هم قراره اضافه کنم.
                    اگه از آزمون و خطا زیاد استفاده کنید میتونید به 95 درصد حالت ایده آل در کنترل دیجیتال نزدیک بشید.این دیگه بسته به تلاش خودتون واسه تعیین ضرایب داره...
                    موفق باشید
                    دوباره سلام
                    منم دقیقا همین کارو کردم....ولی فک میکنم زمان اپدیت pid نباید 200 میلی ثانیه باشه.چندتا سورس انگلیسی خوندم که اونجا هم نوشته بود 1 ثانیه و یه جایی هم نوشته بود بین 1/10 تا 1/100 زمان پاسخ گویی سیستم...حالا چندتا مطلب جدید پیدا کردم.امتحان میکنم دوباره نتایج و میزارم.خیلی ممنون

                    دیدگاه


                      #40
                      پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

                      نوشته اصلی توسط کیوان قاسمی
                      دوباره سلام
                      منم دقیقا همین کارو کردم....ولی فک میکنم زمان اپدیت pid نباید 200 میلی ثانیه باشه.چندتا سورس انگلیسی خوندم که اونجا هم نوشته بود 1 ثانیه و یه جایی هم نوشته بود بین 1/10 تا 1/100 زمان پاسخ گویی سیستم...حالا چندتا مطلب جدید پیدا کردم.امتحان میکنم دوباره نتایج و میزارم.خیلی ممنون
                      سلام بر شما...خب زمان پاسخ گویی یک المنت حرارتی مگه چقدره؟حدودا یک یا دو ثانیه س...اگه حساب کنید همون میشه.یعنی اگه شما زمان pidرو 1ثانیه بذارید یعنی تاخیر سیستم 100ثانیه س؟اینطور یعنی اینکه وقتی ولتاژ بهش اعمال بشه 100 ثانیه بعد دماش شروع میکنه به بالا رفتن در صورتی که اینطور نیس و میزان تاخیرش در حد همون یک دو ثانیه س...
                      در کل هر چه میزان زمان پردازش pid کمتر باشه ، به حالت ایده آل آنالوگ نزدیک تر میشه...
                      شما با زمان های متفاوت تست کنید.لطفا نتیجه ش رو هم اینجا بگید.
                      فقط یادتون نره زمان pid رو هرچه گرفتید باید زمان نمونه گیری حداکثر نصف اون باشه...
                      تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                      www.intelart.ir


                      ساخت کنترلر دما PID فازي با AVR [آموزشی]

                      دیدگاه


                        #41
                        پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

                        نوشته اصلی توسط Mahdi.Faani
                        سلام بر شما...خب زمان پاسخ گویی یک المنت حرارتی مگه چقدره؟حدودا یک یا دو ثانیه س...اگه حساب کنید همون میشه.یعنی اگه شما زمان pidرو 1ثانیه بذارید یعنی تاخیر سیستم 100ثانیه س؟اینطور یعنی اینکه وقتی ولتاژ بهش اعمال بشه 100 ثانیه بعد دماش شروع میکنه به بالا رفتن در صورتی که اینطور نیس و میزان تاخیرش در حد همون یک دو ثانیه س...
                        در کل هر چه میزان زمان پردازش pid کمتر باشه ، به حالت ایده آل آنالوگ نزدیک تر میشه...
                        شما با زمان های متفاوت تست کنید.لطفا نتیجه ش رو هم اینجا بگید.
                        فقط یادتون نره زمان pid رو هرچه گرفتید باید زمان نمونه گیری حداکثر نصف اون باشه...
                        سلام.
                        من بیشتر به خاطر تاخیر بین سنس کردن و بالا رفتن دمای هیتر میگم....یه کنترلر صنعتی بود واسه هینر هر چند دقیقه ، 1دقیقه هیتر خاموش میکرد تا از دمای setpoint دور نشه و overshoot نکنه فک کنم pid هم روش داشت...واسه همین این نظریه تاخیر 5 یا 10 ثانیه رو اجرا کردم ...
                        چشم امروز کاراشو انجام میدم با چند timeinterval مختلف، یکم هم تغییر در کد
                        فقط یک سوال :
                        مقدار ret = pTerm + iTerm - dTerm; رو باید مستقیم توی ocr بریزم یا ocr+=ret کنم ؟ کدم درست تره ؟
                        نظر خودم با ocr+=ret این هست

                        دیدگاه


                          #42
                          پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

                          نوشته اصلی توسط کیوان قاسمی
                          سلام.
                          من بیشتر به خاطر تاخیر بین سنس کردن و بالا رفتن دمای هیتر میگم....یه کنترلر صنعتی بود واسه هینر هر چند دقیقه ، 1دقیقه هیتر خاموش میکرد تا از دمای setpoint دور نشه و overshoot نکنه فک کنم pid هم روش داشت...واسه همین این نظریه تاخیر 5 یا 10 ثانیه رو اجرا کردم ...
                          چشم امروز کاراشو انجام میدم با چند timeinterval مختلف، یکم هم تغییر در کد
                          فقط یک سوال :
                          مقدار ret = pTerm + iTerm - dTerm; رو باید مستقیم توی ocr بریزم یا ocr+=ret کنم ؟ کدم درست تره ؟
                          نظر خودم با ocr+=ret این هست
                          سلام
                          اگه ocr+=ret باشه که هیچ وقت مقدارش 0 نمیشه...ممکنه بعضی حالات اصلا سیگنال کنترلرتون بخاد صفر بشه...نباید باهاش جمع بشه بلکه مستقیما درونش قرار بگیره...قسمت مشتقگیر رو چرا کم میکنید؟تمام این مقادیر باید علامت مثبت داشته باشند...
                          تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                          www.intelart.ir


                          ساخت کنترلر دما PID فازي با AVR [آموزشی]

                          دیدگاه


                            #43
                            پاسخ : پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کم

                            نوشته اصلی توسط Mahdi.Faani
                            سلام
                            اگه ocr+=ret باشه که هیچ وقت مقدارش 0 نمیشه...ممکنه بعضی حالات اصلا سیگنال کنترلرتون بخاد صفر بشه...نباید باهاش جمع بشه بلکه مستقیما درونش قرار بگیره...قسمت مشتقگیر رو چرا کم میکنید؟تمام این مقادیر باید علامت مثبت داشته باشند...
                            #قسمت مشتقگیر رو چرا کم میکنید؟تمام این مقادیر باید علامت مثبت داشته باشند...
                            -اون واسه اینه که توی فرمول قسمت مستق گیر برعکس کم شده بود چون من این کدو از روی یه برنامه دیگه اصلاخ کردم دیگه این قسمتو نغییر ندادم و موند .فرقی نمیکنه کد نویسیش یه جور دیگه شد

                            float UpdatePID(float setPoint, float processValue, SPid * pid)
                            {
                            float error,ret,pTerm,dTerm, iTerm;

                            error = setPoint - processValue;

                            pTerm = pid->pGain * error;
                            // calculate the proportional term
                            // calculate the integral state with appropriate limiting
                            pid->iState += error;
                            if (pid->iState > pid->iMax) pid->iState = pid->iMax;
                            else if (pid->iState<pid->iMin) pid->iState = pid->iMin;
                            iTerm = pid->iGain * pid->iState; // calculate the integral term
                            dTerm = pid->dGain * (processValue - pid->dState);
                            pid->dState = processValue ;

                            ret = pTerm + iTerm - dTerm;
                            if(ret > pid->iMax)
                            {
                            ret = pid->iMax;
                            }
                            else if(ret < -pid->iMax)
                            {
                            ret = -pid->iMax;
                            }
                            return (int16_t)ret;
                            }
                            نه مقدار سیگنالمون صفر میشه چون مقدار ret هم منفی میشه و مقدار منفی با ocr جمع میشه
                            خب حالا اگه خود مقدار ret رو درون ocr بریزم فرض اگه مقدار error 10 باشه و kp 6 و ki kd هم صفر باشند ؛ مقدار ocr 60 میشه و ممکنه هیچوقت دما به setpoint نرسه با یه شیب ملایم دما زیاد میشه و به یه دمای ثابت زیر set point میرسه مثلا به 30 میرسه و موازی با مقداری که ما میخوایم ادامه میده (setpoint 35) و بهش نمیرسه....پس ما به ائن نمودار نوسانی که I ,D رو صقر کردیم اصلا نمیرسیم
                            حالا اگه ocr+=ret بشه در هم زمان از پدیت pid مقدار ocr زیاد میشه ...وقتی به ست پوینت میرسه چون error منفی میشه مقدار ret هم منفی میشه...واسه همین نت اصرار داشتم که timeinterval ما خیلی سریع نباشه که به اون نوسانه برسیم اینجوری نوسان Pwm فقط بین 1024 و 0 میبود...
                            ولی توی اولین آزمایش (هرچند که خودم هم قبول دارم 20 ثانیه تاخیر خیلی زیاده) که نمودارش هم هست من به یه نوسان رسیدم و بهد از 1 ساعت هم تقریبا دما به ست پوینت رسید با صفر بودن I , D
                            الان نمودارای دمایی که من فرستادم همه ocr+=ret میشدن

                            خب حالا باز هم ocr+=ret یا ocr=ret ؟
                            با ocr=ret و صفر بودت ضرایت I, D اصلا به ست پونیت ممکنه نزدیک نشم...

                            دیدگاه


                              #44
                              پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

                              اینکه همیشه یه خطای حالت ماندگار دارید به خاطر کم بودن تاثیر انتگرالگیره...ضریبشو بیشتر کنید...
                              باز هم نباید OCR+= باشه...باید مقدار سیگنال کنترلی مستقیما داخل ocr ریخته بشه....البته scale کردن رو که حتما در نظر گرفتید دیگه...
                              در ضمن یک ساعت؟؟؟؟؟؟؟؟؟؟؟....نهایتا باید بعد یکی دو دقیقه به ست پوینت برسید...تازه من حالت بدش رو گفتم...یک ساعت که خیلیه..دیگه کنترلر نمیخاد که!
                              شما ضریب انتگرالگیر رو بیشتر کنید وضعیت بهتر میشه...نهایتا بعد از یکی دو دقیقه (تازه اونم خیلی زیاده) باید به ست پوینت برسید...

                              میگردم ببینم پروژه کارشناسیمو اگه پیدا کردم نتیجشو میذارم اینجا...اونم خروجی از یه سیستم حرارتی واقعی گرفته بشده....با المنت 750 وات و فن...
                              تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                              www.intelart.ir


                              ساخت کنترلر دما PID فازي با AVR [آموزشی]

                              دیدگاه


                                #45
                                پاسخ : کنترل کننده PID برای دمای کوره(نیاز به کمک فوری)

                                نوشته اصلی توسط Mahdi.Faani
                                اینکه همیشه یه خطای حالت ماندگار دارید به خاطر کم بودن تاثیر انتگرالگیره...ضریبشو بیشتر کنید...
                                باز هم نباید OCR+= باشه...باید مقدار سیگنال کنترلی مستقیما داخل ocr ریخته بشه....البته scale کردن رو که حتما در نظر گرفتید دیگه...
                                در ضمن یک ساعت؟؟؟؟؟؟؟؟؟؟؟....نهایتا باید بعد یکی دو دقیقه به ست پوینت برسید...تازه من حالت بدش رو گفتم...یک ساعت که خیلیه..دیگه کنترلر نمیخاد که!
                                شما ضریب انتگرالگیر رو بیشتر کنید وضعیت بهتر میشه...نهایتا بعد از یکی دو دقیقه (تازه اونم خیلی زیاده) باید به ست پوینت برسید...

                                میگردم ببینم پروژه کارشناسیمو اگه پیدا کردم نتیجشو میذارم اینجا...اونم خروجی از یه سیستم حرارتی واقعی گرفته بشده....با المنت 750 وات و فن...
                                اره یک ساعت البته تا 1ساعت ocr ثابت شد و دما رو 35 درجه واستاد ...
                                پدیت در 20 ثانیه :

                                #اینکه همیشه یه خطای حالت ماندگار دارید به خاطر کم بودن تاثیر انتگرالگیره...ضریبشو بیشتر کنید...
                                - مگه برای بدست آوردن Kc و Pc اول نباید فقط Kp داشته باشیم و Ki Kd صفر باشن ؟ چطور ضریبو ببرم بالا وقتی قراره صفر باشه ؟

                                کد من همون کدی بود که آقای طراح(مهندس کی نژاد)از خود اتمل (AVR221) گذاشته بودند توی پست های قبل بود...این کد یه مقدار - و + رو با timeinterval 5 میلی ثانیه میداد که من فقط خروجی pid رو OCR+= کردم و تاخیرو رو 20 ثانیه بردم (شکل بالا)

                                من واسه همین گیج شدم یکم . همش مشکلم یه این += هست و با اینکه اگه قراره مستقیم خروجی pid بریزم توی ocr در حالی که من اصلا مقدار انتگرال گیر و مشتق گیر و میخوام 0 برازم برای بدست آوردن ضرایب....چون اینجوری اصلا قدرت هیترم بالا نمیره ...روی یه عدد ثابت میمونه...نمیدونم تونسم منظورو برسونم یا نه...
                                #در ضمن یک ساعت؟؟؟؟؟؟؟؟؟؟؟....نهایتا باید بعد یکی دو دقیقه به ست پوینت برسید...
                                اگه timeinterval همون 5 میلی ثانیه یا 200 میلی باشه دما سریع توی 2 دقیقه overshoot میکنه ...(البته تو دماهای پایین)
                                مثل این : پدیت در 200میلی ثانیه


                                هردو هم OCR+= بودن

                                #شما ضریب انتگرالگیر رو بیشتر کنید وضعیت بهتر میشه...نهایتا بعد از یکی دو دقیقه (تازه اونم خیلی زیاده) باید به ست پوینت برسید...
                                -با فرض اینکه من مقدار pid رو مستقیم بریزم توی ocr و با برداشتی که من کردم اگه ضرایب رو با سعی و خطا بدست بیاریم دیگه ؟

                                باز هم نتیجه کارو تا شب میزارم...سعی میکنم به یه جایی برسم.
                                باز هم ممنون :job:

                                دیدگاه

                                لطفا صبر کنید...
                                X