PID control initiates heater at startup though temperature below set point

Hello,

I starting with basic PID control set-up, with a DS18B20 temperature sensor connected to an Arduino UNO with a Real Time Clock (RTC) and controlling a silicon heater pad connected to an aluminum block. The setup is designed to begin a controlled heat ramp of the aluminum block at a set time each day. Currently everything is residing on my desk and so while the set temperature begins at 13C the sensor/block are already at 19C. Thus when the program is uploaded to the Arduino one would expect that the PID would not turn on the heater. What happens, however, is that the PID pulses the heater on and off for ~1 min right after upload before going quiet until the set temperature rises above the sensor temperature and the heat ramp commences.

My question is regarding this initial "on" behavior and if its normal? Does the PID need to "collect" some data before it really settles into control and "realize" that no heating is necessary? The problem is that the heater pad is really quite powerful and even 1 min of heating initially is really going to throw off the controlled heat ramp I have set up. After the initial min it does seem to settle in and work just great. I have played a bit with the tuning parameters to see if I could lengthen or shorten the initial heating period and I haven't seen a great deal of change in this initial behavior.

I have just tested my setup with a TMP36 sensor running on an analog rather than digital pin (DS18B20 is digital) and found that after two quick ~1s switches, the controller did not turn on the heater until the measured temperature went above the set temperature. So it appears this might be an analog vs digital sensor/signal issue, though I don't know why or how to work around it. I would rather use the DS18B20 sensors as they have proven work better over longer distances and the ability to use a slightly higher resolution eliminates some relay switching from the "jumpy" TMP36 sensor when controlling the heater.

I can provide the code I am using as well, but figured I would start with a description and then add the code if that would be helpful for troubleshooting.

Thanks for any assistance,
Nate

A first iunspection would seem to indicate that the thermal coupling between sensor and work is not what it should be... there is apparently a large enough thermal lag to account foe the 'delay'. This was the red flag that caused me to comment... A non contact IR thermometer might point to the real issue.. The heated object has less coupling to the sensor than the heater... thus causing the converging lag in the heating profile parameters. A PID loop is a very serious piece of code and the measurements must be as good as possible.. There is an OLD expression that might well fit... GiGo for 'in and 'out'

Doc

Find out what temperature the DS18B20 is actually reading, when the arduino starts up. Is the first temperature reading correct ?

The PID control scheme, incorporates the temperature error ( difference between measurement and set-point ), and the cumulative error ( the integral of it ), and the derivative error ( the rate of change of the error ). You obviously need at least two temperature measurements to start calculating the integral and derivative terms. Make sure they are initialised to sensible values.

I have just tested my setup with a TMP36 sensor running on an analog rather than digital pin (DS18B20 is digital) and found that after two quick ~1s switches, the controller did not turn on the heater until the measured temperature went above the set temperature.

Normally, you want to turn on the heat when the measured temperature goes BELOW the set temperature. Not above it.

Be aware that if the first temperature reading is zero, than your algorithm will be calling for the heater to start. You can avoid this by doing a basic credibility check on the temperature readings. I suggest you post the code of your sketch.

Hi all,

Thank you for your help. I'm still exploring what is causing the PID controller to turn on a heater when the measured value is above the set point and you have all provided good feedback.

  1. The initial set temperature set is not set to zero (its 13C). Currently this is below the temperature of the room/metal block so the heater should not come on.
  2. The initial temperature readings are accurate and above the set temperature.
  3. While I have run the whole system with a heater and the TMP36 analog temperature sensor and gotten good results, I would like to use a Maxim DS18B20 sensor and I currently troubleshooting using an LED to signal when the heater is "on".
  4. I see the same behavior where for several minutes after the initial upload of the sketch the heater/LED flicks on and off (but not in a regular way so I don't think its a repetitive/timer issue). Eventually the on/off slows and finally stops. During this time there is no actual heating of the sensor (I am watching the LED), but the sensor temperature always remains above the set temperature (e.g., sensor reads: 16.5C, set temperature is: 13C). It seems as though in this set-up the controller should quickly "recognize" and remain "quiet" until the set temp goes above the measured temp (sorry if I misspoke about this in my earlier post).
  5. What is perhaps most perplexing to me is that different temperature sensors (as mentioned above) give different behavior. I attached the code file.

This sketch is replicating heating that occurs during low tide. So the heating of the aluminum plate is at a controlled rate during a period when the tide is out (a valve opens so no water is in the tank).
A couple details about it that I am aware of.
1.Yes, I am concerned that the Timer.h library may relate to my issue in some ways (though again the PID behavior is really very good with the TMP36 sensor). I have tried using millis() to generate timers so that the PID refreshes every 200ms, while the set temperature increases every min. So far I have struggled to get that to work properly and so I have resorted to the Timer.
2. The tuning parameters (200, 100, 10) for the PID have worked for this setup using the TMP36 so I have left them for the DS18B20.
3. There are some extraneous details here (Serial Monitor, LCD) hopefully you can look past those to focus on the PID issue, but I left them in, in case they are contributing to this issue somehow through the Timer.

Finally, I am a biologist not a programmer so I welcome all comments you wish to contribute on ways to make this code better/more efficient/clearer, etc.

Thank you,

Nate

TempRampPID_loop_LCD_1Wire_Arduino.ino (11 KB)

Hello,

I apologize, but I just realized that in the code I attached to my last message I had mistakenly reassigned the variable "timeDelay" as "int" when it needs to be "float". Without this the temperature ramp will not work.

Very sorry for the confusion,
Nate

This doesn't look good:

     Input = getTempFunc(); //get an input (temperature) from the getTempFunc
  //---------------------------------------------------------
  //getTempFunc function. This function takes a digital reading
  //and returns a temperature value. - No it doesn't
  //---------------------------------------------------------
  float getTempFunc()
  {
    sensors.requestTemperatures();
    temp = sensors.getTempC(Temp01);
  }

getTempFunc needs a return statement. Right now, Input is getting whatever was left on the stack.

What happens, however, is that the PID pulses the heater on and off for ~1 min right after upload before going quiet until the set temperature rises above the sensor temperature and the heat ramp commences.

Sorry can you clarify, SET temp should not move.

I have just tested my setup with a TMP36 sensor running on an analog rather than digital pin (DS18B20 is digital) and found that after two quick ~1s switches, the controller did not turn on the heater until the measured temperature went above the set temperature.

If controller is turning ON after measured temp is above set temp them you have the project setup for cooling rather than heating.

Need some clarification over exactly what is going on.

Tom..... :slight_smile:

PS, try setting your initial temp measurement to 10, this will mean that the PID initially sees a stepup in input, which for a heating PID should keep the output low.
Or do a temp reading in SETUP, to seed the temp value.

Tom and wildbill,

Thanks for your comments and help.
First for wildbill: Thank you for noting that. I have added a return temp; statement to the getTempFunc.
However, I still get the same behavior which I will comment on in response to Tom.

Tom:
Yes, in the initial post I misspoke/wrote. I am heating and thus when the measured temperature is below the set temperature I want the controller ON, and when the measured temperature is above the set temperature I want the controller OFF. Sorry, not the type of mistake you want to make in the initial posting. Hopefully this makes this clear and that should be how the sketch is set up.

Second. For these tests I upload the sketch prior to the low tide time specified in the sketch so I can verify the controller remains off. So initially the set point is constant at 13C and is not changing, but it is during this period when the controller is turning on.

I'm not sure I understand one of your final comments regarding setting the initial temperature to 10. If the initial temperature is 10, but the set temperature is 13 this will turn the controller on, correct? I have actually played with specifying the initial temp to be 0, 10, 30 and it doesn't seem to change things.

In the room where I am currently doing these tests, the initial temperature measurements from the sensor are ~19-20C, which is well above the 13C set point so it seems like the controller should be off, or at least quickly turn off.

To try to clarify this I wrote out the exact same sketch for the TMP36 sensor using the same format. I have attached this one so that it can be compared side-by-side to sketch attached to my last posting. Do note that I have since added the "return temp;" statement to "getTempFunc" as recommended by wildbill.

In the TMP36 sketch (attached here) the PID controller comes on once in the first second following upload and then remains off until the set temperature is higher than the measured temperature. So it works!
In the 1Wire sketch (attached to my last posting) the PID controller flips on and off for the first 1-2 minutes following upload before turning off, until the set temperature is higher than the measured temperature. This doesn't work.

I have been going through both sketches trying to figure out why they have these different behaviors with different sensors and I can't see it. Again, note that I have added a "return temp;" statement to the most recent version 1Wire sketch, though I haven't posted this new sketch.

Thank you all for your help. I greatly appreciate it,

Nate

TempRampPID_loop_LCD_TMP36_Arduino.ino (10.7 KB)

I think I'd put a print statement in Pidloop to see what value output has.

BTW, why is the PID set up for REVERSE?