---
# System prepended metadata

title: Simple temperature and humidity sensor for Greenhouse

---

# Simple temperature and humidity sensor for Greenhouse
Ahmed Shawky Abdelhamid
aa224qd@student.lnu.se


## Project Overview
This project is a simple temperature and humidity sensor device that can be used both indoors and outdoors.  The main purpose of this device is to monitor the temperature and humidity using "PYCOM Lopy4" and DHT11 sensor.
This project can take between 5 to 20 hours to be ready for use. depending on the level of knowledge.


---

## Objective
The main purpose of building this project was to test and explore the different IoT sensors and various platforms, besides building something useful to use in my greenhouse to give me some information about the weather status of my plants in the greenhouse, which is about 2 kilometers far from the house. 



---

## Materials
### *List of materials*

| Parts | Discreption |
| -------- | -------- |
| PYCOM Lopy4     | WIFI, Bluetooth, LoRa, Sigfox|
| PYCOM Expantion board     ||
| USB Powerbank   | 5000mA|Output 2.0A, 9V
| DHT11 sensor    | Temrature and humidity sensor|

![](https://i.imgur.com/YcDhkY5.png)Lopy4
![](https://i.imgur.com/IFizUSU.png)Expantion board
![](https://i.imgur.com/pD1pIa5.jpg) 
DHT11 Sensor


---



**Computer setup**

Please note I’m running Windows 10, so there are things that will have to be done differently on other operating systems.
At the time of there is firmware update released for the Pycom expansion board 3.0, and Lopy4, we can go straight onto updating the firmware. Before we can do that, we have to put the components together, as explained in Putting the hardware together further down.
To be able to update the Lopy4 you need to install “Pycom Firmware Update” on your computer. The latest version of the program can be found [here](https://https://docs.pycom.io/gettingstarted/installation/firmwaretool/). Once installed, start the program and follow the instructions. You should not need to check any boxes in the process. Now you’re ready to move on to the IDE.
Start by downloading the latest version of Atom from www.atom.io. Ones installed on your computer, start the program, and from the “Welcome Guide” choose “Install a Package” > “Open Installer.” Search for and install “pymakr.” This extension will make Atom able to talk to your device while connected and will make the entire process off coding easier. You’re now ready to start coding.

## Putting things togther
![](https://i.imgur.com/keyUXRL.jpg)
The expansion board is connected to the computer through a micro USB cable which will be replaced then by the powerbank.


---

## Platform
I used Pybytes platform for presenting my data. Where data is automatically stored in the cloud, and it uses an MQTT protocol. Pybytes is a user-friendly platform that is automatically connected to the device through the Pycom library, that you get if you update your device with “type” Pybytes.
I also tried to connect to Ubidots platform for data visualisation.


---

## Code
Code that is used in the project consists of a folder named lib that contains dht.py and urequests.py and then a main.py file.

urequests.py
```
import usocket

class Response:

    def __init__(self, f):
        self.raw = f
        self.encoding = "utf-8"
        self._cached = None

    def close(self):
        if self.raw:
            self.raw.close()
            self.raw = None
        self._cached = None

    @property
    def content(self):
        if self._cached is None:
            try:
                self._cached = self.raw.read()
            finally:
                self.raw.close()
                self.raw = None
        return self._cached

    @property
    def text(self):
        return str(self.content, self.encoding)

    def json(self):
        import ujson
        return ujson.loads(self.content)


def request(method, url, data=None, json=None, headers={}, stream=None):
    try:
        proto, dummy, host, path = url.split("/", 3)
    except ValueError:
        proto, dummy, host = url.split("/", 2)
        path = ""
    if proto == "http:":
        port = 80
    elif proto == "https:":
        import ussl
        port = 443
    else:
        raise ValueError("Unsupported protocol: " + proto)

    if ":" in host:
        host, port = host.split(":", 1)
        port = int(port)
    try:
        ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM)
    except:
        ai = usocket.getaddrinfo(host, port)
    s = usocket.socket()
    ai = ai[0]

    try:
        s.connect(ai[-1])
        if proto == "https:":
            s = ussl.wrap_socket(s, server_hostname=host)
        s.write(b"%s /%s HTTP/1.0\r\n" % (method, path))
        if not "Host" in headers:
            s.write(b"Host: %s\r\n" % host)
        # Iterate over keys to avoid tuple alloc
        for k in headers:
            s.write(k)
            s.write(b": ")
            s.write(headers[k])
            s.write(b"\r\n")
        if json is not None:
            assert data is None
            import ujson
            data = ujson.dumps(json)
            s.write(b"Content-Type: application/json\r\n")
        if data:
            s.write(b"Content-Length: %d\r\n" % len(data))
        s.write(b"\r\n")
        if data:
            s.write(data)

        l = s.readline()
        #print(l)
        l = l.split(None, 2)
        status = int(l[1])
        reason = ""
        if len(l) > 2:
            reason = l[2].rstrip()
        while True:
            l = s.readline()
            if not l or l == b"\r\n":
                break
            #print(l)
            if l.startswith(b"Transfer-Encoding:"):
                if b"chunked" in l:
                    raise ValueError("Unsupported " + l)
            elif l.startswith(b"Location:") and not 200 <= status <= 299:
                raise NotImplementedError("Redirects not yet supported")
    except OSError:
        s.close()
        raise

    resp = Response(s)
    resp.status_code = status
    resp.reason = reason
    return resp


def head(url, **kw):
    return request("HEAD", url, **kw)

def get(url, **kw):
    return request("GET", url, **kw)

def post(url, **kw):
    return request("POST", url, **kw)

def put(url, **kw):
    return request("PUT", url, **kw)

def patch(url, **kw):
    return request("PATCH", url, **kw)

def delete(url, **kw):
    return request("DELETE", url, **kw)

```

main.py
```
# my first project ..
import pycom
import time
from machine import Pin
import _thread
from dht import DHT
from network import WLAN
import urequests as requests
import machine
import time

TOKEN = "" #Put here your TOKEN
DELAY = 1  # Delay in seconds

wlan = WLAN(mode=WLAN.STA)
wlan.antenna(WLAN.INT_ANT)

# Assign your Wi-Fi credentials
wlan.connect("SSID", auth=(WLAN.WPA2, "PassWord"), timeout=5000)

while not wlan.isconnected ():
    machine.idle()
print("Connected to Wifi\n")


pycom.heartbeat(False)
pycom.rgbled(0x000008) # blue

# Type 0 = dht11
# Type 1 = dht22

th = DHT(Pin('P23', mode=Pin.OPEN_DRAIN), 0)
time.sleep(2)
avg = 20

def send_env_data():
    while True:
        result = th.read()
        pycom.rgbled(0x001000) # green
        while not result.is_valid():
            time.sleep(1800)
            result = th.read()
        print('Temp:', result.temperature)
        print('RH:', result.humidity)


        pycom.rgbled(0x7f0000) # red
        pybytes.send_signal(1,result.temperature)
        pybytes.send_signal(2,result.humidity)


_thread.start_new_thread(interval_send,[1800])


# Sends the request. Please reference the REST API reference https://ubidots.com/docs/api/
def post_var(device, value1, value2, value3):
    try:
        url = "https://industrial.api.ubidots.com/"
        url = url + "api/v1.6/devices/" + device
        headers = {"X-Auth-Token": TOKEN, "Content-Type": "application/json"}
        data = build_json("TEMP: ", temperature, "Humidity", humidity)
        if data is not None:
            print(data)
            req = requests.post(url=url, headers=headers, json=data)
            return req.json()
        else:
            pass
    except:
        pass

while True:
    temperature = result.temperature # Data values
    humidity = result.humidity # Data values
    post_var("pycom", temperature, 1, humidity)
    time.sleep(DELAY)

```



---

## Transmitting the data / connectivity
For this project, data is sent every 30 minutes (1800 sec), when the device is plugged in with micro USB. The choice of sending interval is based on the average temperature and humidity change. Usually, that doesn´t happen very often. Therefore I send data every 30 minutes.

The data is further transmitted to the internet through WiFi as a wireless protocol and MQTT as transport protocols. WiFi means that the wireless protocol can handle high data rates and also can consume a lot of battery power. 
My DHT11 sensor sends temperature and humidity values of low data rate (one byte per value) which means that I don´t need the big data rate advantage the WiFi gives. 



---

## Presenting the data
Until Now the data is only presented on pybytes dashboard which is partly nice I am still working on Ubidots connectevity and dashboards.

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


---

## Finalizing the design

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

My purpose with this project was to get a comprehensive understanding of IoT technology and how it works, which I did. I also gained knowledge of micropython coding, which I think is a neat thing to know.  Besides that, everything was new to me, which means that I developed a lot of valuable knowledge from this course and by doing this project.




 

