-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPID_temperature_control_woLCD.ino
142 lines (116 loc) · 3.86 KB
/
PID_temperature_control_woLCD.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* Max6675 Module ==> Arduino
* CS ==> D5
* SO ==> D6
* SCK ==> D7
* Vcc ==> Vcc (5v)
* Gnd ==> Gnd */
//LCD config (i2c LCD screen, you need to install the LiquidCrystal_I2C if you don't have it )
//#include <Wire.h>
//#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x3f,20,4); //sometimes the adress is not 0x3f. Change to 0x27 if it dosn't work.
/* i2c LCD Module ==> Arduino
* SCL ==> A5
* SDA ==> A4
* Vcc ==> Vcc (5v)
* Gnd ==> Gnd */
#include <SPI.h>
#include "Adafruit_MAX31855.h"
//We define the SPI pìns
#define MAX31855_CS 5
#define MAX31855_DO 6
#define MAX31855_CLK 7
//Pins
int PWM_pin = 3;
//Variables
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;
//PID constants
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; // pin 3 and 11 PWM frequency of 980.39 Hz
Time = millis();
Serial.begin(9600);
// lcd.init();
// lcd.backlight();
}
void loop() {
// First we read the real value of temperature
temperature_read = readThermocouple();
// if (temperature_read == 0){
// break;
// }
//Next we calculate the error between the setpoint and the real value
PID_error = set_temperature - temperature_read;
//Calculate the P value
PID_p = kp * PID_error;
//Calculate the I value in a range on +-3
if(-3 < PID_error <3)
{
PID_i = 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 = 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
analogWrite(PWM_pin,PID_value);
previous_error = PID_error; //Remember to store the previous error for next loop.
delay(300);
//lcd.clear();
Serial.println("S:");
Serial.print(set_temperature,1);
Serial.print("/t");
Serial.print("R:");
Serial.print(temperature_read,1);
// 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(MAX31855_CS, OUTPUT);
pinMode(MAX31855_DO, INPUT);
pinMode(MAX31855_CLK, OUTPUT);
digitalWrite(MAX31855_CS, LOW);
delay(1); // ms
// 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(MAX31855_DO, MAX31855_CLK, MSBFIRST);
v <<= 8;
v |= shiftIn(MAX31855_DO, MAX31855_CLK, MSBFIRST);
digitalWrite(MAX31855_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;
}