---
# System prepended metadata

title: ReHydrator Tutorial

---

---
title: 'ReHydrator Tutorial'
disqus: hackmd
---

ReHydrator Tutorial - Build your own IoT-drinking water monitor
===
**Author:** Christina Knepper (ck222xy)

## Introduction
This tutorial was created as a part of the "Applied IoT" summer course [1DT305](https://lnu.se/kurs/tillampad-internet-of-things-introduktion/distans-sommar/) at Linnaeus University, Sweden. The basic idea of this project was to develop a prototype for a smart water monitor (ReHydrator) using sensors and a Pycom microcontroller. The main objective of the ReHydrator is to keep track of one's water intake (especially during hot days) and warn you in case you have not drunk enough. 

If you have all the materials listed below and are somewhat familiar with coding in Python and wiring sensors, setting up the project might take approximately 3 -4 hours. If you are completely new to programming and IoT you should add 1 -2  extra hours. 


## Objective

Dehydration occurs when your body loses more water than it takes in. The risk for dehydration increases significantly during hot days in summer and may have serious consequences for your health, such as low blood pressure, dizziness and increased risk for falls [1].

Dehydration is especially common among the elderly; studies have shown that up to 50% of older adults show symptoms of dehydration [2]. There are three main reasons why the elderly are more susceptible to dehydration:  
![](https://i.imgur.com/jBhwCbO.png)
*Figure 1: Common reasons for dehydration [3].*

1. Mobility challenges
2. Decreased sensitivity for thirst cues
3. Medical reasons such as reduced kidney function or medication

Luckily, it is quite simple to prevent dehydration: the only thing you need to do is to drink enough fluids. The objective of this project is to address the first two of the difficulties mentioned above. 

The ReHydrator is a smart water tank, big enough to be able to contain the recommended daily quantity of water (at least 2 liters), which can be placed on a nearby table so that it isn't necessary to get up in order to get a drink. An ultrasonic distance sensor is mounted to the lid of the tank so that the water volume in the tank can constantly be monitored. If a(n elderly) person forgets to drink, an encouraging reminder will be sent via Email.

Since the risk for dehydration is significantly higher during heat waves, the ReHydrator also monitors temperature and humidity. Alerts are generated if the temperature is above 25°C or if the relative humidity is above 70% in combination with a temperature of over 20°C (a high relative humidity additionally increases the risk for dehydration since air temperature is experienced to be hotter than it actually is, which in turn activates your body's cooling mechanisms, e.g. production of sweat) [4].


The data  collected by the two sensors is sent to the Ubidots cloud and visualized on a dashboard. The data that is collected is not only interesting for the person using the ReHydrator, but might also provide valuable insights for caregivers, e.g. nurses, doctors, home care staff or caring relatives.

## Material
The following items are needed in order to build the ReHydrator. The total cost for all the material is approximately 1200 SEK.


| What?                                  | Why?                                                              | Where?     | Price (approx.)    |
| -------------------------------------- | ----------------------------------------------------------------- | ---------- | --- |
| LoPy4 and sensors bundle                           | this starter kit includes the Pycom LoPy4 microcontroller, the Pycom expansion board 3.0, a micro USB cable, breadboard, resistors and jumper wires, this will be the "brain" of the ReHydrator; if you do not plan to use LoRa, a WiPy might be a cheaper option for you                                                         | [Electrokit](https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-lopy4-and-sensors-bundle/)      |955 SEK     |
| HC-SR04 ultrasonic distance sensor             | this sensor is mounted to the lid of the water tank and will measure the distance between sensor and water surface in order to calculate volume changes | [Electrokit](https://www.electrokit.com/produkt/avstandsmatare-ultraljud-hc-sr04-2-400cm/) |  59 SEK   |
| DHT-11 temperature and humidity sensor | will be used to measure current temperature and humidity                          | [Electrokit](https://www.electrokit.com/produkt/digital-temperatur-och-fuktsensor-dht11/) |   49 SEK  |
| water tank with lid and tap                       | the water quantity in the tank will be monitored using the ultrasonic distance sensor; with a capacity of more than 5 liters it can contain the recommended daily amount of water that should be consumed by an adult                                                              | [Jysk](https://jysk.se/utemobler/tradgard-ovrigt/diverse/behallare-m-kran-glass-55-l-glas?gclsrc=aw.ds&&gclid=Cj0KCQjwudb3BRC9ARIsAEa-vUuC77WrqH7IeZzYlFlm6iRfqH2VXzqpZAKSLXEg1iMuvfbaisq1zxcaAhJsEALw_wcB&gclsrc=aw.ds)       |  125 SEK   |
| jumper wires (4 x male / female; 10 x male / male)                         | are used to connect sensors to the Pycom device, the male / female wires are needed to connect the HC-SR04 sensor to the breadboard                                                              | [Electrokit](https://www.electrokit.com/produkt/labsladd-1-pin-hane-hona-150mm-10-pack/)       |   included in LoPy4 and sensors bundle  |
| 3 1K resistors                              | are needed to step down the echo voltage from the HC-SR04 sensor from 5V to 3.3V                                                             | [Electrokit](https://www.diyelectronics.co.za/store/10509-thickbox_default/resistor-1k-ohm-14w-5.jpg)     |  included in LoPy4 and sensors bundle   |
| spare wooden board + 3 wooden dowels                          | will be used as a lid for the water tank to which the ultrasonic distance sensor will be attached                      | you probably have some at home, otherwise most DIY / hardware stores have scrap pieces of wood for free     |  free   |


Here are some pictures of the most important components of the ReHydrator:

![](https://i.imgur.com/C3JxJxZ.jpg)
*Figure 2: LoPy microcontroller and expansion board. The antennae is only needed if you transmit data via LoRa.*

![](https://i.imgur.com/nxvdS6q.jpg)
*Figure 3: Water tank with lid and tap.*

![](https://i.imgur.com/Q4odqp8.png)

*Figure 4: HC-SR04 ultrasonic distance sensor & DHT-11 temperature and humidity sensor.*


## Computer setup
Before connecting your Pycom device to your computer, make sure that you have downloaded and installed the following programs / plugins:
* Pycom updater: needed to flash your pycom device with the latest firmware, follow the steps described [here](https://docs.pycom.io/gettingstarted/installation/firmwaretool/) to update your device. 
:::info
If you have already installed Atom, make sure to close it before using the Pycom updater.
:::
* Atom IDE: the text editor I used to write / edit code. You can download it [here](https://atom.io).
* node.js: needed for the Pymakr plugin to work in Atom, you can download it [here](https://nodejs.org/en/).
* Pymakr plugin: a plugin for the Atom IDE which allows you to easily interact with your pycom device via the so called REPL-interface and upload the code you have written. You can install the plugin directly from the settings view in Atom, click [here](https://atom.io/packages/pymakr) for more information and instructions.

![](https://i.imgur.com/lpBHE0R.png)

*Figure 5: Interacting with the Pycom device via the REPL-interface. If you power your Pycom with micro USB via your computer, you can print information in the REPL-interface.*

I worked on this project using a MacBook Pro (2019) running MacOS Catalina 10.15.5 and did not have to install any additional drivers or software. This might be different if you are using another OS, please read the [Pycom docs](https://docs.pycom.io) for more information if you are encountering any problems.  
## Putting everything together
#### Step 1: Connecting the sensors to the Pycom device.
Connect the sensors to the Pycom device according to the circuit diagram below (inspired by [this tutorial](https://core-electronics.com.au/tutorials/hc-sr04-ultrasonic-sensor-with-pycom-tutorial.html)). In order to be able to attach the HC-SR04 sensor to the lid of the water tank, do not connect it directly to the breadboard but use female/male jumper wires as "extension cords". 

Use the following pins for connecting the sensors:
* DHT-11
    * S - Pin23
    * V - 3V3
    * G - GND
* HC-SR04
    * VCC - Vin
    * Trigger - Pin21
    * Echo - Pin20
    * GND - GND

The HC-SR04 is a 5V device, whereas the Pycom board is a 3.3V device. Thus, the echo voltage of the sensor has to be stepped down from 5V to 3.3V, which is done here by using a voltage divider (in this case 3 1k resistors). Here is the electrical calculation based on Ohms law:

Vs = source voltage in Volts (here: 5)
R1 = resistance of the first resistor measured in Ohms (here: 1000)
R2 = resistance of the second resistor measured in Ohms (here: 1000 + 1000)
Vout = output Voltage in Volts

![](https://i.imgur.com/nTR9ZgE.png)



:::info 
Make sure to put the resistors in the correct place, otherwise you might damage your device!
:::

![](https://i.imgur.com/DHyZyIx.png)
*Figure 6: Circuit diagram for connecting sensors to the Pycom microcontroller. Attention: the labels for the pins in the picture above are not correct, please use the pins indicated in the list above.*


#### Step 2: Constructing the lid
To complete this step you will need a wooden board, an electric drill (16mm and 6mm) and some wooden dowels. Depending on which water tank you chose the dimensions for your lid may be different. Here are some sketches and pictures for the lid I built.

![](https://i.imgur.com/t1mBvst.png)

![](https://i.imgur.com/FD5RdYD.png)
*Figure 7: Tinkercad Sketches of the tank lid with holes for the ultrasonic distance sensor and holes for dowels.*

![](https://i.imgur.com/ZC5gyHF.jpg)
*Figure 8: Drilling holes for the sensor. I used a spare piece of wooden board.*

![](https://i.imgur.com/I288OEX.jpg)
*Figure 9: Bottom view of the lid with three wooden dowels to keep it in place.*

#### Step 3: Attaching the lid to the tank
The only thing that is left now is placing the microcontroller and sensors on the lid and attaching it to the tank. Now you can connect to your computer (using a micro USB-cable) and start doing measurements. Please note that the setup presented here is only for development, for production you would for example need a more professional lid which hides all the wires and protects the sensors in a better way.
![](https://i.imgur.com/hPhIYav.jpg)
*Figure 10: Prototype sketch.*

## Platform
The data which is collected by the sensors will be transmitted via WiFi/HTTP to the Ubidots platform. While working on this project I even tested the pybytes platform but changed to Ubidots since pybytes turned out to be quite limited when it comes to visualizing data. I found Ubidots to be visually more appealing and the platform offers a greater variety of options. 

In order to be able to send and visualize your own sensor data, you have to create an account at Ubidots. For development, I would recommend the free [STEM account](https://ubidots.com/stem/), which lets you connect three free devices with up to 10 variables per device. You can send 4000 "dots" (i.e. datapoints consisting of a value and a timestamp) per day and data is retained for one month. The platform supports various protocols (e.g. HTTP or MQTT) as well as SMS (only Canada and the US) or Email alerts. Thus, the functionality offered by Ubidots fits the purpose for this project well. However, if you want to scale the idea you might want to consider a paid subscription or a completely different solution (e.g. if you want to use the ReHydrator in a health care context a more secure solution for storing personal data might be required). 

Once you have created your account, make sure to copy the Ubidots token from the API credentials. You will need this in the next step.

## The Code

#### Code structure
The code is organized in the following way:
* boot.py: contains code that is executed on boot, here the WiFi connection is established
* main.py: is executed automatically after boot, here sensor data collection is initialized, values are assigned to variables and then sent to the Ubidots platform

```python

#Variables are sent to Ubidots via HTTP-post request
ubidots.post_var("ReHydrator",  temp, RH, tank_status, RDA_percentage, water_quantity, dehydration_warning, temp_warning)

```
* lib: this folder contains different libraries and modules called in the main.py file
    * HC-SR04: library for the ultrasonic distance sensor, based on [this library](https://core-electronics.com.au/tutorials/hc-sr04-ultrasonic-sensor-with-pycom-tutorial.html), but some minor adjustments have been made to eliminate false readings
    * DHT: library for the DHT-11 sensor
    * send_data: module for sending data to Ubidots
    * urequests: library for making HTTP-requests
    * keys: module containing WiFi-credentials and Ubidots token (this should not be shared)
    * rehydrator: main module containing functions to collect sensor data and do various calculations (see code example below)
    ### rehydrator.py

    ```python
    #Tankinfo
    #diameter = 16,8cm
    #radius = 8,4cm
    #max waterlevel (= height) = 20cm
    #max volume = 4433,42cm3
    #sensorheight (from tank bottom)= 29,3cm
    import time
    from machine import Pin
    from dht import DHT
    import HCSR04 as dist

    def calibrate():
        #Function measuring the initial distance from sensor to water surface and returning the initial water quantity of the tank
        distance = get_distance()
        initial_volume = get_volume(distance)
        print("ReHydrator calibrated")
        return initial_volume

    def get_distance():
        #Returns distance between sensor and water surface
        distance = dist.distance_median()
        print('Distance:', abs(distance), 'cm')
        return abs(distance)

    def get_volume(distance):
        #Returns current water volume
        height = 29.3 - abs(distance) #must be adjusted if different tank is used
        print('Height: ', height, 'cm')
        current_volume = round((3.14 * height * 8.4**2), 2)
        print('Current volume: ', current_volume, 'ml')
        return current_volume

    def get_tank_status(current_volume):
        #Returns percentage of total volume, if the percentage (due to minor measurement errors) is greater than 100, 100 is returned
        current_percentage = current_volume / 4433.42 * 100 #must be adjusted if different tank is used
        print('Current percentage: ', round(current_percentage, 1), '%')
        if current_percentage >= 100:
                return 100
        else:
            return round(current_percentage, 1)

    def get_temp_rh():
        #Gets values from the DHT-11 sensor and returns the result
        th = DHT(Pin('P23', mode=Pin.OPEN_DRAIN), 0)
        time.sleep(2)
        result = th.read()
        while not result.is_valid():
            time.sleep(5)
            result = th.read()
        print('Temperature: ', result.temperature, '°C')
        print('RH: ', result.humidity, '%')
        return result

    def get_water_quantity(initial_volume, current_volume):
        #Returns the water quantity change since the last measurement
        difference = initial_volume - current_volume
        print('Difference: ', difference, 'ml')
        if difference <= 0:
            return 0
        else:
            return difference

    def get_RDA_percentage(quantities_sum):
        #Returns the percentage of the recommended daily amount of water (here: 2.5 liters, this might have to be adjusted to individual values) that has been consumed
        RDA_percentage = quantities_sum / 2500 * 100
        print('RDA percentage: ', RDA_percentage, '%')
        if RDA_percentage >= 100:
            return 100
        else:
            return RDA_percentage
    ```


#### Using / adjusting the code

The code for this project can be cloned / downloaded from the following Github repository: https://github.com/Christina3107/LNU_1DT305_ReHydrator. 

Open the project in Atom and go to the keys_examples.py file. Rename the file to keys.py and enter your Wifi-Credentials and your Ubidots token. In case you have a different water tank from the one I used, make sure to make the appropriate adjustments in the get_volume() and get_tank_status()-functions in the rehydrator.py module (see comments in the code).  

Once the above steps have been completed, use the upload icon in the Atom-pymakr extension to upload the code to your pycom device. Now, data will be sent to Ubidots once an hour and you can create your own dashboard. You can see an example dashboard below.


## Transmitting the data / connectivity
Since LoRa connectivity turned out to be quite unstable at my current location, I decided to send data via a WiFi connection using the HTTP protocol. Even though WiFi has some disadvantages in comparison to LoRa, e.g. a shorter range and the fact that it usually requires more power, I consider it to be a reasonable alternative for this project,  since the ReHydrator is a device that is expected to be used in a person's private home or maybe at the workplace.

As I had some previous experience with HTTP requests I decided to transmit my data to the Ubidots platform by sending a HTTP post request (see [this tutorial](https://help.ubidots.com/en/articles/961994-connect-any-pycom-board-to-ubidots-using-wi-fi-over-http) for more information). A total of 7 variables is sent in the JSON-format once an hour, 12 times a day (i.e. during "active hours"). 

## Presenting the data
Data is saved in the Ubidots database every time a post request is sent to the API endpoint, i.e. once an hour 12 times a day. The data is preserved in the database for one month when using a free STEM account. The following variables are sent and visualized on the dashboard:
* current temperature
* temperature alert (turns red when temperature exceeds 25 degrees)
* current humidity
* tank status (current percentage of maximum tank volume)
* RDA-percentage: how much water of the recommended daily amount (I chose an RDA of 2.5 liters, but this can be adjusted by making minor changes in the code) has been consumed 
* dehydration warning: turns red when less than 170ml of water have been consumed since the last measurement
* temperature / water intake: combined line/bar graph visualizing water intake and changes in temperature over time

For more information on how to build a dashboard on Ubidots, visit the [Ubidots for Education Youtube Channel](https://www.youtube.com/watch?v=p3DVe7TLvdI&list=PLlZkMpUnBb2b33bANxC4uY3iBNJaXB5J3). 

![](https://i.imgur.com/mGlEFKh.png)


![](https://i.imgur.com/jAc1q7v.png)


*Figure 11: Dashboard screenshots.*

Ubidots also allows for triggering events if certain conditions are met. I use this function to send Email alerts for dehydration warnings and high temperatures.

![](https://i.imgur.com/EdfYuwi.png)


*Figure 12: Email alerts.*


## Finalizing the design
Here is a picture of the finished ReHydrator prototype. 

![](https://i.imgur.com/70Gc4rx.jpg)

*Figure 13: Finished prototype.*

<iframe width="560" height="315" src="https://www.youtube.com/embed/1n7SK_GVEzw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

*Figure 14: ReHydrator in action.*

It is important to note that this is JUST a prototype and there is much room for improvement and further development. Some reflections on potential problems and future steps:
* one major disadvantage is that the ReHydrator does not keep track of how much water you actually drink, it only monitors the quantity tapped from the tank
* the device does not take a person's current activity level or personal data (age, weight, height etc.) into consideration: the amount of fluids a person needs might vary considerably, e.g. depending on how physically active you are; it would be interesting if the ReHydrator could be connected to some kind of activity tracker or health app in order to be able to give more personalized recommendations
* in the future, I would like to try out 3D printing, e.g. for creating a more professional lid and a case for the Pycom device

All in all, working on this project has been an interesting and informative experience and an exciting first encounter with the world of IoT. 


## Resources
[1] https://www.nutrition.org.uk/nutritionscience/life/dehydrationelderly

[2] https://www.ncbi.nlm.nih.gov/pubmed/16182639

[3] https://caringpeopleinc.com/blog/dehydration-elderly/

[4] https://blog.getawair.com/6-health-symptoms-associated-with-humidity
