humidity controller with outside Temp sensor

Hi Pals,
This is my first project and just started working with arduino last week.

I copied the codes from a similar projects by a talented member ,BertZ and trying to modify it.
(Problem defining set point for humidity controller - Programming Questions - Arduino Forum)

So objective is to adjust inside room humidity in relation to Outside temperature using a 5V relay controlled room humidifier. Idea is based on this publication from Aprilaire

The changes I made from original code is to adjust for and 128x64 SSD1306 based OLED display and changed to a Relay instead of solenoid.

Wondering if some one can look through it and recommend corrections. I am waiting on my hardware peripherals to arrive.

/* 
A DS18B20 Temperature sensor is connected to 5VDC, ground and (Data) to the Arduino's Pin D2
and measures the outdoor temperature.  This value gets converted to a range of 25 to 50 and 
is used as a set point for the humidity. It is compared to the humidity read from the AM2302
(DHT22) and is used to trigger the relay to turn on the Humidifier.

An AM2302 Humidity/Temperature sensor is connected to the Arduino's Pin D4 and measures 
Temperature and Humidity. The program reads the value of this sensor every 5 seconds. 

Pin D7 of the Arduino is connected to a General Purpose Relay SPDT (5VDC)with 5 mA coil trigger current. If pin D7 goes high, the relay
triggers to the on state and completes the circuit between the N.O. contacts of the relay.
If the relay contacts are energized (closed),it turn Humidifier on .

The program is written with a test to make sure that the DHT sensor is connected and working.
If the sensor cannot be read, the Water Solenoid LED will flash for 10 times, ½ second on,
1 second off to let you know there is a problem. In addition a "Fault: DHT22" message will 
display on the OLED.
If the Humidifier relay is energized, it will latch for two minutes, before sampling the return
air's ambient humidity again. Once the return air humidity reaches the set point, the Humidistat's 
relay will de-energize and the program will again start to sample the ambient humidity and test
it against the set point every 5 seconds. 
The LCD displays the Relative Humidity set point as well as the actual humidity.  
This indicates whether or not the DHT-22 is working properly.  The outdoor temperature is displayed
on the second line of the LCD to verify that the DS18B20 is working properly. The only LED is 
connected to Pin D13 on the Arduino and lights when the relay is energized supplying
power to the humidifier.

*/

#include <DHT.h> 
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>

// initialize the library with the numbers of the interface pins
// OLED display TWI address
#define OLED_ADDR   0x3C

Adafruit_SSD1306 display(-1);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif



// DS18B20 Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
#define DHTPIN 4 // AM2302 is plugged into pin 4 
#define DHTTYPE DHT22 // DHT 22 (AM2302) 
#define Relay 3 // Pin to Activate relay
#define flow 13 // Pin to show relay is on (blue)
DHT dht(DHTPIN, DHTTYPE); 
#define DEADBAND 3
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
int tempF = 0;
int setPoint;

void setup() { 
  sensors.begin();
  dht.begin(); 
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.display();

  pinMode(flow,OUTPUT); 
  pinMode(Relay, OUTPUT); 
  Serial.begin(9600); //Begin serial communication
  Serial.println("Arduino Humidistat // LCD Set Point Version"); //Print a message 
} 

void loop() { 
// Wait 5 seconds between measurements. 
delay(5000); 
// Reading temperature or humidity takes about 250 
//milliseconds! 
// Sensor readings may also be up to 2 seconds 'old' 
// (its a very slow sensor) 

delay(100); 
int h = dht.readHumidity(); 
// Read temperature as Celsius 
int t = dht.readTemperature(); 
int tt = dht.convertCtoF(t); 
// Check if any reads failed and exit early (to try again). 
if (isnan(h) || isnan(t)) { 
Serial.println("Failed to read from DHT sensor!"); 
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(27,30);
display.print("Fault: DHT22");
// If the sensor fails to read successfully execute for loop 
// and flash the RELAY LED for 10 times
// a total of 15 seconds 
for(int x=0; x < 10; x++){ 
digitalWrite(flow,HIGH); 
delay(1000); 
digitalWrite(flow,LOW); 
delay(500); 
} 
return; 
} 
// Read DS18B20 and convert to humidity values between 25 and 50% 
// setPoint = the set point for the target humidity level 
{ 
  // Send the command to get temperatures
  int tempOut; //create a variable to hold the temperature value
  sensors.requestTemperatures();  
  tempOut = (sensors.getTempFByIndex(0));
  // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire

  if (tempOut <= -20) {
    setPoint=20;
    Serial.print ("Humidity Set Point is: ");
    Serial.println (setPoint);
    }
    else if (tempOut > -20 && tempOut <=-10) {  
      setPoint=25;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > -10 && tempOut <=0) {  
      setPoint=30;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > 0 && tempOut <=10) {  
      setPoint=35;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > 10 && tempOut <=20) {  
      setPoint=40;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else  {  
      setPoint=45;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
// Test to see if the humidity is less than the set point 
// if so turn on relay 
// If not turn off relay

if(h < setPoint + DEADBAND) { 
digitalWrite(Relay, HIGH); 
digitalWrite(flow, HIGH); 
Serial.println ("Humidifier on");
delay(120000); 
} 
else { 
digitalWrite(Relay, LOW); 
digitalWrite(flow,LOW); 
Serial.println ("Humidifier off");
} 
Serial.println (setPoint); 
Serial.print("Humidity: "); 
Serial.print(h); 
Serial.print("%"); 
Serial.print(" Temperature: "); 
Serial.print(tempOut); 
Serial.println(" degF "); 
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(2,2);
display.print("SP:  ");
display.print(setPoint);
display.print("%");
display.print(" RH: ");
display.print(h);
display.print("%");
display.setCursor(0,1);
display.print("OutTemp: ");
display.print(tempOut);
display.print(" degF");
  }
}

Awaiting all valuable recommendations.

temp and humidity.jpg

First of, the publication from Aprilaire seems to only advertise their products - I can see no references to scientific publications to reenforce their "Recommended Indoor Humidity Levels".

Nonetheless, if you are going for this approach, you really should divide your task into separate functions. Because your code will be read several times more often than written (mainly by yourself, but also by this community), you should strive for readability.

This means a typical function body should not exceed 7-10 lines (although there are exceptions). Group logical parts together and extract them to a function. For example writing certain things to a display can be grouped into separate functions. You should also look into your temperature sensor and its default temperature unit. If it outputs temperature in degrees celsius by default, you might want to avoid converting it to fahrenheit but convert the fixed thresholds to celsius. Also to check if a value is in range of something, create a new function:

if(isInRange(tempOut, -20, -10))

is more readable than

if (tempOut > -20 && tempOut <= -10) {

To reduce code size, put

Serial.print ("Humidity Set Point is: ");

before your temperature check and

Serial.println (setPoint);

right after it. This way you only call Serial.print(ln) one time, reducing code size. This is also a good opportunity to extract the determination of setPoint to a function called determineSetPoint.

From your task to control the indoor humidity level based on outdoor temperature (only if you exchange air frequently between inside and outside), your main loop should look something like this:

void loop()
{
    auto outdoorTemperature = outdoorSensor.readTemperature();
    auto humiditySetpoint = determineSetPoint(outdoorTemperature);

    auto indoorHumidity = indoorSensor.readHumidity();
    controlHumidity(indoorHumidity, humiditySetpoint);
}

You can add debug statements to the serial port as you wish, but put them into separate functions if they are getting annoying to read.

High LightuC! Thanks for the comments and code suggestions.
I think those set point are for preventing condensation of water on surfaces from excess humidity inside. I read similar values at different online sources ( dew point , I think is the word they use).

I am hoping for litttle more hand holding here, as I am totally new. I understood simplifying code.
But could not figure out using serial. print() before temperature check reducing the code size. Please explain if with an example in my written code itself if possible so I can comprehend better.
Also could you Please verify if the codes I wrote for OLED display going to work?

They don't have to go before and after the if/else block, I was pretty tired as I wrote the post.
Just take a look at the following two snippets:

    if (tempOut <= -20) {
      setPoint = 20;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > -20 && tempOut <= -10) {
      setPoint = 25;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > -10 && tempOut <= 0) {
      setPoint = 30;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > 0 && tempOut <= 10) {
      setPoint = 35;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else if (tempOut > 10 && tempOut <= 20) {
      setPoint = 40;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }
    else  {
      setPoint = 45;
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
    }

vs

    if (tempOut <= -20) {
      setPoint = 20;
    }
    else if (tempOut > -20 && tempOut <= -10) {
      setPoint = 25;
    }
    else if (tempOut > -10 && tempOut <= 0) {
      setPoint = 30;
    }
    else if (tempOut > 0 && tempOut <= 10) {
      setPoint = 35;
    }
    else if (tempOut > 10 && tempOut <= 20) {
      setPoint = 40;
    }
    else  {
      setPoint = 45;

    }
    
    Serial.print ("Humidity Set Point is: ");
    Serial.println (setPoint);

Since I don't have an OLED display laying around, I can't test that part.

Nice suggestion! Thanks LightuC.
Will wait for someone with OLED experience.

made some corrections in code as the first part failed with humidity reading stored in 'int'

from this thread used float instead of int

https://forum.arduino.cc/index.php?topic=348025.0

still not sure if the flashing LED part will work or not.

int tempF = 0;
int setPoint;

void setup() { 
  sensors.begin();
  dht.begin(); 
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.display();

  pinMode(LED,OUTPUT); 
  pinMode(Relay, OUTPUT); 
  Serial.begin(9600); //Begin serial communication
  Serial.println("Arduino Humidistat // LCD Set Point Version"); //Print a message 
} 

void loop() { 

float tempOut; //create a variable to hold the temperature value
sensors.requestTemperatures();  
tempOut = (sensors.getTempFByIndex(0));
delay(5000); // Wait 5 seconds between measurements.

// Reading temperature or humidity takes about 250 ms
// Sensor readings may also be up to 2 seconds

delay(100); 
float h = dht.readHumidity(); 

// Check if any reads failed and exit early (to try again). 
if (isnan(h)) { 
Serial.println("Failed to read from DHT sensor!"); 
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(27,30);
display.print("Fault: DHT22");}
if (tempOut <= -55)) { 
Serial.println("Failed to read from OUTDOOR sensor!"); 
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(27,30);
display.print("Fault: DS18B20");
// If the sensor fails to read successfully execute for loop 
// and flash the RELAY LED for 10 times
// a total of 15 seconds 

for(int x=0; x< 10; x++){ 
digitalWrite(LED,HIGH); 
delay(1000); 
digitalWrite(LED,LOW); 
delay(500); 
} 
return; 
} 
// Read DS18B20 and convert to humidity values between 25 and 50% 
// setPoint = the set point for the target humidity level 
{ 
  
  if (tempOut <= -20) {
    setPoint=20;
    }
    else if (tempOut > -20 && tempOut <=-10) {  
      setPoint=25;
    }
    else if (tempOut > -10 && tempOut <=0) {  
      setPoint=30;
    }
    else if (tempOut > 0 && tempOut <=10) {  
      setPoint=35;
    }
    else if (tempOut > 10 && tempOut <=20) {  
      setPoint=40;
    }
    else  {  
      setPoint=45;

    }
      Serial.print ("Humidity Set Point is: ");
      Serial.println (setPoint);
   
// Test to see if the humidity is less than the set point 
// if so turn on relay 
// If not turn off relay

if(h < setPoint + DEADBAND) { 
digitalWrite(Relay, LOW); 
digitalWrite(LED, HIGH); 
Serial.println ("Humidifier on");
delay(120000); 
} 
else { 
digitalWrite(Relay, HIGH); 
digitalWrite(LED,LOW); 
Serial.println ("Humidifier off");
} 
Serial.println (setPoint); 
Serial.print("Humidity: "); 
Serial.print(h); 
Serial.print("%"); 
Serial.print(" Temperature Outside: "); 
Serial.print(tempOut); 
Serial.println(" degC "); 
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(2,2);
display.print("SP:  ");
display.print(setPoint);
display.print("%");
display.print(" RH: ");
display.print(h);
display.print("%");
display.setCursor(0,1);
display.print("OutTemp: ");
display.print(tempOut);
display.print(" degF");
  }
}