PID Thermal controller

I'm trying to rig up a PID controller for a mash tun using a DS18b20 temp sensor on pin 3 and a n SSR on pin 11. My programming skills are next to zero so I'm surprised I made it as far as I have on m,y own. I can read the temp probe but I'm having trouble handing off it's input to the PID library. I'm sure I'm missing something simple but could use some help. Here's the sketch:

#include <PID_v1.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3
#define PIN_OUTPUT 11

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Define the aggressive and conservative Tuning Parameters
double aggKp=4, aggKi=0.2, aggKd=1;
double consKp=1, consKi=0.05, consKd=0.25;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

// 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:
// Arduino 1-Wire Address Finder

DeviceAddress HLTlow = { 0x28, 0xFF, 0xC5, 0xE9, 0x64, 0x15, 0x02, 0xF6 };

void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(HLTlow, 10);

//initialize the variables we're linked to
Input = ONE_WIRE_BUS 3;
Setpoint = 100;

//turn the PID on
myPID.SetMode(AUTOMATIC);
}

void printTemperature(DeviceAddress deviceAddress)
{
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));
}
}

void loop(void)
{
delay(2000);
Serial.print("Getting temperatures...\n\r");
sensors.requestTemperatures();

Serial.print("Low HLT temp: ");
printTemperature(HLTlow);
Serial.print("\n\r");
Serial.print("\n\r\n\r");
;
Input = ONE_WIRE_BUS 3;

double gap = abs(Setpoint-Input); //distance away from setpoint
if (gap < 10)
{ //we're close to setpoint, use conservative tuning parameters
myPID.SetTunings(consKp, consKi, consKd);
}
else
{
//we're far from setpoint, use aggressive tuning parameters
myPID.SetTunings(aggKp, aggKi, aggKd);
}

myPID.Compute();
analogWrite(PIN_OUTPUT, Output);
}

And here's my error message on compiling:

Arduino: 1.6.12 (Linux), Board: "Arduino/Genuino Uno"

/home/pi/Desktop/firstarduino/PID_controller/PID_controller.ino: In function 'void setup()':
PID_controller:48: error: expected ';' before numeric constant
Input = ONE_WIRE_BUS 3;
^
/home/pi/Desktop/firstarduino/PID_controller/PID_controller.ino: In function 'void loop()':
PID_controller:79: error: expected ';' before numeric constant
Input = ONE_WIRE_BUS 3;
^
exit status 1
expected ';' before numeric constant

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

1 Like

Please post your code properly, using code tags.

Although you state you have been able to read the temperature sensor, this is not how you do so (it won't even compile):

  Input = ONE_WIRE_BUS 3;

We recommend starting the with basic examples provided with the Arduino IDE before jumping into a project like this, cold.

You might also want to take a look at the article "Home Brewed HERMS" from Circuit Cellar issue 191 (June 2006) for some ideas. The author is using a PIC processor to implement a PID controller for his home brew mash heater and gives all the details of how he does it. I used a number of his ideas in my hummingbird heater controller when I built it a few years ago.

@jremington: I was able to read the temp sensors until I added the PID controller to the system and tried to figure out what the input variable to the controller was supposed to be. That's the part I figure I obviously have wrong.

You must have taken out the part where you read the temperature sensor properly. Study your original code!

'Input' is the current state of the variable you are trying to control. It must be in the same units of measure as 'Setpoint', the state you are trying to reach. Since you are trying to control temperature, Input and Setpoint must be a measure of temperature using the same units.

The units for 'Output' are arbitrary. The DIRECT setting tells the PID that to increase Input it should increase Output.

godivaPrima:
Wow- I didn't know Byte was still around. Still Steve Ciarcia?

Circuit Cellar - Byte was gone by then I believe. Steve Ciarcia (I think) started Circuit Cellar and was very active for a number of years although he vanished from the back page some time ago. Don't remember seeing any notice about him going, just not there any more. I think I still have a box of Killobaud magazines downstairs too :slight_smile:

I figured it out. The input variable should have been "tempC". Now I just have to figure the right parameters for my system.

Thanks to everyone for helping. It's been almost 20 years since I last tried to program anything and that was in FORTRAN.