Code works only when Uno is reset

I'm trying to create a controller for frost protection.
When temperature drops it turns on a relay and water pump. It uses AM2301 sensor and an UNO.
There is a lot of IF and ELSE IF statements, because based on humidity changes temperature when system should start.
System works when arduino is reset or loses power. If I leave it on, system does not respond and relay does not work, but serial monitor and screen shows correct and updated temperature.
My code:

#include <DHT.h>
#include <LiquidCrystal.h>

#define DHTPIN 7
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(12,11,5,4,3,2);

int relay = 8;  //relay connected to pin 8

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);

  pinMode(relay, OUTPUT);
  dht.begin();
}

void loop() {
  delay(2000);

  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) { //to check if there is a signal from sensor
    Serial.print(F("No data"));
    return;
  }

  float Tp = ((pow((h-10) / 100, 0.125)) * (112 + (0.9 * (t-1))) + (0.1 * (t-1)) - 112);  //to calculate dew point

  delay (1000);
  
  Serial.print(F("Humidity: "));  //all this stuff to help monitor how system works
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(F("Dew point: "));
  Serial.println(Tp);
  lcd.clear();
  lcd.print("Temperatura");
  lcd.setCursor(0,1);
  lcd.print(t);
  lcd.print(F("C"));
  delay(2000);
  lcd.clear();
  lcd.print("Dregme");
  lcd.setCursor(0,1);
  lcd.print(h);
  lcd.print(F("%"));
  delay(2000);
  lcd.clear();
  lcd.print("Dew point:");
  lcd.setCursor(0,1);
  lcd.print(Tp);
  lcd.print(F("C"));

  delay (1000);
  
  if (relay == HIGH) {  //if relay is working
    if ((t > 3) || (Tp > -1)) { // temperature and dew point when relay can be turned off
      digitalWrite (relay, LOW);
    }
  } else if ((t < 5.5) && (Tp < -8.5)) {   //at these temperature and dew point intervals relay should be on
    digitalWrite (relay, HIGH);
  } else if ((t < 5) && (Tp < -7.5)) {
    digitalWrite (relay, HIGH);
  } else if ((t < 4.5) && (Tp < -5.5)) {
    digitalWrite (relay, HIGH);
  } else if ((t < 3.5) && (Tp < -4.5)) {
    digitalWrite (relay, HIGH);
  } else if ((t < 3) && (Tp < -3.5))  {
    digitalWrite (relay, HIGH);
  } else if ((t < 2.5) && (Tp < -2.5)) {
    digitalWrite (relay, HIGH);
  } else if ((t < 2) && (Tp < -1)) {
    digitalWrite (relay, HIGH);
  }

  delay(20000); // there is no need to check temperature every second

}
#include <DHT.h>
#include <LiquidCrystal.h>

#define DHTPIN 7
#define DHTTYPE DHT22
#define RelayON (digitalWrite (relay_Pin,HIGH))
#define Relay_off (digitalWrite (relay_Pin,LOW))


DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int relay_Pin = 8;  //relay_Pin connected to pin 8

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);

  pinMode(relay_Pin, OUTPUT);
  dht.begin();
}

void loop() {
  delay(2000);

  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) { //to check if there is a signal from sensor
    Serial.print(F("No data"));
    return;
  }

  float Tp = ((pow((h - 10) / 100, 0.125)) * (112 + (0.9 * (t - 1))) + (0.1 * (t - 1)) - 112); //to calculate dew point

  delay (1000);

  Serial.print(F("Humidity: "));  //all this stuff to help monitor how system works
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(F("Dew point: "));
  Serial.println(Tp);
  lcd.clear();
  lcd.print("Temperatura");
  lcd.setCursor(0, 1);
  lcd.print(t);
  lcd.print(F("C"));
  delay(2000);
  lcd.clear();
  lcd.print("Dregme");
  lcd.setCursor(0, 1);
  lcd.print(h);
  lcd.print(F("%"));
  delay(2000);
  lcd.clear();
  lcd.print("Dew point:");
  lcd.setCursor(0, 1);
  lcd.print(Tp);
  lcd.print(F("C"));

  delay (1000);

  if (digitalRead(relay_Pin)) {  //if relay_Pin is working
    if ((t > 3) || (Tp > -1))Relay_off;  // temperature and dew point when relay_Pin can be turned off
  }
  else {
    if ((t < 5.5) && (Tp < -8.5)) RelayON;   //at these temperature and dew point intervals relay_Pin should be on
    else if ((t < 5) && (Tp < -7.5))RelayON;
    else if ((t < 4.5) && (Tp < -5.5))RelayON;
    else if ((t < 3.5) && (Tp < -4.5))RelayON;
    else if ((t < 3) && (Tp < -3.5))RelayON;
    else if ((t < 2.5) && (Tp < -2.5))RelayON;
    else if ((t < 2) && (Tp < -1))RelayON;
  }

  delay(20000); // there is no need to check temperature every second // but you may want to display current options on states
}

Thank you. Will know if it works in the morning.

  1. 'relay' is 8. It will never be HIGH (1). Your output will never be set to LOW.

  2. Most Arduino relay modules seem to have Active Low input (LOW=ON, HIGH=OFF).

  3. The fact that output pins default to LOW on power on or reset could explain why your relays only 'work' (turn on) on power or reset.

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