LORA PROJECTS

Swimming Pool Monitoring System using Arduino and LoRa, Save a child from drowning

Swimming Pool Monitoring System, Description:

 

Swimming Pool Monitoring System using Arduino and LoRa, Save a child from drowning- In this article, you will learn how to make a smart swimming pool monitoring system using Arduino boards, a pair of SX1278 LoRa Transceiver modules, MPU6050 accelerometer, and Gyroscope Module, and a 5V buzzer. if you want to display the mpu6050 data on 16×2 i2c LCD and ssd1306 OLED display then check out this article.

The objective behind designing this swimming pool monitoring system is actually based on my commitment that during the ongoing summer and during the summers coming ahead, we do not have to let any child drown. So, you are requested guys to share this article as much as possible, so that more and more people come to know about this useful system.


According to the US Consumer Product Safety Commission, 390 deaths a year on average are attributed to drowning in a swimming pool. The majority of the deaths occur during the months of June, July, and August, mostly in the backyard pools. If this is the situation in a country like the US, where everything is so systematic, just imagine for yourself what will be the kid’s death rates due to drowning incidents throughout the world.  

As an engineer, I consider it my duty to devise a kind of a system, which may prove helpful in the protection of any precious life, so, I will go ahead and definitely work on the accomplishment of this cherished obligation.

A lot of people, mostly the parents, usually enquire about how to save a child from drowning and how to keep their kids safe at the pool? Well, you have two options for this.

1). As a precaution, you can build a sort of barricade around the swimming pool to keep the kids away, and

2). You can make a smart swimming pool monitoring system to alert the parents when there is any kind of activity in the water.

swimming pool monitoring system

If you select option 1, then believe me kids are very sharp and clever these days, they will definitely find out some sort of a mechanism to reach out to the pool, however; 



If you select option number 2 (My designed swimming pool monitoring system), then rest assured even the slightest activity in the water will trigger the system, and parents will abruptly come to know that somebody is venturing in the water, and then they can go around and check the scenario by themselves.

Now, let me tell you a bit about this swimming pool monitoring system. At the time of designing this system, I studied water ripples, my goal was that from whichever direction ripples or waves come, my designed system should be so sensitive that it can detect these ripples. I kept thinking about different types of sensors for a significant period of time, and then all of a sudden, the MPU6050 module came into my mind.

swimming pool monitoring system


The MPU6050 module is best for the project because, with the help of the MPU6050 module, we can monitor three axes (x-axis, y-axis, and z-axis) simultaneously.

swimming pool monitoring system

So, I made this prototype model. You can clearly see that I have connected MPU6050 and LoRa SX1278 modules with Arduino. This particular side is the transmitter and it will be placed on the swimming poolside.

swimming pool monitoring system

And this side is the receiver, which will be installed somewhere inside the house. A buzzer is attached to it. As soon as ripples are generated in water, this buzzer will automatically turn ON.  

Let us kick off our practical demonstration so that you can see how beneficial this swimming pool monitoring system can be;


Altium Designer, Altium 365, & Octopart:

swimming pool monitoring system

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.


Practical Demonstration:

swimming pool monitoring system

First, I am going to do some basic testing, and thereafter I will practically test it in water. So, you can see that I have powered up both the transmitter as well as receiver’s side. I have done its programming in such a way that when MPU6050 is on an absolutely flat-water surface, it does not send any trigger message to the receiver side, however, if the slightest change occurs in any of its axis, its system triggers, and buzzer on the receiver’s side turns ON.



In the above image, you can’t see how this system activates when I touch the transmitter side. For visual demonstration, you can watch the video, given at the end of this article.

It has the capacity to detect even the smallest of vibrations. My designed system is so sensitive that even when I hit the table the buzzer on the receiver side is activated. So, if you observe during the testing that this system is very sensitive, then you can modify its threshold values in the programming, which later I will explain.

I didn’t face any issues while performing the basic tests, the only thing I did, I changed the threshold values to make it less sensitive.

Now we move on and practically test this project in water.

swimming pool monitoring system

For the practical demonstration, I placed the Transmitter side circuit in a plastic container. While you can design your own 3D printed waterproof plastic enclosure.


swimming pool monitoring system

You can see that there is no ripple on the water surface, and that’s why the buzzer on the receiver side remains OFF. So, let us move forward and produce some ripples in the water, and then we see whether the system detects these ripples or not.

swimming pool monitoring system

I generated some ripples by slowly throwing a Doll in the water, and my system quickly detected the ripples and the buzzer on the receiver side turned ON. For practical demonstration, watch the video given at the end of this article.


It has been working amazingly, even better than my imagination. So, the prototype model has turned out to be a success. 

swimming pool monitoring system

If you want to implement this swimming pool monitoring system, in reality, you can reduce the transmitter size by designing a small PCB. You can see my development board is big, the unnecessary female headers can be removed. You can also use Arduino Pro Mini, which will render it into a significantly small size, and as such you will be able to power up this system even though a small 3.7V Lipo battery.

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

MPU6050 Module

5V buzzer

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!



Swimming Pool Monitoring System, Circuit Diagram:

swimming pool monitoring system

This is the circuit diagram of the transmitter side.  The VCC of the SX1278 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.

The VCC and GND pins of the MPU6050 Module are connected with the Arduino 3.3V and GND pins. While the SCL and SDA pins of the MPU6050 module are connected with the A5 and A4 pins of the Arduino. A5 is the SCL and A4 is the SDA.

On the left side is the regulated 5V power supply based on the LM7805 voltage regulator.


Receiver Side, Circuit Diagram:

swimming pool monitoring system

On the receiver side, the connections of the 5v regulated power supply and SX1278 LoRa transceiver module remain exactly the same. A 5V buzzer is connected with the Arduino Pin 3. A 2n2222 NPN transistor is used to control the buzzer. The 10K resistor and 2n2222 NPN transistor make the driver circuit. Now, let’s take a look at the transmitter and receiver side programming.


Swimming Pool Monitoring system, Arduino Programming:

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 hartway_digital Library: hartway_digital

The hartway_digial consists of the MPU6050.h and I2Cdev.h header files.

Let’s first start with the transmitter side programming.

Arduino, LoRa, and MPU6050, Programming:

/*
  Transmitter side, Swimming Pool Side

*/
#include "I2Cdev.h"
#include "MPU6050.h"
#include <SPI.h>              // include libraries
#include <LoRa.h>

byte msgCount = 0;            // count of outgoing messages
byte localAddress = 0xBB;     // address of this device
byte destination = 0xFF;      // destination to send to

String outgoing;              // outgoing message
String Mymessage;             // stores message from the bluetooth


// for MPU6050
MPU6050 mpu;
 
int16_t ax, ay, az;
int16_t gx, gy, gz;
 
 
 
int val;
int prevVal;
 
int valax; 
int valay;
int valaz;

void setup() {
  Wire.begin();
  Serial.begin(9600);                   // initialize serial
  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.");
  mpu.initialize();
 
}

void loop() {


mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
valax = map(ax, -17000, 17000, 0, 255) ;
valay = map(ay, -17000, 17000, 0, 255);
valaz = map(az, -17000, 17000, 0, 255);
 
//Serial.println("ax: ");
//Serial.println(valax);
//Serial.println("ay:");
//Serial.println(valay);
//Serial.println("az: ");
//Serial.println(valaz);
//Serial.println("");
//Serial.println("");

/*

 I got the following values, when the sensor was lying on a flat surface
ax: 
153
ay:
127
az: 
-1
 */

if ( (valax < 148) || (valax > 155) || (valay < 124) || (valay > 132) || (valaz < -4) || (valaz > 4) )
 
  {
    
    //read data
    Mymessage= Mymessage + 1 + ",";
    sendMessage(Mymessage);
    delay(100);
    Mymessage = "";

  } else

  {
     Mymessage= Mymessage + 0 + ",";
    sendMessage(Mymessage);
    delay(100);
    Mymessage = "";
  }
   

  }


void sendMessage(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
}

Maximum of the code I have already explained in my previous tutorials. The purpose of this code is to read the X-axis, Y-axis, and Z-axis values and then compare these values with the pre-defined values. So, if the value on any Axis is less than or greater than the pre-defined value, then a value of 1 is sent to the receiver side. Otherwise, a value of 0 is sent which means there is no activity in the water. Now, let’s take a look at the receiver-side programming.


Arduino, LoRa, and Buzzer, Programming:

/*
  Receiver side, monitoring station

*/
#include <SPI.h>              // include libraries
#include <LoRa.h>

byte msgCount = 0;            // count of outgoing messages
byte localAddress = 0xFF;     // address of this device
byte destination = 0xBB;      // destination to send to

int buzzer=3;

int TriggerSignal;                  // stores the command

void setup() {
  Serial.begin(9600);                   // initialize serial
  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.");
  pinMode(buzzer, OUTPUT);
}

void loop() {

  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}



void onReceive(int packetSize) {
  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
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = 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
  }

  // if message is for this device, or broadcast, print details:
 // Serial.println("Received from: 0x" + String(sender, HEX));
 // Serial.println("Sent to: 0x" + String(recipient, HEX));
  //Serial.println("Message ID: " + String(incomingMsgId));
 // Serial.println("Message length: " + String(incomingLength));
  //Serial.println("Message: " + incoming);
  //Serial.println("RSSI: " + String(LoRa.packetRssi()));
  //Serial.println("Snr: " + String(LoRa.packetSnr()));
  //Serial.println();
    String q = getValue(incoming, ',', 0);
    TriggerSignal = q.toInt();
   // Serial.println(q);
if(TriggerSignal == 1)
{
 digitalWrite(buzzer, HIGH);
 delay(1000);
 digitalWrite(buzzer,LOW);
 delay(1000);
  digitalWrite(buzzer, HIGH);
 delay(1000);
 digitalWrite(buzzer,LOW);
 delay(1000);
  digitalWrite(buzzer, HIGH);
 delay(1000);
 digitalWrite(buzzer,LOW);
 delay(1000);

 TriggerSignal = 0;  
    
  }


//incoming = "";
  
}
String getValue(String data, char separator, int index)
{
    int found = 0;
    int strIndex[] = { 0, -1 };
    int maxIndex = data.length() - 1;
 
    for (int i = 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]) : "";
}

The purpose of this program is to check if a value of 1 or 0 is received. If a value of 1 is received then turn ON and Turn OFF the buzzer a few times. And then finally we make the TriggerSignal = 0.

getValue() function is a user-defined function that I have been using in all those projects where I needed to split a string message. So, the purpose of this function is to split any string message using any character as the delimiter. In my case, I am using a comma as the delimiter. 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...

2 Comments

  1. Hi, Thanks for this project – I’ve build according your instructions, but as i’m waiting on the delivery of the Lora modules, I disabled the LORA functionality in the code and replaced by a printing message so I could discover the az/ay/ax values.
    on the MPU6050 I see the led flashing when there is movement, but the values i’m reading are all same for az/ay/ax no matter how hard I move the sensor. value = 127

    This is the monitoring message
    —————————————
    Moving detected – msg = 1,
    ax:
    127
    ay:
    127
    az:
    127

    What could be wrong?
    is the length of the wires between the Arduino & the MPU sensor critical? this is about 8 cm long now.
    Hope you can help me further.
    Thanks

    Below the modified code for testing
    ———————————————————
    /*
    Transmitter side, Swimming Pool Side
    modified by JSTAL 10/08/2023
    */
    #include “I2Cdev.h”
    #include “MPU6050.h”
    #include // include libraries
    //#include

    byte msgCount = 0; // count of outgoing messages
    byte localAddress = 0xBB; // address of this device
    byte destination = 0xFF; // destination to send to

    String outgoing; // outgoing message
    String Mymessage; // stores message from the bluetooth

    // for MPU6050
    MPU6050 mpu;

    int16_t ax, ay, az;
    int16_t gx, gy, gz;

    int val;
    int prevVal;

    int valax;
    int valay;
    int valaz;

    void setup() {
    Wire.begin();
    Serial.begin(9600); // initialize serial
    // 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.”);
    mpu.initialize();

    }

    void loop() {

    mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    valax = map(ax, -17000, 17000, 0, 255) ;
    valay = map(ay, -17000, 17000, 0, 255);
    valaz = map(az, -17000, 17000, 0, 255);

    Serial.println(“ax: “);
    Serial.println(valax);
    Serial.println(“ay:”);
    Serial.println(valay);
    Serial.println(“az: “);
    Serial.println(valaz);
    Serial.println(“”);

    /*

    I got the following values, when the sensor was lying on a flat surface
    ax:
    153
    ay:
    127
    az:
    -1
    */

    if ( (valax 155) || (valay 132) || (valaz 4) )

    {

    //read data and activate buzzer – 3 beeps
    Mymessage= Mymessage + 1 + “,”;
    // sendMessage(Mymessage);
    // delay(100);
    Serial.println(“Moving detected – msg = ” + Mymessage);
    Serial.println(“”);
    Mymessage = “”;

    } else

    {
    Mymessage= Mymessage + 0 + “,”;
    // sendMessage(Mymessage);
    Serial.println(“NO Moving “);
    Serial.println(“”);
    delay(100);
    Mymessage = “”;
    }

    }

    //void sendMessage(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
    //}

  2. Sir,it only shows like this #include
    ^~~~~~~~
    compilation terminated.
    exit status 1

    Compilation error: LoRa.h: No such file or directory
    Please make a tutorial on uploading the code or please contact us to correct our mistakes.
    Thanking you!!

Leave a Reply

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

Back to top button