Aquarium - time/date auto fan condensation purging

Hi, Im using a nano to control x4 PC fans to turn on if between 26-28 degreesC. The temp sensor is a DS18B20. All works perfectly and has been for some time. However, I do get a lot of condensation on the fans when they're not on.

So, the way this works is...
Aquarium heater turns on at 25C and auto turns off at 25.7C. If the temp reaches 26C, the nano maps between 26 and 28C respectively. So during the winter months the fans never turn on creating condensation. Im worried they will get damaged as they're not cheep.

Ive put a code in setup so I can hit the reset button on the nano manually to spin the fans dry.

I have a DS1307. My thought is to have a time set each day for the fans to purge for 10 seconds. Ive googled how to use the date/time and its very overwhelming.

My question is, as the temp sensor has a delay, how would I write in the code if time is in a 2 or maybe 3 second window? I hope Ive made sense. please excuse my ignorance. Im generally new to coding. I will post the code below along with the circuit diagram.

/*
 ******************************************
 ************** FRY TANK ******************
 ******************************************
*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2);

#define ONE_WIRE_BUS 4

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensor(&oneWire);

// *****************************************************************

/*
 Heater On        Off
                  25.82 
 */



float tempMin = 26;       // adjustment for MIN tank degrees
int tempMax = 28;         // adjustment for MAX tank degrees

int fanSpeedMin = 1;      // adjustment for MIN fan speed display
int fanSpeedMax = 100;    // adjustment for MAX fan speed display

int PWMvalMin = 40;       // adjustment for MIN fan speed
int PWMvalMax = 255;      // adjustment for MAX fan speed

float CalibrateTemp = 2.2;     // manual temp calibration
float CorrectedTemp;

int LoopDelay = 500;

//******************************************************************

int PWMfanPin = 9;
int PWMval;
int fanSpeed;

int Pre_Sec;

void setup()
{

  Serial.begin(9600);
  sensor.begin();

  pinMode(9, OUTPUT);

  //chnages PWM frequency to eliminate fan noise - pins D9 and D10 - 31.4kHz
  TCCR1A = 0b00000001; // 8bit
  TCCR1B = 0b00000001; // x1 phase correct

  lcd.init();
  lcd.clear();
  lcd.backlight();

  digitalWrite(PWMfanPin, HIGH);
  
  lcd.setCursor(0,0);
  lcd.print("Purging Fans");
  
  lcd.setCursor(0,1);
  lcd.print("10");
  delay(1000);
  
  lcd.setCursor(0,1);
  lcd.print("9 ");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("8");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("7");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("6");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("5");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("4");
  delay(1000);
  
  lcd.setCursor(0,1);
  lcd.print("3");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("2");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("1");
  delay(1000);

  lcd.setCursor(0,1);
  lcd.print("0");
  delay(1000);

  digitalWrite(PWMfanPin, LOW);

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temp:");
  lcd.setCursor(0,1);
  lcd.print("Fan Speed:");
  
}

void loop()
{ 
  sensor.requestTemperatures();
   
  CorrectedTemp = (sensor.getTempCByIndex(0) + CalibrateTemp);

if (CorrectedTemp < tempMin)
{
    PWMval = 0;
    fanSpeed = 0;
    digitalWrite(PWMfanPin, LOW);
    //analogWrite(PWMfanPin,PWMvalMin);
}

else

if (CorrectedTemp > tempMax)
{
    PWMval = PWMvalMax;
    fanSpeed = fanSpeedMax;
    digitalWrite(PWMfanPin, HIGH);
}

else

{
    PWMval = map (CorrectedTemp * 10, tempMin * 10, tempMax * 10, PWMvalMin, PWMvalMax);
    fanSpeed = map (CorrectedTemp * 10, tempMin * 10, tempMax * 10, fanSpeedMin, fanSpeedMax);
    analogWrite(PWMfanPin, PWMval);
}

    
    lcd.setCursor(6,0);
    lcd.print(CorrectedTemp);
    lcd.print((char)223); 
    lcd.print("C   ");
    lcd.setCursor(11,1); 
    lcd.print(fanSpeed);
    lcd.print("%   ");

    Serial.println();
    Serial.print("Water Temp: ");
    Serial.print(CorrectedTemp);
    Serial.print("°C");
    Serial.print(", Fan Speed: ");
    Serial.print(fanSpeed);
    Serial.print("%, ");
    Serial.print("PWMval: ");
    Serial.print(PWMval);

    delay(LoopDelay);

}

Sorry, I can post the schem.

Sorry, I cant post the Schem.

Would a humidity sensor work to indicate when to turn the fans on?

Take a look at my "pet feeder" simulation. It starts by setting two "feed" times, then waits for the feed time, then moves a servo. Very similar to your project. Most of it is comments and printing to the LCD. Very little is time keeping.

Cheat: Turn the fans on for a short time after you turn the heaters off and again when you turn them on. There are a lot of examples of RTC (Real Time Clock) programs posted that you could use parts of.

No. That wouldn't work because the humidity would be quite high. It would constantly purge until there is no humidity in the tank. Could take an hr to do that. I just need the fans to spin for 10secs every 24hrs to remove the water from possibly getting inside the fans and causing electrical corrosion.

not possible. The aquarium heaters are automatic.

A DS3231 is a much better RTC than the DS1307, and I would recommend using that.

What library do you want to use with the RTC?

There are simple ways to look for an hour changing in value, and run the fans for 10 seconds at that time.

Adapt the pet feeder sketch with an RTC for your use.

Only if you programmed it to do that. You can set other points.

You probably find build-up above a certain humidity.

Agreed. I should probably get the more accurate 1.

I didn't know there was a library option to give different outcomes. Could you please educate me on that?

The library you use will not give a different outcome, it will just determine the syntax you use to get the time you need.

Why?

You just need to run the fans approximately one every 24 hours. I don't see any need for precision timing. Just use millis().

Take a look at the "blink without delay" example sketch in the IDE.

hmmm :thinking:

/*
 ******************************************
 ************** FRY TANK ******************
 ******************************************
*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2);

#define ONE_WIRE_BUS 4

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensor(&oneWire);

// *****************************************************************

/*
 Heater On        Off
                  25.82 
 */



float tempMin = 26;       // adjustment for MIN tank degrees
int tempMax = 28;         // adjustment for MAX tank degrees

int fanSpeedMin = 1;      // adjustment for MIN fan speed display
int fanSpeedMax = 100;    // adjustment for MAX fan speed display

int PWMvalMin = 40;       // adjustment for MIN fan speed
int PWMvalMax = 255;      // adjustment for MAX fan speed

float CalibrateTemp = 2.2;     // manual temp calibration
float CorrectedTemp;

int LoopDelay = 500;
unsigned long LastFanPurge;

unsigned long TwentyFourHours = 24UL*60*60*1000;

//******************************************************************

int PWMfanPin = 9;
int PWMval;
int fanSpeed;

int Pre_Sec;

void PurgeFans()
{
  digitalWrite(PWMfanPin, HIGH);
  
  lcd.setCursor(0,0);
  lcd.print("Purging Fans");
  
  for (int t=10; t>=0; t--)
    {
      lcd.setCursor(0,1);
      lcd.print(t);
      if (t==9) lcd.print(" ");
      delay(1000);
    }

  digitalWrite(PWMfanPin, LOW);

}

void setup()
{

  Serial.begin(9600);
  sensor.begin();

  pinMode(9, OUTPUT);

  //chnages PWM frequency to eliminate fan noise - pins D9 and D10 - 31.4kHz
  TCCR1A = 0b00000001; // 8bit
  TCCR1B = 0b00000001; // x1 phase correct

  lcd.init();
  lcd.clear();
  lcd.backlight();

  PurgeFans();

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temp:");
  lcd.setCursor(0,1);
  lcd.print("Fan Speed:");
  
}

void loop()
{ 
  sensor.requestTemperatures();
   
  CorrectedTemp = (sensor.getTempCByIndex(0) + CalibrateTemp);

if (CorrectedTemp < tempMin)
{
    PWMval = 0;
    fanSpeed = 0;
    digitalWrite(PWMfanPin, LOW);
    //analogWrite(PWMfanPin,PWMvalMin);
}

else

if (CorrectedTemp > tempMax)
{
    PWMval = PWMvalMax;
    fanSpeed = fanSpeedMax;
    digitalWrite(PWMfanPin, HIGH);
}

else

{
    PWMval = map (CorrectedTemp * 10, tempMin * 10, tempMax * 10, PWMvalMin, PWMvalMax);
    fanSpeed = map (CorrectedTemp * 10, tempMin * 10, tempMax * 10, fanSpeedMin, fanSpeedMax);
    analogWrite(PWMfanPin, PWMval);
}

    
    lcd.setCursor(6,0);
    lcd.print(CorrectedTemp);
    lcd.print((char)223); 
    lcd.print("C   ");
    lcd.setCursor(11,1); 
    lcd.print(fanSpeed);
    lcd.print("%   ");

    Serial.println();
    Serial.print("Water Temp: ");
    Serial.print(CorrectedTemp);
    Serial.print("°C");
    Serial.print(", Fan Speed: ");
    Serial.print(fanSpeed);
    Serial.print("%, ");
    Serial.print("PWMval: ");
    Serial.print(PWMval);

    delay(LoopDelay);

    if(millis() - LastFanPurge >= TwentyFourHours)
    {
      PurgeFans();
      LastFanPurge += TwentyFourHours;
    }

}

nice touch. :+1:
I knew the setup part was on the ugly side :laughing:
Thanks for fixing that.
The only thing that might frustrate me is that if I have a power out millis() will reset to when the nano turns back on. So it may digitalwrite HIGH all hrs of the night. Which isnt really a bad thing. I was just hoping for some time consistancy.
I def give this a crack tho. Legend!!!!!

For that you would need an RTC. Your DS1307 will be accurate enough!

can you please explain this line to me please. how it works?

It's calculating 24 hours in milliseconds. That's a big number, too large for an int to hold on many common types of Arduino. On most types of arduino, int can only hold numbers in the range -32,000 to +32,000 approximately. So here we must use an unsigned long type, which can hold much larger numbers. The "UL" forces the value to be an unsigned long, otherwise it will be calculated as an int and would overflow.

This works brilliantly. Thank you so, so much :slight_smile:
All I needed to add were conditions in the loop if fans are running.
Absolutely brilliant mate!!!!