PID control
So now we know how to read the original temperature, let us control the heating element with this next planned mounted mountfat. I again mounted a routine circuit and uploaded the next code. This second code already has the PID algorithm created. We read the temperature, count the error, add the pid values, and create a PWM signal in the digital pin D3 that will be applied to MOSFET. I set the desired temperature at 100 degrees and use the LCD to print the set quality and real temperature.

Code for specific PID control
Ok so the code below is a little bigger. But do not worry. It’s very easy. We set a variable set point at 100 degrees for this example. Then we read the actual temperature values of the temperatures as past examples. Then we use 3 constant and calculate PID sum. Depending on the quality, we make a PWM signal at pin D3 and apply it to a MOSFET gate using a BJT driver.
ARDUINO CODE
 |
/* Max6675 Module ==> Arduino * CS ==> D10 * SO ==> D12 * SCK ==> D13 * Vcc ==> Vcc (5v) * Gnd ==> Gnd */ #include #include LiquidCrystal_I2C lcd(0x3f,20,4); #include #define MAX6675_CS 10#define MAX6675_SO 12#define MAX6675_SCK 13 int PWM_pin = 3; float temperature_read = 0.0; float set_temperature = 100; float PID_error = 0; float previous_error = 0; float elapsedTime, Time, timePrev; int PID_value = 0; int kp = 9.1; int ki = 0.3; int kd = 1.8; int PID_p = 0; int PID_i = 0; int PID_d = 0; void setup() { pinMode(PWM_pin,OUTPUT); TCCR2B = TCCR2B & B11111000 | 0x03; Time = millis(); lcd.init(); lcd.backlight(); } void loop() { temperature_read = readThermocouple(); PID_error = set_temperature – temperature_read; PID_p = kp * PID_error; if(-3 < PID_error <3) { PID_i = PID_i + (ki * PID_error); } timePrev = Time; Time = millis(); elapsedTime = (Time – timePrev) / 1000; PID_d = kd*((PID_error – previous_error)/elapsedTime); PID_value = PID_p + PID_i + PID_d; if(PID_value < 0) { PID_value = 0; } if(PID_value > 255) { PID_value = 255; } analogWrite(PWM_pin,255-PID_value); previous_error = PID_error; delay(300); lcd.setCursor(0,0); lcd.print(“PID TEMP control”); lcd.setCursor(0,1); lcd.print(“S:”); lcd.setCursor(2,1); lcd.print(set_temperature,1); lcd.setCursor(9,1); lcd.print(“R:”); lcd.setCursor(11,1); lcd.print(temperature_read,1); } double readThermocouple() { uint16_t v; pinMode(MAX6675_CS, OUTPUT); pinMode(MAX6675_SO, INPUT); pinMode(MAX6675_SCK, OUTPUT); digitalWrite(MAX6675_CS, LOW); delay(1); v = shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST); v <<= 8; v |= shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST); digitalWrite(MAX6675_CS, HIGH); if (v & 0x4) { return NAN; } v >>= 3; return v*0.25; }

You can see that the quality of the temperature is as having. But after many constant efforts of PID it and the tricky part of this project. So, try your own values to do what you need to do until you get the right. I suggest you start with 0 and equal to 0, and then gradually increase those values until you get good results.
Here I have the PWM signal of the MOSFET connected to my aceoloscope.
|
Initially, the system does not reach the desired value, because the pulse has a small width due to using the BJT to activate the N channel gate, so the mosque is activated with a lower quality in this field. Once it reaches the set quality it is used to maintain temperature and almost wambble begins. As you can see, if I try to cool the heating element by air in this air with the tube, the PWM signal width is low in keeping the same value. So, the control works.The default value is now 0 degrees. Press the Rotary Encoder Set button to enter or leave it to the left to decrease the temperature value. Again press the Set button and now you can set P constant for PID control. Press again and I select the value. Finally, press the button again and select D value. Now press the button and exit the menu and save the new settings. I put it at 100 degrees.