Hey I am working on a temperature controller and have come up with the following code. I have one problem and that is I am controlling a compressor for the cooling and do not want to short cycle the equipment. How can i set it up so that the relay output is high for say at least 10 minutes?
Here is the PID code:
void doPID(){
myPID.Compute();
unsigned long now = millis(); //get now time
if(now - windowStartTime > WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if(output > now - windowStartTime) {
digitalWrite(relayOut,HIGH); //ON
}
else {
digitalWrite(relayOut,LOW); //OFF
}
Serial.print(relayOut);
}
Also here is the full thing:
// This Arduino sketch reads DS18B20 "1-Wire" digital
// temperature sensors and displays it on a 16x2 LCD
// Include the libraries below
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <PID_v1.h>
// initialize the lcd library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// Data wire for one wire sensors is on pin 3
#define ONE_WIRE_BUS 4
//Define encoder pins
#define encoderPinA 2
#define encoderPinB 3
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
DeviceAddress Temp1 = { 0x28, 0xA8, 0x4B, 0x22, 0x05, 0x00, 0x00, 0x38 };
const int displaySwitch = 5;
const int displayOnOff = 6;
const int relayOut = 14;
int onCount;
double tempSP = 33;
float maxTemp =-100;
float minTemp=100;
int resetCount = 0;
double inputTemp, output;
int WindowSize = 5000; //5 sec
unsigned long windowStartTime;
PID myPID(&inputTemp, &output, &tempSP,2,5,1, DIRECT);
void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
// set the resolution to 10 bit
sensors.setResolution(Temp1, 10);
//Setup LCD
lcd.begin(16, 2);
//Setup Button pins
pinMode(displaySwitch, INPUT);
pinMode(displayOnOff, OUTPUT);
//setup encoder
pinMode(encoderPinA, INPUT_PULLUP);
digitalWrite(encoderPinA, HIGH); // turn on pullup resistor
pinMode(encoderPinB, INPUT_PULLUP);
digitalWrite(encoderPinB, HIGH); // turn on pullup resistor
//Setup interupt
attachInterrupt(0, doEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2
attachInterrupt(1, doEncoder, CHANGE); // encoder pin on interrupt 1 - pin 3
myPID.SetMode(AUTOMATIC);
pinMode(relayOut,OUTPUT);
windowStartTime = millis();
myPID.SetOutputLimits(0, WindowSize);
}
void doEncoder() {
/* If pinA and pinB are both high or both low, it is spinning
* forward. If they're different, it's going backward.
* For more information on speeding up this process, see
* [Reference/PortManipulation], specifically the PIND register.
*/
if (digitalRead(encoderPinA) == digitalRead(encoderPinB)) {
tempSP = tempSP + 0.5;
} else {
tempSP = tempSP - 0.5;
}
lcd.clear();
lcd.print("SetPoint:");
lcd.print(tempSP,2);
lcd.print(" F");
}
void doPID(){
myPID.Compute();
unsigned long now = millis(); //get now time
if(now - windowStartTime > WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if(output > now - windowStartTime) {
digitalWrite(relayOut,HIGH); //ON
}
else {
digitalWrite(relayOut,LOW); //OFF
}
Serial.print(relayOut);
}
void printTemperature(DeviceAddress deviceAddress)
{
// This is the Serial Print function to see temperature if the diplay is not working
Serial.print("Getting temperatures...\n\r");
sensors.requestTemperatures();
Serial.print("Current temperature is: ");
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
Serial.print("Error getting temperature");
} else {
Serial.print("C: ");
Serial.print(tempC);
Serial.print(" F: ");
Serial.print(DallasTemperature::toFahrenheit(tempC));
Serial.print("\n\r");
}
}
void displayTemperature(DeviceAddress deviceAddress)
{
delay(2000);
float tempC = sensors.getTempC(deviceAddress);
float tempF = sensors.getTempF(deviceAddress);
//calculate min and max
if (tempF>maxTemp){maxTemp = tempF;}
if (tempF<minTemp){minTemp = tempF;}
if (tempC == -127.00) // Measurement failed or no device found
{
lcd.clear();
lcd.print("Temperature Error");
}
else
{
lcd.clear();
lcd.print("SetPoint=");
lcd.print(tempSP,2); //Display Setpoint
lcd.print(" F");
lcd.setCursor(0,1); //Start at character 0 on line 1
lcd.print("Act.Temp=");
lcd.print(tempF,2); //Display temperature reading with 2 decimal places
lcd.print(" F");
tempF = 0;
inputTemp = tempF;
}
}
void displayMinMaxTemperature(DeviceAddress deviceAddress)
{
delay(2000);
lcd.clear();
lcd.print("Min Temp=");
lcd.print(minTemp,2); //Display min temp
lcd.print(" F");
lcd.setCursor(0,1); //Start at character 0 on line 1
lcd.print("Max Temp=");
lcd.print(maxTemp,2); //Display max temp
lcd.print(" F");
}
void backLightReset()
{
//Now turn on the backlight if the button is pressesd
//Now rest min and max temps if button is held down
if (digitalRead(displaySwitch) == HIGH){
onCount = 5; // This determines time that it will stay on
// Remember delay also affects the time it is on
resetCount = resetCount + 1;}
else{
resetCount = 0;
if(onCount > 0){
onCount = onCount - 1;
}
else{
onCount = 0;
}
}
if(onCount > 0){
digitalWrite(displayOnOff, HIGH);
}
else{
digitalWrite(displayOnOff, LOW);
}
if(resetCount > 3){
maxTemp = -100;
minTemp = 100;
}
}
void loop(void)
{
// Thiw will print the temp reading so it can be read
// through serial connection when a display is not attached
// Remove this to speed things up once the display is working
//printTemperature(Temp1);
// This will display temp and setpoint on the LCD
displayTemperature(Temp1);
doPID();
// Now turn on the backlight if the button is pressesd
// Now rest min and max temps if button is held down
backLightReset();
// Display Min and Max Temperatures
displayMinMaxTemperature(Temp1);
// Now turn on the backlight if the button is pressesd
// Now rest min and max temps if button is held down
backLightReset();
}
I would appreciate any help I'm sure this has been done but I have not been able to find it.