Hello All,
I am quite new to this and have just made a system to help me keep water at a constant temperature.
The setpoint is a potmeter scaled to 0-100, the input is a DS18B20 and I print current temperature and setpoint temperature to my LCD. The output is going to a SSR to turn on and off the water heater.
First I tested this setup with a program which just turned on and off on +/- 2 Deg C, but I wanted to use PID control for this.
I have now used the examples I have found and scanned several other projects to make the program below.
Of course the program doesn't work 100% and I have used Serial.print to detail it down to that the Output of the PID is not changing at all, always 0.00.
Is there anyone which can help me to figure out where I messed up?
/* A fair portion of the code here is from Arduinotronics and I would have been lost with out it. This is my first “big” Arduino project. So, there is probably a ton of things that can be improved on and tweeked. I would love to know your thoughts and see your improvements! If you would like to share your thoughts with me on this please email me at modsbyus at modsbyus dot com and make the subject line RE: Arduino Thermostat Thoughts, or write a comment on the tutorial at DIY: Arduino Thermostat With the DS18B20 | Modsbyus.com */
/*Changed Set Temp Range 0-50 Deg C, Added Heating indication to Display (Used Fan Running Indication), Added DegC to Set temp on display, */
#include <OneWire.h> //This temperature sensor requires a 4.7k Ohm resistor across its pins 2 and three!!!!
#include <DallasTemperature.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> // F Malpartida's NewLiquidCrystal library
#include <PID_v1.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
int sensorPin = A0; // select the input pin for the 10K potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
int setTemp = 0; // variable to store temp desired
int SSRHPin = 6; //Turn on heat (electric or gas)
char* heat;
double currentTemp = 0;
//Define Variables we'll be connecting to for PID
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters for PID
double Kp=2, Ki=5, Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
int WindowSize = 5000;
unsigned long windowStartTime;
//This temperature sensor requires a 4.7k Ohm resistor across its pins 2 and three!!!! Thats the middle pin and the GND pin
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
// 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);
DeviceAddress insideThermometer = { 0x28, 0x8C, 0xB8, 0x49, 0x06, 0x00, 0x00, 0x5A };
// DeviceAddress outsideThermometer = { 0x28, 0x8E, 0xE6, 0x4A, 0x06, 0x00, 0x00, 0x8B };
void setup(void)
{
Serial.begin(9600);
// Start up the library
sensors.begin();
// set the resolution to 9 bit (good enough?)
sensors.setResolution(insideThermometer, 12);
// sensors.setResolution(outsideThermometer, 12);
lcd.begin (20,4); // columns, rows. use 16,2 for a 16x2 LCD, etc.
pinMode(SSRHPin, OUTPUT);
digitalWrite(SSRHPin, LOW);
windowStartTime = millis();
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
//Setting the unchanged text to the display
//lcd.clear(); // start with a blank screen
lcd.setCursor(0,0);
lcd.print("Current:");
lcd.setCursor(0,1);
lcd.print("Set:");
lcd.setCursor(7,1);
lcd.print("DegC");
lcd.setCursor(2,3);
lcd.print("HeatOn: ");
}
void printTemperature(DeviceAddress deviceAddress)
{
sensors.requestTemperatures(); // was in loop
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00)
{
lcd.print("Error");
} else {
// lcd.print(tempC);
// lcd.print("/");
currentTemp = (tempC);
lcd.print(currentTemp);
}
}
void loop(void)
{
//initialize the variables we're linked to
Input = (currentTemp);
//Serial.print (Input);
Setpoint = (setTemp);
//Serial.print (Setpoint);
myPID.Compute();
static boolean bHeatOn = false;
delay(500);
sensorValue = analogRead(sensorPin);
setTemp = sensorValue / 10.24; //Gives us a set temp range between 0 and 99 degrees
lcd.setCursor(8,0);
printTemperature(insideThermometer);
lcd.setCursor(4,1);
lcd.print(setTemp);
lcd.setCursor(10,3);
if (bHeatOn) {
lcd.print("On ");
}
else {
lcd.print("Off");
}
//Heating PID Relay ON/OFF
if (millis() - windowStartTime > WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if (Output < millis() - windowStartTime)
{
digitalWrite(SSRHPin, HIGH);
bHeatOn = true ;
Serial.print(Output);
}
else
{
digitalWrite(SSRHPin, LOW);
bHeatOn = false ;
}
}
PID_TEST_rev1.ino (4.06 KB)