اطلاعیه

Collapse
No announcement yet.

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

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

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

    نوشته اصلی توسط evergreen نمایش پست ها
    اپتوکوپلری که پایه 3 بهش وصل میشه چه شماره ایی است؟
    اپتو 3021 -پین 3 به پایه یک اپتو وصل میشه با ی مقاومت100اهم

    دیدگاه


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

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

      دیدگاه


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

        نوشته اصلی توسط evergreen نمایش پست ها
        با سلام مجدد
        اگر همه شرایط سخت افزار و نرم افزار درست باشد این مشکل روشن نشدن لامپ تنها میتواند بدلیل درست عمل نکردن مدار عبور از صفر باشد شاید اختلاف بیش از حدی است که انتظار داریم. یعنی برد آردویینو زودتر از زمان عبور از صفر آنرا تشخیص میدهد و باعث میشود ترایاک خیلی سریع خاموش شود. زمان هر نیم پریود برق 50 هرتز 10 میلی ثانیه است. اینبار اگر فرصت کردید بجای delayMicroseconds(maximum_firing_delay - PID_value) در حالتیکه لامپ وصل است اعداد بزرگتر حتی تا 1 میلی ثانیه را امتحان کنید یعنی بجای آن delayMicroseconds(1000) بگذارید تا معلوم شود بالاخره لامپ روشن میشود یا نه؟
        سلام مجدد
        من اون مقادیر رو عوض کردم ولی پیرو فرمایش شما مشکل نقطه صفر رو کنترل کردم دیدم اصلا سیمشو قطع میکنم هیچ اتفاقی نمی افته(ولی خروجی اپتو 817 دقیقا 5 ولت هست یعنی اپتو 817 داره از پل دیود برق میگیره و سالمه) در حالی ک تشخیص نقطه صفر برای پروژه حیاتیه(یعنی ممکنه مربوط به قسمت خوندن نقطه صفر باشه).فقط من به جای el817 از pc817 استفاده کردم.و پل دیودم هم این(https://eshop.eca.ir/%D9%BE%D9%84-%D...%AF&results=65) هست. اینم بگم ک دکمه افزایش ست پوینت روی پایه 12 فرمان نمیگیره جای کلیدارو عوض کردم جفت کلید ها روی پایه 11 فرمان کاهش دما رو انجام میدن ولی روی پین 12 هیچ افزایشی انجام نمیشه.جالبتر پرش ناگهانی مقادیر ستپوینت هست یهو فضایی جابه جا میشه
        من الان کد اصلی رو بدون تغییر روی آردوینو کامپایل کردم دیدم کلید های افزایش و کاهش درست کار میکنه و لامپ با تمام قدرت روشنه ولی دقیقا روی نقطه صفر یا همون 7400میکروثانیه خاموش و روشن میشه.مدار pc817 رو کنترل کردم و با قطع کردن زیرو کراس چراغ پرپر زد و با وصل کردنش به آردیونو دوباره به حالت چشمک زنش برگشت دقیقا از زمانی ک میایم برای real_temperature مقدار خوانده شده از سنسور ds18b20 رو قرار میدیم کل مجموعه به هم میریزههرچی هست زیر سر خروجی این سنسوره
        جدیدترین ویرایش توسط abbasjavanmardi; ۲۳:۰۰ ۱۴۰۰/۰۴/۲۵.

        دیدگاه


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

          نوشته اصلی توسط abbasjavanmardi نمایش پست ها
          سلام مجدد
          من اون مقادیر رو عوض کردم ولی پیرو فرمایش شما مشکل نقطه صفر رو کنترل کردم دیدم اصلا سیمشو قطع میکنم هیچ اتفاقی نمی افته(ولی خروجی اپتو 817 دقیقا 5 ولت هست یعنی اپتو 817 داره از پل دیود برق میگیره و سالمه) در حالی ک تشخیص نقطه صفر برای پروژه حیاتیه(یعنی ممکنه مربوط به قسمت خوندن نقطه صفر باشه).فقط من به جای el817 از pc817 استفاده کردم.و پل دیودم هم این(https://eshop.eca.ir/%D9%BE%D9%84-%D...%AF&results=65) هست. اینم بگم ک دکمه افزایش ست پوینت روی پایه 12 فرمان نمیگیره جای کلیدارو عوض کردم جفت کلید ها روی پایه 11 فرمان کاهش دما رو انجام میدن ولی روی پین 12 هیچ افزایشی انجام نمیشه.جالبتر پرش ناگهانی مقادیر ستپوینت هست یهو فضایی جابه جا میشه
          من الان کد اصلی رو بدون تغییر روی آردوینو کامپایل کردم دیدم کلید های افزایش و کاهش درست کار میکنه و لامپ با تمام قدرت روشنه ولی دقیقا روی نقطه صفر یا همون 7400میکروثانیه خاموش و روشن میشه.مدار pc817 رو کنترل کردم و با قطع کردن زیرو کراس چراغ پرپر زد و با وصل کردنش به آردیونو دوباره به حالت چشمک زنش برگشت دقیقا از زمانی ک میایم برای real_temperature مقدار خوانده شده از سنسور ds18b20 رو قرار میدیم کل مجموعه به هم میریزههرچی هست زیر سر خروجی این سنسوره
          با سلام
          ممکنه سنسور دما هم از اینتراپت استفاده میکنه و باعث تداخلی بین اینتراپتها میشه

          دیدگاه


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

            نوشته اصلی توسط evergreen نمایش پست ها
            با سلام
            ممکنه سنسور دما هم از اینتراپت استفاده میکنه و باعث تداخلی بین اینتراپتها میشه
            سلام
            من به جای سنسور ds18b20 از سنسور lm35 استفاده کردم و کنترل pid دقیق کار کرد ولی به خاطر دقت و پرش زیاد سنسور lm35 یکم دقت pid پایین میاد.از کجا بفهمیم به محض اضافه شدن کد ds18b20 چه مشکلی برای برنامه ایجاد میکنه؟و چطوری رفعش کنیم؟

            دیدگاه


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

              نوشته اصلی توسط abbasjavanmardi نمایش پست ها
              سلام
              من به جای سنسور ds18b20 از سنسور lm35 استفاده کردم و کنترل pid دقیق کار کرد ولی به خاطر دقت و پرش زیاد سنسور lm35 یکم دقت pid پایین میاد.از کجا بفهمیم به محض اضافه شدن کد ds18b20 چه مشکلی برای برنامه ایجاد میکنه؟و چطوری رفعش کنیم؟
              با سلام مجدد
              پایه دیتای سنسور دما را بجای D2 به D5 وصل نمایید و تغییر پایه را در برنامه اعمال کنید. سپس تست کنید ببینید آیا شرایط بهتر نمیشود؟

              دیدگاه


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

                سلام دوستان
                بعد ی وقفه شش ماهه من بجای سنسور ds18b20 یه سنسور sht11 توپروژه قرار دادم.الان با برنامه ای ک دارم دما با اختلاف دو دهم درجه حول ست پوینت در نوسان هست.الان مونده تنظیم ظرایب pid که تنظیم بشه.کسی میتونه کمکم کنه چطوری میتونم به شکل تجربی تنظیمشون کنم؟
                کد:
                #include <SHT1x.h>
                #include <SPI.h>
                #include <Wire.h>
                #include <Adafruit_GFX.h>
                #include <Adafruit_SSD1306.h>
                #include <PIDController.h>
                // SHT1x Pins
                #define dataPin  7
                #define clo 6
                SHT1x sht1x(dataPin, clo);
                // Define Rotary Encoder Pins
                #define CLK_PIN 3
                #define DATA_PIN 4
                #define SW_PIN 2
                // Mosfet Pin
                #define mosfet_pin 11
                // Serial Enable
                #define __DEBUG__
                #define SCREEN_WIDTH 128 // OLED display width, in pixels
                #define SCREEN_HEIGHT 64 // OLED display height, in pixels
                #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
                /*In this section we have defined the gain values for the 
                 * proportional, integral, and derivative controller I have set
                 * the gain values with the help of trial and error methods.
                */ 
                #define __Kp 100 // Proportional constant
                #define __Ki 4 // Integral Constant
                #define __Kd 2 // Derivative Constant
                int clockPin; // Placeholder por pin status used by the rotary encoder
                int clockPinState; // Placeholder por pin status used by the rotary encoder
                int set_temperature = 31; // This set_temperature value will increas or decreas if when the rotarty encoder is turned
                float temperature_value_c = 0.0; // stores temperature value
                long debounce = 0; // Debounce delay
                int encoder_btn_count = 0; // used to check encoder button press
                
                
                Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);// Create an instance for the SSD1306 128X64 OLED "display"
                PIDController pid; // Create an instance of the PID controller class, called "pid"
                void setup() {
                #ifdef __DEBUG__
                  Serial.begin(9600);
                #endif
                  pinMode(mosfet_pin, OUTPUT); // MOSFET output PIN
                  pinMode(CLK_PIN, INPUT); // Encoer Clock Pin
                  pinMode(DATA_PIN, INPUT); //Encoder Data Pin
                  pinMode(SW_PIN, INPUT_PULLUP);// Encoder SW Pin
                  pid.begin();          // initialize the PID instance
                  pid.setpoint(50);    // The "goal" the PID controller tries to "reach"
                  pid.tune(__Kp, __Ki,__Kd);    // Tune the PID, arguments: kP, kI, kD
                  pid.limit(0, 255);    // Limit the PID output between 0 and 255, this is important to get rid of integral windup!
                  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
                #ifdef __DEBUG__
                    Serial.println(F("SSD1306 allocation failed"));
                #endif
                    for (;;); // Don't proceed, loop forever
                  }
                  //
                  display.setRotation(2); //Rotate the Display
                  display.display(); //Show initial display buffer contents on the screen -- the library initializes this with an Adafruit splash screen.
                  display.clearDisplay(); // Cleear the Display
                  display.setTextSize(2); // Set text Size
                  display.setTextColor(WHITE); // set LCD Colour
                  display.setCursor(48, 0); // Set Cursor Position
                  display.println("PID"); // Print the this Text
                  display.setCursor(0, 20);  // Set Cursor Position
                  display.println("Temperatur"); // Print the this Text
                  display.setCursor(22, 40); // Set Cursor Position
                  display.println("Control"); // Print the this Text
                  display.display(); // Update the Display
                  delay(2000); // Delay of 200 ms
                }
                void set_temp()
                {
                  if (encoder_btn_count == 2) // check if the button is pressed twice and its in temperature set mode.
                  {
                    display.clearDisplay(); // clear the display
                    display.setTextSize(2); // Set text Size
                    display.setCursor(16, 0); // set the diplay cursor
                    display.print("Set Temp."); // Print Set Temp. on the display
                    display.setCursor(45, 25); // set the cursor
                    display.print(set_temperature);// print the set temperature value on the display
                    display.display(); // Update the Display
                  }
                }
                void read_encoder() // In this function we read the encoder data and increment the counter if its rotaing clockwise and decrement the counter if its rotating counter clockwis
                {
                  clockPin = digitalRead(CLK_PIN); // we read the clock pin of the rotary encoder
                  if (clockPin != clockPinState  && clockPin == 1) { // if this condition is true then the encoder is rotaing counter clockwise and we decremetn the counter
                    if (digitalRead(DATA_PIN) != clockPin) set_temperature = set_temperature - 3;  // decrmetn the counter.
                    else  set_temperature = set_temperature + 3; // Encoder is rotating CW so increment
                    if (set_temperature < 1 )set_temperature = 1; // if the counter value is less than 1 the set it back to 1
                    if (set_temperature > 150 ) set_temperature = 150; //if the counter value is grater than 150 then set it back to 150 
                #ifdef __DEBUG__
                    Serial.println(set_temperature); // print the set temperature value on the serial monitor window
                #endif
                  }
                  clockPinState = clockPin; // Remember last CLK_PIN state
                  
                  if ( digitalRead(SW_PIN) == LOW)   //If we detect LOW signal, button is pressed
                  {
                    if ( millis() - debounce > 80) { //debounce delay
                      encoder_btn_count++; // Increment the values 
                      if (encoder_btn_count > 2) encoder_btn_count = 1;
                #ifdef __DEBUG__
                      Serial.println(encoder_btn_count);
                #endif
                    }
                    debounce = millis(); // update the time variable
                  }
                }
                void loop()
                {
                  read_encoder(); //Call The Read Encoder Function
                  set_temp(); // Call the Set Temperature Function
                  if (encoder_btn_count == 1) // check if the button is pressed and its in Free Running Mode -- in this mode the arduino continiously updates the screen and adjusts the PWM output according to the temperature.
                  {
                    temperature_value_c = sht1x.readTemperatureC(); // Read the Temperature using the readCelsius methode from MAX6675 Library.
                    int output = pid.compute(temperature_value_c);    // Let the PID compute the value, returns the optimal output
                    analogWrite(mosfet_pin, output);           // Write the output to the output pin
                    pid.setpoint(set_temperature); // Use the setpoint methode of the PID library to
                    display.clearDisplay(); // Clear the display
                    display.setTextSize(2); // Set text Size
                    display.setCursor(16, 0); // Set the Display Cursor
                    display.print("Cur Temp."); //Print to the Display
                    display.setCursor(45, 25);// Set the Display Cursor
                    display.print(temperature_value_c); // Print the Temperature value to the display in celcius
                    display.display(); // Update the Display
                #ifdef __DEBUG__
                    Serial.print(temperature_value_c); // Print the Temperature value in *C on serial monitor
                    Serial.print("   "); // Print an Empty Space
                    Serial.println(output); // Print the Calculate Output value in the serial monitor.
                #endif
                    delay(200); // Wait 200ms to update the OLED dispaly.
                  }
                }
                جدیدترین ویرایش توسط abbasjavanmardi; ۱۰:۴۷ ۱۴۰۱/۰۲/۰۲.

                دیدگاه


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

                  نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                  سلام دوستان
                  بعد ی وقفه شش ماهه من بجای سنسور ds18b20 یه سنسور sht11 توپروژه قرار دادم.الان با برنامه ای ک دارم دما با اختلاف دو دهم درجه حول ست پوینت در نوسان هست.الان مونده تنظیم ظرایب pid که تنظیم بشه.کسی میتونه کمکم کنه چطوری میتونم به شکل تجربی تنظیمشون کنم؟
                  کد:
                  #include <SHT1x.h>
                  #include <SPI.h>
                  #include <Wire.h>
                  #include <Adafruit_GFX.h>
                  #include <Adafruit_SSD1306.h>
                  #include <PIDController.h>
                  // SHT1x Pins
                  #define dataPin  7
                  #define clo 6
                  SHT1x sht1x(dataPin, clo);
                  // Define Rotary Encoder Pins
                  #define CLK_PIN 3
                  #define DATA_PIN 4
                  #define SW_PIN 2
                  // Mosfet Pin
                  #define mosfet_pin 11
                  // Serial Enable
                  #define __DEBUG__
                  #define SCREEN_WIDTH 128 // OLED display width, in pixels
                  #define SCREEN_HEIGHT 64 // OLED display height, in pixels
                  #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
                  /*In this section we have defined the gain values for the 
                   * proportional, integral, and derivative controller I have set
                   * the gain values with the help of trial and error methods.
                  */ 
                  #define __Kp 100 // Proportional constant
                  #define __Ki 4 // Integral Constant
                  #define __Kd 2 // Derivative Constant
                  int clockPin; // Placeholder por pin status used by the rotary encoder
                  int clockPinState; // Placeholder por pin status used by the rotary encoder
                  int set_temperature = 31; // This set_temperature value will increas or decreas if when the rotarty encoder is turned
                  float temperature_value_c = 0.0; // stores temperature value
                  long debounce = 0; // Debounce delay
                  int encoder_btn_count = 0; // used to check encoder button press
                  
                  
                  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);// Create an instance for the SSD1306 128X64 OLED "display"
                  PIDController pid; // Create an instance of the PID controller class, called "pid"
                  void setup() {
                  #ifdef __DEBUG__
                    Serial.begin(9600);
                  #endif
                    pinMode(mosfet_pin, OUTPUT); // MOSFET output PIN
                    pinMode(CLK_PIN, INPUT); // Encoer Clock Pin
                    pinMode(DATA_PIN, INPUT); //Encoder Data Pin
                    pinMode(SW_PIN, INPUT_PULLUP);// Encoder SW Pin
                    pid.begin();          // initialize the PID instance
                    pid.setpoint(50);    // The "goal" the PID controller tries to "reach"
                    pid.tune(__Kp, __Ki,__Kd);    // Tune the PID, arguments: kP, kI, kD
                    pid.limit(0, 255);    // Limit the PID output between 0 and 255, this is important to get rid of integral windup!
                    if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
                  #ifdef __DEBUG__
                      Serial.println(F("SSD1306 allocation failed"));
                  #endif
                      for (;;); // Don't proceed, loop forever
                    }
                    //
                    display.setRotation(2); //Rotate the Display
                    display.display(); //Show initial display buffer contents on the screen -- the library initializes this with an Adafruit splash screen.
                    display.clearDisplay(); // Cleear the Display
                    display.setTextSize(2); // Set text Size
                    display.setTextColor(WHITE); // set LCD Colour
                    display.setCursor(48, 0); // Set Cursor Position
                    display.println("PID"); // Print the this Text
                    display.setCursor(0, 20);  // Set Cursor Position
                    display.println("Temperatur"); // Print the this Text
                    display.setCursor(22, 40); // Set Cursor Position
                    display.println("Control"); // Print the this Text
                    display.display(); // Update the Display
                    delay(2000); // Delay of 200 ms
                  }
                  void set_temp()
                  {
                    if (encoder_btn_count == 2) // check if the button is pressed twice and its in temperature set mode.
                    {
                      display.clearDisplay(); // clear the display
                      display.setTextSize(2); // Set text Size
                      display.setCursor(16, 0); // set the diplay cursor
                      display.print("Set Temp."); // Print Set Temp. on the display
                      display.setCursor(45, 25); // set the cursor
                      display.print(set_temperature);// print the set temperature value on the display
                      display.display(); // Update the Display
                    }
                  }
                  void read_encoder() // In this function we read the encoder data and increment the counter if its rotaing clockwise and decrement the counter if its rotating counter clockwis
                  {
                    clockPin = digitalRead(CLK_PIN); // we read the clock pin of the rotary encoder
                    if (clockPin != clockPinState  && clockPin == 1) { // if this condition is true then the encoder is rotaing counter clockwise and we decremetn the counter
                      if (digitalRead(DATA_PIN) != clockPin) set_temperature = set_temperature - 3;  // decrmetn the counter.
                      else  set_temperature = set_temperature + 3; // Encoder is rotating CW so increment
                      if (set_temperature < 1 )set_temperature = 1; // if the counter value is less than 1 the set it back to 1
                      if (set_temperature > 150 ) set_temperature = 150; //if the counter value is grater than 150 then set it back to 150 
                  #ifdef __DEBUG__
                      Serial.println(set_temperature); // print the set temperature value on the serial monitor window
                  #endif
                    }
                    clockPinState = clockPin; // Remember last CLK_PIN state
                    
                    if ( digitalRead(SW_PIN) == LOW)   //If we detect LOW signal, button is pressed
                    {
                      if ( millis() - debounce > 80) { //debounce delay
                        encoder_btn_count++; // Increment the values 
                        if (encoder_btn_count > 2) encoder_btn_count = 1;
                  #ifdef __DEBUG__
                        Serial.println(encoder_btn_count);
                  #endif
                      }
                      debounce = millis(); // update the time variable
                    }
                  }
                  void loop()
                  {
                    read_encoder(); //Call The Read Encoder Function
                    set_temp(); // Call the Set Temperature Function
                    if (encoder_btn_count == 1) // check if the button is pressed and its in Free Running Mode -- in this mode the arduino continiously updates the screen and adjusts the PWM output according to the temperature.
                    {
                      temperature_value_c = sht1x.readTemperatureC(); // Read the Temperature using the readCelsius methode from MAX6675 Library.
                      int output = pid.compute(temperature_value_c);    // Let the PID compute the value, returns the optimal output
                      analogWrite(mosfet_pin, output);           // Write the output to the output pin
                      pid.setpoint(set_temperature); // Use the setpoint methode of the PID library to
                      display.clearDisplay(); // Clear the display
                      display.setTextSize(2); // Set text Size
                      display.setCursor(16, 0); // Set the Display Cursor
                      display.print("Cur Temp."); //Print to the Display
                      display.setCursor(45, 25);// Set the Display Cursor
                      display.print(temperature_value_c); // Print the Temperature value to the display in celcius
                      display.display(); // Update the Display
                  #ifdef __DEBUG__
                      Serial.print(temperature_value_c); // Print the Temperature value in *C on serial monitor
                      Serial.print("   "); // Print an Empty Space
                      Serial.println(output); // Print the Calculate Output value in the serial monitor.
                  #endif
                      delay(200); // Wait 200ms to update the OLED dispaly.
                    }
                  }
                  همچنان نیازمند یاری سبزتان هستیم

                  دیدگاه


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

                    نوشته اصلی توسط abbasjavanmardi نمایش پست ها
                    سلام دوستان
                    بعد ی وقفه شش ماهه من بجای سنسور ds18b20 یه سنسور sht11 توپروژه قرار دادم.الان با برنامه ای ک دارم دما با اختلاف دو دهم درجه حول ست پوینت در نوسان هست.الان مونده تنظیم ظرایب pid که تنظیم بشه.کسی میتونه کمکم کنه چطوری میتونم به شکل تجربی تنظیمشون کنم؟
                    کد:
                    #include <SHT1x.h>
                    #include <SPI.h>
                    #include <Wire.h>
                    #include <Adafruit_GFX.h>
                    #include <Adafruit_SSD1306.h>
                    #include <PIDController.h>
                    // SHT1x Pins
                    #define dataPin  7
                    #define clo 6
                    SHT1x sht1x(dataPin, clo);
                    // Define Rotary Encoder Pins
                    #define CLK_PIN 3
                    #define DATA_PIN 4
                    #define SW_PIN 2
                    // Mosfet Pin
                    #define mosfet_pin 11
                    // Serial Enable
                    #define __DEBUG__
                    #define SCREEN_WIDTH 128 // OLED display width, in pixels
                    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
                    #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
                    /*In this section we have defined the gain values for the 
                     * proportional, integral, and derivative controller I have set
                     * the gain values with the help of trial and error methods.
                    */ 
                    #define __Kp 100 // Proportional constant
                    #define __Ki 4 // Integral Constant
                    #define __Kd 2 // Derivative Constant
                    int clockPin; // Placeholder por pin status used by the rotary encoder
                    int clockPinState; // Placeholder por pin status used by the rotary encoder
                    int set_temperature = 31; // This set_temperature value will increas or decreas if when the rotarty encoder is turned
                    float temperature_value_c = 0.0; // stores temperature value
                    long debounce = 0; // Debounce delay
                    int encoder_btn_count = 0; // used to check encoder button press
                    
                    
                    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);// Create an instance for the SSD1306 128X64 OLED "display"
                    PIDController pid; // Create an instance of the PID controller class, called "pid"
                    void setup() {
                    #ifdef __DEBUG__
                      Serial.begin(9600);
                    #endif
                      pinMode(mosfet_pin, OUTPUT); // MOSFET output PIN
                      pinMode(CLK_PIN, INPUT); // Encoer Clock Pin
                      pinMode(DATA_PIN, INPUT); //Encoder Data Pin
                      pinMode(SW_PIN, INPUT_PULLUP);// Encoder SW Pin
                      pid.begin();          // initialize the PID instance
                      pid.setpoint(50);    // The "goal" the PID controller tries to "reach"
                      pid.tune(__Kp, __Ki,__Kd);    // Tune the PID, arguments: kP, kI, kD
                      pid.limit(0, 255);    // Limit the PID output between 0 and 255, this is important to get rid of integral windup!
                      if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
                    #ifdef __DEBUG__
                        Serial.println(F("SSD1306 allocation failed"));
                    #endif
                        for (;;); // Don't proceed, loop forever
                      }
                      //
                      display.setRotation(2); //Rotate the Display
                      display.display(); //Show initial display buffer contents on the screen -- the library initializes this with an Adafruit splash screen.
                      display.clearDisplay(); // Cleear the Display
                      display.setTextSize(2); // Set text Size
                      display.setTextColor(WHITE); // set LCD Colour
                      display.setCursor(48, 0); // Set Cursor Position
                      display.println("PID"); // Print the this Text
                      display.setCursor(0, 20);  // Set Cursor Position
                      display.println("Temperatur"); // Print the this Text
                      display.setCursor(22, 40); // Set Cursor Position
                      display.println("Control"); // Print the this Text
                      display.display(); // Update the Display
                      delay(2000); // Delay of 200 ms
                    }
                    void set_temp()
                    {
                      if (encoder_btn_count == 2) // check if the button is pressed twice and its in temperature set mode.
                      {
                        display.clearDisplay(); // clear the display
                        display.setTextSize(2); // Set text Size
                        display.setCursor(16, 0); // set the diplay cursor
                        display.print("Set Temp."); // Print Set Temp. on the display
                        display.setCursor(45, 25); // set the cursor
                        display.print(set_temperature);// print the set temperature value on the display
                        display.display(); // Update the Display
                      }
                    }
                    void read_encoder() // In this function we read the encoder data and increment the counter if its rotaing clockwise and decrement the counter if its rotating counter clockwis
                    {
                      clockPin = digitalRead(CLK_PIN); // we read the clock pin of the rotary encoder
                      if (clockPin != clockPinState  && clockPin == 1) { // if this condition is true then the encoder is rotaing counter clockwise and we decremetn the counter
                        if (digitalRead(DATA_PIN) != clockPin) set_temperature = set_temperature - 3;  // decrmetn the counter.
                        else  set_temperature = set_temperature + 3; // Encoder is rotating CW so increment
                        if (set_temperature < 1 )set_temperature = 1; // if the counter value is less than 1 the set it back to 1
                        if (set_temperature > 150 ) set_temperature = 150; //if the counter value is grater than 150 then set it back to 150 
                    #ifdef __DEBUG__
                        Serial.println(set_temperature); // print the set temperature value on the serial monitor window
                    #endif
                      }
                      clockPinState = clockPin; // Remember last CLK_PIN state
                      
                      if ( digitalRead(SW_PIN) == LOW)   //If we detect LOW signal, button is pressed
                      {
                        if ( millis() - debounce > 80) { //debounce delay
                          encoder_btn_count++; // Increment the values 
                          if (encoder_btn_count > 2) encoder_btn_count = 1;
                    #ifdef __DEBUG__
                          Serial.println(encoder_btn_count);
                    #endif
                        }
                        debounce = millis(); // update the time variable
                      }
                    }
                    void loop()
                    {
                      read_encoder(); //Call The Read Encoder Function
                      set_temp(); // Call the Set Temperature Function
                      if (encoder_btn_count == 1) // check if the button is pressed and its in Free Running Mode -- in this mode the arduino continiously updates the screen and adjusts the PWM output according to the temperature.
                      {
                        temperature_value_c = sht1x.readTemperatureC(); // Read the Temperature using the readCelsius methode from MAX6675 Library.
                        int output = pid.compute(temperature_value_c);    // Let the PID compute the value, returns the optimal output
                        analogWrite(mosfet_pin, output);           // Write the output to the output pin
                        pid.setpoint(set_temperature); // Use the setpoint methode of the PID library to
                        display.clearDisplay(); // Clear the display
                        display.setTextSize(2); // Set text Size
                        display.setCursor(16, 0); // Set the Display Cursor
                        display.print("Cur Temp."); //Print to the Display
                        display.setCursor(45, 25);// Set the Display Cursor
                        display.print(temperature_value_c); // Print the Temperature value to the display in celcius
                        display.display(); // Update the Display
                    #ifdef __DEBUG__
                        Serial.print(temperature_value_c); // Print the Temperature value in *C on serial monitor
                        Serial.print("   "); // Print an Empty Space
                        Serial.println(output); // Print the Calculate Output value in the serial monitor.
                    #endif
                        delay(200); // Wait 200ms to update the OLED dispaly.
                      }
                    }
                    کسی نیست بنده رو راهنمایی کنه؟

                    دیدگاه

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