//Definitions for pins of Trinket 3.3V
//AnalogWrite()
#define AW_PB0 0
#define AW_PB1 1
#define AW_PB4 4
//AnalogRead()
#define AR_PB2 1
#define AR_PB3 3
#define AR_PB4 2
//Digital pins
#define D_PB0 0
#define D_PB1 1
#define D_PB2 2
#define D_PB3 3
#define D_PB4 4
// variables and definitions
//Important parameter, set to match environment
const int dt = 500; // [ms] time constant in milliseconds (controller clock rate = 1/(dt/1000) [Hz])
#define SetTemp 62.8 // [degC] set temperature in DegC
#define MinTemp 20 // [degC] minimum expected temperature (needed for rescaling inputs)
#define MaxTemp 65 // [degC] maximum allowed temperature, over which heater is turned off (needed for rescaling inputs)
int SetTime = 1800; // [s] timer in seconds, if reached, running stops [Default: 1800]
//I/O pins - don't edit unless replaced
#define thermistorPin AR_PB4 //number of thermistor pin
#define FETPin AW_PB1 //the number of the MOSFET pin
//#define LEDPin ? //the number of the LED pin
//control parameters - editing not recommended
double K_P_ctrl = 15; //proportional gain
double K_I_ctrl = 0; //integral gain (set to lower values i.e. 10^-3)
double K_D_ctrl = 0; //derivative gain
// including headers
#include <math.h>
//Inititalization
//target temperature reached?
bool bInRange = 0;
//ticks per ms
int TicksPerMS = floor(1000/dt);
//Initialize PID variables:
float previous_error = 0;
float s_integral = 0;
//Thermistor code - hard-coded constants for generic 10K NTC thermistor
double Thermistor(int RawADC) {
double Temp;
Temp = log(10000.0*((1024.0/RawADC-1)));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
Temp = Temp - 273.15; // Convert Kelvin to Celcius
return Temp;
}
//PID controller code
void Control_PID(double iTemp){
//Overheat protection
if(iTemp>MaxTemp){
analogWrite(FETPin, 0);
return;
}
//In range? If in range, do something (maybe turn on LED?)
if((iTemp) >= SetTemp){
if(bInRange==0){
//TODO: add code what to do when in range
//digitalWrite(LEDPin, HIGH);
bInRange=1;
}
}else{
if(bInRange==1){
//TODO: add code what to do when out of range
//digitalWrite(LEDPin, LOW);
bInRange=0;
}
}
//PID subroutine
float err = SetTemp - iTemp;
s_integral += err*dt;
float s_derivative = (err - previous_error)/dt;
int U_in_ctrl = (K_P_ctrl*err + K_I_ctrl*s_integral + K_D_ctrl*s_derivative)/(MaxTemp-MinTemp)*255;
previous_error = err;
// put voltage to output
if (U_in_ctrl<=255){
if (U_in_ctrl > 0){
analogWrite(FETPin, U_in_ctrl);
}
else
{
analogWrite(FETPin, 1);
}
}
else{
analogWrite(FETPin,255);
}
}
void setup() {
pinMode(FETPin, OUTPUT);
//rescale timer according to dt
SetTime = SetTime * TicksPerMS;
}
void loop() {
//Take a temperature reading and display it
double Temp = double(Thermistor(analogRead(thermistorPin)));
//Call controller algorithm
Control_PID(Temp); // call controller algorithm
//Timer ticking (countdown)
if (SetTime>0){
SetTime--;
// if zero reached
if (SetTime==0){
while(1) {
//loop until disconnected - you might want to flash the LED or something...
digitalWrite(FETPin, LOW);
delay(dt);
}
}
}
//wait dt before next cycle
delay(dt);
}
Comments
Please log in or sign up to comment.