|
| 1 | +--- |
| 2 | +title: 'Environmental Monitoring with the Nicla Sense Env' |
| 3 | +description: "This application note describes how to implement an outdoor air quality monitor with the Nicla Sense Env." |
| 4 | +difficulty: intermediate |
| 5 | +compatible-products: [nicla-sense-env] |
| 6 | +tags: |
| 7 | + - Environmental monitor |
| 8 | + - Air quality |
| 9 | + - Application note |
| 10 | + - Nicla Sense Env |
| 11 | + - Portenta C33 |
| 12 | +author: 'José Bagur' |
| 13 | +hardware: |
| 14 | + - hardware/04.pro/boards/portenta-c33 |
| 15 | + - hardware/06.nicla/boards/nicla-sense-env |
| 16 | +software: |
| 17 | + - ide-v1 |
| 18 | + - ide-v2 |
| 19 | + - IoT-Cloud |
| 20 | +--- |
| 21 | + |
| 22 | +## Introduction |
| 23 | + |
| 24 | +Air pollution is a growing concern in urban and industrial areas due to the harmful effects of airborne pollutants such as nitrogen dioxide (NO2), ozone (O3) and airborne particulate matter (PM) on human health and the environment. This application note presents the development of an outdoor air quality monitor using the Portenta C33 and the Nicla Sense Env. The outdoor air quality monitor provides real-time data on temperature, humidity, concentrations of NO2 and O3, and the outdoor air quality index (AQI), making it suitable for use in urban areas, industrial zones, or environmental research. |
| 25 | + |
| 26 | +## Goals |
| 27 | + |
| 28 | +The main goals of this application note are as follows: |
| 29 | + |
| 30 | +- Develop a simple outdoor air quality monitor that provides real-time data on temperature, humidity, and pollutants such as nitrogen dioxide (NO2) and ozone (O3). |
| 31 | +- Collect accurate readings of NO2, O3 and the outdoor air quality index (AQI) to assess overall outdoor air quality. |
| 32 | +- Display real-time data from the Nicla Sense Env on the Arduino IDE Serial Monitor for immediate data observation and analysis. |
| 33 | +- Establish a connection to the Arduino Cloud to enable remote monitoring and data analysis of the collected outdoor air quality data. |
| 34 | + |
| 35 | +## Hardware and Software Requirements |
| 36 | + |
| 37 | +### Hardware Requirements |
| 38 | + |
| 39 | +- [Portenta C33](https://store.arduino.cc/products/portenta-c33) (x1) |
| 40 | +- [Nicla Sense Env](https://store.arduino.cc/products/nicla-sense-env) (x1) |
| 41 | +- USB-C® cable (x1) |
| 42 | +- Wi-Fi® W.FL antenna (x1) |
| 43 | + |
| 44 | +### Software Requirements |
| 45 | + |
| 46 | +- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Cloud Editor](https://create.arduino.cc/editor). |
| 47 | +- For the Wi-Fi® connectivity feature of Portenta C33, we will use the [Arduino Cloud](https://create.arduino.cc/iot/things). If you do not have an account, create one for free [here](https://cloud.arduino.cc/). |
| 48 | + |
| 49 | +## Hardware Setup Overview |
| 50 | + |
| 51 | +The electrical connections of the proposed outdoor air quality monitor are shown in the diagram below: |
| 52 | + |
| 53 | +The diagram illustrates the connection of all the monitor's components. The Portenta C33 is the monitor's main controller; the Nicla Sense Env board provides temperature, humidity, and outdoor air quality data. |
| 54 | + |
| 55 | +The Nicla Sense Env is connected to the Portenta C33 via ESLOV. The monitor has one main voltage bus (+5 VDC from the Portenta C33) that powers the Nicla Sense Env, the Portenta C33 is powered through its onboard USB-C port for testing purposes. |
| 56 | + |
| 57 | +## Understanding Outdoor Air Quality |
| 58 | + |
| 59 | +Air pollution is not just a problem in urban areas; rural environments also face significant risks from pollutants like nitrogen dioxide (NO2) and ozone (O3). These gases pose serious health risks, especially for vulnerable populations. NO2, produced by combustion engines and industrial processes, can travel far beyond urban centers. O3, formed by atmospheric chemical reactions, affects urban and rural regions, especially during warmer seasons of the year. |
| 60 | + |
| 61 | +Real-time monitoring is critical in urban and rural settings to manage exposure to these pollutants properly. Air quality tracking and monitoring helps individuals and communities to proactively reduce health risks. |
| 62 | + |
| 63 | +### The Role of Sensors in Air Quality Monitoring |
| 64 | + |
| 65 | +This application note uses modern and state of the art sensors to provide accurate, real-time measurements of various pollutants. The Nicla Sense Env board offers an interesting solution for monitoring outdoor air quality. |
| 66 | + |
| 67 | +- **NO2 Sensor**: Detects nitrogen dioxide, a harmful gas released by vehicles and industrial activities. |
| 68 | +- **O3 Sensor**: Measures ozone, a gas that forms in the atmosphere through reactions between pollutants and sunlight, contributing to respiratory problems. |
| 69 | +- **Outdoor Air Quality Index (AQI)**: The AQI simplifies the interpretation of air quality by combining data from multiple pollutants (PM, NO2, O3) into a single value. |
| 70 | + |
| 71 | +The AQI index is based on a scale that ranges from 0 to 500, where: |
| 72 | + |
| 73 | +- 0-50 indicates good air quality. |
| 74 | +- 51-100 is moderate. |
| 75 | +- 101-150 is unhealthy for sensitive groups. |
| 76 | +- 151-200 is unhealthy for everyone. |
| 77 | +- 201-300 is very unhealthy. |
| 78 | +- 301-500 signals hazardous conditions. |
| 79 | + |
| 80 | +The AQI makes it easy to understand how outdoor air quality might affect public health, particularly when pollutant levels rise to unhealthy levels. |
| 81 | + |
| 82 | +Monitoring NO2, O3, and AQI in real-time allows for immediate responses when air quality worsens. This is especially important in rural areas with less visible air quality issues. The data collected can be sent to platforms like Arduino Cloud, enabling remote monitoring and long-term trend analysis, improving public awareness and policy decisions. |
| 83 | + |
| 84 | +## Environmental Monitor Example Sketch |
| 85 | + |
| 86 | +Now that we have covered the hardware components of our environmental monitor and how they are interconnected, let's study the software that brings this monitor to life. The example sketch in the following section manages data collection from the Nicla Sense Env board and the PMS7003 sensor connected to the Portenta C33 board, allowing us to monitor real-time environmental data such as temperature, humidity, outdoor air quality, and particulate matter concentrations. |
| 87 | + |
| 88 | +This section breaks down the provided example sketch, guiding you through its functionality. We will explore how the sensors are initialized, how the data is collected every 10 seconds, and how the results are displayed in the Arduino IDE's Serial Monitor. |
| 89 | + |
| 90 | +The complete example sketch is shown below. |
| 91 | + |
| 92 | +```arduino |
| 93 | +/** |
| 94 | + Outdoor Air Quality Monitoring with Arduino |
| 95 | + Name: outdoor_air_quality_monitor.ino |
| 96 | + Purpose: This sketch reads temperature, humidity, and outdoor air quality |
| 97 | + from the Nicla Sense Env connected to the Portenta C33 board. |
| 98 | + The data is reported to the Arduino IDE's Serial Monitor every 10 seconds. |
| 99 | + |
| 100 | + @version 1.0 01/09/24 |
| 101 | + @author Arduino Product Experience Team |
| 102 | +*/ |
| 103 | +
|
| 104 | +// Include the necessary libraries for Nicla Sense Env sensors |
| 105 | +#include "Arduino_NiclaSenseEnv.h" |
| 106 | +
|
| 107 | +// Time interval (in milliseconds) for sensor readings of 10 seconds |
| 108 | +static const uint32_t READ_INTERVAL = 10000; |
| 109 | +uint32_t lastReadTime = 0; |
| 110 | +
|
| 111 | +// Sensor objects for Nicla Sense Env data (using pointers) |
| 112 | +NiclaSenseEnv device; |
| 113 | +TemperatureHumiditySensor* tempHumSensor; |
| 114 | +OutdoorAirQualitySensor* airQualitySensor; |
| 115 | +
|
| 116 | +/** |
| 117 | + Initializes the sensors and serial communication. |
| 118 | + Configures the Nicla Sense Env board to enable the onboard |
| 119 | + temperature/humidity sensor and the onboard outdoor air |
| 120 | + quality sensor. |
| 121 | +*/ |
| 122 | +void setup() { |
| 123 | + // Initialize serial communication at 115200 bits per second. |
| 124 | + Serial.begin(115200); |
| 125 | + |
| 126 | + // Wait for Serial to be ready with a timeout of 5 seconds |
| 127 | + for(auto start = millis(); !Serial && millis() - start < 5000;); |
| 128 | +
|
| 129 | + // Initialize NiclaSenseEnv sensors |
| 130 | + if (device.begin()) { |
| 131 | + Serial.println("- Nicla Sense Env is connected"); |
| 132 | +
|
| 133 | + // Get the temperature and humidity sensor (use pointer) |
| 134 | + tempHumSensor = &device.temperatureHumiditySensor(); |
| 135 | +
|
| 136 | + // Get and enable the outdoor air quality sensor (use pointer) |
| 137 | + airQualitySensor = &device.outdoorAirQualitySensor(); |
| 138 | + airQualitySensor->setEnabled(true); |
| 139 | + } else { |
| 140 | + // Error message if the Nicla Sense Env is not found |
| 141 | + Serial.println("- ERROR: Nicla Sense Env device not found!"); |
| 142 | + } |
| 143 | +} |
| 144 | +
|
| 145 | +/** |
| 146 | + Main loop that reads sensor data every 10 seconds. |
| 147 | + This function continuously checks the time interval and calls |
| 148 | + the displayAllData() function to print sensor readings. |
| 149 | +*/ |
| 150 | +void loop() { |
| 151 | + // Get the current time (in milliseconds) |
| 152 | + uint32_t currentTime = millis(); |
| 153 | +
|
| 154 | + // Read sensors every 10 seconds and update the last read time |
| 155 | + if (currentTime - lastReadTime >= READ_INTERVAL) { |
| 156 | + lastReadTime = currentTime; |
| 157 | +
|
| 158 | + // Read and display all sensor data in a single line |
| 159 | + displayAllData(); |
| 160 | + } |
| 161 | +} |
| 162 | +
|
| 163 | +/** |
| 164 | + Displays temperature, humidity, and air quality data. |
| 165 | + Reads data from the Nicla Sense Env and prints it in a single line format. |
| 166 | +*/ |
| 167 | +void displayAllData() { |
| 168 | + // Check if both temperature/humidity and air quality sensors are enabled |
| 169 | + if (tempHumSensor->enabled() && airQualitySensor->enabled()) { |
| 170 | + // Read data from the Nicla Sense Env sensors |
| 171 | + float temperature = tempHumSensor->temperature(); |
| 172 | + float humidity = tempHumSensor->humidity(); |
| 173 | + float NO2 = airQualitySensor->NO2(); |
| 174 | + float O3 = airQualitySensor->O3(); |
| 175 | + int airQualityIndex = airQualitySensor->airQualityIndex(); |
| 176 | +
|
| 177 | + // Print all sensor data in a single line, with AQI at the end |
| 178 | + Serial.print("- Temperature: "); |
| 179 | + Serial.print(temperature, 2); |
| 180 | + Serial.print(" °C, Humidity: "); |
| 181 | + Serial.print(humidity, 2); |
| 182 | + Serial.print(" %, NO2: "); |
| 183 | + Serial.print(NO2, 2); |
| 184 | + Serial.print(" ppb, O3: "); |
| 185 | + Serial.print(O3, 2); |
| 186 | + Serial.print(" ppb, Air Quality Index: "); |
| 187 | + Serial.println(airQualityIndex); |
| 188 | + } else { |
| 189 | + // Error message if one or more sensors are disabled |
| 190 | + Serial.println("- ERROR: One or more sensors are disabled!"); |
| 191 | + } |
| 192 | +} |
| 193 | +``` |
| 194 | + |
| 195 | +The following sections will help you to understand the main parts of the example sketch shown before, which can be divided into the following: |
| 196 | + |
| 197 | +- Library imports |
| 198 | +- Sensors initialization |
| 199 | +- Data collection |
| 200 | +- Data display |
| 201 | + |
| 202 | +### Library Imports |
| 203 | + |
| 204 | +The first step is to ensure that all necessary libraries are included to control the Nicla Sense Env board. These libraries provide all the functionality to communicate with and extract sensor data. |
| 205 | + |
| 206 | +```arduino |
| 207 | +// Include the necessary libraries for Nicla Sense Env sensors |
| 208 | +#include "Arduino_NiclaSenseEnv.h" |
| 209 | +
|
| 210 | +// Time interval (in milliseconds) for sensor readings of 10 seconds |
| 211 | +static const uint32_t READ_INTERVAL = 10000; |
| 212 | +uint32_t lastReadTime = 0; |
| 213 | +
|
| 214 | +// Sensor objects for Nicla Sense Env data (using pointers) |
| 215 | +NiclaSenseEnv device; |
| 216 | +TemperatureHumiditySensor* tempHumSensor; |
| 217 | +OutdoorAirQualitySensor* airQualitySensor; |
| 218 | +``` |
| 219 | + |
| 220 | +The Nicla Sense Env library handles data such as temperature, humidity, and outdoor air quality, including also the NO2 and O3 gas concentrations. |
| 221 | + |
| 222 | +### Sensors Initialization |
| 223 | + |
| 224 | +The `setup()` function initializes the monitor sensors and prepares them to start collecting data. This is where the sensors "wake up" and prepare to make measurements. |
| 225 | + |
| 226 | +```arduino |
| 227 | +void setup() { |
| 228 | + // Initialize serial communication at 115200 bits per second. |
| 229 | + Serial.begin(115200); |
| 230 | + |
| 231 | + // Wait for Serial to be ready with a timeout of 5 seconds |
| 232 | + for(auto start = millis(); !Serial && millis() - start < 5000;); |
| 233 | +
|
| 234 | + // Initialize NiclaSenseEnv sensors |
| 235 | + if (device.begin()) { |
| 236 | + Serial.println("- Nicla Sense Env is connected!"); |
| 237 | +
|
| 238 | + // Get the temperature and humidity sensor (use pointer) |
| 239 | + tempHumSensor = &device.temperatureHumiditySensor(); |
| 240 | +
|
| 241 | + // Get and enable the outdoor air quality sensor (use pointer) |
| 242 | + airQualitySensor = &device.outdoorAirQualitySensor(); |
| 243 | + airQualitySensor->setEnabled(true); |
| 244 | + } else { |
| 245 | + // Error message if the Nicla Sense Env is not found |
| 246 | + Serial.println("- ERROR: Nicla Sense Env device not found!"); |
| 247 | + } |
| 248 | +} |
| 249 | +``` |
| 250 | + |
| 251 | +In the code snippet shown before: |
| 252 | + |
| 253 | +- Serial communication is initialized to allow data transmission. |
| 254 | +- The Nicla Sense Env board is initialized to read temperature, humidity and the outdoor air quality index (AQI). |
| 255 | + |
| 256 | +### Data Collection |
| 257 | + |
| 258 | +Once the sensors are ready, the example sketch must continuously collect data. The `loop()` function ensures that data is captured every 10 seconds and sent to the IDE's Serial Monitor. |
| 259 | + |
| 260 | +```arduino |
| 261 | +void loop() { |
| 262 | + // Get the current time (in milliseconds) |
| 263 | + uint32_t currentTime = millis(); |
| 264 | +
|
| 265 | + // Read sensors every 10 seconds and update the last read time |
| 266 | + if (currentTime - lastReadTime >= READ_INTERVAL) { |
| 267 | + lastReadTime = currentTime; |
| 268 | +
|
| 269 | + // Read and display all sensor data in a single line |
| 270 | + displayAllData(); |
| 271 | + } |
| 272 | +} |
| 273 | +``` |
| 274 | + |
| 275 | +In the code snippet shown before: |
| 276 | + |
| 277 | +- A time-based condition ensures that readings are taken every 10 seconds. |
| 278 | +- Calls the `displayAllData()` function every 10 seconds to gather and print sensor data to the IDE's Serial Monitor. |
| 279 | + |
| 280 | +### Data Display |
| 281 | + |
| 282 | +The `displayAllData()` function pulls together the data from each sensor and displays it in a single line on the IDE's Serial Monitor. This is the most dynamic part of the example sketch, where the sensors provide real-time readings. |
| 283 | + |
| 284 | +```arduino |
| 285 | +void displayAllData() { |
| 286 | + // Check if both temperature/humidity and air quality sensors are enabled |
| 287 | + if (tempHumSensor->enabled() && airQualitySensor->enabled()) { |
| 288 | + // Read data from the Nicla Sense Env sensors |
| 289 | + float temperature = tempHumSensor->temperature(); |
| 290 | + float humidity = tempHumSensor->humidity(); |
| 291 | + float NO2 = airQualitySensor->NO2(); |
| 292 | + float O3 = airQualitySensor->O3(); |
| 293 | + int airQualityIndex = airQualitySensor->airQualityIndex(); |
| 294 | +
|
| 295 | + // Print all sensor data in a single line, with AQI at the end |
| 296 | + Serial.print("- Temperature: "); |
| 297 | + Serial.print(temperature, 2); |
| 298 | + Serial.print(" °C, Humidity: "); |
| 299 | + Serial.print(humidity, 2); |
| 300 | + Serial.print(" %, NO2: "); |
| 301 | + Serial.print(NO2, 2); |
| 302 | + Serial.print(" ppb, O3: "); |
| 303 | + Serial.print(O3, 2); |
| 304 | + Serial.print(" ppb, Air Quality Index: "); |
| 305 | + Serial.println(airQualityIndex); |
| 306 | + } else { |
| 307 | + // Error message if one or more sensors are disabled |
| 308 | + Serial.println("- ERROR: One or more sensors are disabled!"); |
| 309 | + } |
| 310 | +} |
| 311 | +``` |
| 312 | + |
| 313 | +In the code snippet shown before: |
| 314 | + |
| 315 | +- The function first checks that the temperature/humidity sensor and the air quality sensor are enabled. |
| 316 | +- The function retrieves temperature, humidity, gas concentrations (NO2 and O3), and the air quality index (AQI) from the Nicla Sense Env board. |
| 317 | +- Finally, the data is printed in a single line on the IDE's Serial Monitor, with the AQI displayed at the end. |
| 318 | + |
| 319 | +### Complete Example Sketch |
| 320 | + |
| 321 | +The complete example sketch can be downloaded here. |
| 322 | + |
| 323 | +## Conclusions |
| 324 | + |
| 325 | +The development of this outdoor air quality monitor demonstrates the effectiveness of using affordable and accessible sensors to measure key environmental parameters in real-time. Integrating the Nicla Sense Env with the Portenta C33 allows the system to track temperature, humidity, NO2, and O3 levels. The ability to monitor these pollutants, combined with the outdoor AQI, provides valuable insights for understanding air quality in urban and rural areas. Furthermore, the system's connection to the Arduino Cloud allows for remote monitoring and analysis, making it versatile for various applications, from personal use to environmental research. |
| 326 | + |
| 327 | +## Next Steps |
| 328 | + |
| 329 | +Several improvements can be considered to extend the functionality of the outdoor air quality monitor: |
| 330 | + |
| 331 | +- Add more sensors to the monitor to measure pollutants such as carbon monoxide (CO) or sulfur dioxide (SO2). |
| 332 | +- Improve the monitor's energy efficiency for long-term deployment in remote or outdoor environments. |
| 333 | +- Build a custom dashboard on Arduino Cloud to visualize trends over time and allow for more detailed analysis of air quality data. |
| 334 | +- Implement an alert system that notifies users when pollutant levels exceed safe thresholds. |
| 335 | +- Scale the system for use in different geographical regions to collect comparative data on air quality. |
0 commit comments