Temperature controller without analog output (PID?)

I am working on a project where I need to control a several hundred watt heater using a digital output fed in to a solid state relay. Most of what I can find on temperature and PID control is either reliant on analog control over heater power or just a simple deadband systems where the output is on if the temp is below the setpoint.

The former doesn't work for me because of the relay output and the latter will have major overshoot issues due to the separation of the heating element and thermocouple. I know it is possible to get good control even with the limitations because that is how discrete temperature controllers work. I've done some searching on google and on this forum but haven't found much. I know it has to be out there so I must not be using the right search terms.

TIA

If you have a reasonable model for the system, you can anticipate the overshoot and compensate by shutting the heater off early, vice versa for the cooling phase.

Develop that model by experimentation. Many home HVAC smart thermostats do just that, by learning the system response from day to day and adjusting internal model parameters.

in order for that to work I would need to track whether the temperature reading is heating up or cooling down at that moment in time, right?

so something like

loop(){
    if (tempNow >tempPrev && tempNow < setpoint - offset){
      applyHeat ()
    }
    
    if (tempNow < tempPrev && tempNow < setpoint + offset){
      applyHeat ()
    }
  tempPrev = tempNow
}

Usually on/off control with a setpoint will work quite well for water baths etc.
You do not want to shut on/off a relay every second. So if you need more switching you should look at a SSR.
If your sensor is far away from the heater (large dead time) control will be difficult...

1 Like

I am already using an SSR. The large dead time leading to control difficulties is exactly what I am seeking help with.

the thermocouple is not that far physically from the heaters but it is separated by an air gap leading to a relatively long delay between heat being applied and the TC seeing a temp rise

That is required. Then, experimentation is needed to figure out the timing.

it is separated by an air gap

Another approach is to eliminate the cause of the delay, the air gap.

Hi @davidgee,

as @jremington wrote it will require some tests and measurements to find out when to switch on and when to switch off the heater. If you know what your minimum temperature will be when you have to start heating, that would be a good point to begin.

Let's assume the minimum temperature is 10°, you might switch on the heater and check the temperature of the water as well as the sensor data in certain intervals.

  • Relation between "heater on" and real water temperature
  • Relation between real water temperature and sensor data

Just a simple sketch to illustrate how it might look like:

image

Obviously the amount of water, the start temperature and end temperature as well as the environmental temperature (and the temperature loss, is dissipation the right word in English?) will have an influence. So if any of those changes you'll have to adjust the time the heater is on ...

Good luck
ec2021

P.S.: And do not forget a safety circuit that cuts off the heater either after a certain time or when a certain temperature has been reached. I would recommend something completely independed from software ... :wink:

How fast is your system?

Common ($40 at Amazon) controllers for larger, slower heaters do PID with a duty cycle on a user-selected period in seconds. The one on my desk had an adjustment of this as "cTL Output Control Mode" with 1-120 sec. The user selects this control period, and the PID chooses the fraction of that period to be on.

Using a default Arduino PID library setup, the recalculation interval is 0.1s, which would be too fast for a system with response times/time constants on the order of minutes. If you know your system's time constant, try a sampling time of about 1/10 of the system time constant.

Without knowing your system's time constant, perhaps the standard Arduino PID library would work more with a sampling interval of 1-20 seconds and turning the Ki=0 and Kd=0. With large Kp, and Ki=0, Kd=0, the Arduino PIDs act like the simple bang-bang systems.

Sorry about the constant edits etc, I am new to the forum and still figuring it out. It's been a while since I've used this interface.

The problem is that I want to control things based on the temperature of the actual media into which the thermocouple is embedded. I could put it on the heating element itself which wraps around the outside of the container but there would be a significant difference between that and the media contained within that I am attempting to heat with some degree of precision.

This is helpful. Is the time constant the time between turning on the heater and the temperature starting to rise?

By "simple bang-bang systems" do you mean those standalone temperature controllers?

I think I found my solution here Arduino Playground - PIDLibrary since it specifically gives relay output examples

The time between calling for a change and when it starts to move at all is called "dead time", while the time it takes for a system to move substantially (67%* of the way towards finished moving) is called the "time constant" (* 67% because of the mathematics of exponential decay)

Dead Time versus Time Constant | Control Notes has a good chart:


image per https://blog.opticontrols.com/archives/499

If your system was off, and you turned your heater on at 10% power with a while(true)digitalWrite(pin,HIGH); delay(10000);digitalWrite(pin,LOW),delay(90000); (or a better millis() based blink) how hot would your system ultimately get and how long would it take to get about 2/3 of the way there?

ETA: Oh -- And bang-bang is another name for those controllers that work like a thermostat:

  if (Temperature < Setpoint){ 
     digitalWrite(heaterPin,HIGH);
  } else {
     digitalWrite(heaterPin,LOW);
  }
1 Like

Yes,
https://playground.arduino.cc/Code/PIDLibraryRelayOutputExample/
is good -- though if your system is slow, that 5 in the

  PID myPID(&Input, &Output, &Setpoint, 2, 5, 1, DIRECT);

will be super slow and oscillate like mad. A setting with Kp=5000/10=500, Ki=0, Kd=0 like this:

PID myPID(&Input, &Output, &Setpoint, 500, 0, 0, DIRECT);

...will act a bit softer than a +/- 10 degree deadband, by beginning to proportionally trim the output from 100% (or 5000ms on out of each 5000ms) when the process reaches 10° from the setpoint.

1 Like

@DaveX your posts have been invaluable. Thank you so much for your help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.