# How to make a IoT thermometer, using LoPy4, MCP9700, and io.adafruit.com
This tutorial shows you how to set up a simple internet-connected thermometer, for remote monitoring of air temperature.
Estimated time: 1 hour
By: Joel Stenlund, js225qh
## Objective
The purpose of the project is to enable remote temperature monitoring of my summer house. It will be most useful in spring and autumn. During this period, the house is mostly empty, so it might be interesting and useful to be able to check the temperature remotely, before traveling.
## Materials
The following hardware is used:
- LoPy4 with extention board - WiFi, BT, LoRa and SigFox-enabled ESP32.
- MCP9700 - Temperature sensor with analog output. Datasheet can be found here: https://www.microchip.com/wwwproducts/en/en022289
- Breadboard and wires - For connecting the sensor to the microcontroller
- Power source (I used a 5V USB phone-charger)
Everything except the USB-cable and charger (which I already had) was sourced from http://www.electrokit.com, as a bundle, and cost 995 SEK
## Computer setup
This guide will focus on setting up a **Windows 10** machine with Visual Studio Code for use with the LoPy, and how to upload your project to the LoPy4.
### 1. Installing the required software
Before you download the IDE for this project, you will need to install Python on your machine (If you know you have python installed, you can skip this step)
Go to: https://www.python.org/downloads/ and download the latest version of Python, and install it on your machine.
You'll need Node.js to be able to run the correct plugins. Download the latest LTS version from https://nodejs.org/en/. Start the installer and follow the steps. Make sure you allow the installer to install the neccessary dependencies.

When the first installer is done, a new installer will appear. Continue through it until it is done.

You will need to install software to make a project for the LoPy4. In this tutorial, we will use Visual Studio Code. You can find it here: https://code.visualstudio.com/
Download the Windows 10 version and install it. When the installation is complete, start Visual Studio Code.
Click the extensions-tab  on the left side of the window. Search for **Python** and install the Python extension. When it is installed, search for the **PyMakr**-plugin and install it.
Now we are ready to create a project in Visual Studio Code. Create a folder on your computer. This will be the location of your project. Go to the explorer tab.  Go to file, and click **Add folder to workspace**. Find your newly created project folder and select it. The folder should appear in the explorer in Visual Studio Code.
Almost done! This project uses the umqtt-library to communicate with the IoT dashboard. Download it from here: https://pypi.org/project/micropython-umqtt.simple/
Create a new folder in your project, and name it **lib**. Extract **"simple.py"** from the umqtt-download into **lib** and rename it **"umqtt.py"**. Doing this will allow us to include this library in our Python project.
### 2. Installing drivers and updating firmware
Now that our software is setup, we need to update the firmware of our LoPy4. First go to https://zadig.akeo.ie/ and download the Zadig utility. I recommend using version 2.3, as the latest version gave me trouble when trying to use it. For the next step, the LoPy4-board must be disconnected from the expansion board.
Open Zadig and press Options -> List all devices

All USB-devices connected to your computer will be displayed. Now press and hold the button labeled **S1** on your expansion board, and, while holding the button, plug it in to a USB-port on your computer. After the USB-LED on the board lights up, release the button. Immediately look at the list in Zadig. You should se a new device, called **Unknown device**. After a few seconds, it will disappear again.
Scroll through the list to the left of the green arrow, and find libusbK.

The next step might be a little bit tricky, but don't give up!
Unplug your expansion board, and, while holding **S1**, plug it back in. Immedietly select **Unknown device** in Zadig, and click replace driver, making sure that libusbK is selected. You will get a message when you are successful.
When you have completed the install, verify it by pressing **windows-button + R** and typing **'devmgmt.msc'**. This will open the device manager. Do the button-and-plugin procedure once again, and look for a entry called **libusbK USB Devices**. There should be an entry under it that disappears shortly after plugging in the board.

While you have Zadig running, plug the board in and find Expansion 3 in the list in Zadig. Make sure it's listed Driver is **usbser**, if not, find **USB Serial** in the list to the left of the green arrow, and use Zadig to install it.

Next, go to https://pycom.io/downloads/ and find the **Firmware Updater** for windows, download, and install it. While installing it, unplug the expansion board, plug in the LoPy4 (the big white RGB-LED goes toward the USB-connector on the expansion board). Now you can plug in the USB-cable once more.
Start the **Firmware updater**. Follow the wizard until you reach the *communications* step:
Choose the correct COM-port, if you're unsure', go back to Device manage, look under the Ports-category, and find the COM-port that corresponds to **USB Serial Device** and proceed to the next step. The updater will download and flash your LoPy4 with the latest firmware. Once done, you may exit the updater and go back to Visual Studio Code.
### 3. Uploading code and libraries
In the explorer of Visual Studio Code, you should have a folder named lib, with a file named umqtt.py inside it. Go ahead and create a new file in the root folder of the project, called **main.py** and write a Hello world script:
`print ('Hello World')`
This will be the file that runs on your LoPy when it powers up.
Select PyMakr terminal at the top of the Terminal pane.

Open the command palette by clicking **All commands** in the bottom of the window, and select connect from the list that appears.

Once connected, open the command palette once again, and select **Upload project**. The files and folders in your project will be uploaded to your LoPy, and when complete, it will execute **main.py**, and print out 'Hello World' in the terminal window.
Time to connect the sensor to the board.
## Electronics
Find your MCP9700, a breadboard, and a few wires. Disconnect the USB-cable from any power source. Spread the legs of the MCP9700 carefully, so they fit the breadboard. Make sure each leg is in it's own row (marked with numbers, as opposed to letters). With the flat side of the MCP9700 facing you, connect the first pin from the left to **3V3**, the center pin to **pin 16** of of the extension board, and the right-most pin to **GND**. Double check your wiring, and then reconnect the extension board to your computer.
The schematic looks like this:


This is a developmental setup. Should you want to use this configuration long term, I recommend soldering up a perfboard.
## Platform
Time to look at our chosen IoT platform. We will be using http://io.adafruit.com for this project. It offers free and paid service, but we will stick to the free service for this project. The platform takes privacy and security seriously and works with a wide variety of hardware.
The free service will provide database and visualization in the cloud. More specificly, it gives us 30 data points per minute, 30 days of data storage and 5 feeds, which is more than enough for the purpose of this tutorial.
Simply create an account by following the steps on the website. Once your registration is complete, go to IO in the top bar of the page.
To have somewhere to send your data, create a feed. Go to the **Feeds**-page and click **view all**. In action, select **Create a New feed**

Name it, add a short description and press Create. You'll see your feed in the list. When opened, it is empty, Click **Feed Info** on the right side of the page.

At the bottom of the pop-up you'll see an entry named **MQTT by Key**, along with a text snippet that looks like
`username/feeds/feedname`
Copy the snippet and save it for later. We'll use it to tell our program where to send our data. You can always come back to this page if you lose it.
## Code
To get the thermometer up and running, copy the code below, and paste it into **main.py**.
```python
#import neccessary libraries
from umqtt import MQTTClient
from network import WLAN
import machine
from machine import ADC
import time
import pycom
temp_co = 10 #10mV/C as per datasheet
t_0 = 500 #typical figure from datasheet
#Calibration the voltage reference for ADC
# optional, but recommended, see https://docs.pycom.io/tutorials/all/adc/
adc = ADC(0)
adc.vref(1130)
#SETTINGS
#Pin that the sensor is connected to
ADC_PIN = 'P16'
#number of samples to be averaged
NUM_OF_SAMPLES = 5
#publishing interval in seconds
INTERVAL = 5
#WIFI CREDENTIALS
SSID = 'Snurr'
PASS = 'kebabtallrik'
#MQTT SETTINGS
CLIENT_ID = 'sysse'
MQTT_PLATFORM = 'io.adafruit.com'
USERNAME = 'sysse'
MQTT_KEY = 'aio_jvNJ19Qizo4eaXEXnsoKdOGcQW9N'
FEED = 'sysse/feeds/temp-olsboda'
#create a callback function
def sub_cb(topic, msg):
print(msg)
pycom.heartbeat(0)
#create a wlan object in client mode
wlan = WLAN(mode=WLAN.STA)
wlan.disconnect() #release wifi modem for connection, incase it was already being used.
wlan.connect(SSID, auth=(WLAN.WPA2, PASS), timeout=5000)
print("Connecting to WiFi")
while not wlan.isconnected():
machine.idle()
print("Connected to WiFi\n")
#Blink the RGB-LED green when connected to WiFi
for i in range (0,3):
pycom.rgbled(0x00ff00)
time.sleep_ms(200)
pycom.rgbled(0x00)
time.sleep_ms(200)
#create a client object
client = MQTTClient(CLIENT_ID, server = MQTT_PLATFORM, user=USERNAME, password=MQTT_KEY, port=1883)
#initialize the client, connect to the platform and subscribe to the specified feed
client.set_callback(sub_cb)
client.connect()
client.subscribe(topic=FEED)
#Create an ADC channel to read from
adc_c = adc.channel(pin = ADC_PIN, attn = ADC.ATTN_11DB)
#This is the main loop which will run indefinitely
while True:
#Take readings at set intervals and average them
temp = 0
for i in range (0, NUM_OF_SAMPLES):
time.sleep(INTERVAL / NUM_OF_SAMPLES)
vout = adc_c.voltage()
temp = temp + ((vout - t_0) / temp_co)
print('collected sample number: ', i+1)
#blink blue when taking a sample
pycom.rgbled(0x00000f)
time.sleep_ms(200)
pycom.rgbled(0x00)
#average and round the samples
temp = temp / NUM_OF_SAMPLES
temp = round(temp, 1)
print('temp is', temp, 'C')
#Publish the temperature to your feed
client.publish(topic=FEED, msg=str(temp))
#blink green when publishing
pycom.rgbled(0x000f00)
time.sleep_ms(200)
pycom.rgbled(0x00)
#Check the feed for the most recent message
#this is neccessary to keep the connection from going stale
client.check_msg()
```
Note that the code is commented through out, explaining what it does.
For the code to work, you'll need to change some settings. Take the adress of your feed that you copied earlier, and put it in the **FEED** variable, find your username and key by clicking the link called **Adafruit IO Key** in the top right corner of io.adafruit.com
Paste them into the **USERNAME** and **MQTT_KEY** variables respectively. It should look something like this:
```python
CLIENT_ID = 'some_name'
MQTT_PLATFORM = 'io.adafruit.com'
USERNAME = 'your_username'
MQTT_KEY = 'your_key'
FEED = 'username/feeds/feed_name'
```
The client ID isn't important, but can be useful if you add more devices later, so you don't forget which is which.
Once this is done, you're ready to upload. Save **main.py** and click **Upload** in the blue bar at the bottom of Visual Studio Code.

Visual Studio Code will upload any changes to your project to you board, and once it's done, you should see the board connecting to your WiFi, and then starting to take measurements and publishing them to your feed.

Go to your feed page and watch your data arriving!

## Transmission details
By default, you collect one reading per seconds, and published the average once per five readings. This is excessive for a thermometer, so I recommend turning down the rate using the **INTERVAL** variable. A value once per ten minutes is more reasonable. The most power is consumed when transmitting data, especially using WiFi, so less WiFi usage will result in longer battery life.
This project used WiFi, simply because, most of the time, it requires no extra hardware as most of us have a WiFi router set up already. It should be noted that compared to LoRa and SigFox, WiFi has shorter range, and uses more power.
The transport protocol is MQTT, which is a common IoT protocol supported by many platforms, and is ideal for sending small amounts of data.
## Dashboard
The database is built into the platform, and will save data when ever it is received, and stores it for a maximum of 30 days, when using the free service.
In io.adafruit.com, go to **Dashboards**, click view all, and under Actions, select **Create a New Dashboard**. Name your dashboard, and give it a short description. When done, open it and you'll see a blank canvas. To add a block to the dashboard, click the blue plus-symbol 
in the top right corner. I suggest starting with a Line Chart, to visualize change in temperature over time. Click the Line Chart and select your feed as the data source. Give your block a name, and name the axis. You can always come back and change your settings later, by pressing the green gear-symbol. .
Reload the page might see something like this:

## My final design
Here is what my finished dashboard looks like:

You can watch it live here: https://io.adafruit.com/sysse/dashboards/olsboda?kiosk=true
There is certainly room for improvement, but as a first IoT project, it turned out quite well. I will be extending the functionality of the project with triggers, to alert me when the temperature goes outside a specified range.