#include <PID_v1.h>
#include<math.h>
#include <LiquidCrystal.h>
/*The PID functions by adjusting a certain output in order to * minimize the error between two values, which are the setpoint * and the input. * The PID function itself creates a PID controller and takes * five parameters: * Input: The value that needs to be controlled * Output: The value that the PID will adjust * Setpoint: The value that the input will be maintained at * Kp,Ki,KD: Parameters that will affect how the output is adjusted * Direct: Defines which direction the output will proceed given an error */
// Define PID varaibles
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint, 1550, 800, 780, DIRECT);
//LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );
//PCR Variables
int stepnow = 1;
int cycle = 2;
int laststep = 0;
int count = 1;
int startup = 2;
// Cycles
int cycles = 35;
int cyclenum = (cycles-1)*3 +1;
//Startup cycle
int meltT1 = 96;
int pcrT1 = 59;
//All cycles
int meltT = 96;
int pcrT = 59;
int extensionT = 73;
//End cycle
int endextT = 73;
int endT = 4;
int deathT = 97;
int val0;
int val1;
int val;
int tempPin0 = 2;
int tempPin1 = 3;
int signalr1 = 3;
int signalr2 = 5;
String pcr = "starting ";
boolean cooling = false;
//Startup cycle
unsigned long Melt1 = 180;
unsigned long t1Melt = Melt1*1000;
unsigned long PCR1 = 20;
unsigned long t1PCR = PCR1*1000;
unsigned long extension1 = 20;
unsigned long textension1 = extension1*1000;
// All cycles
unsigned long Melt = 30;
unsigned long tMelt = Melt*1000;
unsigned long PCR = 30;
unsigned long tPCR = PCR*1000;
unsigned long extension = 20;
unsigned long textension = extension*1000;
//End cycle
unsigned long extend = 30;
unsigned long textend = extend*1000;
unsigned long cycleStart;
int WindowSize = 500;
unsigned long windowStartTime;
// Sets up the staring environment and will only run once
void setup() {
Serial.begin(9600);
//lcd.begin(16, 2);
windowStartTime = millis();
myPID.SetOutputLimits(0, WindowSize);
myPID.SetMode(AUTOMATIC);
pinMode(signalr1, OUTPUT);
pinMode(signalr2, OUTPUT);
Setpoint = meltT1;
}
void loop()
{
if (stepnow < cyclenum) {
/**The following code is only implemented once as the first cycle of the PCR * This allows for the user to set conditions which may be different from the subsequent * cycles. The code, however, works in much the same way as the other cycles * at the most basic level. It divides each cycle into subcycles: activation, pcr and extension * and enters each step based on stepnow(which denotes how many subcyles the program has entered) divisiblity by 3. * The remainder for activation will always be 1, * the remainder for pcr will be 2 and the remainder for extension will be 3 */
//Begins activation of the PCR by checking that this is the first cycle and that the current subcycle is activation
if (((stepnow % 3) == 1) && (cycle == 2)) {
// sets the setpoint that the pcr will heat up to as meltT1
Setpoint = meltT1;
// prints out the current cycle number and the step it is currenly on
Serial.println(pcr + count);
// If the setpoint has reached the desired temperature, it will enter this loop
if (((Input - meltT1 + 1) > 0) && (laststep != stepnow)) {
// Starts the timer and maintains this temperature for the desired amount of time
cycleStart = millis();
pcr = "maintaining cycle activation: cycle ";
laststep++;
}
//If the pcr has maintained the setpoint for the desired amount of time, it will enter this loop and begin cooling
if ((millis() > (t1Melt + cycleStart)) && (laststep == stepnow)) {
stepnow++;
pcr = "cooling to pcr ";
cooling = true;
}
}
// Checks that the current step is the subcycle pcr
if (((stepnow % 3) == 2) && (cycle == 2)) {
// sets the temperature as pcrT1
Setpoint = pcrT1;
Serial.println(pcr + count);
//checks that the machine has reached the setpoint
if (((Input - pcrT1 - 1) < 0) && (laststep != stepnow)) {
cooling = false;
cycleStart = millis();
pcr = "maintaining cycle pcr: cycle ";
laststep++;
}
//checks if the machine has maintained the temperature for the desired amount of time, and begins the next step
if ((millis() > (t1PCR + cycleStart)) && (laststep == stepnow) && (cycle == 2)) {
stepnow++;
pcr = "heating to extension ";
}
}
// Checks that the current step is the subcycle extension
if ((cycle == 2) && ((stepnow % 3) == 0)) {
// sets the temperature as extensionT
Setpoint = extensionT;
Serial.println(pcr + count);
//checks that the machine has reached the setpoint
if (((Input - extensionT + 1) > 0) && (laststep != stepnow)) {
pcr = "maintaining cycle extension: cycle ";
cycleStart = millis();
laststep++;
}
//checks if the machine has maintained the temperature for the desired amount of time, and begins the next step
if ((millis() > (textension1 + cycleStart)) && (laststep == stepnow)) {
pcr = "heating to melt ";
stepnow++;
cycle++;
count++;
}
}
/** * Begins the intermediate steps which work in an identical manner to the startup cycle * and may differ only in the alloted temperatures and times for each subcycle */
if (((stepnow % 3) == 1) && (cycle != 2)) {
Setpoint = meltT;
Serial.println(pcr + count);
if (((Input - meltT + 1) > 0) && (laststep != stepnow)) {
pcr = "maintaining melt: cycle ";
cycleStart = millis();
laststep++;
}
if ((millis() > (tMelt + cycleStart)) && (laststep == stepnow)) {
stepnow++;
cooling = true;
pcr = "cooling to pcr ";
}
}
if (((stepnow % 3) == 2) && (cycle != 2)) {
Setpoint = pcrT;
Serial.println(pcr + count);
if (((Input - pcrT - 1) < 0) && (laststep != stepnow)) {
cooling = false;
pcr = "maintaining pcr: cycle ";
cycleStart = millis();
laststep++;
}
if ((millis() > (tPCR + cycleStart)) && (laststep == stepnow) ) {
stepnow++;
pcr = "heating to extension ";
}
}
if (((stepnow % 3) == 0) && (cycle != 2)) {
Setpoint = extensionT;
Serial.println(pcr + count);
if (((Input - extensionT + 1) > 0) && (laststep != stepnow)) {
cycleStart = millis();
pcr = "maintaining extension: cycle ";
laststep++;
}
if ((millis() > (textension + cycleStart)) && (laststep == stepnow)) {
stepnow++;
count++;
pcr = "heating to melt ";
}
}
/* * Begins the last step, which again works in a similar fashion to the other steps, but may differ in the * final extension temperature */
} else if ((stepnow >= cyclenum && stepnow <= cyclenum + 2 )) {
if (((stepnow % 3) == 1)) {
Setpoint = meltT;
Serial.println(pcr + count);
if (((Input - meltT + 1) > 0) && (laststep != stepnow)) {
pcr = "maintaining melt: cycle ";
cycleStart = millis();
laststep++;
}
if ((millis() > (tMelt + cycleStart)) && (laststep == stepnow)) {
stepnow++;
cooling = true;
pcr = "cooling to pcr ";
}
}
if (((stepnow % 3) == 2)) {
Setpoint = pcrT;
Serial.println(pcr + count);
if (((Input - pcrT - 1) < 0) && (laststep != stepnow)) {
cooling = false;
pcr = "maintaining pcr: cycle ";
cycleStart = millis();
laststep++;
}
if ((millis() > (tPCR + cycleStart)) && (laststep == stepnow) ) {
stepnow++;
pcr = "heating to extension ";
}
}
if (((stepnow % 3) == 0)) {
Setpoint = extensionT;
Serial.println(pcr + count);
if (((Input - extensionT + 1) > 0) && (laststep != stepnow)) {
cycleStart = millis();
pcr = "maintaining extension: cycle ";
laststep++;
}
if ((millis() > (textend + cycleStart)) && (laststep == stepnow)) {
stepnow++;
count++;
pcr = "cooling to end ";
}
}
/** * Once the last step has been completed, determined by stepnow being greater than cyclenum+2, * the code will tell the pcr to hold at 4 C. It will continue looping at this step indefinitely * because the conditions will no longer satisfy any of the other if statement */
} else {
int strt = 1;
boolean cooldown = true;
if (strt == 1) {
Setpoint = endT;
Serial.println(pcr);
}
// begins cooldown to 4
if (cooldown) {
digitalWrite(signalr1, HIGH);
digitalWrite(signalr2, LOW);
}
//Once the pcr has reached 37 C, the pcr will print out that the pcr has shutt off
if ((Input - 38 + 1) < 0) {
digitalWrite(signalr1, HIGH);
digitalWrite(signalr2, LOW);
pcr = "turn off";
}
}
// creates the window
unsigned long now = millis();
if (now - windowStartTime > WindowSize) {
windowStartTime += WindowSize;
Input = val;
// this function is called once every loop, and contains the pid algorithm
myPID.Compute();
}
// if cooling is true, it will begin cooling until cool is set to false
if (cooling){
digitalWrite(signalr1, HIGH);
digitalWrite(signalr2, LOW);
Serial.println("COOLING");
// if the pcr machine's temperature reaches 97, cooling will automatically be initiated and a death message will be displayed
}else if ((Input - deathT +1) > 0){
digitalWrite(signalr1, HIGH);
digitalWrite(signalr2, LOW );
Serial.println("DEATH");
/* these two statements work on the maintaining the temperature, by controlling heating and cooling when there is overshoot or undershoot in the temperature*/
} else if (Output > now - windowStartTime - 1) {
digitalWrite(signalr1, HIGH);
digitalWrite(signalr2, HIGH);
}
else
{
digitalWrite(signalr1, HIGH);
digitalWrite(signalr2, LOW);
}
//int reading = analogRead(tempPin);
val0 = (((analogRead(tempPin0) / 1024.0) * 5000) / 10);
val1 = (((analogRead(tempPin1) / 1024.0) * 5000) / 10);
//val = (val0 + val1)/2;
val = val1;
// determines the value of the current temperature and prints it out
Serial.println(val);
// loops back to the top of the code, this will occur indefinitely
}