Hello, I am trying to implement PID with my temperature controller. My current issue is getting my output from the PID to give reasonable results. My code is a combination of a simple on off temperature controller and the PID Relay Output example from Arduino. I am using the PID library because I thought it would make my life easier but there is something wrong with how my code is structured. I attached a picture of what the output looks like as well as my code. My goal is for a nice smooth transition for my relay to turn on and off my hotplate. The blue line is the output, orange -> input, red -> set point.
/*
Digital Temperature Controller
*/
#include <LiquidCrystal.h>
#include <PID_v1.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
const int LED_RED=10; //Red LED
const int LED_GREEN=11; //Green LED
const int RELAY=12; //Lock Relay or motor
//Key connections with arduino
const int up_key=3;
const int down_key=2;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, 2, 5, 1, DIRECT); //Kp, Ki, Kd
int WindowSize = 5000;
unsigned long windowStartTime;
//=================================================================
// SETUP
//=================================================================
void setup(){
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
windowStartTime = millis();
//initialize the variables we're linked to
Setpoint = 50;
pinMode(LED_RED,OUTPUT);
pinMode(LED_GREEN,OUTPUT);
pinMode(RELAY,OUTPUT);
pinMode(up_key,INPUT);
pinMode(down_key,INPUT);
//Pull up for Setpoint keys
digitalWrite(up_key,HIGH);
digitalWrite(down_key,HIGH);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Andre Chavez");
lcd.setCursor(0,1); //Move coursor to second Line
lcd.print("Temp. Controller");
digitalWrite(LED_GREEN,HIGH); //Green LED Off
digitalWrite(LED_RED,LOW); //Red LED On
digitalWrite(RELAY,LOW); //Turn off Relay
delay(2000);
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
//=================================================================
// LOOP
//=================================================================
void loop(){
//float Vout = (analogRead(0) * aref_ext_voltage) * 0.005;
Input = analogRead(A0) - 1.25/0.005;
myPID.Compute();
Serial.print(Output);
Serial.print(" ");
Serial.print(Input);
Serial.print(" ");
Serial.println(Setpoint);
lcd.setCursor(0,0);
lcd.print("Temperature:"); //Do not display entered keys
lcd.print(Input);
//Get user input for Setpoints
if(digitalRead(down_key)==LOW)
{
if(Setpoint>0)
{
Setpoint--;
}
}
if(digitalRead(up_key)==LOW)
{
if(Setpoint<150)
{
Setpoint++;
}
}
//Display Set point on LCD
lcd.setCursor(0,1);
lcd.print("Set Point:");
lcd.print(Setpoint);
lcd.print("C ");
//Check Temperature is in limit
//if(Temperature > Setpoint)
//{
// digitalWrite(RELAY,LOW); //Turn off heater
// digitalWrite(LED_RED,LOW);
// digitalWrite(LED_GREEN,HIGH); //Turn on Green LED
//}
//else
//{
// Temperature - 2;
// digitalWrite(RELAY,HIGH); //Turn on heater
// digitalWrite(LED_GREEN,LOW);
// digitalWrite(LED_RED,HIGH); //Turn on RED LED
//}
/************************************************
turn the output pin on/off based on pid output
************************************************/
unsigned long now = millis();
if (now - windowStartTime > WindowSize)
{
//time to shift the Relay Window
windowStartTime += WindowSize;
}
if (Output > now - windowStartTime)
{
digitalWrite(RELAY,LOW); //Turn off heater
digitalWrite(LED_RED,LOW);
digitalWrite(LED_GREEN,HIGH); //Turn on Green LED
}
else
{
digitalWrite(RELAY,HIGH); //Turn on heater
digitalWrite(LED_GREEN,LOW);
digitalWrite(LED_RED,HIGH); //Turn on RED LED
}
// delay(100); //Update at every 100mSeconds
}
//=================================================================