Projects Research & Design Hub

Multi-Sensor Device Measures Water Pollution

Written by Andrei Florian

The UnifiedWater Project

Water pollution is a serious problem that these days often gets drowned out within the broader issue of climate change. In this project article, Andrei details a system he designed that uses sensors and IoT technologies to enable the easy monitoring of water quality from anywhere.

  • How to build an IoT-based water quality monitoring system

  • How to do the data collection

  • How the personal modes and enterprise modes are different

  • How GNSS is used in the system

  • Developing the two dashboards

  • Arduino MKR GSM 1400 module

  • 3.7V 1,800mA-hour LiPo battery

  • GY-21 Temp and Humidity sensor module

  • Water pH Sensor

  • Water turbidity Sensor

  • Water temperature Sensor

  • Wires, breadboard, button

  • NeoPixel ring

  • Enclosure – 3D printed or cut pieces

  • Solar panel module

  • Security and battery life

UnifiedWater is an application that allows for the easy monitoring of water quality from anywhere in the world. The device is equipped with multiple sensors that together monitor the overall quality of the water (Figure 1). This data is then centralized in a database where it is visualized on a dashboard.

FIGURE 1 – UnifiedWater device in the field

The device is an affordable, mass producible and open source end-to-end application, which allows governments, private associations and even individuals to take water quality readings and share them with the community. This enables data analysis and observations that can allow authorities to identify places that are being polluted (rivers, lakes, seas, oceans) and take appropriate action to ensure that the water is clean.

UnifiedWater operates in two modes: Enterprise mode is created for monitoring large water bodies with multiple fixed devices while Personal Mode allows a surveyor to take readings at different points along a water body with a single device (Figure 2).

FIGURE 2 – UnifiedWater device being held above a canal

Saying water pollution today is like shouting out climate change in a high school discourse and getting looks from everyone bored to their bones of this topic. I learned to look the other way to the guy missing the trash bin and never bothering to pick up their wrapper and the fumes ejected from factories wherever I go.

We, as humans, are great at hiding in our daily routines, not daring to peek outside, knowing what we are to find if we do. This keeps us going and forces us to look the other way when climate change, world hunger and water pollution are on the news. All that said, as a person, I feel the obligation to help make the world a better place—to help us humans grow as a collective and help heal the wounds we have inflicted on our world.

Ok, enough with the inspirational talk. Yearly, we dump more than 3 million tons of trash into the world’s oceans—from companies dejecting their waste products to individuals blind to bins, we all contribute to this jaw-dropping number. A staggering 80% of water pollution is directly or indirectly caused by humans, making pollution one of the greatest challenges our society has ever faced in its endless expansion.

Agricultural operations are the greatest polluter by far. As our population is growing, we need to feed more and more people. Supply cannot keep up with the demand without advances in fertilizers and antibiotics to ensure that our crops and animals can be produced at maximum capacity. The problem is that over 70% of agricultural waste ends up in oceans. Hormones, antibiotics, salts, and other dangerous chemicals are ejected by farms daily through fertilizers, manure and other waste products. These chemicals dramatically pollute the water and can alter or even disintegrate entire ecosystems.

Industrial operations also pose a great threat to the ecosystems in water bodies. Nitrogen, phosphorus and other heavy chemicals can cause the water body in which they are dumped to change color, turbidity or even temperature having a dramatic impact on the ecosystem found there. These chemicals can also cause algae to bloom out of control leading to dead zones in bodies of water—zones deprived of oxygen where life cannot be supported. It is estimated that there are about 400 dead zones in the world today.

Almost 33% of reef-forming corals, sharks, and shark relatives, and 33% of marine mammals are threatened with extinction at present. At least 680 vertebrate species were driven to extinction by human actions since the 16th century, many of these marine species. The list goes on… And this issue does affect us directly. Over 250 million people die yearly due to diseases contracted by drinking dirty water such as cholera and typhus. That’s 1 in 32 people (I had to double check that just to be sure). That is a scary figure.


So, what can be done? Well before we get into paper straws and countrywide regulations, we need to identify the sources of pollution in streams, lakes and oceans and act on them before they get out of hand. Water quality monitoring is a relatively new concept. Data collection is done in unstable environments, technologies are often proprietary and the cost of operation is very high—bringing water quality monitoring out of the reach of even developed countries.

Existing solutions more often than not collect water samples to send to labs for inspection as opposed to collecting the data in the field. This takes longer and incapacitates live tracking of pollution. Modules that do collect data in the field are often large and bulky and lack flexibility. All that makes it a pain to mount them and apply maintenance. And, on top of this, they often don’t collect sufficient and meaningful data.

But most importantly, they lack IoT connectivity. Devices that do send data to a central location often use proprietary technologies such as XBee and other radio communication methods that do not directly connect online. Adding pain to injury, these implementations are extremely expensive for what they offer. This is where UnifiedWater comes in. Using industry standard sensors and IoT connectivity, UnifiedWater redefines water quality monitoring through a set of distinct features, setting it apart from other devices on the market.

UnifiedWater is a portable (Figure 3), baggable device that can operate in two modes: Either as a stand-alone, portable device, or as part of a network of tens or hundreds of fixed devices collecting critical water pollution parameters. UnifiedWater sends all data collected to IoT Central via GSM, meaning that the device can work anywhere in the world with cellular coverage. The data collected by the device(s) can be monitored and analyzed in real time on an online, interactive dashboard using Azure IoT Central anywhere in the world, at any time (Figure 4).

FIGURE 3 – UnifiedWater being carried around by a surveyor
FIGURE 4 – A look at the UnifiedWater dashboard

Interacting with the device is essential for longevity and ensuring its functionality. UnifiedWater can be configured remotely using twin properties in IoT Central allowing the authorities, universities, or private institutions to change the number of samples taken, interval of data collection and many other parameters. This reduces the amount of maintenance required by people on the field dramatically.

By just clicking a button online, the device can transition between Enterprise Mode (where it works with other devices) and Personal Mode (where it can be submerged at different points by a surveyor). The flexibility of the implementation together with the low production cost, scalability, security, sustainability and high accuracy set UnifiedWater apart from existing solutions. The only way we can make our waters cleaner and save marine species from extinction is by identifying the root causes of pollution by monitoring water quality. Be it in rivers, lakes or oceans, UnifiedWater is in the front-line combating water pollution. A GitHub repository for this project is available at [1].


UnifiedWater collects data from multiple sensors to encapsulate the overall quality of the body of water. Measuring water quality is difficult because there are a lot of parameters to look for (from temperature to presence of chemicals). It is not plausible to collect data on every parameter as that would require tens of sensors and significantly impact the device’s battery life and increase costs.

The balance between battery life and data collected has been carefully analyzed. I reached the conclusion that the main data points needed are the water temperature, pH (acidity) and turbidity (as well as atmospheric temperature and humidity to be able to contrast them with the water temperature). Table 1 details the data collected by each sensor and the unit it is measured in.

TABLE 1 – This table details the data collected by each sensor and the units in which the data is measured.

All the data collected is relevant and significant in measuring the overall quality of the water. As previously mentioned, a balance between volume of data and battery life must be reached. It would not make sense to only measure temperature and humidity (as this data does not mean much on its own) but nor would it make sense to include many more sensors as that would impeach the battery life of the device and exponentially increase costs.

The optimal values vary greatly by circumstance. This is especially valid for the pH of the water. For example, the average pH of a river is 7.4 while an ocean is around 8.1. If a river that in month X had a pH of 7.5 and in month Y had 5.6, then it is plausible to say that it was polluted with an acidic substance such as phosphorus fertilizer. This measurement is very significant to deduce the overall quality of the water.

It is easier to judge the water turbidity value. Turbidity is measured by shining a beam of light through a water sample at a 90-degree angle and measuring the intensity of the scattered light. The light is blocked by insoluble particles suspended in the water—the more particles suspended, the greater the turbidity. Turbidity is measured in NTU (Nephelometric Turbidity Units), this measures the quantity of insolubles in water (in milligrams) per 1 liter of water. Drinking water has a turbidity of anywhere between 0 and 4 NTU. The more polluted the water is with dirt, debris, manure and/or human waste, the higher the turbidity. Water turbidity is essential for getting the overall water quality.

Finally, the water temperature reading is useless without the atmospheric temperature reading to contrast to (and vice versa). Very seldom are both temperatures the same—the smaller the body of water, the more similar they are. Usually, large bodies of water (seas, oceans) are warmer than the atmosphere during the winter and colder during the summer because of water’s heat absorption.

But a recent Harvard University study has directly linked differences between water and atmospheric temperature to oxygen levels in the body of water. Oxygen becomes lighter when heated and becomes heavier when cooled. Using this logic, if the water is warmer than the atmosphere directly above it by a considerable amount (2 degrees up), the oxygen will leave the body of water by slowly rising. Note that if the atmospheric temperature is greater, the opposite effect will not take place.

Bodies of water are home to a vast quantity of life, if they were to be deprived of oxygen, their volume would decrease due to the area not being able to provide oxygen for the same volume of life. This means that species may be reduced in size and even endangered and migrations could take place.

Calibrating the sensors: All sensors offer precise readings and are suitable for long term exposure. It is recommended that all sensors be replaced every 12 to 16 months of staying in the field to ensure their precision. All sensors come calibrated out of the box except the water pH sensor. It is essential that this sensor is calibrated every 3 to 4 months to ensure its precision. The steps below reflect the recommendations provided by DF Robot.

1. Clean the probe and ensure it is dry.
2. Place the tip of the probe in the small container it comes with filled with distilled water (pH 7).
3. Change the phCalibration variable found in UnifiedWater/configure.h to 0.
4. Wait for around 10 minutes, run the code, and see what value the device posted to IoT Central for pH.
5. Set the variable phCalibration to the difference between 7 and the value sent.

The device collects the data from the sensors at an interval of time defined by the user in IoT Central (I discuss this more later). The device will query data from the pH sensor and turbidity sensor a defined number of times at intervals of 1 second to eliminate any outlier data and average the values. This exponentially increases the precision of the readings. The data is then stored locally until it is sent to IoT Central thereafter being deleted.


This section will detail the two operating modes of the device. As previously mentioned, the device can operate in two modes making it extremely flexible under multiple use cases.

Personal mode: This is what sets the project apart from its competitors. In Personal Mode (Figure 5), the device can be carried around by a surveyor as opposed to being fixed in a location. The surveyor can submerge the sensors in water, press a button and collect the data from the specific point. The data is then sent to the backend together with the geolocation of the reading and plotted on a map.

FIGURE 5 – Architecture diagram of the device in Personal Mode

This mode is very useful because it allows multiple points along a stream, sea or ocean to be measured with a single device. The device can be attached to a boat, for example, and set to take samples at set periods of time, hence tracking the water quality as the boat sails and sending it to the cloud via GSM. The device can also be manually handled by a surveyor tasked with collecting water quality readings at different points on a stream for a monthly report. The surveyor would travel the stream, submerging the device at different points (Figure 6).

FIGURE 6 – The device in Personal Mode taking a sample

The use cases are endless. Multiple teams could be sent with such devices after an oil leak to see where the effects are worse and prioritize action. The device can be taken on a hiking trip to see if water in streams is drinkable. This allows for inexpensive, robust monitoring whenever it is needed.

Enterprise mode: Enterprise mode (Figure 7) allows for the device to be fixed in a specific location and collect data and send it to the cloud at defined intervals of time. Tens or hundreds of devices can be fixed at different points along a stream, sea, or dock to measure the water quality in those respective places.

FIGURE 7 – The architecture diagram of the device in Enterprise Mode

The data from all devices can be visualized as a whole or individually on the dashboard. This mode has endless use cases. A series of devices can be implemented temporarily along a polluted stream to identify the exact point where the pollution originates and allow authorities to take informed action. Devices can be placed along a dock where boats are parked to discover potential leakages before they damage the fauna and flora in the area. This allows for industry-grade efficiency and big data collection allowing authorities and corporations to precisely keep track of pollution in real time in any body of water.

Changing between modes: The best part is that the device’s mode can be changed from the backend with the press of a button. Therefore, if a device has been in Personal Mode and authorities need it to be fixed in a location because the reading there was anomalous and they wish to investigate, all they have to do is press a button and the device will switch from collecting data when instructed to collecting at adjustable intervals of time.


The device uses GNSS to get its location. Because it operates on GSM, the module also allows it to query the precise location from the cell tower. Note that the device is aware of its location both in personal and Enterprise Mode but only reports it to IoT Central in Personal Mode (because its location is fixed in Enterprise Mode).

The device is also aware of the time by synching its onboard RTC to satellite time every time it reboots. This ensures that the device is always aware of the current time for signing certificates for IoT Central and parsing data. Note that if the geolocation from the cell tower is not sufficiently precise, a GPS module can be attached to the device—adding only $5.90 (€5) to the bill of materials (BOM). This will offer pinpoint accuracy at all times.

The device is equipped with a NeoPixel ring (which is 16 LEDs arranged in a circle). NeoPixel rings are available from multiple sources including Adafruit. This ring is used for feedback in Personal Mode so the surveyor can keep track of what the device is currently doing. Table 2 details the significance of different LED colors.

TABLE 2 – Listed here is the significance of each LED color.

GSM connectivity is used in the case of the project because of its wide availability across most of the world. This allows the project to work in most areas without a problem. Hologram was chosen as the sim provider because of the monitoring it allows in the backend. You can see exact usage of data as well as precise and affordable billing. The service also scales very well.

I decided to use Azure IoT Central for a wide range of reasons. IoT Central is industry standard when it comes to IoT management in the cloud and is created by Microsoft. This service is extremely reliable and can handle vast quantities of data streamed by thousands of devices, the services also scale very well and are very cost effective.

The standard pack comes with two free devices (with $0.40 per device per month thereafter) and 5,000 messages (with $0.015 per thousand messages per month thereafter). Therefore, monitoring a long river with 100 devices would cost only around $48 (€40) a month to operate in IoT Central. The other reason IoT Central is so great is device twins. These are parameters that are synced in the cloud and on the device. They are different from telemetry data—which is sensor data reported by the device to the cloud because both the device and backend sync the values between them.

Sending telemetry to IoT Central: In Enterprise Mode, there are different timers set for collecting and sending telemetry to the backend. The device sends all messages to the backend in JSON messages and encrypts them using bit64 encryption.

In Personal Mode, the device will send the sensor readings and geolocation as telemetry directly after the data was collected. Table 3 shows the data sent as telemetry and in which mode it is sent. All communication is based on libraries provided by Microsoft for Arduino devices to connect to IoT Central. All libraries are open source.

TABLE 3 – Shown here is the data sent as telemetry and in which mode it is sent.

Sending properties to IoT Central: Device properties are different from telemetry data. These are pieces of information about the software or firmware of the device that are being sent to the backend. Twin properties are a special type of properties, which are changeable by the user in the dashboard. These properties are then synced with local variables on the device enabling remote control over different device parameters. Table 4 lists all device twins and their roles on the device.

TABLE 4 – This lists all the device twins and their roles on the device.

This improves the device’s autonomy because these critical parameters can be set in the backend without the need of persons interfering with devices on the field. This is particularly helpful if vast quantities of devices are being used because instead of having to go out and manually flash different versions of code on these devices in the field, the values can be set via a computer in seconds.

The Figure 8 diagram shows the way these properties are changed. The device will check if there is a change in a twin property (unless in low power mode). When a change is received, the device will check to ensure that the change is valid (for example the correct data type is sent, and the value is not too large to hold as a local variable). If the change is valid, it will send back an acknowledgement confirming the change (the change will then show up as applied in the dashboard). If there was an error, an error message will be sent back, and the change will be marked as not confirmed.


Advertise Here

FIGURE 8 – Architecture diagram of the property syncing process

The device also sends constant properties when it boots up. It will send information about the device such as its IMEI (International Mobile Equipment Identity) number, model version and firmware version. This allows the users to view credentials of every device in the backend with the click of a button. When booting up, the device will sync all its local variables with twin properties in IoT Central. This ensures that the device retains the same settings even after restarting or receiving a software update.


There are two dashboards in the backend to which the users have access to: the main Dashboard and the Device Dashboard. Note that different roles can be assigned to users allowing them to view only certain sections, control their ability to change twins and prevent them from viewing device details.

The Device Dashboard: This dashboard is specific to each device in the application. If tens or hundreds of devices are being used, each one has an individual dashboard where specific properties can be changed (note that they can also be changed in bulk), device specific data can be read for troubleshooting and device details can be viewed. The home page consists of a map where the location where device readings were made can be seen when the device is in Personal Mode (a single point is seen in Enterprise Mode for the device’s constant location).

Scrolling down will reveal data posted by the device on graphs (Figure 9). This allows data from a single device to be visualized over time. The device info page displays the information about the device such as its IMEI and serial number. Finally, the settings page allows the user to change twin properties and set the exact location of the device when fixed in Enterprise Mode (Figure 10). Note that save must be pressed to update these properties.

FIGURE 9 – The device-specific dashboard showing all data collected on graphs
FIGURE 10 – The device-specific dashboard highlighting the property change page

The (main) Dashboard: The dashboard displays data from all connected devices accumulated in a series of graphs and cards. The largest element is a map that shows the location of all connected devices (in Enterprise Mode) or the location of readings of all devices (in Personal Mode).

All the other values displayed are averages from all devices connected (the number of connected devices is visible on the dashboard). This can be changed to display values for each individually. A graph illustrates the relationship between atmospheric temperature and water temperature over time. Scrolling down will reveal the water pH, temperature and turbidity readings displayed both on cards and online graphs (Figure 11). This data again is the average from all devices but can be changed.

FIGURE 11 – The project dashboard highlighting graphs encapsulating the data collected by all connected devices

There are many articles that talk about how insecure IoT implementations are. UnifiedWater aims to exponentially reduce the risk and damage of an attack on devices. For starters, all communications to and from the backend are encrypted using bit64.

The device itself can be set to send its geolocation even in Enterprise Mode to detect if it was misplaced and alert the authorities to this. Property sealing the project can also go a long way to prevent attacks on the device. Ultimately, if a device was hacked or is malfunctional, it can easily be disabled in the backend until the problem can be fixed to prevent anomalous data from interfering with results.

The battery life of the project in its base configuration is about a week before a recharge is needed (1800mAh battery, bigger battery would proportionally increase battery life). This may not be ideal in Enterprise Mode and therefore many changes have been made to increase battery life. By running the device in low power mode and adding a solar panel implementation, the device can last in the field for weeks to a few months (Figure 12).

FIGURE 12 – UnifiedWater device with a mounted solar panel

Note that battery life is currently only being sent to the backend in the base configuration because the addition of a solar panel to charge the battery does not allow the microcontroller to get the battery reading. I am currently working on this together with other future features I’ll discuss later in this article.

Now, let’s take a look at device’s market, competitors and production of the product. Who is the product targeted at? The target market of UnifiedWater is very broad. The device can be used by everyone from government institutions to monitor the water quality in locations around the country to private individuals who want to occasionally measure the quality of water. The product is focused on companies and institutions through the provision of two modes adding flexibility to the product. It is also reliable, self-sufficient and inexpensive making it a great choice for both developed and developing nations.


In Table 5, I outline the cost of all materials and components used in the project together with links to the page to purchase these (Table 5). Note that extra rows are added at the end for adding solar panel charging to the project. Aside from the costs of the components, it’s also important to understand the cost of operation per device per month. This is calculated under the circumstances shown in Table 6. Note that the amount of data used per message is averaged. Cost for Personal Mode varies by number of samples taken.

TABLE 5 – This lists the costs of the components used in the project. Where applicable, a reference “[ ]” number is provided. These correspond to links available on Circuit Cellar’s article materials webpage. The rows at the bottom show the cost of adding solar panel charging to the project.
TABLE 6 – These tables detail the cost of operation per device per month, for both Personal mode and Enterprise mode. Note that the amount of data used per message is averaged. Cost for Personal Mode varies by number of samples taken. Sending property changes also impacts on the data sent by the device. Please note that these values can vary significantly depending on usage and are only estimates of the cost.

Now let’s talk about scaling and production. The prototype as built can be easily reproduced. All code is 100% open source meaning that anyone can use it free of charge. This dramatically accelerates production for the project. All components used for the project are available off the shelf meaning that they can be bought in bulk at a low price. Finally, all technologies used are scalable and can operate with anywhere from one to 1,000 devices. Below is a list of actions needed to be taken to bring this prototype to market.

• Code is ready to go (on GitHub, open source, clean)
• Components available off the shelves
• Backend can scale with ease
• Device has been tested extensively and all bugs found were addressed

The only step that must be taken to turn this prototype into a distributable product is the construction of a waterproof enclosure. The enclosure I built is handmade and only suitable for the prototype. I don’t posses the tools needed to precisely produce such enclosures in large quantities.


This section will detail improvements added to the project as well as future aspirations and plans for developing the project more.

Solar panel added to project: While developing the project, I came across a solar panel module I bought a while ago that I completely forgot about. So, I decided to implement it in this project. I figured out how to do the wiring and added it. It costs only an extra $24 (€20) to add this feature to a device. This allows the device to recharge the LiPo battery attached using a solar panel, which can extend its battery life to months using low power mode (Figure 13). Setting up has been covered throughout the article. Although the solar panel addition works perfectly with both device modes, it has been targeted at Enterprise Mode.

FIGURE 13 – The architecture diagram for the device in Low Power Mode

Low Power Mode software implementation: This can be found in the low power folder in GitHub [1]. This code branch is designed to exponentially increase the battery life by putting the microcontroller in deep sleep between data reads. The device will only use two properties: telemetry send interval, which will control the amount of time the device sleeps for between reads; and the sample value, which will determine the number of samples to collect from the pH and turbidity sensors. Note that the low power option is only available in Enterprise Mode.

The device will check for property changes when it wakes up, setting the variables accordingly and will then collect sensor data and send it to IoT Central. It will then check for property changes once more before going back to sleep for the defined period of time. It is preferable that low power mode be used in Enterprise Mode to lengthen the device’s battery life. Setup for this mode is covered throughout the article. Here’s a list of some addition ideas for enhancements to the UnifiedWater device:

• A button in the dashboard to allow a sample to be taken while the device is in Personal Mode remotely
• A button in the dashboard to sync the time to a time server
• Pressing a point on the dashboard map in backend to display the sensor readings at that point as well
• Figuring out how to send the battery life of the device even if solar shield is used

If you have any other ideas or features you would like to see in the project, please let me know.


Advertise Here


In this section, we’ll go through each of the steps needed to construct the project.

Step 1: Required components: The complete BOM with links and costs were shown earlier in Table 5 and the components are shown in Figure 14.

FIGURE 14 – All the components required to construct the project

Step 2: Required machinery: You will need the following machinery to hand build the enclosure for the project: a bandsaw, a hot wire strip heater and a sander. Note that CAD files are attached of the enclosure if you prefer 3D printing it.

Step 3: Connecting the circuit: The Figure 15 diagram shows the circuit connections of the project. Please follow it to connect all the modules together. Note that if you are not using the solar-powered version, the LiPo battery is to be connected to the MKR GSM LiPo battery socket.

FIGURE 15 – An image of the schematics for the project

If the solar shield is being used, please connect the solar panel and LiPo battery to corresponding ports on the shield and ensure it is turned on when operating the device. Connect the pins as instructed in Table 7.

Step 4: Setting up IoT Central: Now that everything is connected. We need to set up IoT Central. There are a few prerequisites before we can get started: (a) Create a Microsoft account [11] if you do not have one; (b) Create a free Azure account [12] if you do not have one.

1. Ok, let’s get going. Go to [13] and click on the plus icon in the top left of the screen to create a new app.
2. Give your app a name, set template to custom and pricing to Standard 1. You will be redirected to your dashboard. Now click on device templates from the menu on the right of the screen. Click on the New button and then on IoT Device. Follow the steps until you are directed to your template.
3. Now, click on Custom to create a capability model. The next thing we want to do is click on Cloud Properties from the left of the screen and add a property for the geolocation of the enterprise device.
4. Next, click on the device name and select the Import Interface option. Now from the GitHub repository [1] for the project (pull it, if you have not already), go into the Backend folder and import the uni-wateraid-dev.json file. This should import all fields for you.
5. Next click on the Views option from the menu on the left and create a new view called Settings. Here we will put all the twin properties so we can easily edit them from a centralized place (chose the Edit properties option for the type of view).
6. Now create a new view for the data streamed by the device (using the visualizing the device option). Drag and drop the geolocation card, all sensor readings and battery and location precision onto the canvas.
7. Finally, click on the Publish button at the top of the screen and follow the instructions to publish the device template. Now go into the Devices tab from the menu on the left and create a new device by pressing the “plus” icon. Set the details as shown in Figure 16.

FIGURE 16 – Credentials needed to connect the device to the backend

And that’s it, you are ready to move on!

Step 5: Setting up the MKR GSM: I want to say a big thank you to Ian Hollier and Benjamin Cabé on GitHub for providing the libraries that I used to build this project. Their code is open source and available at [14]. Anyways, before we move on, please install the following Arduino libraries from [15]: MKRGSMArduino_MKRENVRTCZeroPubSubClient and ArduinoHttpClient.

We need to increase the payload size limit in PubSubClient to allow for the larger size of MQTT messages from the Azure IoT Hub. In your favorite code editor, open the file at: %HomePath%\Documents\Arduino\libraries\PubSubClient\src\PubSubClient.h Then change line 128 as follows:


Step 6: Getting credentials: The next thing we need to do is get credentials to connect our application to IoT Central. To do this, please make sure you have the code open in Arduino IDE or your preferred editor.

1. The first thing you need to do is click on the device you just created. In the top right corner, there is a connect button, pressing it will reveal a bunch of credentials.
2. Copy the ID Scope into the iotc_scopeId variable under UnifiedWater/configure.h. Then copy the Device ID and paste it in iotc_modelId in the same file.
3. Finally, click out and select Administration from the menu on the left of the screen. From there, navigate to the Device Connection menu and click on SAS-Devices. From there you can copy the primary key displayed into the iotc_enrollmentKey variable in the file. And that’s it, you are done!

Step 7: Flashing the code: Ok, so now that all of that is ready, you can save the sketch and flash the code onto the device. Make sure you have your SIM inserted and antenna connected. You can turn the serial monitor on to see debug.


Step 8: Making sure everything is working: It took me a long while to get things started. There was a lot of editing of libraries and Googling involved as documentation around connectivity was really limited to that one example above. But in the end, everything worked. Here are some basic troubleshooting tips:


Advertise Here

• Device stops before connecting to GSM? You may need to provide a PIN and password to use your SIM card (not if you use Hologram). You can check that out and set it up in UnifiedWater/gsm.h.
• Device stops while getting time? Error connecting to server. Look up other ways to get the time or another server to query it from.
• Device stops before connecting to IoT Central? If you are getting an error code in the serial monitor, you can look it up in connection to IoT Central. Out of my experience, a -5 and -2 are fixed by resetting the device. If you get something else, then either your connection or authentication is wrong. Try seeing if you can connect to other services (time, and so forth) and recheck your credentials.

In the end, if everything works, you should see data appearing in the RAW data section of the dashboard as shown in Figure 17. And if you are really stuck, you can always contact me, I will try to help you as best as I can.

FIGURE 17 – A look at the data streamed by the device to the backend

Step 9: Building the dashboard: The dashboard is the place where all data collected by all devices is summarized.

1. Go to the dashboard view on the IoT Central page and click the New button to create a new dashboard. Set the permissions according to your needs and then click Create.

2. Now you want to add cards, graphs and maps to the dashboard summarizing all data. Select the device(s) you wish to display data from and then construct your visuals in accordance with your needs. Mine ended up looking like shown in Figure 18.

FIGURE 18 – A look at all the cards on the project dashboard

Step 10: Constructing the enclosure: I started off with a large piece of plastic that I marked for cutting. Then I cut it into pieces using a band saw and sanded the edges making them soft. Next, I bent the large piece into an open box using a hot wire strip heater. At home I started gluing the pieces together and then insulating them. I am no expert at this, so I let my dad take the lead—I designed the 3D drawing in the meanwhile. We then drilled holes in the enclosure (everything is in the STL file available from Circuit Cellar’s article code and files download webpage).

We then stuck the components to the enclosure using a variety of adhesives. I primarily used double-sided tape because I did want to reuse the components I put in the project for other projects. Therefore, being able to remove them was key. Figure 19 shows the inside of the device before the lid was sealed. Finally, we sealed it off and tested it to ensure that water could not get in. If you are building this and intend on distributing it, it’s better to 3D print it. In my case, unfortunately I don’t have a 3D printer, so I make mine manually.

FIGURE 19 – The inside of the device before the lid was sealed

Step 11: Calibration and beyond: The last thing you need to do is calibrate the pH sensor (as I described earlier) and bring it out into the field!


This is the third iteration of this project. Every time I updated it, I started from scratch—completely rewriting the code, backend and updating the components on the device. While developing the project, I realized that I was not getting the battery life I wanted. Although a week or so is fine for Personal Mode— where the device is not left in the field—I felt like this was not fine for Enterprise Mode. So, I designed a new version of the code that puts the device into deep sleep between reads. This would increase the battery life by around two months.

I wanted the battery life to be closer to four or five months—the time interval the sensors must be calibrated—so I added a solar panel battery recharging feature to the project. It was very difficult to do all of this in two and half weeks (considering I also had school) but I managed to pull it off.

If I were to do something different the next time, perhaps I would buy a readymade case/enclosure for the project instead of making one myself. I was just afraid that it would not arrive on time and I didn’t want to take the risk. The thing I enjoyed the most was developing the code for the project and creating the mockups.

Thank you for reading the project and I really hope you enjoyed it. If you have any questions, ideas or want to chat about projects, feel free to get in touch, I’ll get back as soon as I can. 


[1] UnifiedWater GitHub repo:
[2] Arduino MKR GSM 1400
[3] 3.7v 1,800mA-hour LiPo battery
[4] GY-21 Temp and Humidity
[5] Water pH Sensor
[6] Water turbidity Sensor
[7] Water temperature Sensor
[8] Neopixel ring
[9] Hologram Sim
[10] Solar panel module
[11] Create a Microsoft account
[12] Create a free Azure account

Adafruit |
Microsoft Azure |


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
+ posts

Andrei Florian is a student in Dublin, Ireland. He has been working on tightening the connection between humans and technology by designing applications that will help us in our lives. This includes working on projects that combat pollution and climate change as well as monitoring our natural environment and our cities. He has also been working on personal security and big data. Andrei can be contacted at

Supporting Companies

Upcoming Events

Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

Multi-Sensor Device Measures Water Pollution

by Andrei Florian time to read: 28 min