Arduino Irrigation System #2

[Part 1] [Part 2] [Part 3] [Part 4] [Part 5 – ALISS] [Download]

We left off in part 1 with a simple circuit straight out of the Arduino Projects Book that allowed us to manually control a DC Motor. We need to adjust the circuit slightly because we don’t want to have to manually turn on each solenoid valve and then manually turn them all off again; if we did that we might as well have not bothered. (Also, we don’t have the Input/Output pins spare (we could use an Arduino Mega, I suppose, but really I think that that would be overkill for what we’re trying to achieve.))

What we want is for the Arduino to handle all of the turning on and off of the solenoids automatically. We want to simply switch the system on, have it water all the bays (of which there are 11), and then stop (we don’t want to drown the plants).

Before we go any further, we need to talk about Solenoids.

Solenoids

Solenoids come in all sorts of shapes and sizes, there’s a few in your washing machine, they are in automatically locking/unlocking doors such as you’d find in an office building. There are also pneumatic, AC and DC ones. The ones we’re using are 12V DC Normally Closed 3-Way valves for Water.

Choosing the right solenoid took a very long time; finding one that fitted the criteria was tough.

Criteria:

  • 3-Way
  • Normally Closed
  • 12V DC
  • 1/2″ hose connections suitable for hozelock adaptors
  • cheap

That last point, “Cheap”, was the most difficult part. Considering that I needed 15 of them, I couldn’t afford to get the brass valves, or the particularly sturdy looking ones. I needed each unit to cost less than £8 (~$13). In the end, I settled on this one. (which is actually Servo operated, but it does the job.) And at £6.90 each, free postage and 6 Nectar points per unit, this valve easily satisfies the “Cheap” criterion.

3-Way

If you look closely at the below image, you’ll see that the valve has 3 ports, and on the white body, an arrow. The arrow indicates the direction of water flow, so, on the right we have port 1 which is water in. The middle port (middle right) is port 2, which is water out (always) and on the left is port 3, which is water out (when on).

12vDC Solenoid

Normally Closed

The valve is within the white body of the unit, and it is normally closed. Normally Closed means that when the valve is switched off, the water cannot pass through the body of the unit because the valve is closed. When the valve is off, water goes in through port 1 and out through port 2. Nothing comes out of port 3.

If we send 12V to the unit, the valve opens, meaning water enters through port 1 and leaves through port 2 & 3.

There are three very good reasons for choosing a 3-way valve rather than a simple 2-way valve. The primary reason is to do with the batteries, or rather battery. I only have one 12V battery, and I can’t have it konking out half-way through the watering routine because it’s had to hold open 3 valves simultaneously for 10 minutes.

Secondly, we are trying to future-proof the system; we’d like to be able to control individual bays.

The Nursery is set up like so:

[   BAY 10 ]   [   BAY 11  ]

[   BAY 7   ]   [   BAY 8   ]   [   BAY 9  ]

[   BAY 4  ]   [   BAY 5   ]    [   BAY 6   ]

[   BAY 1  ]   [   BAY 2   ]    [   BAY 3   ]

The water origin for each row is found in Bay 1, 4, 7 & 10. If we use simple 2-way valves then activating Bay 3 valve will do nothing, as the Bay 1 valve is stopping the water from reaching the Bay 3 valve.

By replacing the 2-way valves with 3-way valves we can connect Bay 1’s port 2 to Bay 2’s port 1, and Bay 2’s port 2 to Bay 3’s port 1. This means I can switch on Bay 3’s valve and it will water the plants without Bays 1 & 2 also having to be switched on. If the nursery had mains power, then this wouldn’t matter. We could switch on all 11 bays at once if we wanted to!

Thirdly, the water pressure at the nursery isn’t all that great, so only allowing one bay to water at a time means that each bay gets greater water pressure, which means the valves have to be on for less time overall.

 

With that sorted, let’s look at the amendments to the programme.

Imagining for a moment that we only had a system that required 2 valves, then the programme would look like this:


const int BAY1 = 1;
const int BAY2 = 2;

long watering = 300000; //Length of time it takes to water 1 bay = 5 minutes.
const int sec = (50*100); //50*100 = 5 seconds
const int N = 1;
int runXTimes = 0;

void setup() {
Serial.begin(9600);
Serial.println("Serial Begun.");
pinMode(BAY1, OUTPUT);
Serial.println("BAY 1 Initialised.");
pinMode(BAY2, OUTPUT);
Serial.println("BAY 2 Initialised.");
Serial.println("Setup DONE!");
}

void loop() {

delay(sec);

if (runXTimes < N) {

Serial.println("Begin BAY 1.");
digitalWrite(BAY1, HIGH);
delay(watering);
digitalWrite(BAY1, LOW);
Serial.println("End BAY 1.");
delay(sec);

Serial.println("Begin BAY 2.");
digitalWrite(BAY2, HIGH);
delay(watering);
digitalWrite(BAY2, LOW);
Serial.println("End BAY 2.");
delay(sec);

runXTimes++;

Serial.println("Watering is DONE!");
Serial.println("System will not run again until it is RESET.");

}

}

It looks like a lot of code, but really there is just a lot of serial printing happening as well. Without the serial stuff it looks like this:


const int BAY1 = 1;
const int BAY2 = 2;

long watering = 300000; //Length of time it takes to water 1 bay = 5 minutes.
const int sec = (50*100); //50*100 = 5 seconds
const int N = 1;
int runXTimes = 0;

void setup() {
pinMode(BAY1, OUTPUT);
pinMode(BAY2, OUTPUT);
}

void loop() {

delay(sec);

if (runXTimes < N) {

digitalWrite(BAY1, HIGH);
delay(watering);
digitalWrite(BAY1, LOW);
delay(sec);

digitalWrite(BAY2, HIGH);
delay(watering);
digitalWrite(BAY2, LOW);
delay(sec);

runXTimes++;

}

}

Yes, some of that could be done with a loop, but it isn’t.

So, what are we doing here:


const int BAY1 = 1;
const int BAY2 = 2;

First we are creating some variables and giving them integer values, hence the int part, and secondly, they won’t change, so they can be constants, hence const.


long watering = 300000;
const int sec = (50*100);
const int N = 1;
int runXTimes = 0;

Here we are setting some more values, in this case watering becomes 300,000 and sec becomes 5000. These values will be used for the delays later in the programme. 300,000 milliseconds = 5 minutes (the estimated time it will take the sprinklers to properly feed one bay) and 5000 milliseconds = 5 seconds.

N and runXTimes are used together. N becomes the number of times you want the system to run before you have to reset it. We want the system to only run once.


void setup() {

pinMode(BAY1, OUTPUT);
pinMode(BAY2, OUTPUT);

}

In the setup we initialise our variables (which are the numbers 1 & 2) as output pins.


void loop() {

delay(sec);

if (runXTimes < N) {

digitalWrite(BAY1, HIGH);
delay(watering);
digitalWrite(BAY1, LOW);
delay(sec);

digitalWrite(BAY2, HIGH);
delay(watering);
digitalWrite(BAY2, LOW);
delay(sec);

runXTimes++;

}

}

In the loop we first check to see if runXTimes is less than N (where N = 1). In other words, has the loop been run through once already? If the loop has not been run already, then runXTimes will be 00 is less than 1, so the loop will run.

Using digitalWrite we set the output pin assigned to BAY1 which is 1 to HIGH, in other words, we send 5v to Arduino Pin 1. (Yes, Pin 1, not Pin 0 – I deliberately avoided Pin 0.)

Next there is a five minute delay while the Arduino waits 300,000 milliseconds, during which time, Pin 1 remains HIGH. Once the time has elapsed, the pin is set to LOW (0V), and then we move on to the next bay and do the same thing.

Once all bays have been watered, runXTimes gets incremented by 1, and the loop starts again. Now however, runXTimes is not less than (N), it is equal to N, thus the bays will not be watered again unless the Arduino is reset.

 

[Part 1] [Part 2] [Part 3] [Part 4] [Part 5 – ALISS] [Download]

Author: Dan

Share This Post On