/* Max6675 Module ==> Arduino * CS ==> D10 * SO ==> D12 * SCK ==> D13 * Vcc ==> Vcc (5v) * Gnd ==> Gnd */ #include String recieved_data; // I/O int PWM_pin = 3; // Pin for PWM signal to the MOSFET driver (the BJT npn with pullup) // Variables float set_temperature = 100; // Default temperature setpoint. Leave it 0 and control it with rotary encoder float temperature_read = 0.0; float PID_error = 0; float previous_error = 0; float elapsedTime, Time, timePrev; float PID_value = 0; float last_set_temperature = 0; // PID constants ////////////////////////////////////////////////////////// int kp = 5; int ki = 2; int kd = 1; ////////////////////////////////////////////////////////// int PID_p = 0; int PID_i = 0; int PID_d = 0; float last_kp = 0; float last_ki = 0; float last_kd = 0; // Pins for the SPI with MAX6675 #define MAX6675_CS 10 #define MAX6675_SO 12 #define MAX6675_SCK 13 void setup() { Serial.begin(9600); pinMode(PWM_pin, OUTPUT); TCCR2B = TCCR2B & B11111000 | 0x03; // pin 3 and 11 PWM frequency of 928.5 Hz Time = millis(); pinMode(11, INPUT); } void loop() { if (Serial.available() > 0) { recieved_data = (Serial.readString()); } // First we read the real value of temperature temperature_read = readThermocouple(); // Next we calculate the error between the setpoint and the real value PID_error = set_temperature - temperature_read + 3; // Calculate the P value PID_p = 0.01 * kp * PID_error; // Calculate the I value in a range on +-3 PID_i = 0.01 * PID_i + (ki * PID_error); // For derivative we need real time to calculate speed change rate timePrev = Time; // the previous time is stored before the actual time read Time = millis(); // actual time read elapsedTime = (Time - timePrev) / 1000; // Now we can calculate the D calue PID_d = 0.01 * kd * ((PID_error - previous_error) / elapsedTime); // Final total PID value is the sum of P + I + D PID_value = PID_p + PID_i + PID_d; // We define PWM range between 0 and 255 if (PID_value < 0) { PID_value = 0; } if (PID_value > 255) { PID_value = 255; } // Now we can write the PWM signal to the mosfet on digital pin D3 // Since we activate the MOSFET with a 0 to the base of the BJT, we write 255-PID value (inverted) analogWrite(PWM_pin, 255 - PID_value); previous_error = PID_error; // Remember to store the previous error for next loop. Serial.print("Okunan Isı"); Serial.println(temperature_read); Serial.print("PID value"); Serial.println(PID_value); delay(250); // Refresh rate } // Loop end // The function that reads the SPI data from MAX6675 double readThermocouple() { uint16_t v; pinMode(MAX6675_CS, OUTPUT); pinMode(MAX6675_SO, INPUT); pinMode(MAX6675_SCK, OUTPUT); digitalWrite(MAX6675_CS, LOW); delay(1); // Read in 16 bits, // 15 = 0 always // 14..2 = 0.25 degree counts MSB First // 2 = 1 if thermocouple is open circuit // 1..0 = uninteresting status v = shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST); v <<= 8; v |= shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST); digitalWrite(MAX6675_CS, HIGH); if (v & 0x4) { // Bit 2 indicates if the thermocouple is disconnected return NAN; } // The lower three bits (0,1,2) are discarded status bits v >>= 3; // The remaining bits are the number of 0.25 degree (C) counts return v * 0.25; }