Student credentials: Johan Ginman (JG223MV).
Date: July 4, 2022
This is a tutorial for how to configure and install an Arduino rp2040 nano connect with a temperature sensor and later, visualise the data in Arduino IOT Cloud. In addition to the external reading of temperature, the internal sensor of the Arduino is utilised to collect the internal temperature of the device. The tutorial illustrates how a resource cheap sensor is utilised with a microcontroller to measure temperature. The initial tough of the project was to use micropython and program the Arduino with Visual studio code and transmit the data through MQTT or HTTPS to Ubidots, however due to issues with the Arduino dual microcontrollers the initial plan was not achieved. The programing language utilised was instead of micropython the more low-level language C++, and rather than Visual studio code, Arduinos own IDE was used. The final artefact created in the project is a working temperature sensor that measures the current temperature in an interval of 4 seconds and displays the temperature in different ways on a dashboard.
In order to complete this project approximately 60 hours were spent on troubleshooting using micropython and Ubidots. The time spent on this final solution presented here was approximately 8 hours with troubleshooting and programming the code. So even though this project took around 68 hours, a replication of the project by following this tutorial could however be done within just a few hours.
Time spent:
Estimated time required for someone to replicate the project following this tutorial: 2 hours
The decision of creating this project is to measure the indoor temperature and see the values displayed through dashboards on both the computer and cellphone. The purpose of the project is both technically display the actual temperature and provide experience in the field of the Internet of things, and give hands-on knowledge of connecting the components and programming. Insights that can be retrieved through reading this tutorial are general knowledge of how to configure and set up a basic IoT project. The actual insights that the temperature sensor gives is de facto the temperature around the sensor which can come in handy in a home. Besides the reading of room temperature, readings from the internal temperature sensor located on the Arduino will be retrieved as a side part of the project.
Explain all material that is needed. All sensors, where you bought them and their specifications. Please also provide pictures of what you have bought and what you are using.
All of the equipment utilised in the project is retrieved from the website electrokit. The temperature sensor was part of a bigger bundle that was bought from this deal, for 130 SEK. The Arduino RP2040 was bought with headers already soldered through this link, for 300 SEK. The total cost of the components was approximately 430 SEK.
The Arduino is the centrepiece of the project, which can be programmed in micropython and C++, and receive data from various sensors that can be transmitted to cloud sites for visual representation.
The breadboard is used to connect the Arduino with the chosen sensor by putting jumper wires in the holes for leading data and voltage.
The Sensor is the piece allowing the Arduino to get the temperature around it. The sensor is connected with jumper wires to the breadboard and the Arduino.
Jumper wires are cables used to connect different components on a breadboard.
The Micro-USB cable is connected between the computer and the Arduino to allow configuration.
The computer is used to configure the Arduino and to read the data transferred to the dashboard later.
Used like the windows 10 computer when it accessing the see the visualised data presented on the cloud dashboard trough utilisation of the Arduino IoT Cloud Application downloaded on Appstore.
Arduino Nano RP 2040 Connect displayed in figure 1 above is a C++ programmable controller that has the support of python, dual-core controllers, WIFI and Bluetooth compatibilities, accelerometer and gyroscope, microphone, cryptographic co-processor and lastly, an internal temperature sensor. The Arduino has both digital and analogue pins for both input and outputs. The Arduino is connected to the breadboard displayed in figure 2, with jumper wires. The micro-USB cable has been connected to a windows 10 computer, and the temperature sensor MCP9700 displayed in figure 3 were connected between the breadboard and the Arduino with jumper wires. The temperature sensor MCP9700 is capable of measuring temperatures between 0°C and 70°C, however tough with a source of error margin of ±4°C.
The first step was to install Ardunio IDE 2.0 as the IDE softwer. This IDE was utilised to update the Ardunio RP2040 to the latest firmware version, and specifically the WIFI Nina Firmware with the latest version, in this case, version 1.5.0. Besides updating the firmware, the library containing access to the Arduino´s internal temperature was installed. This library can be acquired by searching for Arduino_LSM6DSOX inside Arduino IDE´s library manager.
The second step for proceeding with this project was to connect the Arduino Nano RP2040 connect to Arduino IoT Cloud, following this guide published on Arduino's page. This is performed through two necessary actions on the Arduino cloud, where first of all a (1) "Device" needs to be created. This device is the Arduino Nano RP2040. During the configuration phase, a software called Arduino Create Agent.
The second action that needs to be taken is a (2) "Thing", where a variable for the temperature is to be created. The name given to the variable needs to be reused later for transmitting the data from the device to the cloud. In the create a variable window, a temperature sensor can be searched for in the select variable type window. Besides the variable for the external, another variable called "internaltemp" is created in the same way. This variable is intended to receive the temperature of the internal sensor on the Arduino. The window for how the variables were set up is displayed in figure 4 below.
Both Celsius and Fahrenheit can be chosen here. The permissions of the variable are defined as read-only and the updated policy is defined as On change in order to update itself every time data is retrieved, lastly is the threshold specified as 0.
Inside of the Thing, the previously created device is attached to the project, and network credentials are defined.
The Arduino IoT Cloud is then generating code in C++ that is placed in the "Sketch", where code can be verified and uploaded to the device through a web interface.
In order to connect the MCP9700 temperature sensor with the Arduino, jumper wires were placed as displayed in figure 5 underneath. The black cables are connected between the ground pin on the Arduino and the ground pin on the sensor. The data link is connected on pin 27(A1) of the Arduino and the middle pin of the sensor. The blue cable connects the voltage between the sensor and the 3.3-volt outage of the Arduino. The datasheet of the Arduino can be found on this link, where the specific purposes of the various pins are declared. The datasheet of the temperature sensor can be found here.
An actual picture of how this looks, in reality, can be seen in figure 6 below, note that the blue cable from the previous circuit diagram is here green. Note that this setup is the final setup for the whole project, and is not just for the initial setup for configuration.
The platform utilised for this project was ultimately Arduino IoT Cloud, which just like Ubidots can receive data gathered from the IoT device, and display it in a dashboard with various widgets. Arduino IoT Cloud is a software as a service (SAAS) provided by the developer of my microcontroller (Arduino nano rp2040 connect) and does therefore come with good compatibilities when it comes to connecting the device and transferring data to be displayed. The Arduino IoT Cloud can be accessed through WiFi, which is the project's main intention, as well as an internal IDE for injecting the device with code. Due to issues connecting the device to the Ubidots, the decision finally landed on the Arduino Cloud which for my purpose is free and easy to administrate. However, the Arduino Cloud comes with various price plans and alternatives but for this project the free plan is suitable. The platform allows for the data to be downloaded in CSV format, which can come in handy if the data for other projects. Future projects however could implement Ubidots as a platform, to scale up the project with perhaps more functionality and increase interoperability between different vendors' IoT equipment if such would be implemented in the future.
All of the code can be retrieved on Github here as well as in the appendix at the bottom of this tutorial. In this chapter of the tutorial some specifically important code snippets will be discussed and explained
The main file for the project includes a loop where the execution of the code for reading both the internal and external sensor is done. This code snippet is displayed and explained in more depth below.
void loop() {
ArduinoCloud.update();
int mydata = analogRead(pin);
float volt = (float)mydata * 3.3;
volt /= 1024.0;
float mytemp = (volt - 0.5) * 100;
float rounded = ceil(mytemp * 100.0) / 100.0;
temp = rounded;
if (IMU.temperatureAvailable())
{
int temperature_deg = 0;
IMU.readTemperature(temperature_deg);
internaltemp = temperature_deg;
}
delay(4000);
}
In the void loop() the temperature sensor is read and the values calculated. The code for this was inspired by a post on docs.onion.io where the actual calculation for the read of the data was done. The data is first retrieved from the pin connected to the sensor and is multiplied by 3.3 since this is the voltage used and converts the reading from analogue to digital. An offset of 500mV is also included to calibrate the reading when converting the reading into celsius.
In order to achieve a good readable result, the function ceil() was implemented to adjust the reading retrieved and round up to 2 decimals. The code for this was inspired by java2blogs post on rounding floats in C++. The rounding was achieved by multiplying the reading by 100 and inserting it into the ceil()function, where the output is later divided by 100 which leads to a reading that is rounded up to 2 decimals.
There exist various ways of rounding readings, and ceil() was considered feasible enough, but if the project were to be redone other functions like floor() could be explored in order to handle the data.
To receive the internal temperature of the Arduino board, an if statement is checking if there exists a value within IMU.temperatureAvailable(), this function can return 0 if there is no available data, or 1 if there exists a value. Then the variable that is intended to hold the internal temperature is put to 0 for every iteration of the code, and the actual temperature of the sensor is retrieved and placed in the variable internaltemp, which can be collected by the Arduino Cloud. The code for the internal sensor was inspired from Arduinos official tutorials.
Delay is a way of making the device pause the transmission to the Arduino cloud so that the values are not sent as often. In this case, a delay of 4 seconds is defined, and this is, therefore, the interval of the data being sent.
In order for the device to communicate through wifi, the file thingsProperties.h was created, as well as a file called Secret that contains the WiFi SSID as the variable SECRET_SSID and the WiFi password as the variable SECRET_PASS.
The data transmitted from this project is via WiFi, since LoRa seems unavailable from the location where I'm at WiFi comes in handy. Since the configuration of the networking parts was performed by Arduino when setting up the device to be available for the cloud there were no choices or decisions taken over what protocols should be used or similar. However, the data is sent every 4 seconds over wifi, and are transmitted from the Arduino nano rp2040 connect through MQTT which has become the standard way for IoT communication.
The platform does also allow connections through methods such as HTTP requests, WebSockets and more.
The choice of utilising WiFi for transmission seems like a solid pick as long as the temperature sensor is used inside of the Wifi range. Other methods, like LoRa, might be more effective if the device is within a LoRa zone and are outside of the comfort of the WiFi. The device, however, for this project was never thought of being applied outside the house and therefore WiFi works perfectly. The overhead generated on the WiFi is to be considered minimal and none disturbing, future projects could, however, lower the transmission rate to, for example, sending a measurement every 30 or 60 seconds rather than every 4 seconds as of now.
In order to represent the measurements visually, a dashboard on the Arduino IoT Cloud was created. The data can be presented in various ways, and for this project, four representation ways have been picked, the first way (1) is through a chart where the data points interpolations are presented as "Line" which can be seen in figure 7, the purpose of utilising charts is for representing the data over time and not only from the last measure. With the help of the charts trends of the temperature changing during the day can easily be seen with the bare eye.
the second way is (2) through a box displaying the most recent measure which can be seen in figure 8.
The third way (3) the data is displayed is through a box for the measurements of the internal temperature. This can be seen in figure 9 below.
The fourth (4) and final way of representing data on the dashboard is in the same way as (1), which means a line chart displaying data, as shown in figure 10. The data represented here is however a chart for how the trend of the device's internal temperature. This data is useful if one were to troubleshoot the device, or just to be thought of as a tool to see the health of the Arduino.
The full dashboard view can be seen in figure 11 below.
The dashboard is also accessible through the Arduino IoT cloud app on the phone, an illustration of the phone's dashboard version can be seen in figure 12 below. The phone dashboard is adjustable and scrollable and fully administrated from the computer's dashboard.
The database was chosen for its accessibility, the ease of setting up the environment and utilising it. There are no available ways of utilising automatisation or alert triggers for this project on the Arduino IoT Cloud, otherwise, an alarm for specific temperatures would have been interesting. Triggers for suddenly big increases or decreases in temperature could then also be included. It is unclear if this is a feature that is lacking in the free plan that this project has and could be retrieved through a premium service from the provider.
There seems to lack transparency for how often the data is saved in the database, but at least every new measurement shows up on the dashboard instantly when the data is received on the cloud and is added to the graphs right away. So conclusions could be drawn that the data is saved every 4 seconds (since the program is transmitting a measurement to the cloud every 4 seconds). The data retention on the platform is during the free plan set to 1 day, meaning that the data will only be viewable and kept for the last 24 hours before being rotated out. Different price plans offer different lengths that the data is saved, from 1 day on the free plan, to 1 year on one of the premium ones.
Even though the project initially was going to utilise the language micropython, which lead to numerous hours of troubleshooting resulting in nothing more than just switching language to C++. If the project were to be made over utilisation of micropython would be wished for, even though every measure possible was taken to have this project in micropython this time. Other measurements could also be included, like a sensor measuring humidity.
Another idea for future work on this project is to add more readings from the Arduino´s internal sensor "LSM6DSOX", with functions such as gyroscopes and accelerometers. The utilisation of the gyroscope functions that the Arduino nano RP2040 Connect offers could be used in a project that tests hand gestures or other types of body movements and accelerometers could be utilized to see if the device is being moved.
All in all was the final result of the project a success with a working temperature sensor that can be retrieved through a dashboard on the computer, as shown in previous chapters of this tutorial.
The readings regarding the internal temperature need to be discussed. It seems like the common internal temperature of the Arduino ranges between 31°C and 34°C. However, sometimes the value displayed in the cloud is 0 °C which is an anomaly. The root cause of this issue has not been identified in this project but would be something that could be dealt with if one were to replicate this project in the future. Even though this issue is acknowledged, the internal sensor´s displayed value could be looked at giving a blind eye to the 0 value. The purpose of the internal temperature is not building for this project, since the main objective is to receive the room temperature with the external sensor added to the breadboard. Readings of the internal sensor do provide somewhat of a health update of the device, and perhaps just a neat feature rather than an important one.
In order to prove that the final artefact in the shape of a temperature sensor, actually measures the correct temperature; two external measurement tools (thermometers) have been used to make comparisons. Figure 13 below shows the same value on the external sensors, as well as the one created through this project. The sensor created in this project does get the same results as both of the other thermometers.
Besides uploading the code to Github, the code is displayed in this appendix chapter to be as transparent with the project as possible, but also increase availability for the reader.
SECRET_SSID = "My_credentials";
SECRET_PASS = "My_credentials";
/*
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
CloudTemperatureSensor internaltemp;
CloudTemperatureSensor temp;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include <iostream>
#include <cmath>
#include <iomanip>
#include <Arduino_LSM6DSOX.h>
int pin = A1;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
pinMode(pin, OUTPUT);
// Defined in thingProperties.h
initProperties();
IMU.begin();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
int mydata = analogRead(pin);
float volt = (float)mydata * 3.3;
volt /= 1024.0;
float mytemp = (volt - 0.5) * 100;
float rounded = ceil(mytemp * 100.0) / 100.0;
temp = rounded;
if (IMU.temperatureAvailable())
{
int temperature_deg = 0;
IMU.readTemperature(temperature_deg);
internaltemp = temperature_deg;
}
delay(4000);
}
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
const char SSID[] = SECRET_SSID; // Network SSID (name)
const char PASS[] = SECRET_PASS; // Network password (use for WPA, or use as key for WEP)
CloudTemperatureSensor temp;
void initProperties(){
ArduinoCloud.addProperty(temp, READ, ON_CHANGE, NULL);
}
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);