اطلاعیه

Collapse
No announcement yet.

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

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

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

    با سلام خدمت همه دوستان
    من تو سایت https://electronoobs.com/eng_arduino_tut39.php پروژه کنترلpid دمای هیتر220ولت توسط ترایاک وا آردوینو و سنسور نوع k رو دیدم، با توجه به راهنمایی دوستان کد پروژه رو برای قرائت دما از سنسور ds18b20 تغییر دادم البته چون نمایشگرم i2c نبود اون قسمت رو هم تغییر دادم و مدار رو برابر شکلhttps://electronoobs.com/images/Ardu...tic_AC_PID.png بستم.نتیجه این بود ک پایه pwm آردوینو هر 100میلی ثانیه خاموش و روشن میشد و با تغییرات ست پوینت هیچ عکس العملی نشون نمیداد.من کد اصلی و کدی ک تغییر دادم رو قرار میدم اگه ممکنه بفرمایید مشکل از کجاس؟
    کد اصلی
    کد:
    /*    Max6675 Module  ==>   Arduino
     *    CS              ==>     D10
     *    SO              ==>     D9
     *    SCK             ==>     D13
     *    Vcc             ==>     Vcc (5v)
     *    Gnd             ==>     Gnd      */
    
    
    //LCD config
    #include "max6675.h"
    #include <Wire.h> 
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27,20,4);  //sometimes the adress is not 0x27. Change to 0x3f if it dosn't work.
    
    
    /*    i2c LCD Module  ==>   Arduino
     *    SCL             ==>     A5
     *    SDA             ==>     A4
     *    Vcc             ==>     Vcc (5v)
     *    Gnd             ==>     Gnd      */
    
    
    //Inputs and outputs
    int firing_pin = 3;
    int increase_pin = 11;
    int decrease_pin = 12;
    int zero_cross = 8;
    int thermoDO = 9;
    int thermoCS = 10;
    int thermoCLK = 13;
    
    
    //Start a MAX6675 communication with the selected pins
    MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
    
    
    
    
    //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 = 100;
    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);   
      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.    
      lcd.init();       //Start the LC communication
      lcd.backlight();  //Turn on backlight for LCD
    }
    
    
    
    
    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
        real_temperature = thermocouple.readCelsius();  //get the real temperature in Celsius degrees
    
    
        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;    }
        //Printe the values on the LCD
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Set: ");
        lcd.setCursor(5,0);
        lcd.print(setpoint);
        lcd.setCursor(0,1);
        lcd.print("Real temp: ");
        lcd.setCursor(11,1);
        lcd.print(real_temperature);
        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 & B00001000){          //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
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    [FONT=Yekan][/FONT]
    کدی ک من تغیر دادم
    کد:
    /*    Max6675 Module  ==>   Arduino
     *    CS              ==>     D10
     *    SO              ==>     D9
     *    SCK             ==>     D13
     *    Vcc             ==>     Vcc (5v)
     *    Gnd             ==>     Gnd      */
    
    
    //LCD config
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <LiquidCrystal.h>
    #define ONE_WIRE_BUS 2
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
    
    
      //sometimes the adress is not 0x27. Change to 0x3f if it dosn't work.
    
    
    
    
    //Inputs and outputs
    int firing_pin = 3;
    int increase_pin = 13;
    int decrease_pin = 12;
    int zero_cross = 11;
    
    
    
    
    //Start a MAX6675 communication with the selected pins
    
    
    
    
    
    
    //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.    
      lcd.begin(16, 2);   //Turn on backlight for LCD
    
    
    }
    
    
    
    
    void loop() { 
      sensors.requestTemperatures();     
      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
        real_temperature = sensors.getTempCByIndex(0);  //get the real temperature in Celsius degrees
        Serial.println(real_temperature);
        Serial.println(PID_error);
        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;    }
        //Printe the values on the LCD
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Set: ");
        lcd.setCursor(5,0);
        lcd.print(setpoint);
        lcd.setCursor(0,1);
        lcd.print("Real temp: ");
        lcd.setCursor(11,1);
        lcd.print(real_temperature);
        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 & B00001000){          //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
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    [FONT=Yekan][/FONT]

    دیدگاه


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

      نوشته اصلی توسط abbasjavanmardi نمایش پست ها
      با سلام خدمت همه دوستان
      من تو سایت https://electronoobs.com/eng_arduino_tut39.php پروژه کنترلpid دمای هیتر220ولت توسط ترایاک وا آردوینو و سنسور نوع k رو دیدم، با توجه به راهنمایی دوستان کد پروژه رو برای قرائت دما از سنسور ds18b20 تغییر دادم البته چون نمایشگرم i2c نبود اون قسمت رو هم تغییر دادم و مدار رو برابر شکلhttps://electronoobs.com/images/Ardu...tic_AC_PID.png بستم.نتیجه این بود ک پایه pwm آردوینو هر 100میلی ثانیه خاموش و روشن میشد و با تغییرات ست پوینت هیچ عکس العملی نشون نمیداد.من کد اصلی و کدی ک تغییر دادم رو قرار میدم اگه ممکنه بفرمایید مشکل از کجاس؟
      کد اصلی

      کدی ک من تغیر دادم
      با سلام
      شما شماره پایه های
      D8(zero cross), D11(increase) and D12(decrease) را نسبت به کد اصلی تغییر داده اید ولی در قسمتی که اینتراپت متناظر با پایه توسط دستور PCMSKx باید فعال بشه، اینتراپت متناسب با پایه های تغییر یافته را فعال نکرده اید. پس از تصحیح قسمت قبل باید قسمت ISR هم متناسب با پایه های جدیدی که تعریف کردید اصلاح کنید.
      جدیدترین ویرایش توسط evergreen; ۱۷:۴۹ ۱۴۰۰/۰۴/۲۴.

      دیدگاه


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

        نوشته اصلی توسط evergreen نمایش پست ها
        با سلام
        شما شماره پایه های
        D8(zero cross), D11(increase) and D12(decrease) را نسبت به کد اصلی تغییر داده اید ولی در قسمتی که اینتراپت متناظر با پایه توسط دستور PCMSKx باید فعال بشه، اینتراپت متناسب با پایه های تغییر یافته را فعال نکرده اید. پس از تصحیح قسمت قبل باید قسمت ISR هم متناسب با پایه های جدیدی که تعریف کردید اصلاح کنید.
        من هرچی نگاه میکنم متوجهش نمیشم وقتی تو قسمت int شماره پایه هارو عوض کردیم دیگه کل برنامه با استفاده از اسم پینها رجوع میکنن به پین دیگه
        میشه خواهش کنم تغییرش رو با توجه به پایه هایی ک معرفی کردم اعمال بفرمایید؟

        دیدگاه


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

          نوشته اصلی توسط abbasjavanmardi نمایش پست ها
          من هرچی نگاه میکنم متوجهش نمیشم وقتی تو قسمت int شماره پایه هارو عوض کردیم دیگه کل برنامه با استفاده از اسم پینها رجوع میکنن به پین دیگه
          میشه خواهش کنم تغییرش رو با توجه به پایه هایی ک معرفی کردم اعمال بفرمایید؟
          بخش مربوط به PCMSK0 را در دیتا شیت مطالعه بفرمایید. قسمت زیر با توجه به پایه ها باید اصلاح شود.
          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.

          دیدگاه


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

            نوشته اصلی توسط evergreen نمایش پست ها
            بخش مربوط به PCMSK0 را در دیتا شیت مطالعه بفرمایید. قسمت زیر با توجه به پایه ها باید اصلاح شود.
            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.
            سلام من بخشی ک معرفی کردید رو با توجه به پین اوت بورد اونو به شکل زیر تغییر دادم تو قسمت isr هم نیاز به تغییر داره؟
            PCMSK0 |= (1 << PCINT3); //Set pin D11 (zero cross input) trigger an interrupt on state change.
            PCMSK0 |= (1 << PCINT5); //Set pin D13 (increase button) trigger an interrupt on state change.
            PCMSK0 |= (1 << PCINT4); //Set pin D12 (decrease button) trigger an interrupt on state change.

            دیدگاه


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

              نوشته اصلی توسط abbasjavanmardi نمایش پست ها
              من هرچی نگاه میکنم متوجهش نمیشم وقتی تو قسمت int شماره پایه هارو عوض کردیم دیگه کل برنامه با استفاده از اسم پینها رجوع میکنن به پین دیگه
              میشه خواهش کنم تغییرش رو با توجه به پایه هایی ک معرفی کردم اعمال بفرمایید؟
              این را تست کنید

              کد:
              //LCD config
              #include <OneWire.h>
              #include <DallasTemperature.h>
              #include <LiquidCrystal.h>
              #define ONE_WIRE_BUS 2
              OneWire oneWire(ONE_WIRE_BUS);
              DallasTemperature sensors(&oneWire);
              LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
              
              
              //Inputs and outputs
              int firing_pin = 3;
              int increase_pin = 13;
              int decrease_pin = 12;
              int zero_cross = 11;
              
              
              
              
              //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 << PCINT3);  //Set pin D11 (zero cross input) trigger an interrupt on state change.
                PCMSK0 |= (1 << PCINT5);  //Set pin D13 (increase button) trigger an interrupt on state change.
                PCMSK0 |= (1 << PCINT4);  //Set pin D12 (decrease button) trigger an interrupt on state change.    
                lcd.begin(16, 2);   //Turn on backlight for LCD
              
              
              
              
              }
              
              
              
              
              
              
              
              
              void loop() { 
                sensors.requestTemperatures();     
                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
                  real_temperature = sensors.getTempCByIndex(0);  //get the real temperature in Celsius degrees
                  Serial.println(real_temperature);
                  Serial.println(PID_error);
                  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;    }
                  //Printe the values on the LCD
                  lcd.clear();
                  lcd.setCursor(0,0);
                  lcd.print("Set: ");
                  lcd.setCursor(5,0);
                  lcd.print(setpoint);
                  lcd.setCursor(0,1);
                  lcd.print("Real temp: ");
                  lcd.setCursor(11,1);
                  lcd.print(real_temperature);
                  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 D11(zero cross), D13(increase) and D12(decrease))
              //----------------------------------------------
              
              
              
              
              ISR(PCINT0_vect){
                ///////////////////////////////////////Input from optocoupler
                if(PINB & B00001000){            //We make an AND with the state register, We verify if pin D11 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 D13 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
              جدیدترین ویرایش توسط evergreen; ۲۰:۱۷ ۱۴۰۰/۰۴/۲۴.

              دیدگاه


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

                نوشته اصلی توسط evergreen نمایش پست ها
                این را تست کنید

                کد:
                //LCD config
                #include <OneWire.h>
                #include <DallasTemperature.h>
                #include <LiquidCrystal.h>
                #define ONE_WIRE_BUS 2
                OneWire oneWire(ONE_WIRE_BUS);
                DallasTemperature sensors(&oneWire);
                LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
                
                
                //Inputs and outputs
                int firing_pin = 3;
                int increase_pin = 13;
                int decrease_pin = 12;
                int zero_cross = 11;
                
                
                
                
                //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 << PCINT3);  //Set pin D11 (zero cross input) trigger an interrupt on state change.
                  PCMSK0 |= (1 << PCINT5);  //Set pin D13 (increase button) trigger an interrupt on state change.
                  PCMSK0 |= (1 << PCINT4);  //Set pin D12 (decrease button) trigger an interrupt on state change.    
                  lcd.begin(16, 2);   //Turn on backlight for LCD
                
                
                
                
                }
                
                
                
                
                
                
                
                
                void loop() { 
                  sensors.requestTemperatures();     
                  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
                    real_temperature = sensors.getTempCByIndex(0);  //get the real temperature in Celsius degrees
                    Serial.println(real_temperature);
                    Serial.println(PID_error);
                    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;    }
                    //Printe the values on the LCD
                    lcd.clear();
                    lcd.setCursor(0,0);
                    lcd.print("Set: ");
                    lcd.setCursor(5,0);
                    lcd.print(setpoint);
                    lcd.setCursor(0,1);
                    lcd.print("Real temp: ");
                    lcd.setCursor(11,1);
                    lcd.print(real_temperature);
                    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 D11(zero cross), D13(increase) and D12(decrease))
                //----------------------------------------------
                
                
                
                
                ISR(PCINT3_vect){
                  ///////////////////////////////////////Input from optocoupler
                  if(PINB & B00001000){            //We make an AND with the state register, We verify if pin D11 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 D13 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
                اتفاقا داشتم تو قسمت isr کدهای باینری رو تغییر میدادم تو کد اصلی واسه پایه های 11 و 12 بود دنبال 13 میگشتم ک دیدم شما قرار دادین ولی کد شمارو کامپایل کردم به محض فشردن کلید ها lcd خاموش میشد

                دیدگاه


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

                  نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                  اتفاقا داشتم تو قسمت isr کدهای باینری رو تغییر میدادم تو کد اصلی واسه پایه های 11 و 12 بود دنبال 13 میگشتم ک دیدم شما قرار دادین ولی کد شمارو کامپایل کردم به محض فشردن کلید ها lcd خاموش میشد
                  یک اشتباه تایپی داشت اصلاحش کردم. دوباره یه تست کنید.
                  جدیدترین ویرایش توسط evergreen; ۲۰:۳۰ ۱۴۰۰/۰۴/۲۴.

                  دیدگاه


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

                    نوشته اصلی توسط evergreen نمایش پست ها
                    یک اشتباه تایپی داشت اصلاحش کردم. دوباره یه تست کنید.
                    فرقی نکرد با قبلش،
                    من از شیلد 16*2 استفاده میکردم و تعداد کمی پایه ار آردوینو برای بقیه قسمتها میموند.شیلد رو حذف کردم تا دقیقا مثل کد اصلی و از همون پایه هایی ک تو سایت ازش استفاده کرده استفاده کردم و مقدار دما و ست پوینت رو تو سریال مانیتور خوندم ولی پایه 3 اصلا واکنشی نشون نمیده و مثل قبل هر 100 میکروثانیه صفرو یک میشه
                    کد:
                    /*    Max6675 Module  ==>   Arduino
                     *    CS              ==>     D10
                     *    SO              ==>     D9
                     *    SCK             ==>     D13
                     *    Vcc             ==>     Vcc (5v)
                     *    Gnd             ==>     Gnd      */
                    
                    
                    //LCD config
                    #include <OneWire.h>
                    #include <DallasTemperature.h>
                    
                    
                    #define ONE_WIRE_BUS 2
                    OneWire oneWire(ONE_WIRE_BUS);
                    DallasTemperature sensors(&oneWire);
                    
                    
                    
                    
                      //sometimes the adress is not 0x27. Change to 0x3f if it dosn't work.
                    
                    
                    
                    
                    //Inputs and outputs
                    int firing_pin = 3;
                    int increase_pin = 11;
                    int decrease_pin = 12;
                    int zero_cross = 8;
                    
                    
                    
                    
                    //Start a MAX6675 communication with the selected pins
                    
                    
                    
                    
                    
                    
                    //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() { 
                      sensors.requestTemperatures();     
                      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
                        real_temperature = sensors.getTempCByIndex(0);  //get the real temperature in Celsius degrees
                        Serial.println(real_temperature);
                        Serial.println(PID_error);
                        Serial.println(setpoint);
                        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;    }
                        //Printe the values on the LCD
                    
                    
                        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
                    جدیدترین ویرایش توسط abbasjavanmardi; ۲۳:۰۲ ۱۴۰۰/۰۴/۲۴.

                    دیدگاه


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

                      نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                      فرقی نکرد با قبلش،
                      من از شیلد 16*2 استفاده میکردم و تعداد کمی پایه ار آردوینو برای بقیه قسمتها میموند.شیلد رو حذف کردم تا دقیقا مثل کد اصلی و از همون پایه هایی ک تو سایت ازش استفاده کرده استفاده کردم و مقدار دما و ست پوینت رو تو سریال مانیتور خوندم ولی پایه 3 اصلا واکنشی نشون نمیده و مثل قبل هر 100 میکروثانیه صفرو یک میشه
                      با سلام مجدد
                      آیا شما مدار رابسته اید و به هیتر وصل است؟
                      پایه 3 بر اساس برنامه کارش راه اندازی ترایاک در زمان لازم بر اساس زمان عبور از صفر و مقدار کنترلر PID هست. اون پالس 100 میکرو ثانیه را هم به همین منظور ارسال میکند.
                      جدیدترین ویرایش توسط evergreen; ۲۳:۴۳ ۱۴۰۰/۰۴/۲۴.

                      دیدگاه


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

                        نوشته اصلی توسط evergreen نمایش پست ها
                        با سلام مجدد
                        آیا شما مدار رابسته اید و به هیتر وصل است؟
                        پایه 3 بر اساس برنامه کارش راه اندازی ترایاک در زمان لازم بر اساس زمان عبور از صفر و مقدار کنترلر PID هست. اون پالس 100 میکرو ثانیه را هم به همین منظور ارسال میکند.
                        سلام
                        بله مدار کامل هست حتی خروجی اپتو ۸۱۷ هم چک کردم ک درست بود،به اپتو ۳۰۲۱ هم ۵ ولت دادم و ترایاک مدار رو وصل کرد و هیتر گرم شد فقط من موندم چرا این مدار از اختلاف دمایی خیلی بالا با ستپوینت روی پایه ۳ همش خروجی ۱۰۰ میکروثانیه میده معمولا اولش باید مقدار گرم شدن زیاد باشه به محض نزدیک شدن به نقطه دتنظیم شده خکمتر هیتر رو روشن کنه ، با ۱۰۰ میکرو ثانیه هیتر اصلا نمیتونه گرم بشه

                        دیدگاه


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

                          نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                          سلام
                          بله مدار کامل هست حتی خروجی اپتو ۸۱۷ هم چک کردم ک درست بود،به اپتو ۳۰۲۱ هم ۵ ولت دادم و ترایاک مدار رو وصل کرد و هیتر گرم شد فقط من موندم چرا این مدار از اختلاف دمایی خیلی بالا با ستپوینت روی پایه ۳ همش خروجی ۱۰۰ میکروثانیه میده معمولا اولش باید مقدار گرم شدن زیاد باشه به محض نزدیک شدن به نقطه دتنظیم شده خکمتر هیتر رو روشن کنه ، با ۱۰۰ میکرو ثانیه هیتر اصلا نمیتونه گرم بشه
                          با سلام مجدد
                          همونطور که در پست قبل هم گفتم پایه 3 کلا کارش اینه که پالس 100 میکرو ثانیه بده برای راه اندازی ترایاک. شما هیچ پالس دیگه ایی از این پایه نخواهید دید ولی توجه کنید که زمان ارسال این پالس 100 میکرو ثانیه مهم است که آن هم در بخش زیر میبینید. در صورتیکه عبور از صفر تشخیص داده شد بر اساس delay خط اول زمان ارسال پالس و فعال شدن ترایاک کنترل میشود که نتیجه آن کنترل توان هیتر خواهد بود. توجه کنید که این بخش از برنامه پس از هر بار عبور ولتاژ 220 ولت سینوسی از صفر (چه در جهت پایین و چه در جهت بالا) باید تکرار شود پس در هر پریود ولتاژ دو بار این خروجی فعال میشود.

                          کد:
                            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;
                              }
                          اشتباه شما اینه که فکر میکنید ترایاک فقط در طی پالس 100 میکرو ثانیه روشن میباشد در صورتیکه اینطور نیست. تریاک با دریافت پالس 100 میکرو ثانیه روشن میشود و روشن باقی میماند تا اینکه ولتاژ دو سر اون معکوس بشه. در تصویر زیر که مربوط به همون سایت برنامه هیتر هست میتونید پالس 100 میکرو ثانیه و ولتاژ خروجی رو همزمان ببینید.

                          جدیدترین ویرایش توسط evergreen; ۱۰:۳۶ ۱۴۰۰/۰۴/۲۵.

                          دیدگاه


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

                            نوشته اصلی توسط evergreen نمایش پست ها
                            اشتباه شما اینه که فکر میکنید ترایاک فقط در طی پالس 100 میکرو ثانیه روشن میباشد در صورتیکه اینطور نیست. تریاک با دریافت پالس 100 میکرو ثانیه روشن میشود و روشن باقی میماند تا اینکه ولتاژ دو سر اون معکوس بشه. در تصویر زیر که مربوط به همون سایت برنامه هیتر هست میتونید پالس 100 میکرو ثانیه و ولتاژ خروجی رو همزمان ببینید.
                            با این حساب چرا وقتی ولتاژ 5 به اپتو 3021 میدیم هیتر گرم میشه ولی وقتی از پایه 3 ولتاژ میگیره هیچ تغییری تو دما نمیبینیم؟درواقع خروجی تمام محاسبات ما در قالب پین 3 به قسمت کنترل کننده 220ولت ظاهر میشه بنابر این وقتی پین 3 داره درست کار میکنه ما باید شاهد گرم شدن هیتر باشیم ک عملا اینطور نیست
                            جدیدترین ویرایش توسط abbasjavanmardi; ۱۰:۴۵ ۱۴۰۰/۰۴/۲۵.

                            دیدگاه


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

                              نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                              با این حساب چرا وقتی ولتاژ 5 به اپتو 3021 میدیم هیتر گرم میشه ولی وقتی از پایه 3 ولتاژ میگیره هیچ تغییری تو دما نمیبینیم؟درواقع خروجی تمام محاسبات ما در قالب پین 3 به قسمت کنترل کننده 220ولت ظاهر میشه بنابر این وقتی پین 3 داره درست کار میکنه ما باید شاهد گرم شدن هیتر باشیم ک عملا اینطور نیست
                              مقدار maximum_firing_delay - PID_value که زمان تاخیر روشن شدن ترایاک پس از عبور از صفر در همون تکه کد بالا است رو توسط سریال بخونید. شاید اینقدر دیر فرمان استارت تریاک صادر میشه که ولتاژ خروجی پایینه.
                              جدیدترین ویرایش توسط evergreen; ۱۱:۲۱ ۱۴۰۰/۰۴/۲۵.

                              دیدگاه


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

                                نوشته اصلی توسط evergreen نمایش پست ها
                                مقدار maximum_firing_delay - PID که زمان تاخیر روشن شدن ترایاک پس از عبور از صفر در همون تکه کد بالا است رو توسط سریال بخونید. شاید اینقدر دیر فرمان استارت تریاک صادر میشه که ولتاژ خروجی پایینه.
                                همش 7400 هست

                                دیدگاه

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