Arduino Home Irrigation System With a 7 Segment Display

In this instructable we are building a home irrigation system based on an arduino uno. I know there are tons of similiar projects / tutorials already floating the web, but maybe I did something different and you can pick up an idea or two.

Step 1: Gathering the Tools

You will need:

1 x Arduino Uno (or an atmega328 chip and a programmer)

1 x 10kOhm resistor

1 x 20kOhm resistor (or any other number resistor that you can put in series)

1 x ULN2803a (or MOSFETS + diodes)

1 x TM1637 Display

2 x Hygrometer sensors

2 x pumps (something like these)

1 x momentary push button

1 x relay board

1 x 2 pole terminal

sockets (optional, but highly recommended to be able to easily reprogram the atmega chip if needed)

depending whether you use an arduino or an atmega:

1 x 16 Mhz crystal

2 x 22pF capacitors

1 x 10 µF capacitor

1 x 1N4001 diode

jumper cables

hook up wire


breadboard or perfboard

power supplies (5V or more, and one power supply for your pumps)

You will need basic equipment like:

Soldering Iron


Cable stripper

Digital Multimeter

Step 2: The Schematics

You can see the wiring and schematics both for the atmega328 standalone version and the wiring for using an arduino uno. Since the project is supposed to run on its own after it’s finished I don’t need any of the arduino functionalities and just use the bare chip. You can either use the chip from the arduino or refer to this video to see how you can use your arduino as programmer for another chip.

As you can see I have a GND and 5V rail on either site of my perfboard, all the GND and 5V connections in the schematic refer to these, therefore the filter cap is only drawn once.

Have a look here to see the pin mapping of the atmega chip compared to the arduino.

If you are going to solder everything on a PCB, make sure to use your digital multimeter to check all connections and to make sure all power rails are powered with 5V. If you are going to use a power supply with more than 5V, add appropriate voltage regulators (7805 e.g.). I again would recommend soldering a socket to the board instead of the chip directly, so you can easily take it out again for reprogramming as you are doing the fine tuning for your setup.

Other than that, you should be able to recreate the wiring from the schematics.

I used a ULN2803A module because the output pins of the atmega (and therefore probably from the arduino, too) do not supply enough current to switch the relay. My relay requires around 60mA, but the pins of the atmega are not to exceed around 40mA. Also I read that you shouldn’t switch inductive loads like relays directly anyway. The module protects the chip from any damage. I was advised that this module creates a voltage drop, so if your relay can’t be powered with less than 5V, use MOSFETs and flyback diodes accordingly.

Step 3: Wiring the Relay and Pumps

WARNING: I do not know which pumps or power supplies you are using. When wiring up the relay, make sure to disconnect everything from power before you start cutting / connecting any cables. You may be working with mains voltage. Mistakes can lead to serious injury or death. If not done correctly, you may also start a fire. I do not take responsibility for any damages done to you, others or your property. I’m not an electrician, so maybe the way I did is not correct either. If you do not know what you are doing and feel uncomfortable, leave to project be or consult someone who knows. Proceed at your own risk.

My relay board consists of 3 terminals for each input: NO, NC and COM. I just got into the habbit of switching both neutral and phase for each pump although with the specific power supply I used I know for sure which cable is which. This is not always the case as you may not have polarity protection.

I cut the cables from the power supply and connected them to the COM ports. I then connected the normaly open terminals to my pumps. When the relay turns on, the normally open connection closes and the pump starts. To be able to use 1 power supply for multiple pumps I connected the normally closed port to the COM port of the next set of terminals.

When pump 1 is turned on, terminal 1 and 2 both switch on, neutral and phase are both connected via the NO and COM terminal, the normally closed terminal is now open.

When pump 2 is turned it, the normally closed terminal is closed, so we can draw power from there. I don’t turn on both pumps at the same time but sequentially so this is not a problem.

You can find a more detailed explanation of how the modules work here.

Step 4: The Code

Now that everything is wired up it’s time to dive into the code. I tried to comment every important step. The library for the 7 segment display can be found here.

The hygrometers would corrode rather quickly if constantly supplied with 5V, therefore we only supply them with current if we actually need to measure. That’s why we didn’t connect them to our 5V rails.

const int hygrometer1 = A0;  //Hygrometer sensor at pin A0
const int hygrometer2 = A1; //Hygrometer sensor at pin A int Pump1_1 = 11; // Pump 1, cable 1 int Pump1_2 = 2; // Pump 1, cable 2 int Pump2_1 = 3; // Pump 2, cable 1 int Pump2_2 = 4; // Pump 2, cable 2 int Hygro1 = 9; // VCC Hygrometer 1 int Hygro2 = 10 ; // VCC Hygrometer 2 int value1; int value2; int runs1 = 0; // counts how many times the pumps have been turned on int runs2 = 0;#include "SevenSegmentTM1637.h" const byte PIN_CLK = 8; // define CLK pin (any digital pin) const byte PIN_DIO = 7; // define DIO pin (any digital pin) int inPin = 6; // input of the push button int val = 0; int push_count = 0; // counts how many times the button was pushed int buttonState = 0; // saves the state of the button, low or high SevenSegmentTM1637 display(PIN_CLK, PIN_DIO); unsigned long previousMillis = 0; // taken from the blink with delay example const long interval = 1800000; // only measure every 30 minutesvoid setup() { display.begin(); // init the display display.setBacklight(20); // set the brightness of the display to 20 % Serial.begin(9600); // set all the pin modes accordingly pinMode(Pump1_1, OUTPUT); pinMode(Pump1_2, OUTPUT); pinMode(Pump2_1, OUTPUT); pinMode(Pump2_2, OUTPUT); pinMode(Hygro1, OUTPUT); pinMode(Hygro2, OUTPUT); pinMode(8, OUTPUT); pinMode(inPin, INPUT); // set all the pins to their initial states digitalWrite(8, LOW); digitalWrite(Pump1_1, LOW); digitalWrite(Pump1_2, LOW); digitalWrite(Pump2_1, LOW); digitalWrite(Pump2_2, LOW); digitalWrite(Hygro1, LOW); digitalWrite(Hygro2, LOW); // display that the system is booting display.clear(); display.print("INIT"); delay(2000); display.clear(); }void loop() { // we are counting how many milli seconds have passed since the system booted, if we completed a 30 min intervall, run measure(), else run buttons() unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval || previousMillis == 0) { // note the || previousMillis == 0, we also want to measure on bootup, it's easier to identify mistakes // save the last time we measured the moisture previousMillis = currentMillis; measure(); } buttons(); }void measure() { display.clear(); display.print("read"); digitalWrite(Hygro1, HIGH); // supply the hygrometer with voltage digitalWrite(Hygro2, HIGH); // supply the hygrometer with voltage delay(2000); value1 = analogRead(hygrometer1); // read the value (0-1023) value2 = analogRead(hygrometer2); // read the value (0-1023) delay(2000); digitalWrite(Hygro1, LOW); // turn off the hygrometer digitalWrite(Hygro2, LOW); // turn off the hygrometer display.clear(); if (value1 <= 550) // check if the plant is well watered (lower values mean well watered) { display.clear(); display.print("1 OK"); delay(2000); display.clear(); } else { digitalWrite(Pump1_1, HIGH); digitalWrite(Pump1_2, HIGH); delay(20000); // time in ms how long the pump is turned on, 20 s here digitalWrite(Pump1_1, LOW); digitalWrite(Pump1_2, LOW); runs1++; // increment the number of times pump 1 has run } if (value2 <= 450) { display.clear(); display.print("2 OK"); delay(2000); display.clear(); } else { digitalWrite(Pump2_1, HIGH); digitalWrite(Pump2_2, HIGH); delay(20000); // time in ms how long the pump is turned on, 20 s here digitalWrite(Pump2_1, LOW); digitalWrite(Pump2_2, LOW); runs2++; // increment the number of times pump 2 has run } }// the script to print the values and cycle through the display void buttons() { val = digitalRead(inPin); // read state of the button if (val != buttonState && val == HIGH){ // make sure we detect a change from LOW to HIGH push_count++; // count that the button has been pushed } else { // do nothing } buttonState = val; // save the current state switch (push_count) { case 0: display.clear(); display.print("sns1"); delay(2000); display.clear(); push_count++; break; case 1: display.print(value1); break; case 2: display.clear(); display.print("sns2"); delay(2000); display.clear(); push_count++; break; case 3: display.print(value2); break; case 4: display.clear(); display.print("no 1"); delay(2000); display.clear(); push_count++; break; case 5: display.print(runs1); break; case 6: display.clear(); display.print("no 2"); delay(2000); display.clear(); push_count++; break; case 7: display.print(runs2); break; default: push_count=0; } }

Source: Arduino Home Irrigation System With a 7 Segment Display

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top