Tropical countries, such as Brazil, suffer from high summer temperatures, requiring classrooms to have climate control systems. These systems typically use the air contained in the room, and reduce its temperature, creating a more pleasant environment. However, this system has some disadvantages. For air quality to be maintained, air conditioners need to be regularly cleaned and maintained. Since the air conditioner does the air cooling process, condensation of water vapor in the air can occur, creating a favorable environment for fungal proliferation. The constant contact with this poor air, added to the fact that children have a weaker immune system, causes the emergence of cases of respiratory diseases. Similarly, due to the lack of room ventilation to keep the air conditioning system running, a high concentration of CO2 can occur. This gas is produced during our breathing process, and there is scientific evidence that high concentrations of CO2 in confined environments can lead to drowsiness and even headaches. Considering all these factors, it is justified to create a device to measure air quality in classrooms, to ensure better school performance and an improvement in the quality of life of students.
PurposeThe goal of this project is to build an IoT device using the Microsoft Azure Sphere MT3620 platform that will be responsible for collecting air quality data using the SGP30 sensor, and sending the data to Microsoft Azure allowing school managers to have real time an indicator of air quality in classrooms.
PrototypeFor prototyping the device the Azure Sphere AVNET Starter Kit and Mikroe Air Quality 4 click sensor will be used. The Azure Sphere platform consists of a microcontroller, a secure operating system, and a suite of cloud services that ensure device security and constant operation. The Mikroe Air Quality 4 click sensor is a device for prototyping air quality meters that checks two main parameters: CO2 concentration and TVOC concentration. TVOC stands for Total Volatile Organic Compounds, which is a measure of the concentration of organic compounds in air. The higher the concentration of these two parameters, the worse the quality of breathing air is considered.
This module uses de I2C protocol to exchange data with the microcontroller. I2C is an industrial protocol that uses two data wires SDA e SCL and has one MASTER device and many SLAVE devices. The Azure Sphere will work with MASTER device, and the Air Quality 4 click one SLAVE device. Every device on this network has a unique identifier and all comunication must inform this identifier for the correct device responde the message.
OK now we know what the sensor do and what protocol we will use to comunicate with it. But how we can do that? To start we will use the project provide by Avnet in your GitHub: https://github.com/CloudConnectKits/Azure_Sphere_SK_ADC_RTApp This repository has two projects we will use the AvnetAzureSphereSK_OLED, because this project has the code necessary to use I2C protocol and send data to Azure IoT Central. If you prefer I will publish in another repository my version of this same project with the changes ready. Clone this project and open with Visual Studio 2017 or 2019. If you look at the main.c file, you will find the call for a function named initI2C().
This function initI2C do two important fings, first they inicialize the Azure Sphere as a I2C MASTER device and write the pointer for the I2C library on the variable i2cFd, remeber this name.
At the end of the initI2C function code, it still schedules the execution of the function AccelTimerEventHandler. This second function will be responsible for collect data from sensors and send to Azure IoT Hub or Azure IoT Central. We will code our final code in this function.
Ok now we have to look at the SGP30 datasheet to understand how to communicate. On this section we will find that the sensor will respond on the I2C address 0x58 in hexadecimal.
Most I2C sensors have some type of communication test command. The SGP30 has a measure test, if we send the command 0x2032 we will get a reply default value 0xD400.
To test that we will use this simple code, into the initi2c() after I2C Master inicialization.
uint8_t buff[2];
buff[0] = 0x20;
buff[1] = 0x32;
int32_t retVal;
uint8_t sgp30_buffer[2];
Log_Debug("SEND [%d] 0x%02x [%d] 0x%02x\n", 0, buff[0], 1, buff[1]);
retVal = I2CMaster_Write(i2cFd, 0x58, buff, 16);
sleep(1);
retVal = I2CMaster_Read(i2cFd, 0x58, sgp30_buffer, 2);
Log_Debug("RET [%d] 0x%02x [%d] 0x%02x\n", 0, sgp30_buffer[0], 1, sgp30_buffer[1]);
if (retVal < 0) {
Log_Debug("ERROR: platform_read(read step): errno=%d (%s)\n", errno, strerror(errno));
}
The variable buff is the buffer that contains the command in hexadecimal that we want o send. The I2CMaster_Write send the command in buff variable, using the i2cFd pointer for the MASTER I2C device, and the address 0x58 that represents the sensor. The last parameter is the number of the bytes that has in the buffer variabel (16 bytes).
We wait a long time 1 second, but you can a smaller value. Than we use the I2CMaster_Read to read the response and writes on sgp30_buffer. If we lookat the output console, we will see that the sensor respond with the correct value.
Now we go back to the datasheet and find this instructions to get de sensor data. First we need to send the command Initi_air_quality 0x2003 then we can send the command Measure_air_quality 0x2008. For 15 seconds the response will be 400 for CO2 and zero for TVOC. IMPORTANT: put in comment ou remove the code that we did in the last step.
On the begin of initi2c() function we will put this code, to send the Init_air_quality command.
uint8_t buff[2];
int32_t retVal;
buff[0] = 0x20;
buff[1] = 0x03;
Log_Debug("INIT [%d] 0x%02x [%d] 0x%02x \n", 0, buff[0], 1, buff[1]);
retVal = I2CMaster_Write(i2cFd, 0x58, buff, 16);
On the begin of AccelTimerEventHandler() function we will put this code, they first send the Measure_air_quality command 0x2008 then wait for 1 second. After that, we use the I2CMaster_Read() function to get the values in the sgp30_buffer. The data return will be structured like this:
8bits_CO2 | 8bits_CO2 | 8bits_CRC_CO2 | 8bits_TVOC | 8bits_TVOC | 8bits_CRC_TVOC
In the end we use the command to convert hexadecimal values to decimal.
uint8_t buff[2];
int32_t retVal;
uint8_t sgp30_buffer[6];
buff[0] = 0x20;
buff[1] = 0x08;
Log_Debug("READ [%d] 0x%02x [%d] 0x%02x \n", 0, buff[0], 1, buff[1]);
retVal = I2CMaster_Write(i2cFd, 0x58, buff, 16);
sleep(1);
retVal = I2CMaster_Read(i2cFd, 0x58, sgp30_buffer, 6);
Log_Debug("RET [%d] 0x%02x ", 0, sgp30_buffer[0]);
Log_Debug("[%d] 0x%02x ", 1, sgp30_buffer[1]);
Log_Debug("[%d] 0x%02x \n", 2, sgp30_buffer[2]);
Log_Debug("RET [%d] 0x%02x ", 3, sgp30_buffer[3]);
Log_Debug("[%d] 0x%02x ", 4, sgp30_buffer[4]);
Log_Debug("[%d] 0x%02x \n", 5, sgp30_buffer[5]);
int co2 = (sgp30_buffer[0]<<8) | sgp30_buffer[1];
int tvoc = (sgp30_buffer[3] << 8) | sgp30_buffer[4];
Log_Debug("[ CO2 %d ] [ TVOC %d ]", co2, tvoc);
if (retVal < 0) {
Log_Debug("ERROR: platform_read(read step): errno=%d (%s)\n", errno, strerror(errno));
}
You will see that the sensor reacts as expected, returning constant values first and then changing after 15 seconds.
To send this data to Azure IoT Central, we need to alter the sensor_var struct to include out two new parameters.
And then write this to the sensor_data structure.
Than we need to enable the IOT_CENTRAL_APPLICATION preprocessor on
build_options.h
Than we need to alter de i2c.c file to change the JSON message generation, to add your new parameters. Search for this snprintf on the code.
On the end of this command we add the two new variables and change the format of the JSON message.
You have too change the deviceTwin.h file to increase the JSON_BUFFER_SIZE used to generate the new JSON message.
To connect using a simple way with Azure IoT Central we will use part of this tutorial from Microsoft, to use de Device Provision Service to generate the connection string: https://docs.microsoft.com/pt-br/azure/iot-central/howto-connect-windowsiotcore?WT.mc_id=AZ-MVP-5003638
You have to enter on Azure Portal, and create a new or access a existing instance of Azure IoT Central.
First we click on device models and create a new model.
Than we enter in create a new telemetry parameter, and use the names: co2 and tvoc
Once the two parameters co2 and tvoc are add to your model, we can continue and create a new device.
Enter on devices and create a new device use the new model type we create in the last step. Select the type REAL device when you are creating the new one.
On the device list, select your new device and click on connect link on the top right corner, this screen will show, copy the Azure IoT Central Scope code, the device id and the SAS primary key.
Now you need the NodeJS installed in your computer to use npm package manager to install de dps-keygen. This module will generate connection string we need in your device code.
npm i -g dps-keygen
Use this command fillin the gaps with the informations from Azure IoT Central device connection screen.
dps-keygen -di:<Device ID> -dk:<Primary or Secondary Key> -si:<Scope ID>
Copy the connection string show on the console and paste into the MY_CONNECTION_STRING into the connection_string.h file.
At last, change the app_manifest.json copy the Azure IoT Hub URL from the connection string to the AllowedConnections parameter.
If you run your code on Azure Sphere and go to Azure IoT Central you will see the data from the Air Quality Sensor display into the graph.
Using the Azure IoT Central platform, we can create a dashboard that shows the air quality situation of all classrooms, and generates alerts for school managers to intervene and instruct teachers to have practices that allow the classroom environment of class has higher quality.
Comments