---
# System prepended metadata

title: Tutorial on how to build a temperature and plant moisture sensor

---

# Tutorial on how to build a temperature and plant moisture sensor

Per Rawdin pr222iw

This is a tutorial on how to build a solution for measuring temperature and soil moisture level for a plant.  
The device will connect through the LoRa/Helium network and present the data in a Datacake dashboard. 

approx. time: 5h


## Short project description

In this tutorial we will be building a room temperature and soil moisture sensor that sends its data to a front-end platform for presentation. 
You will get insights into working with sensors and the data received, transfer the data through a network and present them for an end-user.  

Many parts of this project have drawn inspirations and taken learnings gained from the course Applied IOT 1DT305 at Linneaus University. 

Depending on previous experience in the different parts involved, the approximate time required for this project can vary. But with no experience, it should take approximately 5 hours. 

## Objective

The purpose of the project is to explore and get started in the world of Internet of Things. This is a beginner-friendly project that anyone can take part of. 
The project will provide insights into building a simple IoT solution from hardware to code and presentation of data. 

This specific project was chosen because I found it to be reasonable as a starter project while it could also provide me with data that I would personally find useful and be able to solve some problems with.
During summer and winter I could at times feel that there were perhaps some irregular and abnormal temperatures in my living space, either too cold or too warm. I will now be able to monitor these temperatures. I have also been having a hard time watering my plants in time in order to keep them alive. This solution will help me keep track of when I should water a plant while also being able to see the temperature that it is exposed to. 
Completing this project will result in a solution that will give you the ability to monitor the temperature in a room and the soil moisture level of a plant, it will also give you the possibility to view historical charts of the data generated.
The project will result in a quite basic solution but will give you a foundation that can be additionally extended upon. For example with a humidity sensor or perhaps automatic watering of plants when needed can be added to the device later on. With sheltering of some components, the device could also be used in an outdoors setting. 


## Material

Most of the materials required in this project is included in the Applied IOT DT305 bundle that the course has created in collaboration with the reseller [Electrokit](http://www.electrokit.com) where it was bought from. The soil moisture sensor and battery pack (not required) used in the project can also be acquired at ElectroKit. 

The materials that is needed for this project:

|                                     |Store|Price              |Comments|
|---|---|---|---|
|PyCom LoPy4 (and sensors LNU bundle) |[Store link](https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-lopy4-and-sensors-bundle/)     |949.00 SEK          |A development board with CPU and connectivity (LoRA, SigFox, WiFi and Bluetooth).  |
|Soil moisture sensor FC-28           |[Store link](https://www.electrokit.com/produkt/jordfuktighetssensor/)     |29.00 SEK |Sensor for measuring the moisture level in soil. Converts the resistance to a voltage as data. |
|Temperature sensor MCP9700           |     |Included in bundle |Temperature sensor that outputs a linear voltage proportional to the measured temperature.|
| LoPy Extension board                      |     |Included in bundle |Expansion Board - This will extend the possibilities of working with the LoPy4 by enabling us to connect to the board with a USB cable and also a simple way to connect the sensors.|
|Antenna                             |     |Included in bundle |LoRa/SigFox Antenna.|
|Breadboard                           |     |Included in bundle |Solderless construction base for sensors.|
|Jumper wires                         |     |Included in bundle |Electrical wires for connecting sensors.|
|1x LED orange                        |     |Included in bundle |Simple orange LED.|
|1x LED green                         |     |Included in bundle |Simple green LED.|
|2x 1k resistors                         |     |Included in bundle |Used for the LEDs in this project.|
|USB-cable                            |     |Included in bundle |For connecting the board to the computer or power outlet.|
|Battery pack                         |[Store link](https://www.electrokit.com/produkt/batterihallare-3xaaa-med-strombrytare-och-jst-kontakt/)     |29.00 SEK |Optional for this project. For mobile powering of the device.|

Total: 1007.00 SEK

## Computer setup

Applications required: 
- Pycom Firmware Update tool
- A text editor/IDE (Atom or Visual Studio Code)
- Pymakr plugin (for communicating and uploading files to the LoPy board)
- Node.js (required for pymakr)

The environment used for this project is an AMD-powered laptop with Manjaro Linux operating system. The steps and software used for this project should be applicable for all the popular operating systems (Windows, MacOS), but this guide will focus on the setup using Manjaro Linux. 

We will be flashing the firmware and uploading files to the LoPy board by connecting a USB cable from the expansion board to the computer. 
Using Arch-based Linux (Manjaro), I initially ran into problems connecting to the board as I would receive the error message "Permission denied on /dev/ttyACM0". This was easily solved by running ```sudo usermod -a -G uucp $USER``` in the  terminal and restarting the computer. 

Before we can work with the development board, we will need to upgrade the firmware on it. For this we will use the Pycom Firmware Updater software provided by Pycom. 
As the Pycom Firmware Updater is available for Manjaro Linux in this [repo](https://aur.archlinux.org/packages/pycom-firmware-updater/), it was quite easy to install it using the "Add/Remove Applications" tool on my system. You can also obtain the tool for all platforms at [Pycoms website](https://pycom.io/downloads/).  
When the tool has been installed, just start it up and follow the guided process for updating the firmware. We will select the connected device under Port and for this project the PyBytes firmware should be sufficient. 
![](https://i.imgur.com/3Igt9SM.png)


Before we go on, make sure that Node.js is installed on your system as this will be required for the PyMakr plugin that we will use with our text editor. Node.js was already installed on my system but you can see the following [page](https://nodejs.org/en/download/) for how to install it on your system.  
As the Pymakr plugin is only available for Visual Studio Code and Atom, we will need to use one of these text editors. We will be using Atom as our text editor for this project.  
Open up Atom and install the Pymakr plugin under Edit -> Preferences -> Install. Once installed you will now have an additional section in Atom for PyMakr. The PyMakr plugin makes it really easy to work with the development board. Once installed, you get a command line and a number of buttons for interacting with the board. You will have buttons for connecting, uploading or downloading the project to and from the board, this is how we will be uploading our project to the board. 

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


## Putting everything together
Begin by attaching the LoPy board to the expansion board. We will be using the breadboard for connecting the sensors to the development board. 

We will start with connecting the temperature sensor as it is relatively the easiest of them all. Attach the sensor to the breadboard. With two jumper wires, connect the ground and positive wiring from each row to their respective pins on the power rail of the breadboard. 
Connect two additional jumper wires to the endpoints of the power rail. The ground wiring (-) will go to the ```GND``` pin on the expansion board while the positive (+) will be connected to the ```3.3v``` pin. 
From the same row as for the output wiring (middle) of the sensor, connect a jumper wire to the ```P15``` pin of the expansion board. We will program the data output later. 

For the soil moisture sensor, the wiring will be a bit different. The FC-28 sensor supports both analog and digital outputs, and we will be working with the analog output for this project. The sensor module has built in legs that can attach the module directly to the breadboard. Connect the ground wiring with the ground rail on the breadboard. 
We want to be able to send instructions for powering on and off the sensor. We will therefore choose to connect the positive pin directly with the expansion board to a pin where we can send instructions and provide power to the sensor, we will connect it to ```P22```.  
From the sensor we will also connect a wire for receiving the data. As we want to use the analog output from the sensor we will connect a wire from the same row as the ```AO``` leg of the sensor to a data pin on the expansion board, in this case we will use ```P16```. 
We are now done with the wiring for the soil moisture sensor.

For this project we will also connect some LEDs to show the status of the connection with the network used (in this case Helium). We will use an orange and a green LED.  
These LEDs have 2 legs, one longer for the positive and one shorter for the ground. 
You will also need to use two 1K resistors for connecting the ground leg to the ground rail on the breadboard. This is needed because we do not want to burn out the LED by preventing excess current with the resistors. Then connect the positive legs with a wire from the respective rows to pins ```P20``` and ```P21``` on the expansion board. We are using these pins to program when these LEDs should be lit or turned off. 

Make sure that all connections are correctly applied to the right pins on the board and connections are on correct rows on the breadboard. 

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

You will also need to connect the antenna to the LoPy board for the Lora/Helium connection. When we are running the finished version you can also connect the battery pack to the expansion board that will power the device when running, but this is not required if you  want to use USB as the power source. 

The sensors are now connected!

## Platform

There were several platforms presented during the course. I didn't manage to explore all of them but I knew that I wanted something visually appealing and something that would would clearly show the data generated from the device. I did initially connect the device to the PyBytes platform and was able to view data from the device there. But the other other low-code platforms that were shown looked really compelling and I wanted to explore these as well. 
I started with connecting to Ubidots. While I was able to send the data to Ubidots, I had issues working with the decoder code in Ubidots that I didn't manage to resolve. 
I then looked into Datacake, another low-code platform in the cloud. In Datacake, I got the decoder to actually work and managed to get my data there through the Helium-Datacake integration. 
Setting up the device was really easy by following this [guide](https://docs.datacake.de/lorawan/get-started) with the [Helium integration](https://docs.datacake.de/lorawan/lns/helium).
I found Datacake to be a really good solution for what I wanted to do with the data and offered a lot of functionalities that were really interesting. With a lot of options and possibilities with the appearances for the modules in the dashboard. I also like the additional functionalities such as being able to set up notifications through SMS or e-mail. 
Almost no complicated configuration was needed to design a dashboard and it was very simple to add data from the sensor. The flexibility to show the data in different ways and the simplicity of working with Datacake is great. 

## The code
The code in ```main.py```. The temperature sensor parts of the code has mainly been borrowed from [this tutorial in the course](https://hackmd.io/@lnu-iot/BJnuGmJh_). We will turn on the soil moisture sensor only when needed in order to extend the longetivity of the sensor and minimize the risk of corrosion. With the resistance value received from the sensor, we will map it in the scale of 0-100 that will be used as a percentage range. 
Finally, we will transmit the values through LoRa. 

```python=
import machine
import socket
from machine import Pin
from machine import ADC
from time import sleep

# LoRa socket connection.
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
s.setblocking(False)

# ADC and data pins
adc = ADC()
soil_pin = adc.channel(pin='P16', attn = machine.ADC.ATTN_11DB)
temp_pin = adc.channel(pin='P15')

# Pin for turning on and off soil moisture sensor
moisture_power = Pin('P22', mode=Pin.OUT, pull=Pin.PULL_DOWN)

# Value mapping function
# https://rntlab.com/question/percentagem-em-micropython/
def value_map(x, in_min, in_max, out_min, out_max):
    return int((x-in_min) * (out_max-out_min) / (in_max-in_min) + out_min)

while True:
    # Power on soil sensor
    moisture_power.value(1)
    # Sleep for a second to make sure that the moisture sensor has been turned on.
    sleep(1)

    # Temp sensor
    millivolts = temp_pin.voltage()
    celsius = (millivolts - 500.0) / 10.0

    # Soil moisture
    soil_value = soil_pin.value()

    # Map the soil moisture value in a scale between 1 to 100 (%)
    # 1228 is the resistance level when the soil is wet.
    percent = value_map(soil_value, 4095, 1228, 0, 100)

    # Power off soil sensor
    moisture_power.value(0)

    # Transmit rounded data via lora
    soil = round(percent)
    temperature = round(celsius)

    s.send(bytes([temperature, soil]))

    # Deep sleep for an hour
    machine.deepsleep(3600000)

```


The code in ```boot.py``` has the main purpose of connecting the device to the network, the following [code](https://docs.pycom.io/tutorials/networks/lora/lorawan-otaa/#app) from Pycom has been used for this. 

LED blinking and lighting for connection indication in ```boot.py```:

```python=
import machine

p = machine.Pin
yellow_led = p('P20', mode=p.OUT)
green_led = p('P21', mode=p.OUT)
```

```python=
# wait until the module has joined the network
while not lora.has_joined():
    time.sleep(1)
    # blink (turn on) orange led while connecting
    yellow_led.value(1)
    print('Not yet joined...')
    time.sleep(1)
    # blink (turn off) orange led while connecting
    yellow_led.value(0)

# turn green led on when connected
green_led.value(1)
```

## Transmitting the data / connectivity

We will be using LoRa connectivity and the Helium network for transmitting the data from our device. 
LoRa/Helium is a low-power wide-area network that is very well suited for IoT devices and we want to utilize such a solution for our project. This network will provide us with a low-powered connectivity and enable the possibility for additional mobility and potential outdoor use of the device. 
This network was specifically chosen for this project as it provided the best coverage for the location where I reside. There are quite many Helium hotspots available in the area where I live, so a stable connection between the device and the network can be assured. If the Helium coverage is not sufficient where you live, you can also look into other wireless connectivities such as WiFi or SigFox (all of these are compatible with the LoPy board). 
The LoRa connection is initiated from the ```boot.py``` file that we have uploaded to our device. 
To use the device with the Helium network, you will need to register for an account on the Helium Console and add the device there. Follow the steps in the following [guide](https://docs.helium.com/use-the-network/console/quickstart/) on how to do this. 
Using the Helium network also provides us with the Helium Console where we can use built-in integrations to additional platforms. We will use such an integration for transmitting the data to our front-end platform, in this case Datacake (more on this in the Platform section). 
The transport protocol for the communication is HTTP, as this is the protocol used in the Helium-Datacake integration. 

The data is sent once every hour as I found it to be a reasonable interval for the type of data that is gathered and it would provide a sufficiently "real-time" view of the information. The goal is also to not send data too often in order to preserve power used by the device. 
By setting this interval, we will also provide enough historical data that can be utilized to form trends.

## Presenting the data

Using Datacake made it really easy to design the presentation as I envisioned it with mostly a drag-and-drop approach and easy yet powerful configuration. Datacake offered a lot of possibilities to customize the dashboard with different ways of displaying the data.
As this solution is using Datacake, we will be using their database. The data is stored in the database each time we transmit it, so once every hour.

Dashboard:
![](https://i.imgur.com/0PGjfZH.png)

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


E-mail alert:
![](https://i.imgur.com/z2MB0NG.png)



## Finalizing the design
While I am happy with the results of the project, I would perhaps have wanted some additional sensors (like a humidity sensor) and build my own front-end with a database. It would be really nice to have a 3D-printed casing as well. I believe that this can be easily added further on though. 
Accomplishing this project has really shown me a new world of working with electronics and wireless technologies. Basically everything that has been introduced in the course and applied in this project was new grounds for me. 
I am really excited about exploring more of IOT in other projects, extending this device and experimenting with additional sensors in future. 

![](https://i.imgur.com/pJxxMEr.jpg)![](https://i.imgur.com/Tuoagf5.jpg)
