LoRaWAN® Irrigation System Using Arduino® Edge Control

This application note describes how to control a four zones irrigation system using Edge Control and Arduino Cloud with LoRaWAN® connectivity.


Agricultural & farm activities are normally carried out in remote environments, where having access to consistent electricity power sources and good communication connectivity is a challenge.

Smart farming techniques are being implemented more and more due to the importance of optimizing the use of resources while increasing the demand for more efficient, eco-friendly, and profitable crops.

Application Note Overview. Each pot represents one individual irrigation zone capable of watering a crop field
Application Note Overview. Each pot represents one individual irrigation zone capable of watering a crop field

Implementing traditional wired communication infrastructure in remote areas can be expensive and time-consuming. LoRaWAN®, being a wireless technology, provides a cost-effective alternative, as it requires minimal infrastructure setup, reducing installation and maintenance costs.

Arduino has you covered in these scenarios with its Pro solutions, including products designed to work in remote environments, supplying their power from renewable sources, and providing long-distance connectivity and low power consumption.


The goal of this application note is to showcase a LoRaWAN® farming irrigation system that can be implemented on real agriculture fields using a combination of an Edge Control, an MKR WAN 1310, and the Arduino Cloud. The project's objectives are the following:

  • Independently control four irrigation zones using latching valves.
  • Leverage MKR WAN 1310 with LoRa® and a Wisgate (Lite or PRO) to communicate with Arduino Cloud.
  • Monitor soil moisture and decide whether to irrigate based on it.
  • Display the soil humidity level on the Edge Control Enclosure kit LCD.
  • Manually activate irrigation through Enclosure Kit built-in push button.
  • Monitor average humidity level, irrigation time and water consumption on dedicated charts on Arduino Cloud.
  • Get water from a garden hose with a flow sensor able to evaluate the amount of consumed water.

Hardware and Software Requirements

Project main hardware
Project main hardware

Hardware Requirements

  • Arduino Edge Control (x1)
  • Arduino MKR WAN 1310 (x1)
  • Arduino Edge Control Enclosure Kit (x1)
  • Water flow sensor (YF-B2 DN15) (x1)
  • Watermark Soil Moisture Sensors (200SS) (x4)
  • 2-Wires Latching Solenoid Valves (Galcon YLZ S1602) (x4)
  • 12 VDC 5Ah acid/lead SLA battery (NP12-7Ah) (x1)
  • 18 VDC 180 W solar panel (BougeRV 180W 9BB)(x1)
  • 3.4 meters of DN15 PVC pipes (x1)
  • DN15 PVC TEE pipes (x3)
  • DN15 PVC elbow (x8)
  • DN15 Manual Valve (x1)
  • DN15 PVC caps (x4)
  • DN15 PVC male adapters (x11)
  • DN15 wall pipe brackets (x7)
  • DN15 to DN20 adapters (x8)
  • Rectangular planters (x4)
  • DIN rail (x1)
  • Cable glands (x6)
  • 6 meters of duplex cable AWG 18 (x1)
  • Electrical Register Box (x1)
  • Access to the water system, in case you do not have access to the water system and you want to use a water tank instead, please take also a look at the Smart Farm Irrigation application note to know more.

Software Requirements

Irrigation System Setup

  • The Edge Control Enclosure Kit is perfect to enclose the main board alongside the MKR shields:

Edge Control, MKR WAN1310 and the Enclosure Kit Assembly

The electrical connections of the intended application are shown in the diagram below:

Electrical diagram of the irrigation system
Electrical diagram of the irrigation system

  • The Edge Control board will be powered with a 12 VDC acid/lead SLA battery connected to BATT+ and GND of J11 respectively. The battery will be recharged with an 18 VDC 180W solar panel connected to SOLAR+ and GND on the same connector.

Power connection diagram
Power connection diagram

  • The four solenoid valves will be connected to the Edge Control latching outputs of the J9 connector following the wiring below.

Solenoid valves connection diagram
Solenoid valves connection diagram

You can also use 3-Wires motorized valves. See this guide for reference.

  • The water flow sensor will be connected to a +12 VDC output, GND and the signal wire to the P1.15/IRQ_C_CH_1 of the J3 connector.

Watermark and water flow sensors connection diagram
Watermark and water flow sensors connection diagram

  • The four watermark sensors will be connected to a terminal block rail; one terminal to the common and the others to the watermark sensor inputs from 1 to 4 respectively on J8. Depending on the wiring of your sensors, you can use electrical clamps to ease the connection.

The final wiring should be similar to the following picture:

Edge Control with all the wiring
Edge Control with all the wiring

Irrigation System Overview

The irrigation system works as a whole: it integrates the water flow measurement and the activation of the valves, done by the Edge Control, with the Cloud communication using the MKR WAN 1310.

The Edge Control is responsible for:

  • Measuring the water usage with a water flow sensor.
  • Measuring the soil humidity level using watermark sensors.
  • Controlling the LCD screen of the Edge Control Enclosure kit, where different system variables will be shown, including soil humidity.
  • Deciding whether to irrigate based on soil local humidity.

The MKR WAN 1310 is responsible for:

  • Providing Cloud connectivity using LoRaWAN®.
  • Reporting the values of the Edge Control sensors on the Cloud.

The communication between both devices is done leveraging the I2C communication protocol.

Smart irrigation system with Edge Control
Smart irrigation system with Edge Control

Valves Control

The valves can be controlled manually by using the onboard button, one tap opens the first valve, two taps the second valve, and so on. In addition, the valves can be controlled automatically by the system when the soil moisture is poor. To do so, a "Smart mode" has to be enabled by tapping the button five times. The working time of the valves is monitored and reported on the Cloud to enable an efficient visualization of the average daily use.

Latching valves activation pulse
Latching valves activation pulse

The used valves used are latching, which means they are activated by a single pulse. The polarity defines if it opens or closes. This pulse must be in the range of 20-40 ms, more than that time could damage the latching outputs of your device.

Water Usage

The water flow sensor will measure the consumed water and will calculate its volume in liters. This information will be monitored through the Cloud and the integrated LCD.

Water flow sensor output signal
Water flow sensor output signal

The water flow is measured by a Hall effect sensor that generates a pulsed output by the rotation steps of a propeller inside the metal body.

The data is shown on dedicated widgets in the Arduino Cloud.

Water usage widgets in the Arduino Cloud
Water usage widgets in the Arduino Cloud

Soil Moisture Measurement

Instead of measuring the percentage of water by volume in a given amount of soil, we will be using watermark sensors that are capable of measuring the physical force holding the water in the soil. Those measurements are correlated with the effort plants have to make to extract water from the soil, a really interesting data for agricultural applications.

The measurement is done in Centibars, and we can use the following readings as a general guideline:

  • 0-10 Centibars: Saturated soil
  • 10-30 Centibars: Soil is adequately wet (except coarse sands, which are drying)
  • 30-60 Centibars: Usual range for irrigation (most soils)
  • 60-100 Centibars: Usual range for irrigation in heavy clay
  • 100-200 Centibars: Soil is becoming dangerously dry - Proceed with caution!

Arduino Edge Control Code

Let's go through some important code sections to make this application fully operative; starting with the required libraries:

1#include <Arduino_EdgeControl.h>
2#include <Wire.h>
3#include <RunningMedian.h>
5#include "SensorValues.hpp"
6#include "Helpers.h"
8// The MKR1 board I2C address
9#define EDGE_I2C_ADDR 0x05
11constexpr unsigned int adcResolution{ 12 }; // Analog Digital Converter resolution for the Watermark sensors.
13mbed::LowPowerTimeout TimerM;
15// Watermark sensors thresholds
16const long open_resistance = 35000, short_resistance = 200, short_CB = 240, open_CB = 255, TempC = 28;
18// Watermark sensors channels
19uint8_t watermarkChannel[4] = { 0, 1, 2, 3 };
21constexpr float tauRatio{ 0.63f };
22constexpr float tauRatioSamples{ tauRatio * float{ (1 << adcResolution) - 1 } };
23constexpr unsigned long sensorDischargeDelay{ 2 };
25constexpr unsigned int measuresCount{ 20 };
26RunningMedian measures{ measuresCount };
28constexpr unsigned int calibsCount{ 10 };
29RunningMedian calibs{ calibsCount };
31unsigned long previousMillis = 0; // will store last time the sensors were updated
33const long interval = 180000; // interval of the LoRaWAN message (milliseconds)
35// Variables for the water flow measurement
36volatile int irqCounts;
37float calibrationFactor = 4.5;
38volatile byte pulseCount = 0;
39float flowRate = 0.0;
40unsigned int flowMilliLitres = 0;
41unsigned long totalMilliLitres = 0;
42unsigned long oldTime = 0;
43unsigned long oldTime2 = 0;
45// Valves flow control variables
46bool controlV1 = 1;
47bool controlV2 = 1;
48bool controlV3 = 1;
49bool controlV4 = 1;
51// Valves On time keeping variables
52int StartTime1, CurrentTime1;
53int StartTime2, CurrentTime2;
54int StartTime3, CurrentTime3;
55int StartTime4, CurrentTime4;
57// LCD flow control variables
58bool controlLCD = 1;
59int showTimeLCD = 0;
61// Smart mode variables
62#define dry_soil 30
63bool smart = false;
64bool V1open = 0;
65bool V2open = 0;
66bool V3open = 0;
67bool V4open = 0;
68/** UI Management **/
69// Button statuses
70enum ButtonStatus : byte {
80// ISR: count the button taps
81volatile byte taps{ 0 };
82// ISR: keep elapsed timings
83volatile unsigned long previousPress{ 0 };
84// ISR: Final button status
85volatile ButtonStatus buttonStatus{ ZERO_TAP };
87SensorValues_t vals;
  • Arduino_EdgeControl.h
    will enable the support for the Edge Control peripherals; install it by searching for it on the Library Manager.
  • Wire.h
    will enable the I2C communication between the Edge Control, the MKR WAN 1310 and the other peripherals. It is included in the Board Support Package (BSP) of the Edge Control.
  • RunningMedian.h
    handles the calculations regarding the watermark sensor measurements.

There are two headers included in the project code able to handle some helper functions and structures:

  • SensorValues.hpp
    handles the shared variables between the Edge Control and the MKR WAN 1310 through I2C.
  • Helpers.h
    handles the real-time clock (RTC) functions to retrieve the local date and time.

This code's section also contains all the system variables regarding the following:

  • Constants and variables to set and store the watermark sensors data.
  • Constants and variables for the water flow sensor.
  • Flow control variables.
  • Structure to handle the number of button taps to control each valve manually.
2 Main section setup
4void setup() {
6 EdgeControl.begin();
7 Wire.begin();
9 delay(500);
10 Serial.begin(115200);
11 delay(2000);
13 Power.enable3V3();
14 Power.enable5V();
15 Power.on(PWR_3V3);
16 Power.on(PWR_VBAT);
17 Power.on(PWR_MKR1);
19 delay(5000); // giving time for the MKR WAN 1310 to boot
21 // Init Edge Control IO Expander
22 Serial.print("IO Expander initializazion ");
23 if (!Expander.begin()) {
24 Serial.println("failed.");
25 Serial.println("Please, be sure to enable gated 3V3 and 5V power rails");
26 Serial.println("via Power.enable3V3() and Power.enable5V().");
27 } else Serial.println("succeeded.");
29 // Init IRQ INPUT pins
30 pinMode(IRQ_CH1, INPUT);
32 // Attach callbacks to IRQ pins
33 attachInterrupt(digitalPinToInterrupt(IRQ_CH1), [] {irqCounts++;},FALLING);
35 // LCD button definition
36 pinMode(POWER_ON, INPUT);
37 attachInterrupt(POWER_ON, buttonPress, RISING);
39 Watermark.begin();
40 Latching.begin();
41 analogReadResolution(adcResolution);
43 setSystemClock(__DATE__, __TIME__); // define system time as a reference for the RTC
45 // Init the LCD display
46 LCD.begin(16, 2);
47 LCD.backlight();
49 LCD.home();
50 LCD.print("LoRa Irrigation");
51 LCD.setCursor(5, 1);
52 LCD.print("System");
53 CloseAll();
54 delay(2000);
56 LCD.clear();

To save energy and resources, the Edge Control has different power lines that must be enabled to power the different internal and external peripherals. In this case, the 3.3 V, 5 V, Battery, and the MKR1 slot need to be enabled.

An external interruption is being used for the water flow sensor and the LCD button, they are attached to the IRQ_CH1 and the POWER_ON inputs respectively. To handle all the I/Os, the I/O Expander together with the Enclosure Kit LCD and the sensors inputs need to be initialized.

The loop function is in charge of handling the system's repetitive tasks.

1void loop() {
3 // LCD button taps detector function
4 detectTaps();
5 tapsHandler();
7 // reset the valves accumuldated on time every day at midnight
8 if (getLocalhour() == " 00:00:00") {
9 Serial.println("Resetting accumulators every day");
10 vals.z1_on_time_local = 0;
11 vals.z2_on_time_local = 0;
12 vals.z3_on_time_local = 0;
13 vals.z4_on_time_local = 0;
14 delay(1000);
15 }
17 readWatermark();
19 if ((millis() - oldTime2) >= 1000) // Only process counters once per second
20 {
21 oldTime2 = millis();
22 readWaterFLow();
23 auto vbat = Power.getVBat(adcResolution);
24 Serial.print("Battery Voltage: ");
25 Serial.println(vbat);
26 vals.battery_volt_local = vbat;
27 }
29 unsigned long currentMillis = millis();
31 if (currentMillis - previousMillis >= interval) {
33 previousMillis = currentMillis;
35 // send local sensors values and retrieve Cloud variables status back and forth
36 Serial.println("Sending variables to MKR");
37 updateSensors();
38 }
40 // activate, deactivate and keep time of valves function
41 valvesHandler();

The Edge Control will check the number of button taps for the valve's manual control and handle the right action to do through the use of a switch case statement. Then, it will read the watermark sensors and periodically measure the battery voltage.

Every 3 minutes, the Edge Control will request the MKR WAN to send a LoRaWAN® message updating the sensors values in the Cloud.

Finally, in the loop function, we will check the valves states to control them and keep track of their active time.

Arduino MKR WAN 1310 Code

The MKR WAN 1310 needs the following libraries:

  • ArduinoJson.h
    parse and create JSON structures to visualize the I2C sent variables. It can be installed directly from the Arduino Library Manager.
  • Wire.h
    will enable the I2C communication between the Edge Control, the MKR WAN 1310 and the other peripherals. It is included in the BSP of the MKR WAN board.

There are three headers included in the project code that handles some helper functions and structures:

  • thingProperties.h
    is automatically generated by the Arduino Cloud. However, if you are using an offline IDE, verify it is in the same directory as your sketch and includes all the Arduino Cloud variables.
  • SensorValues.hpp
    handles the shared variables between the Edge Control and the MKR WAN 1310 through I2C.
  • arduino_secrets.h
    includes the LoRaWAN® credentials of your device.
1#include "arduino_secrets.h"
2#include "thingProperties.h"
3#include "SensorValues.hpp"
4#include <Wire.h>
6#include <ArduinoJson.h>
8// The MKR1 board I2C address
9#define SELF_I2C_ADDR 0x05
11unsigned long previousMillis = 0;
12const long interval = 3*60000; //180 second interval (3 minutes)

We also define the I2C address of the MKR and the update interval for the LoRaWAN® messages. Due to the LoRaWAN® limitations, we shouldn't define "short" intervals.

2 Main section setup
4void setup() {
5 // Initialize serial and wait for port to open:
6 Serial.begin(115200);
7 // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
8 delay(1500);
10 // Defined in thingProperties.h
11 initProperties();
13 // Connect to Arduino Cloud
14 ArduinoCloud.begin(ArduinoIoTPreferredConnection, false);
16 /*
17 The following function allows you to obtain more information
18 related to the state of network and IoT Cloud connection and errors
19 the higher number the more granular information you’ll get.
20 The default is 0 (only errors).
21 Maximum is 4
22 */
23 setDebugMessageLevel(2);
24 ArduinoCloud.printDebugInfo();
26 // Init I2C coomunication
27 Wire.begin(SELF_I2C_ADDR);
28 Wire.onReceive(receiveEvent); // I2C receive callback
33 Main section loop
35void loop() {
37 ArduinoCloud.update();

In the

function, we initialized the Serial communication, the Arduino Cloud variables, and the connection handler. Also, we initialized the I2C communication and defined a callback function
to handle the received messages.

2 Function that updates the Arduino Cloud variables with local values and those received from the Edge Control
3 @param vals includes the structured values of the shared variables
5void uploadValues(SensorValues_t *vals) {
7 StaticJsonDocument<200> doc;
8 doc["Zone 1"] = vals->valve1_local;
9 doc["Zone 2"] = vals->valve2_local;
10 doc["Zone 3"] = vals->valve3_local;
11 doc["Zone 4"] = vals->valve4_local;
12 doc["Moisture 1"] = vals->z1_moisture_local;
13 doc["Moisture 2"] = vals->z2_moisture_local;
14 doc["Moisture 3"] = vals->z3_moisture_local;
15 doc["Moisture 4"] = vals->z4_moisture_local;
16 doc["Water usage"] = vals->water_usage_local;
18 String output;
19 serializeJson(doc, output);
20 Serial.println(output);
22 // Cloud variable --- Shared I2C Variable
23 water_usage = vals->water_usage_local;
24 water_flow = vals->water_flow_local;
26 z1_on_time = vals->z1_on_time_local;
27 z2_on_time = vals->z2_on_time_local;
28 z3_on_time = vals->z3_on_time_local;
29 z4_on_time = vals->z4_on_time_local;
31 z1_moisture = vals->z1_moisture_local;
32 z2_moisture = vals->z2_moisture_local;
33 z3_moisture = vals->z3_moisture_local;
34 z4_moisture = vals->z4_moisture_local;
36 valve1 = vals->valve1_local;
37 valve2 = vals->valve2_local;
38 valve3 = vals->valve3_local;
39 valve4 = vals->valve4_local;
41 battery_volt = vals->battery_volt_local;


function simply updates the Cloud variables with the ones received from the Edge Control.


LoRaWAN® Gateways
LoRaWAN® Gateways

This project is using LoRaWAN®, which stands for Long Range Wide Area Network, and it is a low-power wireless communication protocol designed for connecting battery-operated devices to the internet over long distances. If you want to learn more about LoRa® and LoRaWAN® check this guide.

The MKR WAN 1310 will be the end-device encharged of connecting to The Things Network (TTN), which is the network server supported by the Arduino Cloud. Learn how to connect the MKR WAN 1310 to TTN using this guide.

After following the guide you will get two important keys that will be needed for the LoRaWAN® connectivity

, define them in the
header of your MKR code.

LoRaWAN® network credentials
LoRaWAN® network credentials

As a gateway we will be using the WisGate Edge Lite 2, which will provide long-range coverage and access to the network. Learn how to set up yours using this guide.

If there is coverage of a TTN public gateway in your area, it is not necessary to install yours. You can check your area network here.

The Arduino Cloud Dashboard

Taking advantage of the Arduino Cloud, it is possible to seamlessly integrate a simple but powerful dashboard to monitor and visualize the status of the system from remote, resulting in a professional Human-Computer Interaction (HCI) as shown below:

Arduino Cloud project dashboard
Arduino Cloud project dashboard

Within the Arduino Cloud's dashboard, the system variables can be monitored as follow:

  • Each solenoid valve status is shown as OFF or ON.
  • The activated time of each valve is graphed next to its state.
  • The watermark sensor instant values are shown in gauges alongside a time series record chart.
  • There is a resources section showing the battery voltage in a gauge and the water flow in liters per minute, also, it shows the liters of water used.

Arduino Cloud project dashboard on a smartphone
Arduino Cloud project dashboard on a smartphone

The dashboard is easily accessible from a browser, mobile phone or tablet, allowing a user to receive updates on the irrigation status from anywhere.

Full Smart Irrigation System Example

All the necessary files to replicate this application note can be found below:

  • The complete code can be downloaded here.

The Irrigation System Working

Below you can find some additional images and animations showing how the system works:

Watermark sensors
Watermark sensors
Battery connection
Battery connection
Irrigation in zone three and four

Remember that the system is designed to be scalable; therefore, it is possible to control 4 bigger irrigation zones independently, like, for example, different cultivated fields, each with different crops and, consequently, different water and soil needs.


In this application note, you have learned how to build a LoRaWAN® irrigation system to water your crops automatically or manually and monitor the crop's status remotely. Thanks to the soil moisture analysis, you can avoid irrigation when it's not necessary, saving water and avoiding over-irrigation or flooding problems.

Arduino Edge Control allows you to easily implement this kind of agriculture systems ready for field deployment. Alongside MKR boards, it can get access to the network using the most suitable technology for your application.

In this project, LoRaWAN® was used leveraging its capabilities: this technology is perfect for remote deployments where there is no internet connection and for battery-powered devices because of its low energy consumption.

Thanks to its capabilities of controlling different types of actuators and handling a vast variety of input sensors, the Edge Control is a great choice for developing robust and agriculture environment-proof solutions.

Next Steps

Since you already know how to develop a Smart Irrigation System with Arduino Edge Control and the MKR WAN 1310, it is time for you to continue exploring all the capabilities of the Arduino Pro portfolio and integrating it into your professional setup.

We have a similar project using motorized ball valves, WiFi® connectivity and scheduled remote control from the Arduino Cloud, click this link to know more.

You can extend the capabilities of your Edge Control-based system by adding different connectivity options, leveraging the Arduino MKR family like WiFi®, GSM, RS-485 or Ethernet.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.


The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.