heat and cool with programmable profiles.

Here's an example of using PID in a situation where all you have is on/off control of your devices:

http://playground.arduino.cc/Code/PIDLibraryRelayOutputExample

BTW - the use of 9800 baud in your serial begin looks like a typo - 9600?

I have seen that pid libray 1,000 times. My question is how do i incorporate it with this type of program ? I have been reading and searching for days now and all iget are those libraries. Isnt there anything that tells me how to use the pid libraries to tie in with my program ? yes i the 9800 is a typo

I'd suggest that the example code in that link is pretty much exactly what you need. Just try using that technique to control the heating and hold phase only. Use millis to determine which phase you're in by time elapsed and adjust the setpoint for whatever temperature is required in that phase and let the PID do its thing. You may need to have a separate PID variable to control the cooling.

Thanks wildbill. I fully understand what your saying. But my problem is fully understanding how to -create and control 2 PID loops in the same scetch. -.se millies and phases to work out how long the chocolate has been at the set temperature then automaticly move on to the next temp.

Im sorry that I ask stupid questions but I am a 100% novice. I know what I am asking the arduino to do is a very simple operation for most people here but for me its confusing when I look at alot of code and see so many different ways of doing the same thing-

Did you look at the code that I supplied? That is one way of doing a temperature profile. The other way is to have a sequence of temperatures and the duration that they are at that temperature. You don’t really want to be switching between heating and cooling all the time. It’s better to have a heating section and a cooling section. Otherwise if your PID parameters aren’t set correctly the two devices could be battling each other. On the other hand if you have your PID values tuned, always switching between heating and cooling should be able to get you better control over the temperature. The code below should work out of the box with just the heating and cooling relays hooked up to an arduino.

#include <PID_v1.h>
#define heatingPin 2
#define coolingPin 12
int RelayPin = 0;
const double RoomTemp = 22;
double[] heatingPID = {2,5,1};  //This needs to be tuned
double[] coolingPID = {3,6,4};  //This needs to be tuned
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint,heatingPID[0],heatingPID[1],heatingPID[2],DIRECT);
double[] temps={50,28,31};  //Set Point temperatures are 50C 28C and 31C
unsigned long[] times={120000,60000,120000};  //Durations are 2min, 1min, 2min
unsigned long setPointStartTime;
unsigned long duration = 0;
int direction = 0;
int index = 0;
int WindowSize = 5000;
unsigned long windowStartTime;
void setup(){
  pinMode( coolingPin, OUTPUT);
  pinMode( heatingPin, OUTPUT );
  digitalWrite( coolingPin, LOW );      // ensure initial state is inactive
  digitalWrite( heatingPin, LOW ); 
  windowStartTime = millis();
  setPoint = temps[index];

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  setDirection(temps[index], getCurrentTemperature());
}
void loop(){
  Input = getCurrentTemperature();
  if((Input - SetPoint)*direction>0 && duration == 0){  //You have reached the setpoint
    duration = times[index];
    setPointStartTime = millis();
    //setDirection(SetPoint, RoomTemp);
  }else if(duration > 0 && (millis()-setPointStartTime)>duration){
    duration = 0;
    if(index<2){
      index++;
      Setpoint = temps[index];
      //setDirection(SetPoint, temps[index - 1]);
    }
  }
  setDirection(SetPoint, Input);  
  myPID.Compute();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime){
    digitalWrite(RelayPin,HIGH);
  }else{
    digitalWrite(RelayPin,LOW);
  }
}
void setDirection(double tempA, double tempB){
  if(tempA>tempB){
    if(direction < 1){
      digitalWrite(CoolingPin,LOW);  //Turn of Cooling
      direction = 1;
      RelayPin = HeatingPin;
      myPID.SetControllerDirection(DIRECT);
      myPID.SetTunings(heatingPID[0] , heatingPID[1] , heatingPID[2]);
    }
  }else{
    if(direction > -1){
      digitalWrite(HeatingPin,LOW);  //Turn of Heating
      direction = -1;
      RelayPin = CoolingPin;
      myPID.SetControllerDirection(REVERSE);
      myPID.SetTunings(coolingPID[0] , coolingPID[1] , coolingPID[2]);
    }
  }
}

Thank you for the code. I cant get it to work though i get a whole bunch of errors. lots of " not declared in scope errors" and all of the [ ] lines. am I missing something ?

I didn't actually check the code in a compiler so there may be errors to fix. I tried to make sure it was as consistent as possible.

Ok I fixed it for you. You just need to make sure you have the PID library in the right spot and add the getCurrentTemperature() function.

#include <PID_v1.h>
#define heatingPin 2
#define coolingPin 12
int RelayPin = 0;
const double RoomTemp = 22;
double heatingPID[] = {2,5,1};  //This needs to be tuned
double coolingPID[] = {3,6,4};  //This needs to be tuned
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint,heatingPID[0],heatingPID[1],heatingPID[2],DIRECT);
double temps[]={50,28,31};  //Set Point temperatures are 50C 28C and 31C
unsigned long times[]={120000,60000,120000};  //Durations are 2min, 1min, 2min
unsigned long setPointStartTime;
unsigned long duration = 0;
int direction = 0;
int index = 0;
int WindowSize = 5000;
unsigned long windowStartTime;
void setup(){
  pinMode( coolingPin, OUTPUT);
  pinMode( heatingPin, OUTPUT );
  digitalWrite( coolingPin, LOW );      // ensure initial state is inactive
  digitalWrite( heatingPin, LOW ); 
  windowStartTime = millis();
  Setpoint = temps[index];

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  setDirection(temps[index], getCurrentTemperature());
}
void loop(){
  Input = getCurrentTemperature();
  if((Input - Setpoint)*direction>0 && duration == 0){  //You have reached the setpoint
    duration = times[index];
    setPointStartTime = millis();
    //setDirection(SetPoint, RoomTemp);
  }else if(duration > 0 && (millis()-setPointStartTime)>duration){
    duration = 0;
    if(index<2){
      index++;
      Setpoint = temps[index];
      //setDirection(SetPoint, temps[index - 1]);
    }
  }
  setDirection(Setpoint, Input);  
  myPID.Compute();
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime){
    digitalWrite(RelayPin,HIGH);
  }else{
    digitalWrite(RelayPin,LOW);
  }
}
void setDirection(double tempA, double tempB){
  if(tempA>tempB){
    if(direction < 1){
      digitalWrite(coolingPin,LOW);  //Turn of Cooling
      direction = 1;
      RelayPin = heatingPin;
      myPID.SetControllerDirection(DIRECT);
      myPID.SetTunings(heatingPID[0] , heatingPID[1] , heatingPID[2]);
    }
  }else{
    if(direction > -1){
      digitalWrite(heatingPin,LOW);  //Turn of Heating
      direction = -1;
      RelayPin = coolingPin;
      myPID.SetControllerDirection(REVERSE);
      myPID.SetTunings(coolingPID[0] , coolingPID[1] , coolingPID[2]);
    }
  }
}

Thankyou very much. err another very ignorant question. What getCurrentTemperature() function is the code refering too exactly ?
dose this mean I need to add in code for the ds18b20 and name it getCurrentTemperature ?

I suspect that laadams85 is referring to your function of the same name, so you can just paste it in. However, I'm not entirely convinced that that function works - have you tried it yet stand alone? The DS18B20 needs to be asked to read temps and then some time later - up to 750ms later, it will be ready to read. I didn't see that happening in your version, though it is a bit cryptic. If it isn't working, consider using the Dallas Temperature library.

I have been trying to get the two codes to work together but im not really getting anywhere. my biggest problem is getting functions to work with other functions. or adding a function into a shetch that already works.

This should combine my code with your getCurrentTemperature function.

#include <OneWire.h>
#include <PID_v1.h>
#define heatingPin 2
#define coolingPin 12
int RelayPin = 0;
const double RoomTemp = 22;
double heatingPID[] = {2,5,1};  //This needs to be tuned
double coolingPID[] = {3,6,4};  //This needs to be tuned
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint,heatingPID[0],heatingPID[1],heatingPID[2],DIRECT);
double temps[]={50,28,31};  //Set Point temperatures are 50C 28C and 31C
unsigned long times[]={120000,60000,120000};  //Durations are 2min, 1min, 2min
unsigned long setPointStartTime;
unsigned long duration = 0;
int direction = 0;
int index = 0;
int WindowSize = 5000;
unsigned long windowStartTime;

const int TEMP_SENSOR_PIN = 3;
OneWire ds(TEMP_SENSOR_PIN); 

void setup(){
  pinMode( TEMP_SENSOR_PIN, INPUT );
  pinMode( coolingPin, OUTPUT);
  pinMode( heatingPin, OUTPUT );
  digitalWrite( coolingPin, LOW );      // ensure initial state is inactive
  digitalWrite( heatingPin, LOW ); 
  windowStartTime = millis();
  Setpoint = temps[index];

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  setDirection(temps[index], getCurrentTemperature());
}
void loop(){
  Input = getCurrentTemperature();
  if((Input - Setpoint)*direction>0 && duration == 0){  //You have reached the setpoint
    duration = times[index];
    setPointStartTime = millis();
    //setDirection(SetPoint, RoomTemp);
  }else if(duration > 0 && (millis()-setPointStartTime)>duration){
    duration = 0;
    if(index<2){
      index++;
      Setpoint = temps[index];
      //setDirection(SetPoint, temps[index - 1]);
    }
  }
  setDirection(Setpoint, Input);  
  myPID.Compute();
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime){
    digitalWrite(RelayPin,HIGH);
  }else{
    digitalWrite(RelayPin,LOW);
  }
}
void setDirection(double tempA, double tempB){
  if(tempA>tempB){
    if(direction < 1){
      digitalWrite(coolingPin,LOW);  //Turn of Cooling
      direction = 1;
      RelayPin = heatingPin;
      myPID.SetControllerDirection(DIRECT);
      myPID.SetTunings(heatingPID[0] , heatingPID[1] , heatingPID[2]);
    }
  }else{
    if(direction > -1){
      digitalWrite(heatingPin,LOW);  //Turn of Heating
      direction = -1;
      RelayPin = coolingPin;
      myPID.SetControllerDirection(REVERSE);
      myPID.SetTunings(coolingPID[0] , coolingPID[1] , coolingPID[2]);
    }
  }
}
double getCurrentTemperature() {
  int highByteData, lowByteData, sensorReading;
  byte data[12];
  float temperature;
  
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);
  
  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);

  for (int i = 0; i < 12; i++) {
    data[i] = ds.read();
  }
  
  lowByteData = data[0];
  highByteData = data[1];
  sensorReading = (highByteData << 8) + lowByteData;
  
  if (sensorReading & 0x8000) { // test the most significant bit for sign
    sensorReading = -sensorReading;
  }
  temperature = sensorReading * 0.0625; // minimum quantised reading from temp sensor DS18B20
  
  return (double)temperature;  
}

Thank you so much. i still has some buggs in thier . ill see if i can work them out. thank you

I'm doing this in a text editor. I apologize for any bugs.

Please dont apologize you have saved me alot of hard work. It works now was an easy fix even for me. so from here i should be able to add other features into it like the lcd and buttons ?

Don't add anything until you get the PID working, You'll thank me later. What I means is get your PID constants ironed out first before continuing. But yah, you should be able to add whatever you want to it.

I assume you fixed the minor issues and got it to compile. Does it actually work if you test it with a bowl of water, or chocolate if you're feeling lucky? I'd be surprised if you got that going so quickly. If so, nice work! If not, I'd suggest you get what you have working and thoroughly tested before you add any more code.

I was just thinking that I need to be able to see what temperature it is reading. at the moment i cant see what temp its at. so I just want the current temp to show on the screen so i can see what is happening.

If you have your arduino connected to your computer you can use the serial monitor to debug and see what is being read and what the output is. You can use Serial.println() to print it to your serial monitor.