# **A temperature sensor that senses often but transmits rarely - A proof of concept**
Oskar Pålsson op222fh
This project describes the process of connecting a FiPy and a PySense and set them up to sense temperature once every hour and transmit it via mqtt to three different Adafruit IO feeds once per day. These will then be displayed on a dashboard.
Depending on the amount of troubleshooting you have to do, I would approximate the time to set it up would be 4-6 hours.
# **Objective**
This project was inspired by the MoleNet example used in one of the early presentations in this course. In this presentation we could see that sensing draws significantly less power than actually transmitting the data. This got me thinking of what useful project I could do for my own home that could give me meaningful information without needing real time updates.
The purpose is to give information that helps me to, for example, decide when I can move my plants out on the balcony or when to take them inside. It also gives me general temperature information about the climate on my balcony. The idea is to collect the temperature once per hour then to, once per day, transmit the highest temperature of the day, the lowest temperature of the day, and the average temperature of the day to three different feeds and display them on a line chart.
Since I'm completely new to IoT my goal with this project was to gain basic insights into the hardware and how collecting and transmitting data works. While working with the project I got a lot of ideas of improvements to the project and how to make it more useful. However I decided to get something simple to work for this course, and will discuss remaining work and the challenges I had during setup in this tutorial. This is why I called the project a "Proof of Concept".
# **Material**
I bought a [FiPy and sensors bundle from Electrokit for 1499 SEK](https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-fipy-and-sensors-bundle/), which for this year came with a PySense. The FiPy is the microcontroller which we upload our code to, and the PySense is like an expansion board containing a few different sensors. Even though I tried some different sensors in the workshops I ended up using only the FiPy and the PySense in my project. Pictures courtesy of the Pycom documentation below.

FiPy

PySense
# **Computer setup**
I chose to use the Atom IDE on my Windows computer. Resources on how to install what's required to use this computer setup aswell as to update the firmware of your devices are covered below.
**Installing the Atom IDE and other relevant things to your computer**
This was done during a workshop, there is a good explanation on the LNU Youtube channel [here](https://www.youtube.com/watch?v=YjeQ934ar7Q&list=PL70wNv4dBdJzuVMTC3OL6YPnENS8Y7TKn&index=21).
The tools I installed according to instructions in this video are:
* Atom IDE with pymakr plugin
* Node.js (necessary to be able to use pymakr on Windows)
**Firmware**
Once this is done you also need to flash your microcontroller, clear instructions for this are found in the course tutorial [here](https://hackmd.io/vvlH0y1WRLes90KeCc5uPA#Windows-OS)
When you have done this, you should be able to open Atom, connect your device and see it appear. You can then write your code in Micropython and upload it to your device using the ctrl+alt+s command.
To get my PySense to work properly together with the libraries I also had to update the firmware of this. This was a bit more tricky and requires fast fingers. Guides can be found in the Pycom documentation, I found it helpful however to view a video of it which was linked on the course Discord. This video can be found [here](https://www.youtube.com/watch?v=FkycTZvj-ss) on Core Electronics Youtube channel.
# **Putting everything together**
There is not much to this part when using the PySense. The FiPy is placed into the PySense, and then you're done. For a development setup this was a nice and easy way to get going with development.
For production use there are a few things I would change. I would use an external temperature sensor and place it some distance from the FiPy since the FiPy heats up the sensor quite a bit at the moment. We did this during one of the workshops in this course, but I decided to keep it simple and avoid having unnecessary wires laying around during the course. It was also a nice learning experience to get the PySense to work after we got help with the external temperature sensor to work.
I could also 3d print a case for the FiPy to make it more weather resistant, however the way I would do it is probably to attach the FiPy as it is to the wall inside and have the sensor outside with the wires between them running through a window or door crack.
# **Platform**
I decided to use Adafruit IO, it looked like a simple way to visualize my data points on a line graph by sending them to a cloud service. The free alternative works well for my needs. I just want to see general trends for low/high/average temperature and Adafruit free version data expires after 30 days which is not a problem. If I wanted to save data for longer to for example, see what time last year there were no temperatures under 0 degrees C on my balcony, i would look into another solution.
[The course tutorial for Adafruit](https://hackmd.io/@lnu-iot/ByPRkQTF9) also offers an introduction to web hooks where you can toggle a button in the Adafruit dashboard and turn on/off the LED on your device which was a nice learning experience. This was not used further in the project however.
# **The code**
Below code snippet is the main loop of the program. During development I've been sensing data every 10 seconds and transmitting data every time the minute changes. This makes the device pretty much a regular temperature sensor, since the average, low and high temperature during the latest minute wont differ that much from eachother. The current date/time are fetched via [NTP](https://docs.pycom.io/tutorials/networkprotocols/ntp/) which was a nice way to do this that was posted in the course Discord.
The main loop prepares the date/time and temperature variables aswell as transmits the data when the nested loop exits.
The nested loop:
* Keeps track of the highest/lowest temperature since last transmission
* Keeps track of the average temperature since last transmission
* Decides when to transmit the data next (the loop condition)
```
while 1:
time1 = time.localtime()
hour = time1[4] # gets the current minute
latestHour = hour
i = 0
high = si.temperature()
low = si.temperature()
avg = 0
while latestHour == hour:
print("Sensing...") # loops until the current minute changes. Decides when to send
currentTemp = si.temperature()
if currentTemp > high:
high = currentTemp
if currentTemp < low:
low = currentTemp
avg = avg + currentTemp
i = i+1
time.sleep(10) # Decides how often to sense
time2 = time.localtime()
latestHour = time2[4] # updates the current minute
print("Sending...")
send_low(low)
send_high(high)
send_average(avg/i)
**TODO**
The goal setup is to sense every hour and to transmit every time the date changes. The changes to achieve this is to fetch index 3(hour) instead of 4(minute) from the local time as well as setting time.sleep to 3600. Tries on lengthening the sensing/transmission has been done during development but I find that when doing this, the transmissions don't end up in the Adafruit feeds even though I get an OK from my send functions. Troubleshooting this to the end has not been done due to the time the device has to run for for the problem to appear.
To minimize the energy the device uses I would also like to use machine.sleep or machine.deepsleep to power down when the device is not doing anything. I only tried this briefly and did not go deeper into troubleshooting why it didn't work instantly.
**The rest of the code**
The setup of the connection has been done a few different ways in the workshops of the course but it's currently implemented as mentioned in the example code of [Tutorial Part 4](https://hackmd.io/@lnu-iot/ByPRkQTF9). If I got the machine sleeps to work properly I would probably have to move the network setup to the boot file in order to reconnect on wakeup.
The libraries used in this project are:
* MQTT library from the course tutorial, [link here](https://github.com/iot-lnu/applied-iot/blob/master/network-examples/mqtt_ubidots/mqtt.py)
* Pycoproc_2 and SI7006A20 (temperature sensor of the PySense) libraries from Pycoms Github repository, link [here](https://github.com/pycom/pycom-libraries/tree/master/shields/lib)
Information on how to use a library can be found on the course tutorial [here](https://hackmd.io/@lnu-iot/BJnuGmJh_#How-to-import-library)
# **Transmitting the data / connectivity**
I decided to use Wi-Fi to send data via MQTT to Adafruit IO since that seemed to be an easy way to get going with the course and the intended placement of the device is within Wi-Fi range. I had no issues connecting to Wi-Fi and adding my Adafruit IO keys to send the appropriate data to the appropriate feed using the course guides [here](https://hackmd.io/@lnu-iot/SJ8TGsUd5) and [here](https://hackmd.io/@lnu-iot/ByPRkQTF9#Project-Code-Publish-amp-Subscribe-To-Adafruit-MQTT-Server).
From the sample code in the course tutorial on sending data to Adafruit IO I made 3 copies of the send_random function and manipulated each one to send data to a different feed. These are then called from the main loop of the program to send the appropriate data to the appropriate feed.
As mentioned above, the data is currently sent every minute though the intention is to send it once per day.
# **Presenting the data**
The data from the three different feeds (low, high, average) are presented together in a line diagram using 3 different lines. As we can see on the pictures, these lines follow eachother since low/high/average temperature during the last minute is pretty redudant information. This effecively makes this project a regular temperature sensor at the moment.

The Adafruit IO free plan allows saving data for 30 days
# Finalizing the design
This is a picture of the final project, about as unexciting as it gets!

Overall I think the project went alright. I learned a lot since I had no experience with this before, so just receiving data from sensors and be able to present it online is good enough for me! As I already mentioned, this is pretty much just a regular temperature sensor at the moment, so I'd like to summarize the things I would like to change to make this more useful towards what the project intended to do.
* Finish the troubleshooting on the longer intervals between transmission, why doesn't it always work?
* Introduce a "proper" sleep.
* Introduce a battery solution so it doesn't have to be connected to power at all times.
* Connecting an external sensor to get more correct readings.
* Mounting the device at its correct position.
Thank you all for a very exciting course!