Try   HackMD

Tutorial on how to build an IoT Indoor Air Quality (IAQ) Monitor System

This is my first IoT project, and in this tutorial, I will show you how to build an IoT IAQ-sensor. This sensor was made during the course "Introduction to Applied Internet of things" at Linnéuniversitetet.

After this tutorial, you'll be able to gather and see visualizations of data that affects indoor air quality like Temperature, Relative humidity (RH), CO2 levels and tVOC levels (Total Volatile Organic Compounds)


Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Jonathan Undhagen (ju222cw)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
30min to 3h (depending on prior experience)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
€88.62 (USB cable, breadboard, and wires included)


Hardware used

  • Lopy4 (with headers) & Expansion board 3.0 from Pycom.
  • CCS811 Air Quality Sensor.
  • DHT11 Humidity & Temperature Sensor.
  • A Generic Breadboard.

Software and online services

  • Visual Studio Code IDE with PYMAKR plugin.
  • Pybytes IoT platform.

Objective

I chose to build this project mainly because I wanted to learn the basics of IoT sensors and platforms. But at the same time, I wanted to monitor the indoor air quality in our apartment as me and my partner both work and study at home right now during the covid19 pandemic. My plan is to give us more insight into healthy levels of CO2, temperature, and relative humidity. And then to use this data to manage air quality issues if we receive bad values.

Material

Hardware Price (in EUR)* Link
Lopy4 (with headers) €34.95 Pycom
Expansion board 3.0 €16.00 Pycom
CCS811 Air Quality Sensor €20.99 Conrad**
DHT11 Humidity & Temperature Sensor €5.24 Electrokit
Wirings & Extra Price (in EUR)* Link
10 x Jumper wires €3.10 Electrokit
Micro USB cable €2.03 Electrokit
Breadboard*** €6.31 Electrokit
Software Link
Visual Studio Code (or Atom) VS Code (or Atom)
Node.js Node.js
Pymakr plugin for your IDE Pymakr

In this tutorial, I used the LoPy4 device (Fig. 1) which is a device from Pycom. Their devices use the lightweight and fast scripting language MicroPython, got plenty of analog and digital in- and outputs and works with LoRa, Sigfox, WiFi, and Bluetooth connectivity.

The Expansion board is needed for connecting the device to your computer.

The breadboard is not mandatory but will make connections easier. We use this tool to connect the jumper wires to the modules and our pycom device.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
(Fig. 1. LoPy4 with headers.)
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
(Fig. 2. Expansion board 3.0.)


*As for time writing (2020-06-30). (VAT included)
**I'm using CCS811v1 from Joy-It, but other CCS811's will do as well!

Computer Setup

1. Setting up your IDE

My preferred IDE is Visual Studio Code, so that's what I'll be using throughout this tutorial. (You can use any other IDE of your liking. Atom for an example.)

If you haven't installed VS Code already, download it here.

Once you got VS Code running, install Node.js.

Now, get the Pymakr extension for VS Code. We'll use this extension to connect, run, upload, and download scripts to our device. Either download it via your browser here or follow these instructions:

1.1 Navigate to the extension marketplace.

You can do this either by pressing the icon in the left navbar:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Or by using the shortcut on Mac (⇧⌘X)

1.2 Search for Pymakrand click on the green button to install the extension.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This should only take a couple of minutes. And you might be prompted to reload VS Code when done.

1.3. When the extension has finished installing. This terminal will automatically pop up at the bottom of your IDE:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Don't worry about these errors just yet. We get these messages as we haven't connected to our LoPy4 device yet.
We will use this terminal to run, download and upload our code to the device.

1.4. Done! Let's set up our device!

2. Setting up your device

Go get your Expansion board. It should look something like this:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Now, pull out your LoPy4 device. It should look like this:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Now put the LoPy4 module on top of the Expansion Board with the reset button pointing towards the USB connector. It should firmly click into place and the pins should now no longer be visible.
When you're done, it should look like this:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


3. Register an account at Pycom's Pybytes platform.

Head to Pycom's Pybytes platform and register an account here.
Once you're registered. Head to the Pybytes platform here.

You'll we presented 4 choices:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

1. Click on 'CREATE PROJECT'.

  • Enter your project name and description. (You're able to change this later in project settings.) Click next.
  • Check the 'WiFi' box. Click next.
  • Add your WiFi credentials and then continue.

When your project is created. Click on it to continue.

2. Click on ADD VIA USB.

Now we get to choose between all these Pycom devices:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • Select LoPy4!
  • Now check the WiFi checkbox again. Click next.
  • Come up with a fancy name for your device, or use the one Pycom's generated for you. Then select your WiFi. Click Save.
  • Now you will be presented by this message:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Save this activation code! (blurred in this photo) We need it for the next step in this tutorial.

4. Upgrading your device

It is highly recommended that you upgrade your device firmware to the latest version as Pycom constantly is making improvements and adding new features. Please follow the instructions carefully.

  1. Download and install Pycom's Firmware Upgrade tool.
  • Windows
  • Mac (MacOS 10.11 or higher)
  • Linux (packages dialog and python-serial are needed)
  1. Close Visual Code/Atom and disconnect any other devices that might use your USB ports.
  2. Connect your device with your Micro USB cable to your computer.
  3. Run your newly installed Firmware Upgrade tool.
  4. Click 'next' until this window show up:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Locate your device in the "Port"-dropdown menu.
Check "Force update Pybytes registration" before you press Continue!

  1. The tool will now load and then you'll receive this prompt:

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    Remember the activation token we got before? Paste it here!

  2. You'll get to this 'Advanced Settings' section now:

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  • Choose the latest version of pybytes.

Don't worry about the rest of the settings for now. Click Continue.

Your device will now upgrade, and it might take up to one minute.

When it's finished. Click Done.

Putting everything together

Before we get into the connection phase:
This IoT IAQ system is aimed for personal use and our goal is to learn how to setup an IoT device. Therefore, this circuit diagram is used for a development setup. Let's continue!

1. Setup Breadboard

The breadboard is used to easily connect our sensors and pycom device with wires altogether. I preferably use red wires to 3V3, and black wires to GND.

Take a red wire and put one end in the "3V3" pin on your pycom device.
Put the other end in the first pin of the + row on your breadboard.

Take a black wire and put one end in the "GND" pin on your pycom device.
Put the other end in the first pin of the - row on your breadboard.

I will use these little tables in the next steps to show how to wire:

Pycom pins Breadboard
GND - row
3V3 + row

When you're done it should look like this picture:

  • All of the pins in your - row will now connect to the "GND" Pin on your pycom device.
  • All of the pins in your + row will now connect to the "3V3" pin on your pycom device.

2. Connect the CCS811 sensor

The CCS811 is used for measuring CO2 levels and tVOC.

Important! My CCS811 sensor may differ from yours. Please have a look at your sensor's datasheet before you continue.

Take 5 of your jump wire cables (remember black wire for GND and red for 3v3) and wire them like this:

Pycom device CCS811
3V3 (breadboard + row) 3v3 / Vcc
GND (breadboard - row) GND
P10 SCA
P9 SDL
GND (breadboard - row) WAKE

When you're finished it should look something like this:

3. Connect the DHT11

Now connect the DHT11 sensor. We will use this sensor to measure both temperature and relative humidity.

Important! Same thing here as with the CCS811 sensor, please look up the datasheet of your device before you move any further.

Take 3 jump wires this time and wire them by this scheme:

Pycom DHT11
P23 S
GND (Breadboard - row) -
3V3 (breadboard + row) +

Now everything should be connected. It should look something like this:

Before you plug in your USB, please look carefully if all the wires are connected correctly.

Platform

I've chosen Pycom's Pybytes platform to manage our device, store, and visualize my data. It's easy to set up and it is also cloud-based so you don't have to run any servers or databases on your local machine.

With the Pybytes platform, we're also able to create a dashboard with different types of charts to visualize our data. The dashboard isn't public, but it doesn't matter in this case as our project is only for personal use.

It's easy to add more pycom devices to Pybytes if you want to expand this project in the future. You're also able to integrate with other platforms as Google, Amazon, and Microsofts IoT platforms or create Webhooks if you want to.

The code

I've used two libraries for the sensors.

Then I've created two python files for reading our values.

This one for DHT11. I have named it dht_read.py.

from dth import DTH # Import DHT11 (yep it says dth here) library from machine import Pin # Dependencies from pycom import time def value(): th = DTH(Pin('P23', mode=Pin.OPEN_DRAIN), 0) # Type 0 = dht11 time.sleep(3) # Get some time to start up result = th.read() # Make a reading if result.is_valid(): # Return result if it is valid. return(result.temperature,result.humidity)

And this one for CCS811. I've named it ccs_read.py.

from machine import I2C # import I2C dependency from pycom lib. import CCS811 # import CCS811 lib. import time i2c = I2C(0) # create on bus 0 i2c = I2C(0, I2C.MASTER) # create and init as a master i2c = I2C(0, pins=('P10', 'P9')) # PIN assignments (P10=SDA, P9=SCL) i2c.init(I2C.MASTER, baudrate=10000) # init as a master ccs = CCS811.CCS811(i2c=i2c, addr=90) time.sleep(3) # Just to get it some slack starting up ... def value(): ccs.data_ready() # Start to make a reading co2 = ccs.eCO2 voc = ccs.tVOC if co2 > 10: # Only return non-faulty values. return(co2, voc)

And in our main.py file, we use both of these files to read and then send the values to Pybytes.

# Import dependencies import time from machine import I2C # Import defs from ccs_read.py and dht_read.py import ccs_read import dht_read while True: dht_TEMP, dht_RH = dht_read.value() # Extract temp and RH values from dht_read.value def and create new variables ccs_CO2, ccs_TVOC = ccs_read.value() # Same here, but with CO2 and tVOC from ccs_read.value def. # Print value in console. print('Temp:', dht_TEMP) print('RH:', dht_RH) print('CO2 level:', ccs_CO2) print('tVOC level:', ccs_TVOC) # Send to pybytes pybytes.send_signal(1, dht_TEMP) # Send a signal "1" to pybytes with our DHT temperature value. pybytes.send_signal(2, dht_RH) # Send signal "2" with our DHT RH value. pybytes.send_signal(4, ccs_CO2) # Send signal "4" with our CCS811's CO2 value. pybytes.send_signal(5, ccs_TVOC) # Send signal "5" with our CCS811's tVoC value. # Wait 1min before the next iteration. time.sleep(60)

My file structure looks like this before we upload it to our Pycom device:

Transmitting the data/connectivity

To upload our code to our device:

  1. Open the project folder in VS code.
  2. Before you plug in your USB, please look carefully if all the wires are connected correctly. Connect your device to your USB port on your computer.
  3. Once our device is connected and found in our pymakr console, click "upload" on the bar right under the terminal:
  4. This process could take a minute, once your done the code will run automatically. And data will be sent to our pybytes platform!

Our data is now transferred using the MQTT protocol over WiFi.
This was already set up for us when we activated our device earlier in this tutorial with our pycom firmware tool.

As seen in our code example recently (line 23 in main.py) our data is sent once every minute to the pybytes platform.

Presenting the data

Now that we're sending data to Pybytes, we're able to visualize it!

1. Select your project, then go to "Signals"

2. Now you'll have a bunch of "Undefined signals" in a box.

You can click on them to give the signal a name, and a unit.

In our code earlier, we sent specific data on specific signals. You can name these after this scheme:

Signal Name Unit
Signal 1 Temperature C
Signal 2 Relative humidity %
Signal 4 CO2 ppm
Signal 5 tVOC ppb

Now as we've defined our signals, let's add some charts to display our data!

3. Visualize your data!

Click on a signal to see data.

You'll now see a dull table by default. Click on "CREATE NEW DISPLAY".

Choose a display of your like. I'll use a bar chart in this example.

You'll now be able to customize your chart by giving it a name, set the pull size and time scale, etc.

Click on Create when you're done.

  • Now repeat these steps with your other signals!

4. Show charts on your dashboard!

Navigate to one of your charts, and click on edit.

Now tick the box that says "Display on Dashboard".

Repeat those steps with all your signals, and then go to your dashboard.

Now you'll be able to see all your charts on your dashboard!
Click on the organize button to customize the look to your likes.

Data is saved on pybytes every time we send a signal. This will then be saved for one month. You can set up an integration with other services if you send your data elsewhere, or if you want to persist your data. I won't cover integrations in this tutorial. But you can read about it here.

Finalizing the design

Our Indoor Air Quality Monitor System is now done!
My goal was to learn the basics of IoT sensors and platforms, but at the same time, monitor the indoor air quality in our apartment. This project isn't advanced at all however, I've learned alot. And I think that this is a good base to continue develop from. Maybe integrate with other services like Amazon AWS, or Google IoT. Maybe build a case for my device, or just to expand this device with more sensors.

I feel like this is a really simble but fun and beginner friendly way to get the hang of the very IoT basics. I think this project went great as I reached my goal, and that by the fact that I'm able to continue building this project. I could've made it more challenging by not using the pybytes platform or by using another protocol than WiFi (especially Sigfox or LoRa). I feel that I've got a hang of the basics for now, so I will absolutely continue to build more advanced projects in the future and maybe post some more tutorials!

Here we see my caseless device in action!

Thanks for reading!