Altium
Arduino Projects

Wireless Soil Moisture Monitor using Arduino & LoRa SX1278

Wireless Soil Moisture Monitor:

Wireless Soil Moisture Monitor

Wireless Soil Moisture Monitor using Arduino & Lora- In this article, you will learn how to make a Wireless Soil Moisture Monitor using Arduino, a pair of Long Range SX1278 LoRa transceiver modules, a Soil Moisture Sensor, DHT11 Sensor, a one-channel relay module,and SSD1306 I2C supported Oled display module.

In my previous article, I have described the specifications of this new type of soil moisture sensor, pinout, and its application along with an Arduino quite in detail. I wrote that article, especially for the beginners and I touched upon everything at a fairly elementary level and explained how will you print the value of soil moisture on the Oled display module. Besides this, I also attempted to elaborate on how will you set the threshold value of soil moisture, so that whenever the soil moisture declines below the threshold level, the buzzer turns ON and starts to beep automatically. I also went on to explain howwill you use that beginner’s level project as a meter for measuring the soil moisture of different plants.




I am talking much about the previous article because the project that I am going to design today, is just a modified version of my previous project. So, in my article, I am not going to explain all those things, which have been extensively discussed and explained during my previous project. Hence, if you are on a beginner’s level, I will highly recommend you to go and read my previous article. So, let us move on to today’s project, which is a wireless soil moisture monitor.

There is an empty plot beside our home, which is actually owned by my uncle. It has not been in any type of use and lying futile since long. So, an idea to grow some plants and vegetables on it clicked in my mind. As I explained in my previous article, plants may be damaged as a result of low or high soil moisture levels. An ordinary soil moisture monitoring system won’t work here properly, because the plot is spaced apart from my home at quite a distance. I cannot use Bluetooth technology either, because Bluetooth’s communication range is short, and it is not actually possible to do real-time monitoring through GSM technology. If you want to use GSM technology just for Alert message purposes, then it is ok. But the real-time monitoring is merely impossible through the application of just GSM technology.

I already have a few LoRa transceiver modules available with me, using which I am going to design a long-range wireless soil moisture monitor. By means of using LoRa transceiver modules, we can monitor different sensors and control different loads within a range of even kilometers.

Wireless Soil Moisture Monitor

Anyway, here is a prototype model of my wireless soil moisture monitor. On the left side is the transmitter, along which a soil moisture sensor, DHT11 sensor, SX1278 LoRa transceiver module, one channel relay module, and a 220 Vac light bulb, are connected. I am using a bulb instead of a water pump so that at the time of carrying out a practical demonstration, you can clearly see for yourself how do I turn this bulb ON or OFF. You can also use a 220 Vac water pump and you can also use a DC water pump; it all depends on your choice. If you have to control a large water pump, then you better use a power relay. I have written a separate article on IoT Power Relay, in which I have practically demonstrated how to control a large water pump.



And on the right side is the receiver. It has been connected with a button, an Oled display module, and an SX1278 LoRa transceiver module. Now I am going to explain it’s working a bit, and then we will kick off our practical demonstration.

Altium Designer + Altium 365 + Octopart:

Arduino LoRa Free SMS

Altium 365 lets you hold the fastest design reviews ever. Share your designs from anywhere and with anyone with a single click. it’s easy, leave a comment tagging your teammate and they’ll instantly receive an email with a link to the design. Anyone you invite can open the design using a web browser. Using the browser interface, you’re able to comment, markup, cross probe, inspect, and more. Comments are attached directly to the project, making them viewable within Altium designer as well as through the browser interface. Design, share, and manufacture, all in the same space with nothing extra to install or configure. Connect to the platform directly from Altium Designer without changing how you already design electronics. Altium 365 requires no additional licenses and comes included with your subscription plan.

Get real-time component insights as you design with Octopart built into Altium 365. Octopart is the fastest search engine for electronic parts and gives you the most up-to-date part data like specs, datasheets, cad models, and how much the part costs at different amounts etc. Right in the design environment so you can focus on your designs. Start with Altium Designer and Activate Altium 365. Search for electronic parts on Octopart.

I will install the receiver side inside my room. I am not using a buzzer this time around, because I can read the soil moisture values on the Oled display at any time and then I can control the water pump accordingly. So, let me tell you how it works; the transmitter will send values related to the soil moisture, temperature, humidity, and motor status, which will show on the Oled display module fitted on the receiver’s side. Now, let us go ahead and start our practical demonstration.

Wireless Soil Moisture Monitor

I have powered up the transmitter as well as the receiver’s side. You can view soil moisture, temperature, humidity, and motor status on the Oled display. At this very moment, soil moisture is 16%. Now, if I press the button, the light will turn ON, which will indicate that the motor has turned ON and I also simultaneously receive feedback that the motor has powered ON.



Now, I am going to add some water and you will see an increase in the soil moisture value.

Wireless Soil Moisture Monitor

 Let’s say that this soil moisture value is enough, so now I can press the button and turn the pump OFF wirelessly.

Wireless Soil Moisture Monitor

You can see that the motor status has changed from 0 to 1 on the display.

It is so simple, isn’t it?   All we need is to read the soil moisture value on the display and then accordingly control the water pump on the remote side.

Wireless Soil Moisture Monitor

It can also be used as a wireless soil moisture meter; this way you can move around and measure the soil moisture of different plants while the supervisor in the control room keeps an eye on the soil moisture values.I am sure by now, you might have got an idea of how does this system work. So, without any further delay let’s get started!!!



Amazon Links:

Arduino Nano

LoRa SX1278 Module

5V buzzer

Soil moisture sensor

12v DC water Pump

5V relay Module

SSD1306 Oled display Module

DHT11 Temperature and Humidity Sensor

Other Tools and Components:

Top Arduino Sensors:

Super Starter kit for Beginners

Digital Oscilloscopes

Variable Supply

Digital Multimeter

Soldering iron kits

PCB small portable drill machines

*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!

About the Soil Moisture Sensor:

Wireless Soil Moisture Monitor

Here is my Soil moisture detection kit. Let’s first take a look at the interface circuit. The board is provided with this blue color potentiometer which is used to adjust the sensitivity.  This board is also provided with the most stable LM393 comparator chip and with On-board power and signal indicator LEDs to display the module working status. The working voltage of this module is from 3.3V to 12 volts. Because of this wide input voltage range, this Soil moisture sensor can be used with 3.3V and 5V compatible controller boards.

All the 4 headers are clearly labeled. The first pin is the Analog output pin and it should be connected with the Analog pin on the Arduino. The 2nd pin is the digital output put pin which can be connected with any digital pin on the Arduino or any other controller board. 3rd pin is the ground pin and the last pin is the VCC pin which you can connect with 3.3V or 5V.

The sensor probes are waterproofed and are made of highly corrosion-resistant material to ensure long lifetime up to 6 months after being plugged into the soil. The Sensor Cable length is 1.3 meters.




Specifications:

Working Voltage: DC 3.3-12V

Working Current: <20m(Output Current:<30mA)

Module Size: 36X15X6mm

Sensor Pin Pitch:5mm

Sensor Cable Length:1.3meter/3.94ft

Sensor Connecting Port: XH2.54 2P

SX1278 LoRa Module:

In this project we are using the same SX-1278 LoRa modules for the transmitter and receiver. In order to use it as a receiver and transmitter we will make change in the code. Lora SX-1278 long distance wireless transceiver module integrates Semtech RF transceiver chip SX1278, which adopts LoRa TM Spread Spectrum modulation frequency hopping technique. The features of long distance and high sensitivity (-139dBm) make this module perform better than FSK and GFSK module. Multi-signal won’t affect each other even in crowd frequency environment; it comes with strong anti-interference performance. This module is 100mW and ultra small size, widely used in AMR , remote industrial control filed.

Wireless Soil Moisture Monitor

Features:

  • Frequency Range: 868 / 915 MHz
  • Sensitivity up to -139dBm @Lora
  • Maximum output power: 20 dBm
  • [email protected] mode
  • Sleep current <200 nA
  • Data transfer rate: @FSK,1.2-300 Kbps
  • @Lora TM, 0.018-37.5 Kbps
  • Lora TM, FSK, GFSK & OOK Modulation mode
  • Built-in ESD Protection
  • 127 dB Dynamic Range RSSI
  • Packet engine up to 256 bytes with FIFO and CRC
  • Hopping frequency
  • Built-in temperature sensor and low battery indicator
  • Excellent blocking immunity
  • Operating Temperature Range:-40 ~ + 85 °C4



Applications:

  • Remote control
  • Remote meter reading
  • Home security alarm and remote keyless entry
  • Industrial control
  • Home automation remote sensing
  • Individual data records
  • Toys control
  • Sensor network
  • Tire pressure monitoring
  • Health monitoring
  • Wireless PC peripherals
  • Tag reading and writing

DHT11 Sensor:

Wireless Soil Moisture Monitor

DHT11 is a Humidity and Temperature Sensor, which generates calibrated digital output. DHT11 can be interface with any microcontroller like Arduino, Raspberry Pi, etc. and get instantaneous results. DHT11 is a low cost humidity and temperature sensor which provides high reliability and long term stability.

It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and outputs a digital signal on the data pin (no analog input pins needed). It is very simple to use, and libraries and sample codes are available for Arduino and Raspberry Pi. 

This module makes is easy to connect the DHT11 sensor to an Arduino or microcontroller as includes the pull up resistor required to use the sensor. Only three connections are required to be made to use the sensor – Vcc, Gnd and Output. 

It has high reliability and excellent long-term stability, thanks to the exclusive digital signal acquisition technique and temperature & humidity sensing technology.

DHT11 Specifications:-

  • Power Supply: 3.3~5.5V DC
  • Output: 4 pin single row
  • Measurement Range: Humidity 20-90%RH, Temperature 0~50℃
  • Accuracy: Humidity +-5%RH, Temperature +-2℃
  • Resolution: Humidity 1%RH, Temperature 1℃
  • Interchangeability: Fully Interchangeable
  • Long-Term Stability:<±1%RH/year



DHT11 Pin Description:-

  • Pin 1:     Power +Ve (3.3VDC to 5.5VDC Max wrt. GND)
  • Pin 2:     Serial Data Output
  • Pin 3:     Power Ground or Power –Ve

Wireless Soil moisture Monitor Tx Side:

Wireless Soil Moisture Monitor
This is the circuit diagram of the Wireless Soil Moisture Monitor transmitter side. The VCC of the LoRa module is connected with 3.3V of the Arduino. The MISO Pin of the LoRa module is connected with the Arduino pin 12. The MOSI pin is connected with pin 11. The SCK pin of the LoRa module is connected with pin 13. The NSS pin is connected with the Arduino’s pin 10 and the ground pin of the LoRa module is connected with the Arduino’s GND.

On the left side, you can see a 5V regulated power supply based on the LM7805 voltage regulator. We use this regulated 5 volts to power up the Arduino and all the other electronics.

The signal or data pin of the DHT11 temperature and humidity sensor is connected with the Analog pin A5 while the VCC and GND pins are connected with the Arduino’s 3.3V and GND pins.

The analog output of the soil moisture sensor board is connected with the Analog pin A1. While the VCC and GND pins are connected with the Arduino’s 5V and GND.

The 5V relay module input wire is connected with the Arduino digital pin 6. We use this relay to controla 12V DC water pump. But if you want you can also control a 110/220Vac water pump.

Wireless Soil moisture Monitor Rx Side:

Wireless Soil Moisture Monitor

The Lora module connections with the Arduino and the 5V regulated power supply wiring remains exactly the same.

The SDA and SCL or SCK pins of the SSD1306 Oled display module are connected with the A4 and A5 pins of the Arduino. While the VCC and GND pins of the Oled display module are connected with the Arduino’s 5 volts and GND pins.

A button is connected with the Digital pin 5 of the Arduino which is used to control the Water pump on the transmitter side.



Required Libraries:

I have written two programs, one for the transmitter side and the other one for the receiver side. Anyway, before you start the programming, first of all, make sure you download all the necessary libraries.

Download: LoRa.h

Download: Adafruit_GFX.h

Download: Adafruit_SSD1306.h

Wireless Soil Moisture Monitor Tx side Code:

/*

  Transmitter, nano

*/

#include <SPI.h>              // include libraries

#include <Wire.h>

#include <LoRa.h>

#include “dht.h”

#define dht_apin A5 // Connect DHT data pin with Analog Pin 5

int Relay=6;  //Relay will be connected with digital pin 6

dht DHT;

intmsensor = A1; // moisture sensor is connected with the analog pin A1 of the Arduino

intmsvalue = 0; // moisture sensor value

intmspercent; // moisture value in percentage

String stat=””; //  Motor status

intbuttonstat;

float temp; // to save the temperature value

int hum;     //humidity value

String outgoing;              // outgoing message

int relay1Status;

bytemsgCount = 0;            // count of outgoing messages

bytelocalAddress = 0xBB;     // address of this device

byte destination = 0xFF;      // destination to send to

longlastSendTime = 0;        // last send time

int interval = 200;          // interval between sends

String Mymessage = “”;

void setup() {

Serial.begin(9600);                   // initialize serial

pinMode(msensor, INPUT);

pinMode(Relay, OUTPUT);

Serial.println(“LoRa Duplex”);

if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz

Serial.println(“LoRa init failed. Check your connections.”);

while (true);                       // if failed, do nothing

  }

Serial.println(“LoRa init succeeded.”);

}

void loop() {

if (millis() – lastSendTime> interval) {

msvalue = analogRead(msensor);

mspercent = map(msvalue,0,1023,100,0); // To display the soil moisture value in percentage

DHT.read11(dht_apin);

hum=DHT.humidity;

temp=DHT.temperature;

    relay1Status = digitalRead(Relay);

Mymessage = Mymessage + mspercent +”,” + temp + “,” + hum +”,”+relay1Status; 

sendMessage(Mymessage);

delay(100);

Mymessage = “”;

    //Serial.println(“Sending ” + message);

lastSendTime = millis();            // timestamp the message

interval = random(50) + 100; 

    }

      // parse for a packet, and call onReceive with the result:

onReceive(LoRa.parsePacket());

  }

voidsendMessage(String outgoing) {

LoRa.beginPacket();                   // start packet

LoRa.write(destination);              // add destination address

LoRa.write(localAddress);             // add sender address

LoRa.write(msgCount);                 // add message ID

LoRa.write(outgoing.length());        // add payload length

LoRa.print(outgoing);                 // add payload

LoRa.endPacket();                     // finish packet and send it

msgCount++;                           // increment message ID

}

voidonReceive(intpacketSize) {

if (packetSize == 0) return;          // if there’s no packet, return

  // read packet header bytes:

int recipient = LoRa.read();          // recipient address

byte sender = LoRa.read();            // sender address

byteincomingMsgId = LoRa.read();     // incoming msg ID

byteincomingLength = LoRa.read();    // incoming msg length

  String incoming = “”;

while (LoRa.available()) {

incoming += (char)LoRa.read();

  }

if (incomingLength != incoming.length()) {   // check length for error

    //Serial.println(“error: message length does not match length”);

    ;

return;                             // skip rest of function

  }

  // if the recipient isn’t this device or broadcast,

if (recipient != localAddress&& recipient != 0xFF) {

   // Serial.println(“This message is not for me.”);

return;                             // skip rest of function

  }

String q = getValue(incoming, ‘,’, 0);

buttonstat = q.toInt();// button status

if(buttonstat==HIGH)

{

digitalWrite(Relay,HIGH);

  }

else

{

digitalWrite(Relay,LOW);

  }

incoming = “”;

}

String getValue(String data, char separator, int index)

{

int found = 0;

intstrIndex[] = { 0, -1 };

intmaxIndex = data.length() – 1;

for (inti = 0; i<= maxIndex&& found <= index; i++) {

if (data.charAt(i) == separator || i == maxIndex) {

found++;

strIndex[0] = strIndex[1] + 1;

strIndex[1] = (i == maxIndex) ? i+1 :i;

        }

    }

return found > index ? data.substring(strIndex[0], strIndex[1]) : “”;

}

This code is the modified version of my previous two projects. LoRa two way communication project and Soil moisture monitoring system. So, for a complete explanationread my previous articles. Anyway, the main purpose of this program is to read the Soil moisture sensor, Dht11 sensor, and relay status. And send these values to the receiver side. And at the same time, it also monitors if any command is received to control the water pump. Now, let’s take a look at the receiver side programming.




Wireless Soil Moisture Monitor Rx side Code:

/*

  Receiver, Nano

*/

#include <SPI.h>              // include libraries

#include <LoRa.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

intmstat;

int button=5;

int  relay1Status;

float temp;

int hum;

String stat=””; //  Motor status

String outgoing;              // outgoing message

intsmoisture;

bytemsgCount = 0;            // count of outgoing messages

bytelocalAddress = 0xFF;     // address of this device

byte destination = 0xBB;      // destination to send to

longlastSendTime = 0;        // last send time

int interval = 200;          // interval between sends

String statusmessage = “”;

#define SCREEN_WIDTH 128 // ORelay display width, in pixels

#define SCREEN_HEIGHT 64 // ORelay display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

#define ORelay_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, ORelay_RESET);

void setup() {

Serial.begin(9600);                   // initialize serial;

pinMode(button,INPUT_PULLUP);

Serial.println(“LoRa Duplex”);

if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz

Serial.println(“LoRa init failed. Check your connections.”);

while (true);                       // if failed, do nothing

  }

Serial.println(“LoRa init succeeded.”);

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

delay(2000);

display.clearDisplay();

display.setTextColor(WHITE);

}

void loop() {

if (millis() – lastSendTime> interval) {

  relay1Status = digitalRead(button);

statusmessage = statusmessage + relay1Status;

sendMessage(statusmessage);

delay(100);

statusmessage = “”;

lastSendTime = millis();            // timestamp the message

interval = random(50) + 100;    // 2-3 seconds

  }

  // parse for a packet, and call onReceive with the result:

onReceive(LoRa.parsePacket());

}

voidsendMessage(String outgoing) {

LoRa.beginPacket();                   // start packet

LoRa.write(destination);              // add destination address

LoRa.write(localAddress);             // add sender address

LoRa.write(msgCount);                 // add message ID

LoRa.write(outgoing.length());        // add payload length

LoRa.print(outgoing);                 // add payload

LoRa.endPacket();                     // finish packet and send it

msgCount++;                           // increment message ID

}

voidonReceive(intpacketSize) {

if (packetSize == 0) return;          // if there’s no packet, return

  // read packet header bytes:

int recipient = LoRa.read();          // recipient address

byte sender = LoRa.read();            // sender address

byteincomingMsgId = LoRa.read();     // incoming msg ID

byteincomingLength = LoRa.read();    // incoming msg length

  String incoming = “”;

while (LoRa.available()) {

incoming += (char)LoRa.read();

  }

if (incomingLength != incoming.length()) {   // check length for error

   // Serial.println(“error: message length does not match length”);

   ;

return;                             // skip rest of function

  }

  // if the recipient isn’t this device or broadcast,

if (recipient != localAddress&& recipient != 0xFF) {

    //Serial.println(“This message is not for me.”);

    ;

return;                             // skip rest of function

  }

String q = getValue(incoming, ‘,’, 0);

String r = getValue(incoming, ‘,’, 1);

String s = getValue(incoming, ‘,’, 2);

String t = getValue(incoming, ‘,’, 3);

smoisture = q.toInt();// soil moisture value

temp = r.toFloat();// tempreature value

hum = s.toInt();// humidity value

Serial.println(hum);

mstat = t.toInt();

Serial.println(mstat);

//if(mstat==1)

//{

//  stat=”ON”;

//  }

//  else

//  {

//      stat=”OFF”;

//

//    }

display.clearDisplay();

display.setCursor(10,0); 

display.setTextSize(2);

display.setTextColor(WHITE);

display.print(“SM:”+String(smoisture)+”%”);

display.setCursor(10,20);

display.setTextSize(2);

  //display.print(“C: “);

display.print(temp);

display.print((char)247);

display.print(“C”);

display.setCursor(10,45);

display.setTextSize(2);

display.print(“H:”+String(hum)+”%”+” M:”+String(mstat));

display.display();

delay(1000);     

incoming = “”;

}

String getValue(String data, char separator, int index)

{

int found = 0;

intstrIndex[] = { 0, -1 };

intmaxIndex = data.length() – 1;

for (inti = 0; i<= maxIndex&& found <= index; i++) {

if (data.charAt(i) == separator || i == maxIndex) {

found++;

strIndex[0] = strIndex[1] + 1;

strIndex[1] = (i == maxIndex) ? i+1 :i;

        }

    }

return found > index ? data.substring(strIndex[0], strIndex[1]) : “”;

}

On the receiver side, we read the button ON or OFF status and send it to the transmitter side to control the water pump. And at the same time, it also monitors if any message is received from the transmitter side. The message simply consists of comma-separated values. The message is first split and the corresponding sensor values are printed on the Oled display module. So, that’s all about the programming.



Watch Video Tutorial

Engr Fahad

My name is Shahzada Fahad and I am an Electrical Engineer. I have been doing Job in UAE as a site engineer in an Electrical Construction Company. Currently, I am running my own YouTube channel "Electronic Clinic", and managing this Website. My Hobbies are * Watching Movies * Music * Martial Arts * Photography * Travelling * Make Sketches and so on...

Leave a Reply

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

Back to top button