Building an thermostate for shed fans

Hello, very new to the Arduino and coding. I started this journey down the Arduino hole trying to bring a concept to reality. I have a collection of battery operated lawn tools that I store in the shed (the batteries are not in the shed). I have found that our summers heat up the shed to 120*+/- at times. I installed a set of fans that are powered by a solar panel. It actually worked on cooling the shed NOT extreme cool but enough that I was not concerned about the tools. Yes, I know that the tools will be fine for the most part but would like to extend the life of them, if I can. So, with that all being said, once the solar panel has the sun hitting it, the fans are kicking on. There are two switches for the fans but are on the other end of the shed (design of the setup) so I would have to remove items to get to the switches, when I do not want the fans to run. I would like to automate the system where I can have the fan only run when temp and/or humidity is over a set values (and extend the life of the fans as well).

Here is my concept: an agm deep cycle battery connected to a solar controller. That solar controller, connected to the solar panel. Along with 5v dedicated power to the Arduino. The Arduino while sensing the temp and humidity, would switch a relay that powers the fans via the solar controller when the real temp and /or humidity is above the adjustable set values.

I have been able to create that coding and seems to be proof of concept, using an LED for the relay. The only thing is, I have it setup where I can press buttons to change the values of the set temp and humidity, up and down. The only problem is I seem to be only to be able to press the up and down button at a certain point in the loop. Any other part of the loop, the button press is not recognized. Is it because of the loop I have or something else. I have a debounce wired setup with 10k resistors, kind of like the "Debounce on a Pushbutton" built-in example for wiring reference. I know that there is a EasyButton library I could use instead of the wiring with resistance. I might go that route for the setup.

Thank you in advanced.

Here is my code:

// Include libraries
  #include <LiquidCrystal.h>
  #include <DHT11.h>

// Define pins for LCD display
  #define LCD_RS 7
  #define LCD_EN 8
  #define LCD_D4 9
  #define LCD_D5 10
  #define LCD_D6 11
  #define LCD_D7 12

// Define pins for DHT11 sensor
  #define DHT_PIN 6

// Define pin for fan (in this case LED)
  #define fanpin 13

// Initialize LCD display RS EN D4 D5 D6 D7
  LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// Variables to store current humidity and temperature values
  int currentHumidity = 0;
  int currentTemperature = 0;

// Variables to store set humidity and temperature values
  int setHumidity = 50;
  int setTemperature = 75;

// Initialize the pushbutton pins
  const int UP_TEMP_BUTTON = 2;
  const int DOWN_TEMP_BUTTON = 3;
  const int UP_HUMID_BUTTON = 4;
  const int DOWN_HUMID_BUTTON = 5;

// Variables to store button states
  int upTempButtonState;
  int downTempButtonState;
  int upHumidButtonState;
  int downHumidButtonState;

// Variables to store previous button states
  int prevUpHumidButtonState = HIGH;
  int prevDownHumidButtonState = HIGH;
  int prevUpTempButtonState = HIGH;
  int prevDownTempButtonState = HIGH;

// Variables to store debounce timestamps
  long upTempButtonDebounceTime = 0;
  long downTempButtonDebounceTime = 0;
  long upHumidButtonDebounceTime = 0;
  long downHumidButtonDebounceTime = 0;

// Variable to debounce time; increase if the output flickers
  long DEBOUNCE_DELAY = 200;

// Initialize DHT11 sensor
  DHT11 dht(DHT_PIN);

void setup() {

// Set button pins as inputs
  pinMode(UP_HUMID_BUTTON, INPUT);
  pinMode(DOWN_HUMID_BUTTON, INPUT);
  pinMode(UP_TEMP_BUTTON, INPUT);
  pinMode(DOWN_TEMP_BUTTON, INPUT);

// Initialize LCD display
  lcd.begin(16, 2);
}

void loop() {

// Read button states
  upHumidButtonState = digitalRead(UP_HUMID_BUTTON);
  downHumidButtonState = digitalRead(DOWN_HUMID_BUTTON);

// Check if up button is pressed and debounce, increase set humidity value by 1, update debounce timestamp
  if (upHumidButtonState == LOW && prevUpHumidButtonState == HIGH && millis() - upHumidButtonDebounceTime > DEBOUNCE_DELAY) {
    setHumidity++;
    upHumidButtonDebounceTime = millis();
  }

// Check if down button is pressed and debounce, decrease set humidity value by 1, update debounce timestamp
  if (downHumidButtonState == LOW && prevDownHumidButtonState == HIGH && millis() - downHumidButtonDebounceTime > DEBOUNCE_DELAY) {
    setHumidity--;
    downHumidButtonDebounceTime = millis();
  }

// Update previous button states
  prevUpHumidButtonState = upHumidButtonState;
  prevDownHumidButtonState = downHumidButtonState;

// Read button states
  upTempButtonState = digitalRead(UP_TEMP_BUTTON);
  downTempButtonState = digitalRead(DOWN_TEMP_BUTTON);

// Check if up button is pressed and debounce, increase set humidity value by 1, update debounce timestamp
  if (upTempButtonState == LOW && prevUpTempButtonState == HIGH && millis() - upTempButtonDebounceTime > DEBOUNCE_DELAY) {
    setTemperature++;
    upTempButtonDebounceTime = millis();
  }

// Check if down button is pressed and debounce, decrease set humidity value by 1, update debounce timestamp
  if (downTempButtonState == LOW && prevDownTempButtonState == HIGH && millis() - downTempButtonDebounceTime > DEBOUNCE_DELAY) {
    setTemperature--;
    downTempButtonDebounceTime = millis();
  }

// Update previous button states
  prevUpTempButtonState = upTempButtonState;
  prevDownTempButtonState = downTempButtonState;

  // Print set humidity and temperature values on LCD display
  lcd.setCursor(0, 0);
  lcd.print("Set Humid: ");
  lcd.print(setHumidity);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Set Temp: ");
  lcd.print(setTemperature);
  lcd.print("F");
  delay(1500);
  lcd.clear();

// Read current humidity and temperature values from DHT11 sensor
  currentHumidity = dht.readHumidity();
  currentTemperature = dht.readTemperature();

// Convert temperature to Fahrenheit
  currentTemperature = (currentTemperature * 9 / 5) + 32;

// Print current humidity and temperature values on LCD display
  lcd.setCursor(0, 0);
  lcd.print("Real Humid: ");
  lcd.print(currentHumidity);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Real Temp: ");
  lcd.print(currentTemperature);
  lcd.print("F");
  delay(1500);
  lcd.clear();


// Check if real temperature is above or below set temperature
  if (currentTemperature > setTemperature) {
// Turn on fan
    digitalWrite(fanpin, HIGH);
    lcd.print("Fan Status: ON");
    delay(1500);
    lcd.clear();
  } else if (currentHumidity > setHumidity) {
// Turn on fan
    digitalWrite(fanpin, HIGH);
    lcd.print("Fan Status: ON");
    delay(1500);
    lcd.clear();
  } else {
// Turn on fan
    digitalWrite(fanpin, LOW);
    lcd.print("Fan Status:OFF");
    delay(1500);
    lcd.clear();
  }
}

1 Like

Do you think it could be related to all the delay that you have coded?

Rather that all the delay, change the logic to ONLY DISPLAY if the value changes from the last time it was read.

1 Like

Thank you, Paul, for the informative response. I tried to find topics and posts in regards to "ONLY DISPLAY" that you were kind enough to point me in the direction of but was unable to find anything that referred to "ONLY DISPLAY" directly. I tried "Serial.print" and "Serial.println" but that only made the screen go blank. I removed the delays on the fan status part of the script.

If you would be so kind, Paul, and point me in the direction of what I am missing, I would appreciate it. Thank you.

I'll try to explain, because I think I get what Paul's saying

He means that you should try and only write text to the display if anything actually changes. Don't write to the display if no information has changed.

The delays in the LCD sections are counterproductive in two ways:
1: they block execution, making the system miss button presses, temperature changes etc.
2: what sense is there in very temporarily showing information only to remove it 1.5 seconds later? Blink and you'll miss it...might as well remove the entire LCD in that case.

Why note remove these lines:

They're not really necessary/useful.

Then think about how you can fit the relevant information together on your display; start by removing redundant information. "Fan status ON" can be shortened to "Fan ON" for starters. Temperature and humidity don't need any words; % and a degree-symbol (or simply F or C) are enough. Just keep the information on the display - and like Paul suggests, only update it if it changes.

Depending on how you have the buttons connected you may want to change to INPUT_PULLUP for noise immunity.

Later, when you get it working and it is rapidly turning on and off read up on hysteresis and implement a dead band.

Personally if this were me and my shed I would just Google Attic Fan Thermostat. Not sure why humidity figures into this? If outside humidity is 60% or 70% I don't see where turning on a fan will do anything other than move moist air? A simple $25 attic fan thermostat will handle everything. That includes power for the fan assuming a 120 or 220 VAC fan.

Ron

2 Likes

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