Arduino as an Aquarium Controller (Pumps and/or Lighting)

If I’m asking the wrong questions, in the wrong place, I apologize in advance.

I’m looking to slowly set up a new aquarium over the winter, and am hoping to build DIY aquarium controller.

Since it will have an overflow siphon, with a continuously running return pump, I want to have a reliable system to cut off the power to the 110v outlet when:

  • the water level in the aquarium gets too high (prevent overflow)

  • the water level in the sump gets too low (prevent motor burn-out)

  • there is too much moisture at floor level (stop leakage from the drain/return lines)

I am also considering adding temperature sensors to detect the absolute temperatures in both the aquarium and the sump tank, turning off the power to the pump when:

  • the temperature in the aquarium is too high

  • the temperature in the sump tank is too low

  • the difference in temperature between the sump tank and the aquarium is too large

As a final consideration, assuming there is enough capacity left on the Arduino, I would would like to be able to control a second set of switched outlets for lighting.


Is it possible for a single Arduino Uno / Red Board to handle all of that at once? Would it be able to do it reliably enough/quickly enough to trust it as a safety measure? Are there specific things I should be considering when attempted to connect the sensors?

Inputs:

-1 SST Liquid Level Sensor (high level)

-2 float switches (high level)

-2 float switches (low level)

-2 moisture sensors (leakage)

-2 temperature sensors (over/under heat)

-1 push button (light timer reset)

Outputs:

  • 10 amp latching relay (pump outlet)

  • 5 amp relay (lighting circuit)

I would appreciate any advice that you’re willing to give me for the project. - I’m at the early stages, I am more than likely missing something critical that I don’t know enough about to ask and/or supply too much information that might not be relevant to the build.

Thanks in advance.

AT first, check how many of your sensors give analog output and how many give digital output. You can connect maximum 6 analog sensors and 14 digital sensors with Arduino UNO.

Thanks @ Bidrohini

So far, about everything seems to be a digital sensor input of some form or another.

(1st Digital IN) SST Liquid Level Sensor (high water) - These output as digital Push/Pull or High/Low signal

(2nd Digital IN) Not Used - I might want to add a 2nd liquid level sensor later.

(3rd Digital IN) 1st pair of float switches (high water) - If I understand correctly, I can’t just short these across the common and input pin. What size load resistor would I need to use?

(4th Digital IN) 2nd pair of float switches (low water)

(5th Digital In) a DIY moisture detector (leakage) - A transistor wired to be a Push/Pull or High/Low output when the exposed leads get shorted with water.

(6th Digital IN) 1st DS18B20 Temperature Sensor (aquarium temperature) - Still uses the digital pins (I think), but outputs as a 16 digit binary code instead of a strict on/off.

(7th Digital IN) 2nd DS18B20 Temperature Sensor (sump temperature)

(8th Digital IN/OUT) Not Used

(9th Digital IN/OUT) Not Used

(10th Digital IN/OUT) Not Used

(11th Digital OUT) 1st 20A Relay (2x 110v Lighting Outlets, NC & NO)

(12th Digital OUT) Not Used - I might want to add a 2nd pair of switched outlets for lighting

(13th Digital OUT) 2nd 20A Relay (110v Heater Outlet)

(14th Digital OUT) 3rd 20A Relay (110v Sump Pump Outlet)

I ordered most of the parts that I need to do the level control part of the project, leaving off the temperature and lighting control aspect for now. (I plan on starting with those as soon as I finish the water control stage)

Am I missing anything?

When I get to the lighting portion of the project (eventually) would I have enough inputs left over to add manual controls for setting the clock? (Assuming that I didn’t want to re-flash the Arduino if I wanted to change the lighting cycle) Would I have to add a clock module?

Thanks again, and still apologize if if I’m not quite asking the correct questions. - I don’t have a lot of background with digital logic circuits, though I could kludge something (at least for the water cut-off portion) out of relay logic, if I had to. -

Your DS18B20s can share the same arduino pin.

https://lastminuteengineers.com/multipl … -tutorial/

Thanks @ YellowDog

I appreciate the heads up, and I’m sure I’ll appreciate having the extra pin to work with.

I started with the idea of doing strictly a pump controller, and within a few hours of thinking about it mission creep comes into play, and I have to start thinking more in terms of aquarium controller.

Any suggestions on project box for the project? Something that would (preferably) resemble the dimensions of an overly bulky/long power strip?

I’m salvaging the 5vdc (4.5" L x 2" W x 1" H) power supply, and “shore power” connector, and surface mount outlets from the an old UPS unit. - So far, planning on surface space for at least 5 single outlets (Always On, N.C. Lighting, N.O. Lighting, Heater, Sump), and a panel mount micro B so I can mount the Arduino inside of the box, without making resetting and reprogramming an issue later on.

I’m most likely going to use several of the “Beefcake” relay kits from SparkFun for the switched outlets, since it already includes the triggering circuit.

I /would/ consider adding an Alphanumeric Display and RTC, but that might be too ambitious for me. With a little bit of luck, some help, and a bit of trial-and-error, I could /probably/ figure out how to output to the display. It’s the adding of a thumb joystick (or similar) to adjust the settings that gives me pause. - I wouldn’t mind having enough space in the project box to revisit the idea later, but think coding that functionality into the Arduino might be a bit far outside of my skillset for now.

I think I’m going to rely on adding a “clock reset” button, so I can press a single button at approximately the correct time of day where I would want my lighting to turn on, and leave it there. (I’m looking at a 6 hours on/6 hours off interval). Also planning to wire in a AA battery pack to supplement the AC supply, to make it easier for the lights to resume current time in the event of a power outage.

As always, thanks for any thoughts and advice.

Just thought of another question. - I’m willing to create a water sensing circuit, but then I happened to see these. I’m willing to spend $4 per sensor to avoid having to add another break-out board to the box, not to mention the cleaner appearance of a properly molded rubber probe.

Is something that is designed for the analog input on an ESP8266 also going to work for the Arduino? -

https://ezmation.com/sensors/53-water-l … ensor.html

Thanks in advance.

@OS_dirk - The sensor you listed should work just fine with an Arduino if you have a free Analog pin. The following two options from SFE should work as well:

https://www.sparkfun.com/products/13322

https://www.sparkfun.com/products/17731

I would be great if you would post on the progress of your project.

Thanks for the response, and extra information @languer.

I had to set the project aside for a little bit (I managed to break the new aquarium while getting it ready, and had to deal with a family emergency or two along the way- all more or less good now, though.)

I’ll be back to focusing on the Arduino programing and breadboard testing this weekend, hopefully. - When I’ve had the time to work on it, lately, I’ve been having a headache with figuring out how to debounce the inputs.

I’m using a basic push button as a stand-in for the float switches during testing, and beyond the normal mechanical switch issues seem to be having an issue with the Arduino picking up RF interference and treating that as an input too.

Is there any particular advantage to doing a push-up versus a pull-down configuration when dealing with debounce, or dealing with RF interference? - I’m willing to wire things either way, but if I could avoid adding more head-shaped dents into my drywall, I’d appreciate it. :slight_smile:

Thanks again, and will add more as I have time.

I spent some time going through Arduino tutorials/forums, came up with a framework, and eventually threw it at chatGPT when I got sick of being stalled.

I understand the basic concept between checking the input, waiting some timeframe, and then checking again. Unfortunately all of the examples I could find started there, and jumped straight into advanced territory without much in the way of intervening steps.

I have a better handle on this than I did a few hours ago, but I’m not sure whether or not I’m on the right track. (I’m also hoping that “bounce.h” does what I think it does, because I was not having much luck writing the “wait and see” part of the sketch myself")

If anyone is willing to take a look, and at least point out if anything is obviously missing, would appreciate it. If not, worst case I’ll do a little bit more tweaking on it tomorrow and see what happens when I try to push it to the Arduino.

Thanks in advance.

#include <Bounce2.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is connected to pin 5 on the Arduino
#define ONE_WIRE_BUS 5

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

// Define pin numbers

const int hiWater = 3;
const int loWater = 4;

const int sumpPump = 13;
const int heater = 14;

const int wetPin = A0; // Analog input pin for moisture sensor

// Define debounce delay
const int debounceDelay = 50;

// Define temperature limits
const int maxTemp = 78; // Maximum temperature
const int minTemp = 66; // Minimum temperature

// Define moisture sensor thresholds	
const int MaxWet = 500; // mV threshold for moisture sensor

// Define pump & heater state
bool pumpState = false;
bool heatState = false;

void setup() {
  // Initialize digital pins as output
  pinMode(sumpPump, OUTPUT);
  pinMode(heater, OUTPUT);

  // Initialize digital pins as input with pullup resistors
  pinMode(hiWater, INPUT_PULLUP);
  pinMode(loWater, INPUT_PULLUP);

  // Attach debounce objects to pins
  Bounce hiWaterBounce = Bounce();
  hiWaterBounce.attach(hiWater, INPUT_PULLUP);
  Bounce loWaterBounce = Bounce();
  loWaterBounce.attach(loWater, INPUT_PULLUP);

  // Set debounce interval to 50 milliseconds
  hiWaterBounce.interval(debounceDelay);
  loWaterBounce.interval(debounceDelay);

  // Start DallasTemperature sensor
  sensors.begin();
}

void loop()
	{
	checkState();
	checkWet();
	checkFloats();
	checkTemp();
	}

void checkState() {
	// Check status of heater and pump
	pumpState=digitalRead(sumpPump;)
	heatState=digitalRead(heater);
	
	
void checkWet() {
  // Check if the sensor is wet
  int wetValue = analogRead(wetPin);
  bool wetState;
  if (wetValue < 600) {
    wetState = true;
  }
  else {
    wetState = false;
  }
}

void checkFloats()
	{
	hiWater.update();
	bool hiWaterState = hiWater.read();
	
	loWater.update();
	bool loWaterState = loWater.read();
	}
	
void checkTemp() {
  // Read temperature from sensor
  sensors.requestTemperatures();
  float tempF = sensors.getTempFByIndex(0);

  // Check if temperature is too high
  if (tempF >= maxTemp) {
    highTemp == TRUE;
  }
  // Check if temperature is too low
  else if (tempF <= minTemp) {
    lowTemp == TRUE;
  }
	
switch(heatState)
	{
	case FALSE: // heater is off (LOW)
	if(wetState == FALSE) && (lowFloat == FALSE) (highFloat == FALSE) && (highTemp == FALSE)
		{
		digitalWrite (sumpPump, HIGH)
		}
	break;
	case TRUE: // heater is on (HIGH)
	if(wetState == TRUE) && (lowFloat == TRUE) && (highFloat == TRUE) && (highTemp == TRUE)
		{
		digitalWrite (sumpPump, LOW)
		}
	break;
	}

switch(pumpState)
	{
	case FALSE: // SumpPump is off (LOW)
	if(wetState == FALSE) && (lowTemp == FALSE) && (highTemp == FALSE) && (lowFloat == FALSE) & (highFloat == FALSE)
		{
		digitalWrite (sumpPump, HIGH);
		}
	break;
	case TRUE: // SumpPump is on (HIGH)
	if(wetState == TRUE) && (lowTemp == TRUE) && (highTemp == TRUE) && (lowFloat == TRUE) & (highFloat == TRUE)
		{
		digitalWrite (sumpPump, LOW);
		}
	break;
	}

Still working on the lighting code, off an on. I spent more time with the parts of the code that I understood (with a little help between forums and chatGPT) I was able to come up with something like this:

I’m probably missing a few things here and there. Planning to upload it to the Arduino on the weekend, and see if I can get everything to work with live sensors. - Once I’ve got that part done, I should be able to post more interesting things about progress and the setup itself.

Thanks again.

// Include these libraries
#include <Bounce2.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is connected to pin 5 on the Arduino
#define ONE_WIRE_BUS 5

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

// Define pin numbers

const int hiFloatL = 1; // High Water Level, Left Side, Display Tank
const int hiFloatR = 2; // High Water Level, Right Side, Display Tank
const int loFLoatL = 3; // Low Water Level, Left Side, Display Tank
const int loFloatR = 4; // Low Water Level, Right Side, Display Tank
// Note: DS18B20 (tempF1) on Pin#5
// Note: DS18B20 (tempF2) on Pin#6
const int sumpPump = 13;
const int heater = 14;

const int leakOne = A0; // Analog input pin for moisture sensor
const int leakTwo = A1; // Two sensors for redundancy

// Define debounce delay
const int debounceDelay = 50;

// Define temperature limits
const int maxTemp = 78; // Maximum temperature
const int minTemp = 66; // Minimum temperature

// Define moisture sensor thresholds	
const int MaxWet = 500; // mV threshold for moisture sensor

// Define bools for status checks
bool pumpState = FALSE;
bool heatState = FALSE;
bool wetState = FALSE;
bool highTemp = FALSE;
bool lowTemp = FALSE;
bool lowWater = FALSE;
bool hiWater = FALSE;

//bool dLightOn = false;
//bool nLightOn = false;

// Define bools for switch() toggles
bool pumpToggle = false;
bool heatToggle = false;
// bool dLightToggle = false;
// bool nLightToggle = false;


// Program Sequence
void loop()
	{
	checkFloat;
	checkLeak;
	checkTemp;
	checkPump;
	checkHeat;
	}

// Check heat operation
void checkHeat()
	{
	if (heatState == TRUE)
	{
	if (wetState == TRUE || highTemp == TRUE || loWater == TRUE)
		{
		heatToggle=FALSE;
		}
	}
if (heatState == FALSE)
	{
	if (wetState == FALSE && lowTemp == TRUE && highTemp == FALSE && loWater == FALSE)
		{
		pumpToggle=TRUE;
		}
	}	
	}
} // end bracket for checkHeat()

// Check pump Operation
void checkPump()
	{
if (pumpState == TRUE)
	{
	if (wetState == TRUE || lowTemp == TRUE || highTemp == TRUE || loWater == TRUE || hiWater == TRUE)
		{
		pumpToggle=FALSE;
		}
	}
if (pumpState == FALSE)
	{
	if (wetState == FALSE && lowTemp == FALSE && highTemp == FALSE && loWater == FALSE && hiWater == FALSE)
		{
		pumpToggle=TRUE;
		}
	}	
	
} // end bracket for checkPump()

// Check water levels
void checkFloat()
	{
	hiFloatL.update();
	hiFloatR.update();
	
	// Rose/Fell tracks the input state of HIGH/LOW
	// and not whether or not the switch itself is floating

	if (hiFloatL.rose() || hiFloatR.rose())
		{
		hiWater = TRUE;
		}
	else if (hiFloatL.fell() && hiFloatR.fell())
		{
		hiWater = FALSE;
		}
	LoFloatL.update();
	LoFloatR.update();
	
	// Rose/Fell tracks the input state of HIGH/LOW
	// and not whether or not the switch itself is floating

	if (loFloatL.rose() || loFloatR.rose())
		{
		loWater = TRUE;
		}
	else if (loFloatL.fell() && loFloatR.fell())
		{
		loWater = FALSE;
		}
} // Closing bracket for checkFloat()
	
// Check for water leakage
void checkLeak()
	{
	// Check if the sensor is wet
	sensors.requestTemperatures();
	int wetL = analogRead(leakOne);
	int wetR = analogRead(leakTwo);
  
	// Check if moisture is too high
	if (wetL >= maxWet || wetR >= maxWet)
		{
		wetState = TRUE;
        }
	else if (wetL < maxWet && wetR < maxWet)
		{
		wetState = FALSE;
		}
	}
	
// Read temperature from sensor & update 
void checkTemp()
	{
  // Read temperature from sensors
  sensors.requestTemperatures();
  
  // Check temperature on first sensor (Pin#5)
  float tempF1 = sensors.getTempFByIndex(0); 
  
  // Check temperature on second sensor (Pin#6)
  float tempF2 = sensors.getTempFByIndex(1); 
  
	// Check if temperature is too high
	if (tempF1 >= maxTemp || tempF2 >= maxTemp)
		{
		highTemp = TRUE;
        }
	else if (tempF1 < maxTemp && tempF2 < maxTemp)
		{
		highTemp = FALSE;
		}
  
	// Check if temperature is too low
	if (tempF1 <= minTemp || tempF2 <= minTemp)
		{
		lowTemp = TRUE;
        }
	else if (tempF1 > minTemp && tempF2 > minTemp)
		{
		lowTemp = FALSE;
		}
	}

// Togle variables to control outputs
switch(pumpToggle)
	{
	case FALSE: // SumpPump needs to be turned off (LOW)
		digitalWrite (sumpPump, LOW);
		pumpState = LOW;
		break;
	case TRUE: // SumpPump needs to be turned on (HIGH)
		digitalWrite (sumpPump, HIGH);
		pumpState = HIGH;
		break;
	}
	
switch(heatToggle)
	{
	case FALSE: // Heater needs to be turned off (LOW)
		digitalWrite (heater, LOW);
		heatState = FALSE;
		break;
	case TRUE: // Heater needs to be turned on (HIGH)
		digitalWrite (heater, HIGH);
		heatState = TRUE;
		break;
	}
	
// switch (dLightToggle)
// 	{
// 	case FALSE: // Daylight needs to be turned off (LOW)
// 		digitalWrite (dLight, LOW);
// 		break;
// 	case TRUE: // Daylight needs to be turned on (HIGH)
// 		digitalWrite (dLight, HIGH);
// 		break;
// 	}
	
// switch (nLightToggle)
// 	{
// 	case FALSE: // Nightlight needs to be turned off (LOW)
// 		digitalWrite (nLight, LOW);
// 		break;
// 	case TRUE: // Nightlight needs to be turned on (HIGH)
// 		digitalWrite (nLight, HIGH);
// 		break;
// 	}

@OS_dirk

If your still looking for a way to do time-based events, the following is a simple example of how to start. The “right” way is to use Timer Interrupts, but this works well if you don’t need exact timing and can tolerate the overhead.

/*************** Main LOOP ***************/
//Global timing
long  seconds = 0;
long  nextSecond = millis();
void loop()
{
  //Keep track of which second it is
  if (millis() - nextSecond >= 1000)
  {
    seconds++;	// increment second counter
    nextSecond += 1000;	// increment when next second count will occur
    doEverySecond();

    if ((seconds > 0) && (seconds % 30 == 0))
    {
      doEvery30Seconds();
    }
    if ((seconds > 0) && (seconds % 60 == 0))
    {
      doEveryMinute();
    }

    if ((seconds > 0) && (seconds % 120 == 0))
    {
      seconds = 0;  // reset second counter on last time gate
      doEvery2Minute();
    }
  }
}

Thanks, again.

The example should help me work our the timing function when I get ready to start plugging one in. As long as the drift in timing can be measured in minutes, that’s more than good enough to handle light timing. (At some point, I would like to be learn how to integrate an LCD screen, Real Time Clock, and a hat switch to make “simpler” versions for friends and family to be able to use, but that’s a few miles along the learning curve yet.)

Still having headache with the debugging and the debouncing. - I keep getting errors about not declaring my debounce variables properly, or maybe not declaring them as members of the “Bounce” class. - Progress is coming, but still slow.

Sooner or later I will get far enough ahead in this to show more details then the sketch, but slower in coming thus far.

// Include these libraries
#include <Bounce2.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire(s) connected to pin 5 & 6 on Arduino
#define ONE_WIRE_BUS1 5
#define ONE_WIRE_BUS2 6

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire1(ONE_WIRE_BUS1);
OneWire oneWire2(ONE_WIRE_BUS2);

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors1(&oneWire1);
DallasTemperature sensors2(&oneWire2);

// Define pin numbers

const int hiFloatL = 1; // High Water Level, Left Side, Display Tank
const int hiFloatR = 2; // High Water Level, Right Side, Display Tank
const int loFloatL = 3; // Low Water Level, Left Side, Display Tank
const int loFloatR = 4; // Low Water Level, Right Side, Display Tank
// Note: DS18B20 (tempF1) on Pin#5
// Note: DS18B20 (tempF2) on Pin#6
const int sumpPump = 13;
const int heater = 14;
 
const int leakOne = A0; // Analog input pin for moisture sensor
const int leakTwo = A1; // Two sensors for redundancy

// Define debounce delay
const int debounceDelay = 50;

// Define temperature limits
const int maxTemp = 78; // Maximum temperature
const int minTemp = 66; // Minimum temperature

// Define moisture sensor thresholds	
const int MaxWet = 500; // mV threshold for moisture sensor

// Define bools for status checks
bool pumpState = false;
bool heatState = false;
bool wetState = false;
bool highTemp = false;
bool loTemp = false;
bool loWater = false;
bool hiWater = false;

//bool dLightOn = false;
//bool nLightOn = false;

// Define bools for switch() toggles
bool pumpToggle = false;
bool heatToggle = false;
// bool dLightToggle = false;
// bool nLightToggle = false;

void setup()
	{
	// Make the pins for the float switches inputs with pull-up resistors
	pinMode(hiFloatL, INPUT_PULLUP);
	pinMode(hiFloatR, INPUT_PULLUP);
	pinMode(loFloatL, INPUT_PULLUP);
	pinMode(loFloatR, INPUT_PULLUP);
	// Make the pins for the pump and heater outputs
	pinMode(sumpPump, OUTPUT); 
	pinMode(heater, OUTPUT);
	sensors1.begin();
	sensors2.begin();
	} // setup() END

// Program Sequence
void loop()
	{
	checkFloat;
	checkLeak;
	checkTemp;
	checkPump;
	checkHeat;
	} // loop() END

// Check heat operation
void checkHeat()
	{
	if (heatState)
		{
		if (wetState || highTemp || loWater)
			{
			heatToggle=false;
			}
		}
	if (!heatState)
		{
		if (wetState && loTemp && highTemp && loWater)
			{
			pumpToggle=true;
			}
		}	
	} // checkHeat() END

// Check pump Operation
void checkPump()
	{
if (pumpState)
	{
	if (wetState || loTemp || highTemp || loWater || hiWater)
			{
			pumpToggle=false;
			}
		}
	if (!pumpState)
		{
		if (!wetState && !loTemp && !highTemp && !loWater && !hiWater)
			{
			pumpToggle=true;
			}
		}	
	
	} // checkPump() END

// Check water levels
void checkFloat()
	{
	hiFloatL.update();
	hiFloatR.update();
	
	// Rose/Fell tracks the input state of HIGH/LOW
	// and not whether or not the switch itself is floating

	if (hiFloatL.rose() || hiFloatR.rose())
		{
		hiWater = true;
		}
	else if (hiFloatL.fell() && hiFloatR.fell())
		{
		hiWater = false;
		}
	LoFloatL.update();
	LoFloatR.update();
	
	// Rose/Fell tracks the input state of HIGH/LOW
	// and not whether or not the switch itself is floating

	if (loFloatL.rose() || loFloatR.rose())
		{
		loWater = true;
		}
	else if (loFloatL.fell() && loFloatR.fell())
		{
		loWater = false;
		}
	} // checkFloat() END
	
// Check for water leakage
void checkLeak()
	{
	// Check if the sensor is wet
	int wetL = analogRead(leakOne);
	int wetR = analogRead(leakTwo);
  
	// Check if moisture is too high
	if (wetL >= maxWet || wetR >= maxWet)
		{
		wetState = true;
        }
	else if (wetL < maxWet && wetR < maxWet)
		{
		wetState = false;
		}
	} // checkLeak() END
	
// Read temperature from sensor & update 
void checkTemp()
	{
	// Read temperature from sensors
	sensors1.requestTemperatures();
	sensors2.requestTemperatures();
	
	// Check temperature on first sensor (Pin#5)
	float tempF1 = sensors1.getTempFByIndex(0); 
  
	// Check temperature on second sensor (Pin#6)
	float tempF2 = sensors2.getTempFByIndex(1); 
  
	// Check if temperature is too high
	if (tempF1 >= maxTemp || tempF2 >= maxTemp)
		{
		highTemp = true;
        }
	else if (tempF1 < maxTemp && tempF2 < maxTemp)
		{
		highTemp = false;
		}
  
	// Check if temperature is too low
	if (tempF1 <= minTemp || tempF2 <= minTemp)
		{
		loTemp = true;
        }
	else if (tempF1 > minTemp && tempF2 > minTemp)
		{
		loTemp = false;
		}
	} // checkTemp END

// Togle variables to control outputs
switch(pumpToggle)
	{
	case false: // SumpPump needs to be turned off (LOW)
		digitalWrite (sumpPump, LOW);
		pumpState = LOW;
		break;
	case true: // SumpPump needs to be turned on (HIGH)
		digitalWrite (sumpPump, HIGH);
		pumpState = HIGH;
		break;
	} // pumpToggle() END
	
switch(heatToggle)
	{
	case false: // Heater needs to be turned off (LOW)
		digitalWrite (heater, LOW);
		heatState = false;
		break;
	case true: // Heater needs to be turned on (HIGH)
		digitalWrite (heater, HIGH);
		heatState = true;
		break;
	} // heatToggle() END
	
// switch (dLightToggle)
// 	{
// 	case false: // Daylight needs to be turned off (LOW)
// 		digitalWrite (dLight, LOW);
// 		break;
// 	case true: // Daylight needs to be turned on (HIGH)
// 		digitalWrite (dLight, HIGH);
// 		break;
// 	} // dLightToggle() END
	
// switch (nLightToggle)
// 	{
// 	case false: // Nightlight needs to be turned off (LOW)
// 		digitalWrite (nLight, LOW);
// 		break;
// 	case true: // Nightlight needs to be turned on (HIGH)
// 		digitalWrite (nLight, HIGH);
// 		break;
// 	} // nLightTogle() END

Took quite a while, but finally have something that resembles working code!

Still no lighting function, but will work on adding that later. I should finally be able to start electrical hookup for testing and validating the operation of my parts.

// Include these libraries
#include <Bounce2.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DS18B20Events.h>

// Data wire(s) connected to pin 5 & 6 on Arduino
#define ONE_WIRE_BUS1 5
#define ONE_WIRE_BUS2 6

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire1(ONE_WIRE_BUS1);
OneWire oneWire2(ONE_WIRE_BUS2);

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors1(&oneWire1);
DallasTemperature sensors2(&oneWire2);

// Define pin numbers

const int hiFloatL = 1; // High Water Level, Left Side, Display Tank
const int hiFloatR = 2; // High Water Level, Right Side, Display Tank
const int loFloatL = 3; // Low Water Level, Left Side, Display Tank
const int loFloatR = 4; // Low Water Level, Right Side, Display Tank
// Note: DS18B20 (tempF1) on Pin#5
// Note: DS18B20 (tempF2) on Pin#6
const int sumpPump = 13;
const int heater = 14;
 
const int leakOne = A0; // Analog input pin for moisture sensor
const int leakTwo = A1; // Two sensors for redundancy

// Define debounce delay
const int debounceDelay = 50;

// Define temperature limits
const int maxTemp = 78; // Maximum temperature
const int minTemp = 66; // Minimum temperature

// Define moisture sensor thresholds	
const int maxWet = 500; // mV threshold for moisture sensor

// Define bools for status checks
bool pumpState = false;
bool heatState = false;
bool wetState = false;
bool highTemp = false;
bool loTemp = false;
bool loWater = false;
bool hiWater = false;

//bool dLightOn = false;
//bool nLightOn = false;

// Define bools for switch() toggles
bool pumpToggle = false;
bool heatToggle = false;
// bool dLightToggle = false;
// bool nLightToggle = false;

void setup()
	{
	// Make the pins for the float switches inputs with pull-up resistors
	pinMode(hiFloatL, INPUT_PULLUP);
	pinMode(hiFloatR, INPUT_PULLUP);
	pinMode(loFloatL, INPUT_PULLUP);
	pinMode(loFloatR, INPUT_PULLUP);
	// Make the pins for the pump and heater outputs
	pinMode(sumpPump, OUTPUT); 
	pinMode(heater, OUTPUT);
	sensors1.begin();
	sensors2.begin();
	} // setup() END

// Program Sequence
void loop()
	{
	checkFloat();
	checkLeak();
	checkTemp();
	checkPump();
	checkHeat();
	} // loop() END

// Check heat operation
void checkHeat()
	{
	if (heatState)
		{
		if (wetState || highTemp || loWater)
			{
			heatToggle=false;
			}
		}
	if (!heatState)
		{
		if (wetState && loTemp && highTemp && loWater)
			{
			pumpToggle=true;
			}
		}
	// switch() function to toggle heat on/off - must be within function or void loop
	switch(heatToggle)
		{
		case false: // Heater needs to be turned off (LOW)
			digitalWrite (heater, LOW);
			heatState = false;
			break;
		case true: // Heater needs to be turned on (HIGH)
			digitalWrite (heater, HIGH);
			heatState = true;
			break;
		} // heatToggle() END
	} // checkHeat() END

// Check pump Operation
void checkPump()
	{
if (pumpState)
	{
	if (wetState || loTemp || highTemp || loWater || hiWater)
			{
			pumpToggle=false;
			}
		}
	if (!pumpState)
		{
		if (!wetState && !loTemp && !highTemp && !loWater && !hiWater)
			{
			pumpToggle=true;
			}
		}	
		// switch() function to toggle pump on/off - must be within function or void loop
		switch(pumpToggle)
		{
		case false: // SumpPump needs to be turned off (LOW)
			digitalWrite (sumpPump, LOW);
			pumpState = false;
			break;
		case true: // SumpPump needs to be turned on (HIGH)
			digitalWrite (sumpPump, HIGH);
			pumpState = true;
			break;
		} // pumpToggle() END
	} // checkPump() END

// Check water levels
void checkFloat()
	{
	Bounce loFloatLBouncer = Bounce();
	Bounce loFloatRBouncer = Bounce();
	Bounce hiFloatLBouncer = Bounce();
	Bounce hiFloatRBouncer = Bounce();

	loFloatLBouncer.attach(loFloatL, INPUT_PULLUP);
	loFloatRBouncer.attach(loFloatR, INPUT_PULLUP);
	hiFloatLBouncer.attach(hiFloatL, INPUT_PULLUP);
	hiFloatRBouncer.attach(hiFloatR, INPUT_PULLUP);

	loFloatLBouncer.update();
	loFloatRBouncer.update();
	hiFloatLBouncer.update();
	hiFloatRBouncer.update();

	if (hiFloatLBouncer.rose() || hiFloatRBouncer.rose())
		{
		hiWater = true;
		}
	else if (hiFloatLBouncer.fell() && hiFloatRBouncer.fell())
		{
		hiWater = false;
		}

	if (loFloatLBouncer.rose() || loFloatRBouncer.rose())
		{
		loWater = true;
		}
	else if (loFloatLBouncer.fell() && loFloatRBouncer.fell())
		{
	loWater = false;
		}
	} // checkFloat() END
	
// Check for water leakage
void checkLeak()
	{
	// Check if the sensor is wet
	int wetL = analogRead(leakOne);
	int wetR = analogRead(leakTwo);
  
	// Check if moisture is too high
	if (wetL >= maxWet || wetR >= maxWet)
		{
		wetState = true;
        }
	else if (wetL < maxWet && wetR < maxWet)
		{
		wetState = false;
		}
	} // checkLeak() END
	
// Read temperature from sensor & update 
void checkTemp()
	{
	// Read temperature from sensors
	sensors1.requestTemperatures();
	sensors2.requestTemperatures();
	
	// Check temperature on first sensor (Pin#5)
	float tempF1 = sensors1.getTempFByIndex(0); 
  
	// Check temperature on second sensor (Pin#6)
	float tempF2 = sensors2.getTempFByIndex(1); 
  
	// Check if temperature is too high
	if (tempF1 >= maxTemp || tempF2 >= maxTemp)
		{
		highTemp = true;
        }
	else if (tempF1 < maxTemp && tempF2 < maxTemp)
		{
		highTemp = false;
		}
  
	// Check if temperature is too low
	if (tempF1 <= minTemp || tempF2 <= minTemp)
		{
		loTemp = true;
        }
	else if (tempF1 > minTemp && tempF2 > minTemp)
		{
		loTemp = false;
		}
	} // checkTemp END