# Temperature visualization using PySense ## Tutorial in IoT ### Anton Andersson | aa225pj This tutorial aims to describe and show how to create a temperature visualization tool. There are many ways to easily create a similar product, but this tutorial will handle the usage of a Pysense developement board with a fipy expansion board. This board runs on MicroPython and is thus very popular in these applications. Adafruit IO was used to visualize and log the temperature data, which came from a sensor (MCP9700) connected through a breadboard. Starting of completely fresh, knowing nothing about Internet of Things, development boards, circuitry and programming you would need a month in estimate to research, order and develop a product like this. For IoT and technology enthusiasts, maybe 4 hours. --- ### Table of contents [ToC] --- ## 1. Introduction of objective My apartment gets very hot in the summers, so the initial plan was to create a climate control system. I wanted to accurately and remotely read the temperature in my room all year around and based on that information turn on either my heaters or roof fans automatically. They are both connetcted to the internet so I felt that a temperature reader was the last step to a completely smart climate system. Based on the deadline set, I opted to develop the temperature reader now and leave the actual climate controlling for a future project. It it also very cool to just be able to see my temperatures online at all times. ## 2. Materials used I bought a 'FiPy and sensors bundle' from Electrokit that was 1499SEK, listed below, in hopes of it making it easy for me to get started. It was also a great choice because it had both a MCP9700 temperature sensor (Fig. 1) included along with the PySense 2.0x (Fig. 2) - which has Temperature and humidity built in to the board. *Higlighted is what was used for this project.* – ==PySense 2.0x Development board== – ==FiPy with headers – Expansion board== – Antennae – ==Micro USB cable== – ==Jumper wires== – ==Breadboard== – 10 x Resistor 1 kohm – 10 x Resistor 10 kohm – 10 x Resistor 330 ohm – 10 x Resistor 560 ohm – 5 x LED red – 5 x LED orange – 5 x LED green – 2 x LDR – Tilt switch – ==Temperature sensor MCP9700== – Hall-effect sensor TLV49645 – Magnet ![](https://i.imgur.com/LzZZkOx.png =200x300) *Fig. 1: PySense 2.0x* ![](https://i.imgur.com/eKpaAze.png =300x200) *Fig. 2: FiPy* ![](https://i.imgur.com/m0J3myl.jpg) *Fig. 3: MCP9700 temperature sensor* ![](https://i.imgur.com/pNX7Ur0.jpg =250x250) *Fig. 4: Breadboard* ![](https://i.imgur.com/BjJDgOJ.jpg =200x250) *Fig. 5: Jumper wires* The ==Development board== is what you program to run your code, it recieves and feeds data and power to the rest of the system. The *PySense* even has 4 built-in sensors to give you an easy platform to experiment on. The ==Expansion board== adds extra functionality to what the dev. board offers. With the FiPy you get 5 bands of connectivity and a wide range of different input and output pins (digital and analog) that is very suitable for a wide range of IoT applications. The ==expansion board== (FiPy) usually sits on top of the ==devevelopment board== (PySense). Leaving it mounted here occupies all the slots of the expansion board though and since we need access to the external sensor we need to use a ==breadboard== (Fig.4). The expansion board (FiPy) can be *mounted on top of the breadboard* and the usual connections made when having it mounted on the dev. board now has to be made with ==jumper wires== (Fig. 5). Each hole on every row on the breadboard is connected to all the other holes of the same row, which makes it possible to connect several sensors to a single port, since all of the columns of a row are connected. The power and ground get their own lanes that span the whole length of the board - this is so that you can power several things from the same power source and ground. The ==sensor== reads the temperature and is also mounted on the breadboard and connected to power, ground and the appropriate pin of the expansion board with jumper wires. How everything is connected can be seen in section **Assembling the hardware**. ## 3. Computer Setup The computer used in this project was running *macOS*, which actually posed little to no effect on the replicability of this project. The first step when connecting the pySense and FiPy to your computer is updating the firmware of both the boards. Make sure your USB-cable can handle transferring data. Pycom makes the *Pycom Firmware Update*-tool, which automatically updates the boards for you. I had hours of trouble trying to get this to work and had to manually update it through the *Terminal* of my MacBook, shown below: **Updating the development board firmware**: - Download your boards Device Firmware Update (DFU) file online. - Install *Homebrew*, which is a package manager for macOS. - Run: *'brew install dfu-util'* - Navigate the terminal to the folder where you downloaded the .dfu file to. 'ls' to list the contents of the current directory, 'cd' to move up or down in the folder hierarchy and find the .dfu file. - Unplug the device - Remove the development module - Press and hold the S1/MCLR button on the device. **Updating the expansion board firmware**: - Downloading the *Pycom Firmware updater* - Unplugging the extension board - Unplugging the device from the computer and putting it in *boot mode* - Pressing the *memory clear* button while inserting the USB-cable again - Start the updater withing 7 seconds - Plug in the USB cable - Run the DFU-util code (below) within 7 seconds - '*sudo dfu-util -D ==pytrack_0.0.8.dfu==*' where you change the ==file name== to match your own. When this is done you it is always good practice to try and run some simple code, to see if there are any errors. ### *3.1 - IDE* I already had ==*Atom*== dowloaded on my computer since I have been developing in Python before, for digital applications. I made sure that ==*PyMakr*== was installed among the plug-ins and after that it was pretty much plug-and-play. I made a simple disco light that switched between all the colors of the rainbow to test the basic connectivity and functionality of the board. ## 4. Assembling the hardware Below you can see how the wires, devices and sensor circuitry was all connected to each other. As you can see this configuration is very exposed and thus exposed to spills, bumps and nosey neighbors. It is therefore important to note that this is mainly meant to be used during testing, a finalized product would need a much higher degree of robustness to be considered useable. ![](https://i.imgur.com/2qKSEzm.png) *Fig. 7: The circuit diagram* In order to feed 3V of power to the pin connected to the sensor (red wire) the main power from the PySense needed to be connected to the FiPy, which is the leftmost wire. The green wires are for ground and it is basically just a serial connection from the ground of the PySense to the ground pin on the sensor, through the ground pin on the FiPy. The middle pin of the analog sensor is what feeds the information and it is thus connected to a ADC input-only pin (blue wire). We also make sure to connect the UART_Rx, UART_Tx, SDA and SCL pins to each other through their coresponding pins in order for the devices to talk and function properly. ## 5. Platform PyCom has a very user friendly tool that makes visualization both easy and fun, *PyBytes*. This can be finicky to use. I didn't manage to get it working after several hours, but the code I could salvage from it made a very solid start for the code used in the boot.py file to connect my devices to wi-fi. Instead I opted for *==Adafruit IO==* because of how neatly it provides MQTT connectivity to your IoT project. Adafruit IO is a cloud service, which means it will be up and running regardless of how your personal computer is doing. It might not be retrieving any posts, but it is online when you aren't. The best thing about Adafruit for someone trying out IoT is that they offer a very appealing free subscription to their services: – ==**30** data points per minute== – ==**30** days of data storage== – ==Actions every **15** minutes== – ==**5** dashboards== – **2** WipperSnapper devices – **5** groups – **10** feeds *Moving forward with this project*, if the goal is to enable users to buy a product and have it connect, write and function properly against the cloud, then you would need to look at different platform solutions. But as long as there is a computer available to do the posting and processing, ==30 days of free data storage with a frequency of 30 times per minute should be more than enough for both a temperature sensor and ultimately a climate controller.== ## 6. Code Coding in python ensures proper indentation compared to a language like C++, where code stacking is done using "{}". A lot of effort was put into making my code readable and almost every line was commented - because you might not understand why you did something when you look back at the code after some time has passed. I wrote a ==boot.py== file that runs everytime the board reboot's, which was mainly used to automatically establish a wi-fi connection after a reboot. I wrote a ==*MCP9700 class*== that collects the temperature measurements from the sensor to be imported into my main.py. I used an exsisting ==*MQTT class*== to connect the device and its sensor to the Adafruit IO cloud service and send sensor data in for later visualization. I wrote the ==main.py file== in small steps at a time. First making sure a stable wi-fi connection was established. Then I tested the sensor and looked over its class code. I made an offline program that simply read in data from the sensor and wrote a temporary sensor test where the LED of the PySense device changed colors based on the sensor data: *– Blue for temperatures below 20 degrees celcius. – Yellow for temperatures between 20-30 degrees celcius. – Red for temperatures above 30 degrees celcius*. These will play an important role in my visualization, which is handled in the following two sections of the tutorial. ## 7. Transmitting data As mentioned before I opted for AdafruitIO because of how neatly it provides MQTT connectivity to your IoT project. This, together with a great tutorial, gave me everything I needed to start sending my sensors data to the Adafruit servers for visualization. To not overflow the servers I chose to send data every 10 seconds, which is more than adaquate for this purpose. Adafruit states in their data policies that the maximum allowed write frequency for non-paying users to their servers is 30 times per minute. ***Some code used:*** ```javascript=1 from network import WLAN # Wi-Fi network import time # Allows time.sleep() import pycom # Base library from mqtt import MQTTClient # MQTT protocol use import machine # For hardware components from machine import Pin # LED pin addressing from machine import ADC # ADC objects from mcp9700 import MCP9700 # Sensor import ``` ***Code 1:** Importing standard libraries and class functions.* ```javascript=16 WIFI_SSID = "4G-Gateway-D20E99" # 2.4 GHz Wi-Fi WIFI_PASS = "5vG4E52H" # Password ``` ***Code 2:** Wireless network authorization.* ```javascript=21 AIO_SERVER = "io.adafruit.com" AIO_PORT = 1883 AIO_USER = "AntonArson" AIO_KEY = "aio_aStC331Z8OWkP1E2U0N40Rr2gihs" AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id()) AIO_CONTROL_FEED = "AntonArson/feeds/lights" AIO_RANDOMS_FEED = "AntonArson/feeds/randoms" ``` ***Code 3:** Configuration for Adafruit, found in a tutorial online.* ```javascript=86 adc = ADC(bits=12) pin = 'P16' # Which ADC pin used led = Pin('P22', mode=Pin.OUT) # Used LED pin as output temp = MCP9700(adc, pin) # read from pin while True: print(temp.read()) # change color of LED if temp.read() > 30: # temp > 30 pycom.rgbled(0xFF0000) # Red if temp.read() < 20: # temp < 20 pycom.rgbled(0x0000FF) # Blue if 20 < temp.read() < 30: # temp between 20 and 30 pycom.rgbled(0x00FF00) # Green ``` ***Code 4:** Sets the correct pin to be read and changes the LED behaviour based on the value returned from *temp.read()* which is a class call to mcp9700.py* ```javascript=86 send_number = temp.read() ``` ***Code 5:** Sets the temp value to be posted to Adafruit servers.* ```javascript=88 try: client.publish(topic=AIO_RANDOMS_FEED, msg=str(some_number)) print("DONE") ``` ***Code 6:** Tries to send the temperature data.* All output and data sent was also printed in the console log to make it easier to keep track of what is going on in the system. Possible future problems with writing/ sending/ posting to the MQTT cloud can then be narrowed down very quickly, just by taking a glance at the latest values in the IDE console and compare it to the Adafruit IO interface. ## 8. Presenting data Below (*Fig. 6*) you can see the data posted from my sensor to AdafruitIO. This data is saved with every post from our MQTT connection, each feed also saves the data for 30 days before it is archived. ![](https://i.imgur.com/eu8bLBf.png) Fig. 6: The Dashboard, AdafruitIO. Looking at the figure you can see the graph visualizing the teperatures posted by my program. It is set to show a history spanning 2h of readings. While it is running, with a stable connection, the LED on the development board has a green light. I added at toggle switch for the user to turn this off, in case you want to do long term readings, get annoyed by it or just want to preserve the life span of the LED. Three indicators can be seen that turn on or off based on the value of the last temperature posted. ==*Can you guess at which time I chose to move my sensor from the middle of my room to my window sill, where the temperatures are lower?*== ## 9. Final product ![](https://i.imgur.com/P2B2fP8.jpg) *Fig. 7: The boards connected to the sensor, sending data to the AdafruitIO seen on the screen. The light is green since there is a stable connection with uninterrupted data transfers.* As someone with years of experience in programming I thought this project would be an easy task. To be fair, when it came to programming things went pretty smooth. I needed to use my prior knowledge both in python, package handling and typescript. This project heavily relies on hardware knowledge, circuitry and a little bit of luck. At several times I had no idea what was wrong, which was only fixed by firmware flashing 3-5 times. This is annoying since after all of these years of learning how to program, at least the hardware and its software should work properly when running my code. I searched online and many people face similar problems/ bugs/ abnormalities. It is a finicky product which takes patience and passion to master, but when you do - there really is no limit to what you can automate, monitor and connect to the Internet. :atom_symbol: ## 10. Final thoughts I had other obligations during the full length of this project. If I knew that it was going to be this time consuming and information-, research- and code heavy I might had been scared off. But pushing myself and trying to puzzle together this project, work and finishing up a bachelors, has been very fun. What I mean is that my project has so many areas to build onto in the future and I now have the right skills, experience and tools to dwell deeper into IoT. :rocket: --- ###### `PyCom, PySense, FiPy, Adafruit IO, MicroPython, IoT, LnU, 2022`