# Tutorial on how to build an IoT temperature and humidity thing
###### tags: `IDT305 LNU` `Tutorial` `IoT for beginners` `goinvent`
- Table of Content
[ToC]
> A beginners project on how to build your own IoT device for your home network.
### Overview of project
==The temp & hum Thingy== By Sofia Nordqvist, sn223di
This project consists of one sensor sending data, about tempterature and humidity, to internet with WiFi and visualized using Pybytes platform.
:::info
:hourglass_flowing_sand: Time to finish **approx. 8-16 h**.
Depending on your skills around electronics and computing as well as how lucky you are with firmware updates. Does not count for buying the components though a compleate BOM is provided in this tutorial.
:::
### Objective
- [ ] I choose to build this since I am completly new to microboards and wiring and wanted to learn the basics.
- [ ] My thought on this is to have a device as a core to build upon with more sensors to come. Maybe attach a LED programmed to show different colors depending on temperature.
- [ ] To monitor temperature and humidity you can gain insights on how this effect your mood for example if you compare and analyze the data with your own pulse. I placed device in a bedroom during days of quite high temperatures to monitor for fun but I could add a warning (push notice) if temp is above a set value or/and automatically start a fan or AC. Another area of use is to monitor your basement, vacation- or mobilehome.
### Material
In this project I work with the Pycom LoPy^4^ device programmed by MicroPython. The device has both digital and analog input and outputs so its perfect if you want to scale up your project. It can also connect to the internet outside of your home or WiFi if you use LoRa or Sigfox. See below for a complete BOM.


> Fig. 1 Expansionboard and LoPy from Pycom.
(Source Pycom)

> Fig. 2 Digital sensor DHT11 for temperature and humidity.
(Source Elektrokit)
**Bill of Material**
| IoT Thing | Description | Cost | Store|
| --------- | -------- | --- | ---- |
| LoPy^4^ | Quadruple bearer board. Works with LoRa, Sigfox, WiFi and Bluetooth | 365 SEK | [:link:][Pycom-Sync] Pycom |
| Expansion Board 3.1 | To be attached to the LoPy | 168 SEK | [:link:][exp-board-Sync] Pycom |
| Antenna | 868/915 MHz LoRa/Sigfox | 109 SEK | [:link:][antenna-Sync] Elektrokit |
| Adaptercable for antenna | To connect antenna to LoPy | 49 SEK | [:link:][antennacable-Sync] Elektrokit |
| Micro USB cable | Power supply | 49 SEK | [:link:][USB-Sync] Elektrokit |
| Breadboard | To fill up with sensors and LED to keep it neet | 59 SEK | [:link:][breadboard-Sync] Elektrokit |
| Wires | To connect sensor on breadboard, male/male | 33 SEK (30-pack) | [:link:][wires-Sync] Elektrokit |
| DHT11 | Sensor for temperature and humidity (digital) | 49 SEK | [:link:][dht11-Sync] Elektrokit |
| Powerbank | Mobile powersupply | 0 SEK | promotion gadget |
| Pycase clear | Box for neat packaging | 39 SEK | [:link:][pycase-Sync]m. nu |
| Wires | For use without breadboard, female/male | 29 SEK | [:link:][wires-case-Sync]Elektrokit |
[USB-Sync]:https://www.electrokit.com/produkt/usb3-0-kabel-a-hane-microb-hane-1-8m/
[breadboard-Sync]:https://www.electrokit.com/produkt/kopplingsdack-400-anslutningar/
[Pycom-Sync]:https://pycom.io/product/lopy4/
[exp-board-Sync]:https://pycom.io/product/expansion-board-3-0/
[wires-Sync]:https://www.electrokit.com/produkt/labbsladdar-100mm-hane-hane-30-pack/
[antennacable-Sync]:https://www.electrokit.com/produkt/adapterkabel-sma-u-fl-100mm/
[antenna-Sync]:https://www.electrokit.com/produkt/antenn-2-4ghz-5dbi-rp-sma/
[dht11-Sync]:https://www.electrokit.com/produkt/digital-temperatur-och-fuktsensor-dht11/
[pycase-Sync]:https://www.m.nu/pycom/pycase-clear
[wires-case-Sync]:https://www.electrokit.com/produkt/labbsladd-20-pin-15cm-hona-hane/
:::info
:bulb: **Hint:** You might also find the stuff at kjell.com or some at m.nu
Pycom has the [antenna kit](https://pycom.io/product/lora-868mhz-915mhz-sigfox-antenna-kit/) and [Pycase](https://https://pycom.io/?s=pycase) aswell if you choose to place an order directly with them.
:::
### Computer setup
- [ ] Install an IDE on your computer. The IDE is short for Integrated Development Environment and is the software for programming the device. Since LoPy is programmed with MicroPython I have choosen to install and use the software [:link:][Atom-Sync]Atom as IDE on my PC, running on Windows 10. (For Pycom hardware you can also use VScode). This doc will help you get started https://docs.pycom.io/pymakr/installation/atom/
- [ ] Open Atom and install the package for Pymakr plugin and you will be all set to write and run your code directly on your LoPy when connected to USB.
[Atom-Sync]: https://atom.io/

> Fig. 3 This is Atom with the REPL (read–eval–print loop) interface for Pymakr plugin. This gives you direct access to your LoPy.
### Putting everything together
- [ ] Assemble and connect everything to the expansionboard. A good idea is to follow the documentation on pycom https://docs.pycom.io/gettingstarted/. Be careful so that you mount the LoPy the right way as seen in diagram below. Micro USB connects to expansionboard, be gentle when handle with components, they are delicate.
Now you can connect the sensor, fig. 4. When connecting a sensor, **always check the datasheet** for correct voltage depending on sensor. DHT11 could connect to 3V-5,5V. In this case when only one sensor is used you could skip the breadboard if you like and use jumper wire female/male to connect the sensor directly. But it is a good idea to use the breadboard while prototyping and you have the opportunity to add stuff in a neat way as you go along.
This sensor is connected to P23 and for a complete schema of pinout see this doc https://docs.pycom.io/gitbook/assets/lopy4-pinout.pdf

>Fig. 4 Circuit diagram. Black for ground, red for current and green for data.
:::info
:bulb: **Hint:** Notice how you mount the sensor in row 1, 2 and 3 (as this one has 3 pins). Then you have connection to this on a-e. In this case I choose to connect in c.
:::

> Fig. 5 Okay, plugged in and ready to launch!
:rocket:
Since I had some trouble getting connected with my Pycom I did install [Node.js](https://https://nodejs.org/en/download/), switched to different USB port and installed the Pycom firmware update. To finally get things up and running I logged in to Pybytes, added a new device and set up a WiFi connection right there. After this step I could run the update of firmware. By now when you open Atom your device should be found and connected to the computer. I downloaded the files that was created automaticly in Pybytes and saved on my computer in a project map. Best practice is to have a project for each new prototype and have a neat folderstructure for your files and libs. After downloading the files from Pybytes this is what you should have on your LoPy and in a map on your computer:

> Fig. 6 Files on your device.
A nice way to testdrive connection with your device is by writing the following code in main.py to turn off the LED on Lopy^4^ (heartbeat) and blink with RGB instead, now you know if it works. It did for me, yejj! :tada:
```phyton=1
# main.py
import pycom
import time
pycom.heartbeat(False) #turn off blue blinking LED
while True:
pycom.rgbled(0xFF0000) # Hex for Red
time.sleep(1)
pycom.rgbled(0x00FF00) # Hex for Green
time.sleep(1)
pycom.rgbled(0x0000FF) # Hex for Blue
time.sleep(1)
```
>Have some fun playing around with colors. Just pick a color of your choice from here https://htmlcolorcodes.com/color-picker/ or any other colorpicker that gives you the hex color code.
Add more colors to create a blinking rainbow :rainbow:
### Platform
In this project I have used [Pybytes](https://pybytes.pycom.io/) platform but there are lots of other platforms, both local and cloud based to send your data to. As our house has a NAS with Docker I would like to try a local installation with a [TIG stack](https://www.youtube.com/watch?v=kimH1ENvalg) in the future. Another fun option to consider would be to fetch the data to Domoticz. To scale this Thingy up I would look into our FTX ventilation system and se if it can connect with modbus to make a smart integration for temperature control.
### The code

> Fig. 7 Projectfolder. This is best practice for a set up. Use a separate folder for lib.
The json-file is automatically created by [Pybytes](https://pybytes.pycom.io/) and holds all sorts of data about network connection and so on. No need to change anything in this file. You only need to write code in main file and create a library for this specific sensor (which you hopefully find on Github).
The following Python code needs to be written in your main file:
```phyton=1
#main.py
import time
import _thread
from machine import Pin
from dht import DHT # get code from library dht
th = DHT('P23', 0) # Type 0 = dht11
time.sleep(2)
def send_env_data() #loop to fetch and send data
while True:
result = th.read()
while not result.is_valid():
time.sleep(.5)
result = th.read()
print('Temp:', result.temperature) # print temp in REPL
print('RH:', result.humidity) # prints RH in REPL
pybytes.send_signal(1,result.temperature) # send signal to Pybytes
pybytes.send_signal(2,result.humidity) # send signal to Pybytes
time.sleep(5) # sleep for 5 sec
_thread.start_new_thread(send_env_data, ())
```
Below is the library code. Put this in folder /lib
Sourcecode used from https://raw.githubusercontent.com/JurassicPork/DHT_PyCom/pulses_get/dth.py
```phyton=1
#dht.py
import time
import pycom
from machine import enable_irq, disable_irq, Pin
class DTHResult:
'DHT sensor result returned by DHT.read() method'
ERR_NO_ERROR = 0
ERR_MISSING_DATA = 1
ERR_CRC = 2
error_code = ERR_NO_ERROR
temperature = -1
humidity = -1
def __init__(self, error_code, temperature, humidity):
self.error_code = error_code
self.temperature = temperature
self.humidity = humidity
def is_valid(self):
return self.error_code == DTHResult.ERR_NO_ERROR
class DHT:
'DHT sensor (dht11, dht21,dht22) reader class for Pycom'
#__pin = Pin('P3', mode=Pin.OPEN_DRAIN)
__dhttype = 0
def __init__(self, pin, sensor=0):
self.__pin = Pin(pin, mode=Pin.OPEN_DRAIN)
self.__dhttype = sensor
self.__pin(1)
time.sleep(1.0)
def read(self):
# pull down to low
self.__send_and_sleep(0, 0.019)
data = pycom.pulses_get(self.__pin,100)
self.__pin.init(Pin.OPEN_DRAIN)
self.__pin(1)
#print(data)
bits = []
for a,b in data:
if a ==1 and 18 <= b <= 28:
bits.append(0)
if a ==1 and 65 <= b <= 75:
bits.append(1)
#print("longueur bits : %d " % len(bits))
if len(bits) != 40:
return DTHResult(DTHResult.ERR_MISSING_DATA, 0, 0)
#print(bits)
# we have the bits, calculate bytes
the_bytes = self.__bits_to_bytes(bits)
# calculate checksum and check
checksum = self.__calculate_checksum(the_bytes)
if the_bytes[4] != checksum:
return DTHResult(DTHResult.ERR_CRC, 0, 0)
# ok, we have valid data, return it
[int_rh, dec_rh, int_t, dec_t, csum] = the_bytes
if self.__dhttype==0: #dht11
rh = int_rh #dht11 20% ~ 90%
t = int_t #dht11 0..50°C
else: #dht21,dht22
rh = ((int_rh * 256) + dec_rh)/10
t = (((int_t & 0x7F) * 256) + dec_t)/10
if (int_t & 0x80) > 0:
t *= -1
return DTHResult(DTHResult.ERR_NO_ERROR, t, rh)
def __send_and_sleep(self, output, mysleep):
self.__pin(output)
time.sleep(mysleep)
def __bits_to_bytes(self, bits):
the_bytes = []
byte = 0
for i in range(0, len(bits)):
byte = byte << 1
if (bits[i]):
byte = byte | 1
else:
byte = byte | 0
if ((i + 1) % 8 == 0):
the_bytes.append(byte)
byte = 0
#print(the_bytes)
return the_bytes
def __calculate_checksum(self, the_bytes):
return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255
```
### Transmitting the data / connectivity
Every 10 minutes data is sent to [Pybytes](https://https://pybytes.pycom.io) using syntax `pybytes.send_signal()`
Depending on powersupply and network you need to consider how frequent you send the data. Maybe every hour is sufficient in this case if you run on powerbank or battery for a longer time.
In this project WiFi is used to send data but the LoPy^4^ and this sort of antenna can handle both LoRa and Sigfox if you happen to have access to that.
To transport data from the device to internet (in this case to [Pybytes](https://https://pybytes.pycom.io)) the MQTT protocol is used, mqtt.pybytes.pycom.io

>Fig. 8 In the REPL you can see that it is connected to MQTT (Message Queuing Telemetry Transport).
### Presenting the data
To visualize the data I have created a dashboard in [Pybytes](https://https://pybytes.pycom.io). One for each signal, temp and humid. You have to define a new signal for 1 and 2 to make it show up. Play around with the settings for the graphs to get a look that you like. I also choose to show data receieved, in this case 8 bytes for each signal, fig. 9.
The data will be saved for one month in Pybytes database. If you want to save your data longer one option is to set up a webhook (which you can do in Pybytes aswell using for example [webhook.site](https://webhook.site)).

>Fig. 9 Screenshot of Pybytes Dashboard.
### Finalizing the design
I think this project is a pretty good beginning for an IoT device. I have bought another sensor for temperature, [LM35 temperature sensor](https://https://www.kjell.com/se/produkter/el-verktyg/arduino/tillbehor/luxorparts-temperatursensor-lm35d-2-pack-p90488) with more accuracy, +/-0,4 C, than DHT11 which is +/- 2 C. My plan for that is to be able to measure temperature with more accuracy, such as bodytemperature.
I think the project went pretty smoothly and here are some points that I have learned:
* Be sure how to assamble the sensor, with breadboard, wires and pins on expansionboard. Unfortunatly some compontents can be damaged if not handled correctly.
* Always be prepared for debugging both computer setup and MicroPython code (and be patient).
* You might get geeky as you discover all possibilities that IoT gives you.
* Focus on your project and don´t get distracted by all possibilities. Take it one step at a time. This is a good start!
* Be imaginative!
:::info
:bulb: **Hint:** Use Jupyter Notebook to testwrite and run Python code. This would come in handy as you develop.
Download from [anaconda.com](https://www.anaconda.com/products/individual)
:::
:::warning
**Fig. 10 Finally the device in action:
==The temp & hum Thingy==**

> Neat placement in a case makes it easier to handle and move around.
I used this very short [videotutorial](https://www.youtube.com/watch?v=TvftS9hpKpE) to put things the right way in the case.
[color=#a7bf9f]

> Here I dropped the breadboard to prepare for mounting in the Pycase. (Use male/female jumper wires).[color=#a7bf9f]

> The original state with breadboard and a powerbank instead of connected to computer.[color=#a7bf9f]
:::
---
> Hope you enjoyed this tutorial and happy building your own IoT project to explore things further! :rocket:
[color=#e35b88]
Check this out to create your own tutorial ➜ [HackMD Tutorials](https://hackmd.io/c/tutorials)