I am experimenting with Aquaponics and since I am a software developer I found it "smart" to use arduino/raspberry in order to control the water flow and not simply use a water pump with mechanical means.
The advantage is that I am able to expand easier the system. The disadvantage is that I haven't yet met the reliability that I would lie to have. I am a software engineer with basic knowledge in the hardware field. That is why I thought of starting with Raspberry.
Initially I made a setup with a single raspberry PI a few float sensors like this: https://www.hellasdigital.gr/electronics/sensors/humidity-sensor/tank-pool-water-level-liquid-sensor-float-switch/
and relay like this one: https://wiki.52pi.com/index.php/DockerPi_4_Channel_Relay_SKU:_EP-0099
I saw that sometimes the system was hanging with the relays open! This had the side effect to loose water. This is the most precious in aquaponics!
Thus I thought of creating a cluster. Thus I made a cluster of three Raspberrys. The two had the relays and only one PI had the sensors. In order to open the water pump both PIs should have given the green light. This worked better and when one of the PIs hanged then we lost no water.
But again I am thinking that it was not acceptable that the system was hanging so often (at least several times per week). Thus I thought maybe if I use an Arduino for this purpose then this would be better.
Thus this is what I did. I created a simple program (no cluster and a single Arduino). Unfortunately this had even worst results!!!
For the Arduino I used normal 5 Volt relays like this one: https://www.nettop.gr/index.php/hlektronika/relay/8-channel-5v-relay-module-with-light-coupling-5v.html and the same float sensors.
I do not believe that is software related the issue but it must be hardware. The problem is that my knowledge in the hardware field is limited! What should I do in order to prevent this? Do you think that is related with the water pumps and the relays ?
The same erroneous behavior happens at both the Raspberry and Arduino, I mean that the relay stays open and the water overflows. For Raspberry I can tell that the system stop to respond, I am sure about it. But for Arduino I cannot say for sure if the whole system was frozen or if input only for the float did not work.
I paste a link to the quick and dirty Arduino code as well for your reference. The temperature were the systems were operating could be quite hot (30 ~ 48 degrees Celsius) for several hours.
Here is the code for the Arduino:
#define POT_1_FLOAT_SENSOR 2
#define POT_1_RELAY_1 11
#define PIPE_1_FLOAT_SENSOR 5
#define PIPE_1_RELAY_1 9
#define PIPE_2_FLOAT_SENSOR 3
#define PIPE_2_RELAY_2 10
#define PIPE_3_RELAY_3 12
#define PIPE_3_FLOAT_SENSOR 4
// pot 1
const unsigned long POT_1_MAX_WATERING_PERIOD = 120000;
const unsigned long POT_1_DRAIN_PERIOD = 70000;
unsigned long pot1StartMillis = 0;
unsigned long pot1DelayStartMillis = 0;
// Pipe 2
const unsigned long PIPE_2_MAX_WATERING_PERIOD = 300000;
const unsigned long PIPE_2_DRAIN_PERIOD = 300000;
unsigned long pipe2DelayStartMillis = 0;
unsigned long pipe2StartMillis = 0;
// Pipe 3
const unsigned long PIPE_3_MAX_WATERING_PERIOD = 760000;
const unsigned long PIPE_3_DRAIN_PERIOD = 300000;
unsigned long pipe3DelayStartMillis = 0;
unsigned long pipe3StartMillis = 0;
// Pipe 1
const unsigned long PIPE_1_MAX_WATERING_PERIOD = 180000;
const unsigned long PIPE_1_DRAIN_PERIOD = 300000;
unsigned long pipe1DelayStartMillis = 0;
unsigned long pipe1StartMillis = 0;
bool pot1RedFlag = false;
bool pot1SetStartTime = false;
bool pipe1RedFlag = false;
bool pipe1SetStartTime = false;
bool pipe2RedFlag = false;
bool pipe2SetStartTime = false;
bool pipe3RedFlag = false;
bool pipe3SetStartTime = false;
void setup()
{
Serial.begin(9600);
// initialize the pushbutton pin as an input:
pinMode(POT_1_FLOAT_SENSOR, INPUT_PULLUP);
pinMode(POT_1_RELAY_1, OUTPUT);
digitalWrite(POT_1_RELAY_1, LOW);
pinMode(PIPE_1_FLOAT_SENSOR, INPUT_PULLUP);
pinMode(PIPE_1_RELAY_1, OUTPUT);
digitalWrite(PIPE_1_RELAY_1, LOW);
pinMode(PIPE_2_FLOAT_SENSOR, INPUT_PULLUP);
pinMode(PIPE_2_RELAY_2, OUTPUT);
digitalWrite(PIPE_2_RELAY_2, LOW);
pinMode(PIPE_3_FLOAT_SENSOR, INPUT_PULLUP);
pinMode(PIPE_3_RELAY_3, OUTPUT);
digitalWrite(PIPE_3_RELAY_3, LOW);
pot1StartMillis = millis();
pipe1StartMillis = millis();
pipe2StartMillis = millis();
pipe3StartMillis = millis();
}
void loop()
{
checkAbstractWateringTimer(pot1SetStartTime, pot1RedFlag, pot1DelayStartMillis,
POT_1_DRAIN_PERIOD, POT_1_MAX_WATERING_PERIOD,
pot1StartMillis, POT_1_FLOAT_SENSOR, POT_1_RELAY_1);
checkAbstractWateringTimer(pipe1SetStartTime, pipe1RedFlag, pipe1DelayStartMillis,
PIPE_1_DRAIN_PERIOD, PIPE_1_MAX_WATERING_PERIOD,
pipe1StartMillis, PIPE_1_FLOAT_SENSOR, PIPE_1_RELAY_1);
checkAbstractWateringTimer(pipe2SetStartTime, pipe2RedFlag, pipe2DelayStartMillis,
PIPE_2_DRAIN_PERIOD, PIPE_2_MAX_WATERING_PERIOD,
pipe2StartMillis, PIPE_2_FLOAT_SENSOR, PIPE_2_RELAY_2);
checkAbstractWateringTimer(pipe3SetStartTime, pipe3RedFlag, pipe3DelayStartMillis,
PIPE_3_DRAIN_PERIOD, PIPE_3_MAX_WATERING_PERIOD,
pipe3StartMillis, PIPE_3_FLOAT_SENSOR, PIPE_3_RELAY_3);
delay(200);
}
void checkAbstractWateringTimer(bool &abstractSetStartTime, bool &abstractRedFlag, unsigned long &abstractDelayStartMillis,
unsigned long abstractDrainPeriod, unsigned long abstractMaxWateringPeriod,
unsigned long &abstractStartMillis, int abstractFloatSensor, int abstractRelay) {
if (!abstractSetStartTime || (abstractSetStartTime && millis() - abstractDelayStartMillis >= abstractDrainPeriod)) {
if(digitalRead(abstractFloatSensor) == LOW && !abstractRedFlag) // Need one more condition in order to emulate the delay...
{
digitalWrite(abstractRelay, LOW);
Serial.println("Pot 1 pump is open");
// Set it only once at the beginning
if (pot1SetStartTime) {
abstractStartMillis = millis();
abstractSetStartTime = false;
}
Serial.print("duration ");
Serial.println(millis() - abstractStartMillis);
if (millis() - abstractStartMillis >= abstractMaxWateringPeriod) //test whether the MAX watering period has elapsed
{
// Close pump and do not oopen it again. Red Flag...
Serial.println("Pot 1 pump is closed and the red flag is ON");
digitalWrite(abstractRelay, HIGH);
abstractRedFlag = true;
}
}
else
{
Serial.println("Pot 1 Pump is closed");
digitalWrite(abstractRelay, HIGH);
abstractSetStartTime = true;
abstractDelayStartMillis = millis();
}
}
}
Please any ideas, suggestions or tests that I could do are more than welcome in order to create a reliable system.
-- UPDATE -- Both when I was using Raspberry and Arduino I haven't included any resistors between the float sensor pins and the ground. Are there any chances that this is related with the instabilities that I experienced?
Maybe I should add a resistor (10K) between the float sensor pin and the ground?
Thank you
loop()
. If it stops blinking, it's frozen.Maybe I should add a resistor (10K) between the float sensor pin and the ground?
-- No, you have (roughly) 30k internal pullup resistors. Adding a 10k pulldown resistor would just confuse everything. However adding 10k pullups to 5V would help with noise rejection.