اطلاعیه

Collapse
No announcement yet.

کنترل دما با ds18b20 به صورت pid با آردوینو

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

    #31
    پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

    نوشته اصلی توسط abbasjavanmardi نمایش پست ها
    همش 7400 هست
    خوب انتظار دارید هیتر گرم بشه؟ این نشون میده که مقدار متغیر PID صفر است و تغییر نمیکند.

    دیدگاه


      #32
      پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

      نوشته اصلی توسط evergreen نمایش پست ها
      خوب انتظار دارید هیتر گرم بشه؟ این نشون میده که مقدار متغیر PID صفر است و تغییر نمیکند.
      پس مشکل چی هست؟من اصلا سر در نمیارم

      دیدگاه


        #33
        پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

        نوشته اصلی توسط abbasjavanmardi نمایش پست ها
        پس مشکل چی هست؟من اصلا سر در نمیارم
        باید با فرستادن مقادیر متغیرهای بخشهای ابتدایی Loop که مقدار PID را محاسبه میکند به خروجی سریال، متوجه شوید که چرا مقدار متغیر PID صفر باقی میماند و تغییر نمیکند.

        دیدگاه


          #34
          پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

          نوشته اصلی توسط evergreen نمایش پست ها
          باید با فرستادن مقادیر متغیرهای بخشهای ابتدایی Loop که مقدار PID را محاسبه میکند به خروجی سریال، متوجه شوید که چرا مقدار متغیر PID صفر باقی میماند و تغییر نمیکند.
          این کد تو ویدیویی ک سایت قرار داده درست کار میکنه من هم فقط چیزاییو حذف کردم ک تو محاسبات pid تاثیری نداشته تو قرائت دمای سنسور هم ک مشکلی نداریم نمیدونم چرا اینقدر مشکل پیچیده شده؟

          دیدگاه


            #35
            پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

            نوشته اصلی توسط abbasjavanmardi نمایش پست ها
            این کد تو ویدیویی ک سایت قرار داده درست کار میکنه من هم فقط چیزاییو حذف کردم ک تو محاسبات pid تاثیری نداشته تو قرائت دمای سنسور هم ک مشکلی نداریم نمیدونم چرا اینقدر مشکل پیچیده شده؟
            اون 7400 که خوندید مطمئنید مقدار (maximum_firing_delay - PID_value) را خواندید .

            دیدگاه


              #36
              پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

              نوشته اصلی توسط evergreen نمایش پست ها
              اون 7400 که خوندید مطمئنید مقدار (maximum_firing_delay - PID_value) را خواندید .
              نه اون maximum_firing_delay بود ک 7400 بود ولی maximum_firing_delay - PID_value برابر با 0 هست و بعد دو سه دیقه به 7400 تغییر میکنه و تغییر بین 0 و 7400 ادامه داره اینم بگم تو این نیم ساعت هیتر 4 درجه گرمتر شده
              کد:
              
              #include <OneWire.h>
              #include <DallasTemperature.h>
              #define ONE_WIRE_BUS 2
              OneWire oneWire(ONE_WIRE_BUS);
              DallasTemperature sensors(&oneWire);
              
              
              //Inputs and outputs
              int firing_pin = 3;
              int increase_pin = 11;
              int decrease_pin = 12;
              int zero_cross = 8;
              
              
              //Variables
              int last_CH1_state = 0;
              bool zero_cross_detected = false;
              int firing_delay = 7400;
              
              
              //////////////////////////////////////////////////////
              int maximum_firing_delay = 7400;
              /*Later in the code you will se that the maximum delay after the zero detection
               * is 7400. Why? Well, we know that the 220V AC voltage has a frequency of around 50-60HZ so
               * the period is between 20ms and 16ms, depending on the country. We control the firing
               * delay each half period so each 10ms or 8 ms. To amke sure we wont pass thsoe 10ms, I've made tests
               * and the 7400us or 7.4ms was a good value. Measure your frequency and chande that value later */
              //////////////////////////////////////////////////////
              
              
              unsigned long previousMillis = 0; 
              unsigned long currentMillis = 0;
              int temp_read_Delay = 500;
              int real_temperature = 0;
              int setpoint = 60;
              bool pressed_1 = false;
              bool pressed_2 = false;
              
              
              //PID variables
              float PID_error = 0;
              float previous_error = 0;
              float elapsedTime, Time, timePrev;
              int PID_value = 0;
              //PID constants
              int kp = 203;   int ki= 7.2;   int kd = 1.04;
              int PID_p = 0;    int PID_i = 0;    int PID_d = 0;
              
              
              
              
              
              
              
              
              
              
              
              
              void setup() {
                //Define the pins
                pinMode (firing_pin,OUTPUT); 
                pinMode (zero_cross,INPUT); 
                pinMode (increase_pin,INPUT); 
                pinMode (decrease_pin,INPUT); 
                Serial.begin (9600);
                sensors.begin();  
                PCICR |= (1 << PCIE0);    //enable PCMSK0 scan                                                 
                PCMSK0 |= (1 << PCINT0);  //Set pin D8 (zero cross input) trigger an interrupt on state change.
                PCMSK0 |= (1 << PCINT3);  //Set pin D11 (increase button) trigger an interrupt on state change.
                PCMSK0 |= (1 << PCINT4);  //Set pin D12 (decrease button) trigger an interrupt on state change.  
              }
              
              
              
              
              void loop() { 
                  
                currentMillis = millis();           //Save the value of time before the loop
                 /*  We create this if so we will read the temperature and change values each "temp_read_Delay"
                  *  value. Change that value above iv you want. The MAX6675 read is slow. Tha will affect the
                  *  PID control. I've tried reading the temp each 100ms but it didn't work. With 500ms worked ok.*/
                if(currentMillis - previousMillis >= temp_read_Delay){
                  previousMillis += temp_read_Delay;              //Increase the previous time for next loop
                  sensors.requestTemperatures(); 
                  real_temperature = sensors.getTempCByIndex(0);  //get the real temperature in Celsius degrees
                  Serial.println(real_temperature);
                  Serial.println(PID_error);
                  Serial.println(setpoint);
                  Serial.println(maximum_firing_delay - PID_value);
                  PID_error = setpoint - real_temperature;        //Calculate the pid ERROR
                  
                  if(PID_error > 30)                              //integral constant will only affect errors below 30ºC             
                  {PID_i = 0;}
                  
                  PID_p = kp * PID_error;                         //Calculate the P value
                  PID_i = PID_i + (ki * PID_error);               //Calculate the I value
                  timePrev = Time;                    // the previous time is stored before the actual time read
                  Time = millis();                    // actual time read
                  elapsedTime = (Time - timePrev) / 1000;   
                  PID_d = kd*((PID_error - previous_error)/elapsedTime);  //Calculate the D value
                  PID_value = PID_p + PID_i + PID_d;                      //Calculate total PID value
              
              
                  //We define firing delay range between 0 and 7400. Read above why 7400!!!!!!!
                  if(PID_value < 0)
                  {      PID_value = 0;       }
                  if(PID_value > 7400)
                  {      PID_value = 7400;    }
              
              
                  previous_error = PID_error; //Remember to store the previous error.
                }
              
              
                //If the zero cross interruption was detected we create the 100us firing pulse  
                if (zero_cross_detected)     
                  {
                    delayMicroseconds(maximum_firing_delay - PID_value); //This delay controls the power
                    digitalWrite(firing_pin,HIGH);
                    delayMicroseconds(100);
                    digitalWrite(firing_pin,LOW);
                    zero_cross_detected = false;
                  } 
              }
              //End of void loop
              // |
              // |
              // |
              // v
              //See the interruption vector
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              //This is the interruption routine (pind D8(zero cross), D11(increase) and D12(decrease))
              //----------------------------------------------
              
              
              ISR(PCINT0_vect){
                ///////////////////////////////////////Input from optocoupler
                if(PINB & B00000001){            //We make an AND with the state register, We verify if pin D8 is HIGH???
                  if(last_CH1_state == 0){       //If the last state was 0, then we have a state change...
                    zero_cross_detected = true;  //We have detected a state change! We need both falling and rising edges
                  }
                }
                else if(last_CH1_state == 1){    //If pin 8 is LOW and the last state was HIGH then we have a state change      
                  zero_cross_detected = true;    //We haev detected a state change!  We need both falling and rising edges.
                  last_CH1_state = 0;            //Store the current state into the last state for the next loop
                  }
              
              
                  if(PINB & B00100000){          //We make an AND with the state register, We verify if pin D11 is HIGH???
                    if (!pressed_1)
                    {
                      setpoint = setpoint + 5;   //Increase the temperature by 5. Change this with your value if you want.
                      delay(20);
                      pressed_1 = true;
                    }
                  }
                  else if (pressed_1)
                  {
                    pressed_1 = false;
                  }
              
              
                  if(PINB & B00010000){          //We make an AND with the state register, We verify if pin D12 is HIGH???
                    if (!pressed_2)
                    {
                      setpoint = setpoint - 5;   //Decrease the temperature by 5. Change this with your value if you want.
                      delay(20);
                      pressed_2 = true;
                    }
                  }
                  else if (pressed_2)
                  {
                    pressed_2 = false;
                  }
              }
              //End of interruption vector for pins on port B: D8-D13
              دلیل: ادغام دو پست برای جلوگیری از اسپم

              دمای ستپوینت روی 60 هست و دمای هیتر 37 من هیتر رو دستی روشن کردم و وقتی به دمای 60 نزدیک شد مقدارmaximum_firing_delay - PID_value بزرگتر میشد تا وقتی ک به ستپوینت رسید و مقدارش به 7400 رسید و ثابت شد وقتی هیتر در حال سر شدن بود وقتی اومد زیر 60 این مقدار رو به کاهش گذاشت و وقتی دمای هیتر 10 درجه کمتر از ست پوینت بود مقدار maximum_firing_delay - PID_value صفر شد ولی همچنان هیتر رو به از دست دادن دما بود
              جدیدترین ویرایش توسط abbasjavanmardi; ۱۱:۳۹ ۱۴۰۰/۰۴/۲۵.

              دیدگاه


                #37
                پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                نه اون maximum_firing_delay بود ک 7400 بود ولی maximum_firing_delay - PID_value برابر با 0 هست و بعد دو سه دیقه به 7400 تغییر میکنه و تغییر بین 0 و 7400 ادامه داره اینم بگم تو این نیم ساعت هیتر 4 درجه گرمتر شده
                چیزی که بنظر میاد اینه که ضریب kp زیاده.

                دیدگاه


                  #38
                  پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                  نوشته اصلی توسط evergreen نمایش پست ها
                  چیزی که بنظر میاد اینه که ضریب kp زیاده.
                  اونم تغییر دادم تفاوتی نداره.داداش شمارو هم حسابی اذیت کردم
                  به نظرت با چکش یک کیلویی بزنم روش یا برم پتک بابامو قرض بگیرم؟

                  دیدگاه


                    #39
                    پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                    نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                    اونم تغییر دادم تفاوتی نداره.داداش شمارو هم حسابی اذیت کردم
                    به نظرت با چکش یک کیلویی بزنم روش یا برم پتک بابامو قرض بگیرم؟
                    مطمئن باش درست میشه. فقط من متوجه بخش آخر نوشته قبلیتان نشدم. گفتید دستی هیتر را روشن کردم . منظورتون چی بود؟
                    یه آزمایش دیگه هم انجام بدید. بجای( maximum_firing_delay - PID_value) عدد صفر قرار بدید و بجای هیتر یک لامپ رشته ایی بگذارید. باید لامپ با تمام توان روشن بشه. اگه نشد یعنی اینکه یه مشکلی هست. این آزمایش میتونه کمک مهمی در پیدا کردن مشکل انجام بده.
                    جدیدترین ویرایش توسط evergreen; ۱۲:۲۱ ۱۴۰۰/۰۴/۲۵.

                    دیدگاه


                      #40
                      پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                      نوشته اصلی توسط evergreen نمایش پست ها
                      مطمئن باش درست میشه. فقط من متوجه بخش آخر نوشته قبلیتان نشدم. گفتید دستی هیتر را روشن کردم . منظورتون چی بود؟
                      یه آزمایش دیگه هم انجام بدید. بجای( maximum_firing_delay - PID_value) عدد صفر قرار بدید و بجای هیتر یک لامپ رشته ایی بگذارید. باید لامپ با تمام توان روشن بشه. اگه نشد یعنی اینکه یه مشکلی هست. این آزمایش میتونه کمک مهمی در پیدا کردن مشکل انجام بده.
                      به جای تحریک 3021با پایه 3 اومدو به vcc وصلش گردم و هیتر گرم شد،
                      الانم ی لامپ 60 وات رشته ای به جای هیتر قرار دادم دقیقا لامپ 100میکروثانیه روشن میشه و خاموش میشه و کامل روشن نمیمونه
                      بجای( maximum_firing_delay - PID_value) عدد صفر قرار بدید---- چطوری؟
                      جدیدترین ویرایش توسط abbasjavanmardi; ۱۲:۵۷ ۱۴۰۰/۰۴/۲۵.

                      دیدگاه


                        #41
                        پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                        نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                        به جای تحریک 3021با پایه 3 اومدو به vcc وصلش گردم و هیتر گرم شد،
                        الانم ی لامپ 60 وات رشته ای به جای هیتر قرار دادم دقیقا لامپ 100میکروثانیه روشن میشه و خاموش میشه و کامل روشن نمیمونه
                        بجای( maximum_firing_delay - PID_value) عدد صفر قرار بدید---- چطوری؟
                        به جای delayMicroseconds(maximum_firing_delay - PID_value); بذارید delayMicroseconds(0) و با همون پایه 3 بگذارید فعال بشه;

                        دیدگاه


                          #42
                          پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                          نوشته اصلی توسط evergreen نمایش پست ها
                          به جای delayMicroseconds(maximum_firing_delay - PID_value); بذارید delayMicroseconds(0) و با همون پایه 3 بگذارید فعال بشه;
                          یبار چراغ با تمام قدرت روشن میشه بعد به حالت قبل برمیگرده

                          دیدگاه


                            #43
                            پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                            نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                            یبار چراغ با تمام قدرت روشن میشه بعد به حالت قبل برمیگرده
                            خوب همین نشون میده یک مشکلی هست. حالا در مرحله اول بجای صفر عدد بزرگتری مثلا 100 بگذارید. اگر لامپ روشن نماند در مرحله بعد پالس 100 میکرو ثانیه فعال ساز ترایاک را بزرگتر کنید مثلا بگذارید 200 میکروثانیه.

                            دیدگاه


                              #44
                              پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                              نوشته اصلی توسط evergreen نمایش پست ها
                              خوب همین نشون میده یک مشکلی هست. حالا در مرحله اول بجای صفر عدد بزرگتری مثلا 100 بگذارید. اگر لامپ روشن نماند در مرحله بعد پالس 100 میکرو ثانیه فعال ساز ترایاک را بزرگتر کنید مثلا بگذارید 200 میکروثانیه.
                              فرقی نداره

                              دیدگاه


                                #45
                                پاسخ : کنترل دما با ds18b20 به صورت pid با آردوینو

                                نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                                فرقی نداره
                                اپتوکوپلری که پایه 3 بهش وصل میشه چه شماره ایی است؟

                                دیدگاه

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