# Temperature Sensor - Adafruit >Joel Bäckrud, jb225hb ## Project Overview This project aims to build and configure an IoT-Device that collects temperature data and then displays it on an Adafruit dashboard to also generate alarms if it is too high. The time required for this project should be between 4-12 hours depending on prior IoT experience. ## Objective **The main reasons** why I choose this project are: - I wanted to learn applied IoT programming while also becoming more familiar with microcontroller systems while keeping the physical part of the project simple. - I wanted an easier way to monitor the temperature in my server room by using a centralized platform to be able to access the data remotely and get automated alarms. **The purpose** of this device is to collect analog sensor data and transform it into an accurate temperature reading. **The project will give a better insight** into how the temperature varies during different times of the day. ## Material | Item | Description | Price | Buy | |:---------------------------------:|:------------------------------------------------------------:|:--------:|:-----------------------:| | Heltec LoRa ESP32 x1 (unsoldered) | Microcontroller | 32.8 € | [Amazon][Heltec] | | MCP9700 * | Analog Temperature sensor | 12.9 € | [Elektrokit][Sensors] | | Breadboard * | Used to connect everything | 12.9 € | [Elektrokit][Sensors] | | Wires * | Used to connect the different components on the breadboard | 12.9 € | [Elektrokit][Sensors] | | Solder Set | Used to solder the headers onto the microcontroller | 28.9 € | [Biltema][Solder] | _* Part of the same bundle_ [Heltec]: https://www.amazon.se/gp/product/B078M74NNN/ [Sensors]: https://www.electrokit.com/produkt/lnu-1dt305-tillampad-iot-sensors-only-bundle/ [Solder]: https://www.biltema.se/verktyg/lodning/lodpennor/lodset-2000018530 ## Computer setup #### IDE I usually prefer to Visual Studio Code but I ended up using Atom instead since I could not get the Pymakr plugin to work correctly in VS Code. #### Uploading Code The code was uploaded/synced by using a console connection between my PC and microcontroller and the built-in sync function in Atom's Pymakr plugin. #### Installation / Setup steps This project was done on a Windows 10 PC and the steps taken are as follows: ##### Preparing the IDE - Download and install [Node js][node] and follow the normal installation procedure - Download and install the [Atom IDE][atom] and follow the normal installation procedure - Install the Pymakr plugin in Atom by clicking `File >> Settings >> Install.` and searching for it ##### Flashing - Connect your Heltec device with and USB cable - Download the latest hardware [driver*][driver], extract it, and then run the **x64** executable (assuming your PC is not very old, since then it might be x86) - Open Windows device manager by pressing Win + R and then typing `devmgmt.msc` - Expand the section `Ports (COM & LPT)` and look for a device called **CP210x** and take note of its assigned COM port. - Download the ESP32 [firmware][firmware] - Open this website and connect to the previous COM port, and then format the device by pressing **erase** - Enter **offset** `1000` and then select your firmware file and press **program** to start the flashing process. _* As of June 2022_ [driver]: https://www.silabs.com/documents/public/software/CP210x_Windows_Drivers.zip [node]: https://nodejs.org/en/ [atom]: https://atom.io/ [firmware]: https://micropython.org/resources/firmware/esp32-20220117-v1.18.bin [flash]: https://nabucasa.github.io/esp-web-flasher/ ##### Connecting * Create a project folder wherever you like and then open it in Atom by clicking `File >> Add Project Folder` - Create a file called `main.py` and then connect to your device by opening the Pymakr plugin and pressing `Connect to Device >> COM (YOUR PORT NUMBER)` ## Connections The physical connections are very simple. The heltec has a connection from its GND to the ground and another connection from its 3V3 pin (since the sensor is designed for that voltage) to the power rail which the sensor subsequently has its voltage and ground leg connected. There is also a connection between the sensor's output pin to one of the heltec's ADC pins. This setup could be used in a production environment as a simple temperature device. But then the device would most likely need a built-in power source, such as a battery holder. The device would also need to have its connections soldered and enclosed in some kind of case instead of relying on a breadboard. ![](https://i.imgur.com/GnAPyVU.png) ## Platform I didn't feel like going through the hassle of hosting my own platform so I ended up using a cloud-based platform. My only requirement was that the platform had to be free and easy to set up. I first tried using the Ubidots platform since I am somewhat familiar with **RESTful APIs** and the fact that it had a better-looking interface than the alternatives. But it turned out that Ubidots did not support Heltec, or rather that I could not get it to work even though I followed the tutorial. This left me with only one choice since Pybytes (which only works with pycom devices) and Datacake (which puts too much focus on LoRa) was out of the question. I ended up using Adafruit which was easier to set up the dashboards for compared to Ubidots. The only downsides were that the website looked a bit cruder and that it was a lot harder to write code for since it uses the MQTT protocol instead of HTTP. #### Adafruit - **Feeds** serve as an identifier and collection point for data streams. - **Blocks** are essentially the same thing as widgets and allow you to visualize feeds in different formats such as graphs. - **Dashboards** is where you place your blocks and get an overview of all your data feeds, or projects. It can be accessed through your web browser and be set to public so that you can see it from anywhere. ## Code The most important part of the code is that the `pollData()` function which reads the sensor value and RAM utilization 1000 times 10 times at 5 seconds intervals. This is necessary since the sensor has a deviation of +-4 and therefore does not produce any usable data. Since the data gets polled 10000 times over a 30-60 second duration we can calculate the average to come close to the actual temperature. The more readings we use for the calculation the more accurate it gets. After testing some different numbers here I concluded that 10000 produces the best result while still not being too resource-intensive. I was initially putting all the polled values in a list and then used the sum() function, but that was not viable when handling 1000+ values since the list became so large that the program crashed, which is why I instead use one variable that contains the accumulated sum of all the polled values. ```python=40 # Poll the temp sensor and measure memory usage def pollData(): avergeTemp = 0 memUsage = 0 # Poll the sensor 1000 times and wait 5 seconds, 10 times for i in range (0,10): for y in range(0,1000): millivolts = apin.voltage() avergeTemp += millivolts memUsage += gc.mem_alloc() time.sleep(5) # Convert the polled voltages to celcius conv = (milivolts - 5000000) / 10 # Get the temperature by calculating the averge value of the polls tempStr = str(round(conv / 10000, 1)) # Get the averge memory utilization memUsageStr = str(round(((memUsage / 10000) / 67008) * 100)) # Free memory gc.collect() return tempStr, memUsageStr ``` The rest of the code can be found [here][code]. [code]: https://github.com/Joel055/IoT-Project #### Libraries All of the libraries that I used are built-in except for: - `mqtt` Which is a library that is required for MQTT support. - `ssd1306` Which contains code that simplifies the use of the Heltecs OLED screen. ## Transmitting the Data - The data is sent at a rate of roughly 1 minute, thanks to the `time.sleep()` delays in the temperature loop. - I used WiFi as my wireless communication protocol since it was more accessible and easy to set up. - The transport protocol that was used is MQTT _(MQ Telemetry Transport)_ since that's the only option when using Adafruit. It is sent in this format `topic=AIO_MEMORY_FEED, msg = data[1]` where `topic` is the feed that you want to send your data to and `msg` which contains the actual data that going to be sent, like a temperature for example. ## Presenting the Data The dashboard was built by creating blocks and connection feeds to them which was easy to do. There is no limit on how much data you can store, but it is deleted after 30 days. The data can be downloaded at any time to preserve it yourself before it is deleted. ![](https://i.imgur.com/wU9578g.png) ![](https://i.imgur.com/6DVFgyb.png) ## Result I am happy with the result, especially since I managed to produce an accurate temperature reading even though the sensor itself was very inaccurate. A somewhat accurate reading can be seen in the picture. If I ever redo this project I will most likely get a more accurate temperature sensor so that I won't have to write code this resource-heavy just to get a usable value. Alternatively, get another microcontroller that has more than 52kB RAM. ![](https://i.imgur.com/NlLOR4r.jpg)