Arduino Home Irrigation System With a 7 Segment Display




Introduction: 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

1 x momentary push button

1 x relay board

2 x pumps (something like these)

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 minutes

void 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; } }

Be the First to Share


    • Stick It Challenge

      Stick It Challenge
    • Home and Garden Contest

      Home and Garden Contest
    • Origami Speed Challenge

      Origami Speed Challenge



    4 years ago

    Allow me one other technical remark and pls dont take it wrong as I really like your design and project:
    The ULN chip is a great choice for driving relays, but if you use a relay board as you have pictured, it is a bit of overkill, as the only thing it is driving then is the optocoupler on that relay board. The ULN is perfectly capable of directly driving a relay.
    Nothing wrong with it, works great and even inverts the signal to the board (the one pictured inverts the signal back to normal).
    The board pictured can be triggered directly from the Arduino (but you need a LOW to activate the relay).
    But let me be clear, great project


    Reply 4 years ago

    Thank you for your positive feedback and your remarks! Yes probably I could leave the sensor module out, but then I would need to make a connection on my perfboard to get one of the connections to an analog pin and an output pin. Probably easier to just leave it that way since they ship with the modules anyway.
    Regarding the ULN2803 comment, I had a different circuit with a relay that fried one of my chips within a day. After adding the ULN no fried chip in a week now. For complete opto isolation I probably would need another power supply and then the current draw for the relay board would still exceed the chips rating, if I understood everything correctly. The ULN chips are pretty cheap. Thanks for pointing the issues out!


    Reply 4 years ago

    oh indeed no problem using am ULN and indeed they are cheap and dont take much space.
    Ofcourse I am not sure whether your relayboard is exactly the same as in your drawing, but that one seems like the fully opto-isolated one. Anyway, doesnt matter, you got rid of fried chips and that's always a plus


    Reply 4 years ago

    I think I understand you now. If I would have made full use of the opto isolation (connecting the other GND / VCC Pins with a separate connection and removing the jumper) I shouldn't need to worry about the current limitations. I will definitely keep that in mind when I do my final design in an enclosure, thank you for your input!


    Reply 4 years ago

    indeed, but on the other hand... what you now have works :-)


    4 years ago on Step 4

    Very nice. Home irrigation systems seem to be a favourite build for microprocessors and I built a couple myself, always interested to see how others do it.
    I never used one of those fancy shiny moisture sensors, as they degrade pretty fast, but you have been smart to feed them from a digital pin that can be switched off and on :-)
    Still a remark though: as you use the analog output from the module, in fact the entire module becomes superfluous. The analog pin of the module is directly linked to the actual sensor and the modules only function then is to supply a pull up resistor. Could just do away with the module and directly attach the sensor itself to the Analog pin