• EUR€
  • £GBP
  • $USD
PROJECTS Arduino Gravity

Water Aid

DFRobot Jun 06 2019 26

Things used in this project

Hardware components:

  • Arduino MKR GSM 1400 x1
  • Adafruit NeoPixel Ring: WS2812 5050 RGB LED ×1
  • GY21 Temperature and Humidity ×1
  • Turbidity Sensor, Phototransistor Output x1
  • Adafruit Waterproof DS18B20 Digital temperature sensor x1
  • Gravity: Analog Spear Tip pH Sensor / Meter Kit x1
  • DFRobot Gravity: Analog Spear Tip pH Sensor / Meter Kit x1
  • Pushbutton switch 12mm x1
  • SparkFun Pushbutton switch 12mm x1
  • Jumper wires (generic) x1
  • Resistor 220 ohm x1

Software apps and online services:

  • Arduino Web Editor
  • SORACOM Air IoT Connectivity Platform
  • SORACOM Harvest
  • SORACOM Lagoon

Hand tools and fabrication machines:

  • Soldering iron (generic) 



Rivers. Essential to our survival, trade and so on. Great efforts have been made in the last decade to reduce our pollution of the world's bodies of water. The rivers are the source of the pollution, as people do not go to the sea to dump their trash. They dump it in the rivers.

These rivers then spill into the sea, the ocean and so the toothbrush that was once thrown in a river makes its way across the world and lands on the other side of it.

In a world trying to combat pollution, data is crucial. It should be easy for companies and businesses to collaborate on a global project to reduce water pollution. This is where WaterAid comes in.

A device cheap enough and scalable that can easily collect and analyse this data, so necessary to know how polluted a river is. WaterAid comes in 2 modes, one that would fit enterprises and another for individuals.

Multiple devices can function together, placed at different points across a stream or in different bodies of water. These devices collect data at an interval of time sending it to the same database. This allows the business to check the status of the river or lake being monitored with the click of a button.

A portable version of the device is also available. In this version, the individual can carry the device with them and when they wish to take a water sample, they press on a button on the device and place it in water for 30 seconds. The data will then be available on an online dashboard.

By collecting water temperature, pH and humidity as well as atmospheric temperature and humidity, WaterAid is packed with all the sensors you would need to monitor the pollution of the river.




WaterAid allows the user, a company or an individual to collect data safely and accurately and visualise all this data in one place thanks to Soracom's cloud. The project is composed of a front end and a backend.

Front End

The front end of the project is the physical device that is used to collect the data and send it to the cloud. The device can be set into mode 1 or 2. In mode 1, the device records a set of data with the press of a button, useful for occasional monitoring of a body of water. Mode 2 sets the device to take readings at a defined interval of time and push this data to the cloud.

An MKR GSM is used for the front end as it is easy to use and reliable. It can also access Soracom through GSM. Below are the steps taken by the device when collecting data.

The device is firstly in setup mode, it synchs the onboard RTC to the epoch time received from the GSM network, initialises libraries used and gets a lock on the location.

Firstly the trigger event occurs, the device is either woken up after sleeping for an amount of time (mode 2) or has been waken up by the press of a button (mode 1).

The device then takes readings from its array of sensors measuring water temperature, pH and turbidity as well as atmospheric temperature and humidity.

The time and geolocation are then extracted from the MKR GSM's network.

The data is then all parsed into a buffer formatted accordingly.

Lastly the data is sent to Soracom's cloud through Soracom Air.

                                                                                 Functionality Overview

                                                                                           Code Overview


The device can be powered through multiple ways. It can be powered by a LiPo battery through the provided port on the device, by a power bank or by connecting a battery through the VIN port on the device.

The lifetime of the device heavily relies on the power of the battery. The device goes into sleep mode between reads to conserve as much energy as possible.

LED Ring

The device is also equipped with an LED ring. This provides the user with feedback on what the device is doing at the moment. There are 3 modes that the ring can be in.

  • Multicolour indicates that the device is setting up or is processing data
  • Flashing Red a warning, usually meaning that the device has to be placed in water though it could also indicate an error
  • Progressing Blue or Green indicates that the device is currently taking a sample and should be placed in water.

                                                                                                      The LED Ring

Takinga Sample

The device's sensors should all be placed in the water when the device is taking a sample. A 6 second delay is placed before the sample is taken to warm up the sensors. For best results, the sensors should be submerged when the warm-up is taking place.

                                                            The device taking a sample in mode 1

Parsing Data

The Data has to be sent to Soracom in the form of a JSON string. This gives all the keys used a value. The data will then be easy to interpret by the backend. Below is an example of a payload that would be sent.


The Backend

The backend of the project refers to Soracom. Data is collected and visualised in the backend on dashboards. These dashboards are created using Soracom Lagoon.

Data is received by Soracom Air from the device
The data is then extracted using Soracom Harvest
The data is finally queried by Soracom Lagoon at intervals of time which then displays the data on a dashboard.

                                                                                            Functionality Overview

The Dashboard

The dashboard sums up all the data collected from the device. It plots the places data was collected from on a map, the colour varies according to how polluted the water is. The data is then graphed on line graphs below that and is then fully summed up on a table.

The user will also get alerts through email if the value of the pH or turbidity of the water are abnormal. Below are some screenshots of the dashboard.

                                                   Map with the points graphed and water-related plots

                                                                         Table and atmosphere-related plots


The device can be easily scalable and all data can be collected and illustrated on the same dashboard. Multiple devices can stream data to the Soracom and have the data visualised on the dashboard.

The price of the device and the extreme ease to build and program it makes it easy for a fleet of devices to be used. These devices can also easily be registered into Soracom using tools like Soracom Krypton.

Each enterprise or individual will have their personalised dashboard where the data collected by their devices will be visualised. Hopefully, people will be able to collaborate on the same dashboard and share their data with each other in the near future.


The individual or company utilising this product will benefit in:

  • Reduced running costs as the device is very self-sufficient.
  • Easily scalable, the device can easily work solo or in a fleet of tens of others.
  • Fast data collection allowing the data to be pushed to the cloud and visualised in real time.
  • Easy visualisation, data can be visualised anywhere and at any time using the online dashboard.

Constructing the Project

Step 1: Required Apparatus

This project requires a lot of sensors that will monitor a lot of parameters related to the water and the atmosphere placed in. Below is a list of all the materials needed.

                                                                                          All the components

Step 2: Connecting the Circuit

The components should be soldered together. To ease the understanding of the schematics out, a breadboard has been used. the schematics are below.

                                                                                        The schematics

Preparing the MKR GSM

After the sensors have been soldered to the device, the SIM card, GSM antenna and battery have to be attached to the device. I am powering the board with 2 AA batteries through the VIN port. The steps are below.

1. Prepare all the components

2. Turn the MKR GSM over

3. Insert the SIM card into the holder

4. Prepare the antenna

5. Attach the antenna to the MKR GSM

6. Make sure it clicks into place

7. Prepare a battery box(2 AA)

8. Insert the batteries inside

9. Connect the +of the battery to VIN on the MKR GSM and the GND to GND, and you are done!

Step 3: Acknowledging the Code

There are 4 main sections to the code of the project.

  • Collect Sensor Data
  • Get time and date
  • Process Data
  • Send Data

All these sections are described and detailed below.

Collect Sensor Data

Serial.println("Taking Sample");
 Serial.println("Taking Sample");
 Serial.println("  OK - Warming Up");
 delay(6000); // delay for sensor calibration
 Serial.println("  OK - Taking Sample");
 Serial.print("  ");
 for (int i = 0; i < 16; i++)
   if (mode == 1)
     strip.setPixelColor(i, strip.Color(0, 255, 0));
     strip.setPixelColor(i, strip.Color(0, 0, 255));
   // going to take multiple water samples - sensors not that precise
   waterTurbidity += getWaterTurbidity();
   waterPh += getWaterPh();
   if (i > 14)
     // take a single sample for high precision sensors
     waterTemperature = getWaterTemp();
     atmoTemperature = getAtmoTemp();
     atmoHumidity = getAtmoHumidity();
 Serial.println("  Success - Samples Taken");
 for (int i = 0; i <= 16; i++)
   strip.setPixelColor(i, strip.Color(0, 0, 0));

The section of code above starts off by waiting 6 seconds for the sensors to calibrate in the water. The device then loops for 16 times, a new LED turning on the ring every loop.

Data from sensors that have fluctuating values is collected 16 times and then the mean is found. The high precision sensors are read on the last loop.

Get Time and Date

void getCredentials()
 Serial.println("  [1/2] Time");
 Serial.println("  OK - Getting Time from RTC");
 currentEpoch = processTime();
 Serial.println("  [2/2] Geolocation");
 Serial.println("  OK - Getting Geolocation from GPRS");
 while (!getLocation());
 Serial.print("  Success - Geolocation is "); Serial.print(latitude, 7); Serial.print(", "); Serial.println(longitude, 7);
bool getLocation()
 if (location.available())
   latitude = location.latitude();
   longitude = location.longitude();
   return true;
   return false;

The first loop handles the credentials. The time is extracted from the onboard RTC as it was synched to the GSM network in setup. The geolocation is extracted from GPRS.

Process Data

void processData()
 Serial.println("  OK - Getting Mean of Water pH and Turbidity");
 waterPh = (waterPh / 16);
 waterTurbidity = (waterTurbidity / 16);
 Serial.println("  OK - Dumping Data to Serial");
 Serial.print("  [Water] pH          "); Serial.println(waterPh);
 Serial.print("  [Water] Turbidity   "); Serial.println(waterTurbidity);
 Serial.print("  [Water] Temperature "); Serial.println(waterTemperature);
 Serial.print("  [Atmo]  Temperature "); Serial.println(atmoTemperature);
 Serial.print("  [Atmo]  Humidity    "); Serial.println(atmoHumidity);
 Serial.println("  Success - Data Processed");
String makeLine()
 Serial.println("  OK - Making String");
 String dataReturned; dataReturned += "{"; dataReturned += " \n";
 dataReturned += "\"Latitude\":" + String(latitude, 7); dataReturned += ", \n";
 dataReturned += "\"Longitude\":" + String(longitude, 7); dataReturned += ", \n";
 dataReturned += "\"waterpH\":" + String(waterPh); dataReturned += ", \n";
 dataReturned += "\"waterTurbidity\":" + String(waterTurbidity); dataReturned += ", \n";
 dataReturned += "\"waterTemp\":" + String(waterTemperature); dataReturned += ", \n";
 dataReturned += "\"atmoTemp\":" + String(atmoTemperature); dataReturned += ", \n";
 dataReturned += "\"atmoHum\":" + String(atmoHumidity); dataReturned += ", \n";
 dataReturned += "\"deviceID\":" + String(deviceID); dataReturned += ", \n";
 dataReturned += "\"deviceName\":"; dataReturned += String("\""); dataReturned += String(deviceName); dataReturned += String("\""); dataReturned += ", \n";
 dataReturned += "\"epoch\":" + String(currentEpoch); dataReturned += ", \n";
 dataReturned += "\"mode\":" + String(mode); dataReturned += " \n";
 dataReturned += "}";
 Serial.println("  OK - Data is below");
 Serial.println("  Success - String is Ready");
 return dataReturned;

processData() gets the mean of the data collected from the sensors that tended to fluctuate and then dumps all the data to the Serial Monitor.

makeLine() compiles all the data into the JSON string that is sent to Soracom. All values are parsed into a JSON buffer ready to be sent to the backend.

Send Data

void parseData(String dataToSend)
 Serial.println("  OK - Setting Up Connection");
 if(client.connect(url, 80))
   Serial.println("  OK - Connection Established, Parsing Data");
   client.println("POST / HTTP/1.1");
   client.println("Host: harvest.soracom.io");
   client.println("User-Agent: Arduino/1.0");
   client.println("Connection: close");
   client.print("Content-Length: ");
   Serial.println("  OK - Data Parsed");
 Serial.println("  OK - Getting Responce");
     char c = client.read();
 Serial.println("  Success - Data is Parsed");

Finally, the data is sent to Soracom. The device established a connection with the server and then prepares the credentials. The data is then sent to the server and the response is printed to the Serial Monitor.

The device then goes to sleep until a trigger wakes it up repeating the steps again.

Step 4: Setting Up the Variables

There are certain variables that have to be edited before the project can be used. These are listed below. Instructions on setting them up are also below.

  • mode the mode of the device dictates if it takes samples periodically or if it takes samples at the action of a button. If this variable is set to 1, the device will need to be actioned through a button. If the mode is set to 2, the device will periodically take samples.
  • deviceID and deviceName these are custom variables that are used to identify the device if a fleet of devices are being used. Each device used should be given a unique ID and Name so that they can be easily identified.
  • sleepTime stores the amount of time that the device sleeps for between reads, it is set to 5 seconds in the code which is appropriate for testing but has to be changed when using it on the field. A sample could be taken at intervals of 15 minutes.
  • proDebug is used when debugging, it is set to false in the code but if the serial monitor is needed when debugging it should be set to true. Note that the device will still print to the serial even if the debug is off. If the debug is on, the device will not run unless the serial monitor is on.

Step 5: Uploading the Code

Before setting up the backend, data has to be sent to it.

If you do not have a Soracom account and the SIM you are using is not registered, you will have to complete step 6 first.

To do this, connect your MKR GSM to your computer and upload the code to the device, ensure that the mode of the device is set to 1 for this setup. After the code has uploaded, place all the sensors in water.

Now press the button on the device and wait for the data to collect and send. Repeat this a couple of times to populate Soracom Air.

Step 6: Setting Up Soracom

This step is split into 2 sections, the first will cover creating an account with Soracom and registering your SIM while the other will cover setting up Soracom Harvest to collect the data from Air. If you already have an account with Soracom, skip the first section.

Section 1: Creating an Account

Section 2: Groupsand Harvest

Step 7: Setting Up Lagoon

The last thing to set up on Soracom is Lagoon, this is the tool that we will use to visualise our data and create email alerts if the data is not good.

Calibration Problems

The turbidity and pH sensors have to be calibrated to be used precisely, you might find that when running the code, the turbidity might by 105% or the pH of water 3. In this case, the sensors have to be calibrated. A quick guide into calibrating them is below.

  • pH Sensor The pH sensor can be calibrated using the potentiometers on the module, place the probe in still bottled water of pH 7 and wait for 5 minutes, now develop a code that prints the pH from the sensor to the serial monitor. Twist the potentiometer until the pH is 7.
  • Turbidity Sensor The turbidity sensor is not very precise and so a relative percentage, compared to pure water is taken. To refine the value of pure water, if your readings exceed 100% turbidity, you will need to place the turbidity sensor in pure water and develop a code that prints the voltage on the analog pin of the pH sensor to the serial monitor. A variable named calibration is found in sensors.h, change the value of that variable to the voltage received when the probe was placed in pure water.


  • ArduinoLowPower (c) 2016 Arduino LLC GNU Lesser General Public Licence this library is in the public domain
  • Adafruit_Neopixel (c) Phil Burges Lesser General Public Licence this library is in the public domain
  • MKRGSM (c) 2016 Arduino AG GNU Lesser General Public Licence this library is in the public domain
  • Wire (c) 2006 Nicholas Zambetti GNU Lesser General Public Licence this library is in the public domain
  • OneWire (c) 2007 Jim Studt GNU General Public Licence this library is in the public domain
  • DallasTemperature GNU General Public Licence this library is in the public domain
  • RTCZero (c) 2015 Arduino LLC GNU Lesser General Public Licence this library is in the public domain


Finally, I got an enclosure done for the project that could be easily portable but be fixed to collect samples both in mode 1 and 2. Steps are below.

1. I cut a box of plastic out and 2 lids

2. Drill one hole in the plastic surface big enough for a button to fit and a small cut on the edge for wires

3. Make holed on the bottom part and stick the water components through the holes ino the water. Attach the bottom to the rest of the enclosure

4. Place the button through and place the LED ring around it

5. Ensure that the sensors are connected and that no water seeks through cracks around the sensors

6. Drill a hole at the top of one of the sides of the box

7. Attach the GSM antenna

8. Now insert all the components in the enclosure

9. Seal it off

10. and it is ready to go

Finally, ensure that the mode is set accordingly and start using the device on the field. Check out your local river or lake and see how clean it is. Play around with the dashboard and see what other widgets it has.


Today, data is the new currency and collecting it easily and efficiently is key to a better environment. By measuring the pollution of rivers and lakes collectively, we can raise awareness that the waters are getting dirtier and something has to be done.

I was thinking of an idea for the Soracom contest and I felt like I had to make something beneficial for the environment, the idea of people and companies working together on collective dashboards to visualise the status of rivers and lakes globally inspired me to take this project on.

What will you do to stop water pollution? Because action has to be taken today, and tomorrow is a day too late.

(This article copied from hackster.ioAuthor: Andrei Florian)