# Tutorial: Connect soil moisture sensor to an IoT device ## About This tutorial was created for the course 1DT305: Introduction to Applied IoT. Linnaeus University, Sweden. > Name: Alex Naga > Student ID: an222zd ### Project overview This tutorial will touch on the subject of how to connect soil moisture sensors to an IoT device and how we could achieve this in a simple manner. The estimated time for completing this tutorial is around 1-2 hours, based on prior knowledge and computer setup. ### Table of Contents * [Tutorial: Connect soil moisture sensor to an IoT device](#Tutorial:-Connect-soil-moisture-sensor-to-an-IoT-device) - [About](#About) - [Project overview](#Project-overview) - [Table of Contents](#Table-of-Contents) - [Objective](#Objective) - [List of material](#List-of-material) - [Computer setup](#Computer-setup) - [Chosen IDE](#Chosen-IDE) - [Circuit diagram](#Circuit-diagram) - [Platform](#Platform) - [Code](#Code) - [Soil moisture sensor library](#Soil-moisture-sensor-library) - [Using the library](#Using-the-library) - [Checking the moist level](#Checking-the-moist-level) - [Main code](#Main-code) - [Sending the data](#Sending-the-data) - [Visualizing the data](#Visualizing-the-data) - [Result](#Result) - [Future work](#Future-work) ### Objective The purpose of creating this project is to get a basic understanding of how to connect a sensor to an IoT device. The idea came from having trouble taking care of plants and getting curious to see how gathering data from the plants could help give better insights into how much water the plant needs. After going through this tutorial, one should be able to take on other IoT projects with a bit more ease. ## List of material | Item | Description | Link | Price ∼ (excluding shipping) | |------------------------|---------------------------------------|-------------------------------------------------------------------------------------------------------|------------------------------| | LoPy4 with headers | MicroPython enabled development board | [pycom.io](https://pycom.io/product/lopy4/) | €39 | | Expansion board | Expansion board for Lopy4 | [pycom.io](https://pycom.io/product/expansion-board-3-0/) | €18 | | Soil hygrometer module | Soil moisture sensor. | [electrokit.com](https://www.electrokit.com/en/product/soil-hygrometer-module/) | €4 | | Micro USB cable | A 1.8m - 3m cable is recommended. | [electrokit.com](https://www.electrokit.com/en/product/usb-cable-a-male-microb-male-1-8m/) | €5 | | Jumper wires | Makes testing easier. | [electrokit.com](https://www.electrokit.com/en/product/jumper-wires-1-pin-male-female-150mm-10-pack/) | €4 | | | **Total cost** | | | €70 | ## Computer setup The first step is to [update the firmware](https://docs.pycom.io/updatefirmware/device/) for the Lopy 4. One will also need to install [Node.js](https://nodejs.org/en/) before installing the [Pymakr plugin](https://pycom.io/products/supported-networks/pymakr/) (for uploading code to the Lopy4 device). A more detailed guide of installing the required steps could be found by following steps 1-2 [here](https://hackmd.io/@lnu-iot/rk4qNlajd#1-Connect-hardware-update-firmware). ### Chosen IDE Even though Visual Studio Code is my daily driver, the chosen IDE for this project is [Atom](https://atom.io/). The reason behind this is that after installing the [Pymakr plugin](https://pycom.io/products/supported-networks/pymakr/), it would make the editor feel a bit clogged in vsCode. I would rather have a separate setup for when dealing with IoT. ## Circuit diagram For connecting the soil moisture sensor to the Lopy4 device, we use pin 16 on the expansion board for AO and pin 11 for VCC. Note that this is only for an introduction/development setup. ![Circuit diagram](https://i.imgur.com/lAOiOF9.png) ## Platform One of the goals of this project was to see how big of an effort it would be to connect a sensor to a device and send this data through the Internet. This goal with simplicity in mind is the reasoning behind choosing one of the recommended platforms (Pybytes) to send data from the lessons in this course. If wanting to develop this further, we will discuss some alternatives in the [future work](#Future-work) section. ## Code The GitHub repo with the source code for this tutorial can be found at [my repo here](https://github.com/AlexNaga/iot-soil-moisture-sensor). ### Soil moisture sensor library The library for reading data from the Lopy4 pins. It has taken inspiration from this [GitHub repo](https://github.com/lwej/Pycom-Soil-Monitor/blob/master/pycom/test.py#L17). ```python from machine import ADC, Pin import time def value_in_millivolt(pin_in, pin_out): """ Parameters: pin_in : AO pin number to read from. pin_out : VCC pin number to turn on/off. Returns: Soil moisture value in millivolt (mV) between ~250-999 mV, where 250 means the plant is moist and 999 is dry. """ adc = ADC() apin = adc.channel(pin=pin_in, attn=ADC.ATTN_11DB) pin_out = Pin(pin_out, mode=Pin.OUT, pull=Pin.PULL_DOWN) pin_out.value(1) time.sleep(2) volts = apin.value() pin_out.value(0) time.sleep(2) volt_reference = 4.096 return volts / volt_reference ``` ### Using the library The function for using the library. ```python def get_moist_level(): ao_pin = "P16" > vcc_pin = "P11" moist_level = moist_sensor.value_in_millivolt(ao_pin, vcc_pin) return moist_level ``` ### Checking the moist level The function for checking the moist level and outputting to the user in the terminal, also displaying different LED colors on the Lopy4 device. ```python import pycom pycom.heartbeat(False) # turn off the default LED # colors GREEN = 0x00FF00 RED = 0xFF0000 BLUE = 0x0000FF BLACK = 0x000000 def check_moist(moist_level): if moist_level > 400 and moist_level < 800: print("The moisture level is OK.") pycom.rgbled(GREEN) elif moist_level < 400: print("The plant has too much water.") pycom.rgbled(BLUE) else: print("Please water the plant.") pycom.rgbled(RED) time.sleep(3) pycom.rgbled(BLACK) ``` ### Main code The main code for reading soil moisture values in millivolts (mV) and sending the data to Pybytes every 5 minutes. ```python import moist_sensor import time def send_data(moist_level): if moist_level is None: print("Error: No moist level when sending data.") return # send data to Pybytes in channel 2 pybytes_channel = 2 pybytes.send_signal(pybytes_channel, moist_level) print("Sending: {}".format(moist_level)) while True: moist_level = get_moist_level() print('Moisture level {} mV'.format(moist_level)) check_moist(moist_level) send_data(moist_level) time.sleep(60 * 5) # five minute interval ``` ## Sending the data The data is transmitted from the device using WiFi and transferring to Pybytes at an interval of 5 minutes. The structure of the data is sent as a string using the built-in [`pybytes.send_signal(channel, data)`](https://docs.pycom.io/pybytes/api/#pybytessend_signalsignal_number-value) function. WiFi is relatively power-hungry, but power consumption will not be an issue in this case since we will not be running on batteries. If wanting to run on solar panels or batteries, then we would most likely want to use another more power-efficient protocol like [LoRa](https://lora-alliance.org/about-lorawan/) or [SigFox](https://www.sigfox.com/en). ## Visualizing the data The data is visualized using [Pybytes dashboard](https://docs.pycom.io/pybytes/dashboard/). ![Pybytes dashboard with a 5-minute interval](https://i.imgur.com/trguoaF.png) _Displaying the Pybytes dashboard with a 5-minute interval._ &nbsp; ![Pybytes dashboard with hourly interval](https://i.imgur.com/lguuEkX.png) _Displaying the Pybytes dashboard with hourly intervals. Notice how the plant was dry at the beginning of the chart and got moister when watered a bit._ ## Result ![Final result of the IoT device](https://i.imgur.com/xhjWzNo.jpg) _Final result of the IoT device._ Overall the project went fine. I'm pleased with how simple it was to send data through Pybytes. I had some issues later on when trying to upload code to the Lopy4 device as it kept freezing; it would require me to put the device in safe-boot mode to be able to upload code. ### Future work An alternative from just using the recommended Pybytes would be to explore the wide range of IoT services provided by AWS due to me working with AWS professionally. Some examples would be: * [Amazon Timestream](https://aws.amazon.com/timestream/) - A serverless time-series database suitable for IoT. * [AWS IoT Core](https://aws.amazon.com/iot-core/) - A service to manage IoT devices in a scalable way. * [AWS IoT Events](https://aws.amazon.com/iot-events/) - A service to detect and respond to events from IoT sensors and applications. * [AWS IoT Analytics](https://aws.amazon.com/iot-analytics/) - A service to run queries on a large amount of IoT data. Furthermore, it would be interesting to test more soil moisture sensors to see how they compare to each other, for example, using the somewhat more expensive [capacitive I2C soil moisture sensor](https://www.electrokit.com/en/product/jordfuktighetssensor-kapacitiv-i2c/) for €13.