Plant Sensor transmitted over Wifi
This tutorial aims to create a plant sensor to be placed inside of a plant pot in order to read temperature, pressure and humidity around the plant as well as measuring the moisture levels inside of the plant pot. We’ll be using the Pycom “Pysense Expansion Board” alongside the Pycom “LoPy Development Board” in order to retrieve and send our data over the LoRa network to be viewable on Pybytes.
What you’ll need:
- Soldering Kit (for moisture sensor)
- MPL3115A2: This contains the functions to read pressure
- SI7006A20: This contains the functions to read temperature and humidity
- pysense: Contains the board specific functions
- mqtt: Allows messages to be sent over Wifi
The Pybytes libraries will all need to be downloaded from Pybytes.
Setting up the board:
Connect the LoPy to the Pysense expansion board, ensuring that the LED of the LoPy is facing on the same side as the micro-USB. After this, we need to solder the moisture sensor onto the Pysense, attaching it to the ground, a pin for signal and a pin for a virtual current. We create a virtual current in order to be able to switch on and off the current whenever we do and don’t want to use the sensor. If we didn’t do this, the continuous current flowing through the moisture sensor would eventually corrode the sensor. If we switch it off until we need it, we don’t have to replace it as often.
With this all set up we can then plug in the micro-USB and start our code.
The boot.py will be used to initialise our wifi connection and set up our connection with the LoPy so that we can send our payload later on.
import machine import os import time uart=machine.UART(0,115200) os.dupterm(uart) if machine.reset_cause()!=machine.SOFT_RESET: from network import WLAN known_nets=[(('WIFI_NETWORK','WIFI_PASSWORD'))] wl=WLAN() original_ssid=wl.ssid() original_auth=wl.auth() wl.mode(WLAN.STA) available_nets=wl.scan() nets=frozenset([e.ssid for e in available_nets]) known_nets_names=frozenset([efor e in known_nets]) net_to_use=list(nets&known_nets_names) try: net_to_use=net_to_use pwd=dict(known_nets)[net_to_use] sec=[e.sec for e in available_nets if e.ssid==net_to_use] wl.connect(net_to_use,(sec,pwd),timeout=10000) while not wl.isconnected(): time.sleep(0.1) print(wl.ifconfig()) except: wl.init(mode=WLAN.AP,ssid=original_ssid,auth=original_auth,channel=6,antenna=WLAN.INT_ANT)
Our main will have to:
- Read the data from the sensors
- Send the data over to Pybytes
Initialising the PyBytes connection:
USERNAME = "firstname.lastname@example.org" DEVICE_ID = "AABBCCDDEEFFGGHHIIJJKKLLMMNNOO" SERVER = "mqtt.pybytes.pycom.io" pybytes = Pybytes(USERNAME, DEVICE_ID, SERVER) pybytes.connect_wifi()
This code will be edited later when we access Pybytes.
Our functions are used to call separate functions from the specific libraries mentioned above. This data is then returned to the main where it’s passed into Pybytes.
The pressure sensor: This sensor takes a reading of the pressure around it using the built in pressure gauge of the PySense. The library and function used for this can also be used to measure Altitude as well, which returns a value in metres.
def press_sensor(): mpp = MPL3115A2(py,mode=PRESSURE) press = mpp.pressure() return press
The temperature and humidity sensor: Both of these measurements use the exact same library and so can both be called in the same function to supply the temperature and pressure by calling the library and then their respective functions.
def humid_temp_sensor(): si = SI7006A20(py) humid = si.humidity() temp = si.temperature() return(humid,temp)
The moisture sensor: The moisture sensor does not use a library like the other two and instead uses an external moisture sensor that has to be attached to the PySense through it’s pins. When the sensor feels moisture it gets a sent a current through it. The maximum current it can send is when the moisture sensor is fully submerged in water and the minimum current it can send is when it’s in dry air. From this we can work out the range and percentage of water currently in the soil.
def moist_sensor(): p_out.value(1) volts = apin.value() p_out.value(0) return volts
Sending over Pybytes: Because we initialise the connection with Pybytes and we install the libraries for it, we don’t need to send the data as a payload and so can use specific functions to send the data to Pybytes.
pybytes.send_virtual_pin_value(False, 16, volts) pybytes.send_virtual_pin_value(False, 15, temp) pybytes.send_virtual_pin_value(False, 14, press) pybytes.send_virtual_pin_value(False, 13, humid)
Overall, the final main.py should look something like this:
from time import sleep from network import LoRa import socket import binascii from pycom import heartbeat,rgbled from pybytes import Pybytes from machine import Pin,ADC from pysense import Pysense from SI7006A20 import SI7006A20 from MPL3115A2 import MPL3115A2,PRESSURE adc = ADC() apin = adc.channel(pin='P15',attn=ADC.ATTN_11DB) p_out = Pin('P9', mode = Pin.OUT, pull = Pin.PULL_DOWN) global py py = Pysense() print('starting up...') py.setup_sleep(30) USERNAME = "email@example.com" DEVICE_ID = "AABBCCDDEEFFGGHHIIJJKKLLMMNNOO" SERVER = "mqtt.pybytes.pycom.io" pybytes = Pybytes(USERNAME, DEVICE_ID, SERVER) pybytes.connect_wifi() def press_sensor(): mpp = MPL3115A2(py,mode=PRESSURE) press = mpp.pressure() return press def humid_temp_sensor(): si = SI7006A20(py) humid = si.humidity() temp = si.temperature() return(humid,temp) def moist_sensor(): p_out.value(1) volts = apin.value() p_out.value(0) return volts def main(): temp = int(humid_temp_sensor()) press = int(press_sensor()) humid = int(humid_temp_sensor()) volts = int(moist_sensor() /4.096) pybytes.send_virtual_pin_value(False, 16, volts) pybytes.send_virtual_pin_value(False, 15, temp) pybytes.send_virtual_pin_value(False, 14, press) pybytes.send_virtual_pin_value(False, 13, humid) sleep(3) main() py.go_to_sleep()
Pybytes is a website created by Pycom that allows you to send the data being provided by our set up and display it through a series of widgets.
Head to pybytes.pycom.io and create an account. On the left hand side bar, click Devices and then Add Device to create a new device for your project. Once this has been done, you’ll be given the device ID that was mentioned earlier in the project. Go back to your main and edit the DEVICE_ID with the code that you’ve just been given.
Once this has been done, we can create the dashboard to display the data. For our example, we’ve created 4 separate line charts to display the data however this data can be displayed in any way that you’d like.
Make sure you go through and edit each of the graphs to ensure that the each of the graphs has a virtual pin that relates to that in our code (For example, Temperature is set to virtual pin 15).
Once all of this is set up, you should have a working sensor that continuously displays your data on Pybytes.