Temperature on/off

I have a large code that I have reduced here to the barest essentials of the part I’m having trouble with. I need to turn on a heat source when a temperature gets below a certain point (36) then turn off when the temperature gets above a higher set point (38).

Seems like it should be simple. I’ve spent four days researching what I could find about temperature control, hysteresis, thermostats etc. The one article about hysteresis that keeps getting pointed to doesn’t make any sense at all to me for this application.

This sketch is as close as I can get but it does nothing between 36 and 38. Other thing I have tried also do nothing between 36 and 38 with the added bonus of turning both on below 26.

#include <Wire.h>
#include <DallasTemperature.h>
#define refresh_time  3000//final is 4000
#define ONE_WIRE_BUS 7
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Addresses of  DS18B20s temp sensors

uint8_t sensor8[8] = {  0x28, 0x4F, 0xEF, 0x7D, 0x08, 0x00, 0x00, 0xEA };// #29
const int relay_4 = 5;

void setup(void)
{
  Serial.begin(9600);
  sensors.begin();
  Serial.println();

  pinMode(relay_4, OUTPUT);
  digitalWrite(relay_4, LOW);
}

void loop(void)
{

  sensors.requestTemperatures();

  float temperature8 = sensors.getTempF(sensor8);

  Serial.print ("Temp: ");
  Serial.println(temperature8);

  if (temperature8 <= 36) {
    Serial.println("Heat Relay:  ON");
    digitalWrite(relay_4, HIGH);
    delay(500);
  }
  if (temperature8 >= 38) {

    Serial.println("Heat Relay:  OFF");
    digitalWrite(relay_4, LOW);
    delay(500);
  }

  Serial.println();
  Serial.println();

  //refresh interval
  delay(refresh_time);


}

This is the serial output of the above sketch

Falling temperature

Temp: 40.10
Heat Relay: OFF

Temp: 36.95

Temp: 35.60
Heat Relay: ON

Rising temperature

Temp: 35.15
Heat Relay: ON

Temp: 36.50

Temp: 37.40

Temp: 38.30
Heat Relay: OFF

As you can see nothing happens between 36 and 38

Based on your description and the serial output, your program works perfectly. It turns off above 38 and on below 36 exactly as you want. What is the issue?

It's doing exactly what you describe in your first paragraph, which seems to make sense to avoid short cycling the heater. What do you want it to do instead?

With hysteresis, nothing is supposed to happen between the high and low set point. That is why it is often called a “dead zone”.

I suggest you don't use hysteresis for controlling temperature, use PWM. If you use PWM you get far better control and maintain the temperature a lot closer to the desired temperature. How you use PWM depends on what you are heating and the kind of heater you are using.

Part of hysteresis is knowing how much delay is caused by the structure holding your heating element. The temperature of the heating element may be much higher or much lower than where you have the temperature sensor.

I once converted an old drying oven to Arduino temperature control. The heating element was contained in a cast iron fixture that had it's own hysteresis of about 5 minutes. So, after first turning on the oven heat, 15 minutes past before the oven reached the minimum temp. Then continued to heat for about 5 minutes after turning off the power to the heater.

Do you have a similar problem?

Paul

OK, now I feel stupid. I have for the most part going by what the serial monitor said not, what the output pin actually did. I assumed they would behave the same. You are right the relay does turn on/off at the correct times.

I have a logging file that outputs comma separated data and those missing ON/OFF's were messing things up. I think if I simply have the logfile simply either be on or off, with no overlap, at a set temp it should fix that.

At least I learned about 10 different ways of saying the same thing. :)

OK, now I feel stupid.

Don’t. We all make daft mistakes and I am no exception to that. Just make sure you learnt something :slight_smile:

Now that I have this sorted out, can someone explain why it works with the pinout but not with serial monitor?

somewhereinusa:
Now that I have this sorted out, can someone explain why it works with the pinout but not with serial monitor?

You print statements only print the state of the output when it changes, so the last value printed is valid.

If you want it printed each loop, you could add a state variable inside the “if” statements that gets set when the pins are set. So you’d remove the print statements inside the “if” and print the pin state after those have been evaluated.