#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
}