element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Better World with Arduino
  • Challenges & Projects
  • Project14
  • Better World with Arduino
  • More
  • Cancel
Better World with Arduino
Blog Simple Remote Air Quality Monitor Project Tutorial
  • Blog
  • Forum
  • Documents
  • Events
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Better World with Arduino to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: javagoza
  • Date Created: 24 May 2022 11:00 PM Date Created
  • Views 24451 views
  • Likes 8 likes
  • Comments 2 comments
  • iaq
  • air quality
  • nicla
  • better world with Arduino
  • arduino
  • betterworldch
Related
Recommended

Simple Remote Air Quality Monitor Project Tutorial

javagoza
javagoza
24 May 2022
Simple Remote Air Quality Monitor Project Tutorial

Good ventilation improves people's quality of life. In this tutorial I present how to build a simple air quality monitor to improve your ventilation routines.

It is a simple remote Air Quality monitor with an Arduino Nicla Sense ME board as a sensor and an Arduino Nano 33 IoT as a monitoring system.

A common problem with portable air quality sensors is that the sensors are too close to the person observing them, which adds noise to the readings with their breathing. In this project we solve the problem by means of a remote monitor that communicates via Bluetooth with the distant sensor.

image

System Description

The system is made up of a Nicla Sense ME board that will act as a remote sensor and an Arduino Nano 33 IoT board and a color TFT LCD display that will allow us to view the data in real time.
The communication between the two subsystems is carried out through Bluetooth Low Energy (BLE) communication.

image

The Arduino Nicla Sense ME board will run the "App" firmware from the Arduino_BHY2 library.

The Arduino_BHY2 library provides the APIs for Nicla Sense ME board to make a Device Firmware Update or configure/read BHY sensors. All these operations can be done either via Eslov or BLE. We will use communication via bluetooth low energy BLE.

To visualize the data in real time we will use a TFT ST7735 display. It is a 1.8″ display with a resolution of 128 × 160 pixels and can display a wide range of colors with its 18 bits. The display uses the SPI protocol for communication and has its own pixel addressable frame buffer and only needs 4 I/O pins. It's a slow display, so we'll have to use display update techniques that minimize flickering, only re-drawing small sections of the display.

To complement the display, it also comes with an SD card slot that we will use to store historical data from our sensor.

The Arduino Nicla Sense ME has a BME688 gas sensor. The MBE688 can also measure pressure, humidity and temperature it can detect Volatile Organic Compounds (VCOs), volatile sulfur compounds (VSCs) and other gases such as carbon monoxide and hydrogen in the part per billion (ppb) range. This sensor will allow us to make measurements of air quality.

image

The BME688 is a metal oxide-based sensor that detects gases by adsorption (and subsequent oxidation/reduction) on its sensitive layer. The intensity of the signal typically scales with the chemical reactivity of the gases. 
The BME688 reacts to most volatile compounds as well as many other gases polluting indoor air (exceptions are very few gases which are chemically pretty inert, e.g. N2 and CO2).In contrast to sensors selective for one specific component, the BME688 is capable of measuring the sum of VOCs/contaminants in the surrounding air. This enables the BME688 to detect e.g. outgassing  from paint, furniture and/or garbage, high VOC levels due to cooking, foo consumption, exhaled breath and/or sweating.

IAQ Index

image
The BSEC software auto-calibrates the low and high concentrations applied during testing to IAQ of 25 and 250, respectively.

User Interface

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Air Quality Monitor User Interface

The monitor presents the information using three different screen layouts. 

With the buttons you can navigate through the different screens and control the brightness of the display LED.

IAQ Gauge Layout

In this layout, indoor air quality information is presented as an IAQ gauge. Adding information on the temperature and humidity detected by the sensor.

The IAQ scale ranges from 0 (clean air) to 500 (heavily polluted air. During operation, the algorithms automatically calibrate and adapt themselves to the typical environments where the sensor is operated (e.g., home, workplace, inside a car, etc..)
This automatic background calibration ensures that users experience consistent IAQ performance. The calibration process considers the recent measurement history (typ. up to four days, configurable) to ensure IAQ ~ 25 corresponds to "typically good" and IAQ ~ 250 indicates "typically polluted" air.

At the top of the display there is an indicator of the accuracy in the measurements that can vary from 0 to 3 and is presented as 4 boxes that may or may not be full.

The accuracy status is equal to zero during the power on stabilization times of the sensor and is equal to 3 when the sensor achieves best performance.

In addition, the current time is displayed with hours and minutes. The time is updated by NTP using the WIFi connection of the Arduino Nano 33 IoT

image

Values Layout

In this layout, the information is displayed in a single column showing the IAQ, the temperature and the relative humidity obtained from the remote sensor.

Again at the top of the display there is an indicator of the accuracy and  the current time.

image

Historical graphs

On this screen you can view historical data from past and current days in graphic form.
The monitor stores historical data on the SD card.

The date of the plotted data is shown at the top.

image

Bill of Material:

Product Name Manufacturer Quantity
Arduino Nano 33 IOT ARDUINO 1 Buy Now
Arduino Nicla Sense ME ARDUINO 1 Buy Now
1.8" SPI TFT display 128 x 160 pixels AZ-DELIVERY 1

show

Hole Grid Board PCB AZ-DELIVERY 1

show

Hex Threaded Spacer + nuts DURATOOL 4

Buy Now

Tactile Switch, D6, Top Actuated,

Through Hole, Round Button

4

Mini Storage Bins with Lids

1

SD card 2GB + Adapter

PCB Receptacle, Board-to-Board,

2.54 mm, 1 Rows,  Through Hole Mount, 2212S

MULTICOMP PRO 4

JST Connectors, male and female

The remote monitor

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Schematics

image
image
Arduino nano 33 IoT pinout
image
image
18 columns x 24 rows vertical strips for the main board
image
18 columns x 4 rows vertical strips for the navigation buttons.
image
5 columns x 5 rows vertical strips for the reset button.

Construction

The monitor has been built inside a small standard transparent plastic box. Look for Mini Storage Bins with Lids.

There is enough space to house a 9v battery that allows us to directly power the IAQ monitor.

Although the original design was made to use a stripboard, in the end it was decided on this other type of board to be able to secure the headers on both sides of the board.

image
The monitor disassembled into parts.
image

Firmware

Setting the development environment for the Nicla Sense ME

We will use the Arduino IDE 2.0.  If you haven't done it yet download and install the Arduino IDE 2.0 
Downloading the Arduino IDE 2.0 is done through the Arduino Software page.

Installing the Nicla Core Support

Open the Arduino IDE 2.0 and navigate to Boards Manager then search for Nicla.

Select The Arduino Mbed OS Nicla Boards by Arduino latest version and install.

image

Then connect your Nicla Sense Board to your computer and select it

image

Installing BHY2 libraries

Now we need to install the BHY2 libraries we are going to use both the Arduino_BHY2 for the Arduino Nicla Sense ME and the Arduino_BHY2Host for the Arduino Nano 33 IoT.

Go to the Library Manager and install both libraries. You can search for BHY2.

Install BHY2 libraries

Installing or updating Arduino BLE

We will use BLE for communication between the two boards. If you do not have the Arduino BLE library installed or updated, it is time to do so.

Again, from the Library Manager search for BLE

Note: For Arduino Nano 33 IoT boards, it requires the NINA module to be running Arduino NINA-W102 firmware v1.2.0 or later.

https://www.arduino.cc/reference/en/libraries/arduinoble/

Install Arduino BLE library

Updating bhi firmware

Use Arduino_BHY2/examples/BHYFirmwareUpdate/ upload the BHYFirmwareUpdate.ino sketch

 
 
Boot status: 11
 
 
Boot status: 13
 
Interrupt ctrl: 0
 
Interface ctrl: 0
[META EVENT WAKE UP] Firmware initialized. Firmware version 5978
[META EVENT] Firmware initialized. Firmware version 5978
 
Present sensors: 
1 - Accelerometer passthrough
3 - Acceler 
 
Boot status: 11
 
 
Boot status: 13
 
Interrupt ctrl: 0
 
Interface ctrl: 0
[META EVENT WAKE UP] Firmware initialized. Firmware version 5978
[META EVENT] Firmware initialized. Firmware version 5978
 
Present sensors: 
1 - Accelerometer passthrough
3 - Accelerometer uncalibrated
4 - Accelerometer corrected
5 - Accelerometer offset
6 - Accelerometer corrected wake up
7 - Accelerometer uncalibrated wake up
10 - Gyroscope passthrough
12 - Gyroscope uncalibrated
13 - Gyroscope corrected
14 - Gyroscope offset
15 - Gyroscope wake up
16 - Gyroscope uncalibrated wake up
19 - Magnetometer passthrough
21 - Magnetometer uncalibrated
22 - Magnetometer corrected
23 - Magnetometer offset
24 - Magnetometer wake up
25 - Magnetometer uncalibrated wake up
28 - Gravity vector
29 - Gravity vector wake up
31 - Linear acceleration
32 - Linear acceleration wake up
34 - Rotation vector
35 - Rotation vector wake up
37 - Game rotation vector
38 - Game rotation vector wake up
40 - Geo-magnetic rotation vector
41 - Geo-magnetic rotation vector wake up
43 - Orientation
44 - Orientation wake up
48 - Tilt detector
50 - Step detector
52 - Step counter
53 - Step counter wake up
55 - Significant motion
57 - Wake gesture
59 - Glance gesture
61 - Pickup gesture
63 - Activity recognition
67 - Wrist tilt gesture
69 - Device orientation
70 - Device orientation wake up
75 - Stationary detect
77 - Motion detect
94 - Step detector wake up
112 - Undefined sensor ID 
115 - Undefined sensor ID 
128 - Temperature
129 - Barometer
130 - Humidity
131 - Gas
132 - Temperature wake up
133 - Barometer wake up
134 - Humidity wake up
135 - Gas wake up
HCI COMMAND TX -> 01030C00
HCI EVENT RX <- 040E0401030C00
HCI COMMAND TX -> 01011000
HCI EVENT RX <- 040E0C01011000090323095F000323
HCI COMMAND TX -> 01010C08FFFFFFFFFFFFFF3F
HCI EVENT RX <- 040E0401010C00
HCI COMMAND TX -> 01022000
HCI EVENT RX <- 040E0701022000000104
HCI COMMAND TX -> 010A200100
HCI EVENT RX <- 040E04010A2000
HCI COMMAND TX -> 0106200FA000A0000000000000000000000700
HCI EVENT RX <- 040E0401062000
HCI COMMAND TX -> 01082020150201061106020012AC4202C1ADEB11AA34BBE3C23400000000000000000000
HCI EVENT RX <- 040E0401082000
HCI COMMAND TX -> 010920200706094E49434C41000000000000000000000000000000000000000000000000
HCI EVENT RX <- 040E0401092000
HCI COMMAND TX -> 010A200101
HCI EVENT RX <- 040E04010A2000
Eslov int pin: 19

Upload BHY2 App to your Arduino Nicla Sense Board.

We will install the BHY2 App on the Nicla Sense Board. This sketch allows you to control nicla from an external device acting as a host.
We will use the Arduino Nano 33 IoT as a host sending stimuli through BLE.

Navigate to File/Examples/Arduino_BHY2/App

image

Also you will need to increment packet length for App firmware. Look for sensors/SensorTypes.h header file  and change

#define SENSOR_LONG_DATA_FIXED_LENGTH (18)

to #define SENSOR_LONG_DATA_FIXED_LENGTH (30) 

It is a very simple sketch, initially we will set DEBUG to true to be able to see through the serial port how it reacts to BLE calls.

#include "Arduino.h"
#include "Arduino_BHY2.h"

// Set DEBUG to true in order to enable debug print
#define DEBUG true

void setup()
{
#if DEBUG
  Serial.begin(115200);
  BHY2.debug(Serial);
#endif

  BHY2.begin();
}

void loop()
{
  // Update and then sleep
  BHY2.update(100);
}

Upload the BHY2 App sketch to your Nicla Sense ME

It's quite a long compile time compared to when you compile for the Arduino UNO

Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = v1.0
Info : CMSIS-DAP: Serial# = A7B3C296
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for nrf52.cpu on 3333
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00006dc4 msp: 0x20010000
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00006dc4 msp: 0x20010000
** Programming Started **
Info : nRF52832-CIAA(build code: E1) 512kB Flash, 64kB RAM
Warn : Adding extra erase range, 0x00055b78 .. 0x00055fff
** Programming Finished **
shutdown command invoked

--------------------------
upload complete.

If we have activated the DEBUG, adjusting the speed of the serial port monitor to 115200 baud we will obtain the following trace.

 
 
Boot status: 11
 
 
Boot status: 13
 
Interrupt ctrl: 0
 
Interface ctrl: 0
[META EVENT WAKE UP] Firmware initialized. Firmware version 5978
[META EVENT] Firmware initialized. Firmware version 5978
 
Present sensors: 
1 - Accelerometer passthrough
3 - Acceler 
 
Boot status: 11
 
 
Boot status: 13
 
Interrupt ctrl: 0
 
Interface ctrl: 0
[META EVENT WAKE UP] Firmware initialized. Firmware version 5978
[META EVENT] Firmware initialized. Firmware version 5978
 
Present sensors: 
1 - Accelerometer passthrough
3 - Accelerometer uncalibrated
4 - Accelerometer corrected
5 - Accelerometer offset
6 - Accelerometer corrected wake up
7 - Accelerometer uncalibrated wake up
10 - Gyroscope passthrough
12 - Gyroscope uncalibrated
13 - Gyroscope corrected
14 - Gyroscope offset
15 - Gyroscope wake up
16 - Gyroscope uncalibrated wake up
19 - Magnetometer passthrough
21 - Magnetometer uncalibrated
22 - Magnetometer corrected
23 - Magnetometer offset
24 - Magnetometer wake up
25 - Magnetometer uncalibrated wake up
28 - Gravity vector
29 - Gravity vector wake up
31 - Linear acceleration
32 - Linear acceleration wake up
34 - Rotation vector
35 - Rotation vector wake up
37 - Game rotation vector
38 - Game rotation vector wake up
40 - Geo-magnetic rotation vector
41 - Geo-magnetic rotation vector wake up
43 - Orientation
44 - Orientation wake up
48 - Tilt detector
50 - Step detector
52 - Step counter
53 - Step counter wake up
55 - Significant motion
57 - Wake gesture
59 - Glance gesture
61 - Pickup gesture
63 - Activity recognition
67 - Wrist tilt gesture
69 - Device orientation
70 - Device orientation wake up
75 - Stationary detect
77 - Motion detect
94 - Step detector wake up
128 - Temperature
129 - Barometer
130 - Humidity
131 - Gas
132 - Temperature wake up
133 - Barometer wake up
134 - Humidity wake up
135 - Gas wake up
171 - Custom sensor ID 
HCI COMMAND TX -> 01030C00
HCI EVENT RX <- 040E0401030C00
HCI COMMAND TX -> 01011000
HCI EVENT RX <- 040E0C01011000090323095F000323
HCI COMMAND TX -> 01010C08FFFFFFFFFFFFFF3F
HCI EVENT RX <- 040E0401010C00
HCI COMMAND TX -> 01022000
HCI EVENT RX <- 040E0701022000000104
HCI COMMAND TX -> 010A200100
HCI EVENT RX <- 040E04010A2000
HCI COMMAND TX -> 0106200FA000A0000000000000000000000700
HCI EVENT RX <- 040E0401062000
HCI COMMAND TX -> 01082020150201061106020012AC4202C1ADEB11AA34BBE3C23400000000000000000000
HCI EVENT RX <- 040E0401082000
HCI COMMAND TX -> 010920200706094E49434C41000000000000000000000000000000000000000000000000
HCI EVENT RX <- 040E0401092000
HCI COMMAND TX -> 010A200101
HCI EVENT RX <- 040E04010A2000
Eslov int pin: 19
HCI EVENT RX <- 043E13010000000101F5D37481CE7324000000F40101
HCI ACLDATA RX <- 0200200B0007000400100100FFFF0028
HCI ACLDATA TX -> 02000012000E0004001106010005000018060009000118
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400100A00FFFF0028
HCI ACLDATA TX -> 0200001A001600040011140A000E00020012AC4202C1ADEB11AA34B8E3C234
HCI ACLDATA RX <- 0200200B0007000400100F00FFFF0028
HCI ACLDATA TX -> 0200001A001600040011140F001700020012AC4202C1ADEB11AA34BBE3C234
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400101800FFFF0028
HCI ACLDATA TX -> 020000090005000400011018000A
HCI EVENT RX <- 0413050100000100
HCI EVENT RX <- 043E0A0300000006000000F401
HCI ACLDATA RX <- 0200200B000700040008010005000228
HCI ACLDATA TX -> 020000090005000400010801000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008010005000328
HCI ACLDATA TX -> 02000014001000040009070200020300002A0400020500012A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008050005000328
HCI ACLDATA TX -> 020000090005000400010805000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008060009000228
HCI ACLDATA TX -> 020000090005000400010806000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008060009000328
HCI ACLDATA TX -> 0200000D000900040009070700200800052A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008080009000328
HCI ACLDATA TX -> 020000090005000400010808000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004000409000900
HCI ACLDATA TX -> 0200000A0006000400050109000229
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400080A000E000228
HCI ACLDATA TX -> 02000009000500040001080A000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400080A000E000328
HCI ACLDATA TX -> 0200001B001700040009150B00080C00020012AC4202C1ADEB11AA34B9E3C234
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400080C000E000328
HCI ACLDATA TX -> 0200001B001700040009150D00080E00020012AC4202C1ADEB11AA34BAE3C234
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400080E000E000328
HCI ACLDATA TX -> 02000009000500040001080E000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400080F0017000228
HCI ACLDATA TX -> 02000009000500040001080F000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B0007000400080F0017000328
HCI ACLDATA TX -> 0200001B001700040009151000081100020012AC4202C1ADEB11AA34BDE3C234
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008110017000328
HCI ACLDATA TX -> 0200001B001700040009151200121300020012AC4202C1ADEB11AA34BCE3C234
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008130017000328
HCI ACLDATA TX -> 0200001B001700040009151500121600020012AC4202C1ADEB11AA34BEE3C234
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200B000700040008160017000328
HCI ACLDATA TX -> 020000090005000400010816000A
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004000414001400
HCI ACLDATA TX -> 0200000A0006000400050114000229
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004000417001700
HCI ACLDATA TX -> 0200000A0006000400050117000229
HCI EVENT RX <- 0413050100000100
HCI EVENT RX <- 0413050100000100
HCI EVENT RX <- 043E0A0300000024000000F401
HCI ACLDATA RX <- 0200200900050004001217000100
HCI ACLDATA TX -> 02000005000100040013
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200700030004000A1700
HCI ACLDATA TX -> 0200000700030004000B0100
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004001214000100
HCI ACLDATA TX -> 02000005000100040013
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200700030004000A1300
HCI ACLDATA TX -> 020000090005000400010A130007
HCI EVENT RX <- 0413050100000100

We already have our remote sensor ready. Let's connect from an Android phone using the Nordic Semiconductor nRF Connect App

image

image

Remote monitor firmware

You can download or review the firmware source code for the Arduino Nano 33 IoT in the following repository on Github.

https://github.com/javagoza/Remote-IAQ-Monitor

Libraries

You will need to install the following Libraries

  • adafruit/Adafruit-ST7735-Library: library for the Adafruit 1.8" SPI display
  • adafruit/Adafruit-GFX-Library: Adafruit GFX graphics core library
  • arduino-libraries/RTCZero: RTC Library for SAMD21 based boards
  • arduino-libraries/NTPClient: Connect to a NTP server (github.com)

The code makes use of a modified library for simulating 7-segment displays on TFT screens that I recently created for an Arduino UNO chess clock project.

The modified library is included in the repository.

How does it work?

When starting the monitor, it connects to the Internet using the WiFi of the wifinina module and retrieves the current time through an NTP client that updates the time from the RTCZero library.

Then the BHYHost module starts indicating that it has to search for a NICLA module by BLE connection.

BHY2Host.begin(false, NICLA_VIA_BLE)


When the connection to the NICLA module, that is running the Bosch App firmware, is established, the monitor registers as a consumer of BSEC packets

SensorBSEC co2Sensor(SENSOR_ID_BSEC);

... co2Sensor.begin();

SENSOR_ID_BSEC is the new data format for the BSEC data. You need to update the Nicla bhi firmware to the last version. See section: ."Updating bhi firmware"

Also you will need to increment packet length for App firmware and BHY2Host Library

sensors/SensorTypes.h 

Change: #define SENSOR_LONG_DATA_FIXED_LENGTH (18) to #define SENSOR_LONG_DATA_FIXED_LENGTH (30)  in both libraries

The monitor continuously polls the remote sensor and receives this information
CO2 ppm: BSEC output values - iaq: 500 iaq_s: 567 b_voc_eq: 1000.00 co2_eq: 5674 accuracy: 2 comp_t: 32.01 comp_h: 31.03 comp_g: 4
The monitor uses external interrupts for sensing the state of the three navigation controls. The buttons are debounced by software.
When large numbers need to be painted without flickering, a library is used to simulate 7-segment displays on TFT screens. I created this library to be able to change the numbers without having to erase large areas of the screen that are very time consuming.
Periodically at regular intervals a snapshot of the data is saved to a comma separated text (csv) file in a daily log file.
Every new day a new file is created. These files can be parsed and graphed from the graph screen.

Historical data format

Historical data is stored on the SD card. One CSV file per day. The file name has the following pattern: YYMMDD.txt

  // if the file opened okay, write to it:
  if (dataLogggerFile) {
    if (isNewFile) {
      // write header
      dataLogggerFile.println( F("'time','IAQ','ACCURACY','TEMP','HUMIDITY','CO2EQ','VOCEQ','IAQS'"));
    }
    dataLogggerFile.print( logTime);
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.iaq());
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.accuracy());
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.comp_t());
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.comp_h());
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.co2_eq());
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.b_voc_eq());
    dataLogggerFile.print(",");
    dataLogggerFile.print( co2Sensor.iaq_s());
    dataLogggerFile.println("");
    // close the file:
    dataLogggerFile.close();
  } 

References

Source code of the project and other related projects that I have previously built:

  • Source Code: javagoza/Remote-IAQ-Monitor (github.com)
  • Venttracker Environmental Monitor Version 2
  • Venttracker Environmental Monitor Version 1
  • Arduino UNO Chess Clock TFT LCD Virtual Clock Display Library
  • Arduino UNO TFT LCD Chess Clock with full time controls

Arduino and Bosch Sensortec Documentation

  • Arduino Nicla Sense ME documentation
  • Arduino Nano 33 IoT documentation
  • Bosch Sensortec: Arduino Nicla Sense ME
  • Nicla Sense ME Firmware
  • Gas sensor BME688 | Bosch Sensortec (bosch-sensortec.com)

Next steps

I had designed a small box for the Nicla Sense ME Arduino board and a Li-Po battery but for reasons unrelated to this project (Tales for Makers - Episode 1: Where is Tommy?) I had to solder pins to the board and it no longer fits.
The idea was to be able to fix the sensor on the back of the chair to minimize the effect of breathing and, incidentally, measure the activity on the chair. Movements, sitting, lifting, leg vibrations, etc.
image

Conclusion

A few weeks ago I made a simple remote CO2 monitor project using an Arduino Nano 33 BLE  and the Arduino Nicla Sense ME board . During the following weeks I was using it in the office and I realized things that were missing, such as multiple screens, navigation buttons, reset button, historical data storage, automatic update of the time from the internet, graphing of the data, reduce flickering, brightness control of the LED of the display...

First attempt with and Arduino BLE as monitor board, BLE connection but no WiFi:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

I have introduced all those improvements to that first project and surely it will not stop at this and I will improve it even more.

Thanks for reading!

  • Sign in to reply

Top Comments

  • javagoza
    javagoza over 3 years ago +1
    After several days of continuous operation without problems, the monitor crashed yesterday. I have not been able to identify the reason so for now I have activated the SAM D21 Watchdog Timer (WDT) that…
  • javagoza
    javagoza over 3 years ago

    After several days of continuous operation without problems, the monitor crashed yesterday.
    I have not been able to identify the reason so for now I have activated the SAM D21 Watchdog Timer (WDT) that restarts the board if it detects 16 seconds without executing the main loop. It is a very long time but it is to be able to give time to the tasks that are executed on the SD card or when setting up the WiFi without complicating the code by clearing the watchdog timer outside the loop() code.

    From the SAM D21 Family Data Sheet. SAM D21 Family Data Sheet (microchip.com)

    "The Watchdog Timer (WDT) is a system function for monitoring correct program operation. It makes it possible to
    recover from error situations such as runaway or deadlocked code. The WDT is configured to a predefined time-out
    period, and is constantly running when enabled. If the WDT is not cleared within the time-out period, it will issue a
    system reset. An early-warning interrupt is available to indicate an upcoming watchdog time-out condition.
    The window mode makes it possible to define a time slot (or window) inside the total time-out period during which
    the WDT must be cleared. If the WDT is cleared outside this window, either too early or too late, a system reset will
    be issued. Compared to the normal mode, this can also catch situations where a code error causes the WDT to be
    cleared frequently.
    When enabled, the WDT will run in active mode and all sleep modes. It is asynchronous and runs from a CPU independent clock source. The WDT will continue operation and issue a system reset or interrupt even if the main
    clocks fail."

    image

    Set up the WDT

    // Set up the WDT to perform a system reset if the loop() blocks for more than 16 seconds
    void setupWDT() 
    {
     // Set up the generic clock (GCLK2) used to clock the watchdog timer at 1.024kHz
      REG_GCLK_GENDIV = GCLK_GENDIV_DIV(4) |            // Divide the 32.768kHz clock source by divisor 32, where 2^(4 + 1): 32.768kHz/32=1.024kHz
                        GCLK_GENDIV_ID(2);              // Select Generic Clock (GCLK) 2
      while (GCLK->STATUS.bit.SYNCBUSY);                // Wait for synchronization
    
      REG_GCLK_GENCTRL = GCLK_GENCTRL_DIVSEL |          // Set to divide by 2^(GCLK_GENDIV_DIV(4) + 1)
                         GCLK_GENCTRL_IDC |             // Set the duty cycle to 50/50 HIGH/LOW
                         GCLK_GENCTRL_GENEN |           // Enable GCLK2
                         GCLK_GENCTRL_SRC_OSCULP32K |   // Set the clock source to the ultra low power oscillator (OSCULP32K)
                         GCLK_GENCTRL_ID(2);            // Select GCLK2         
      while (GCLK->STATUS.bit.SYNCBUSY);                // Wait for synchronization
    
      // Feed GCLK2 to WDT (Watchdog Timer)
      REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN |           // Enable GCLK2 to the WDT
                         GCLK_CLKCTRL_GEN_GCLK2 |       // Select GCLK2
                         GCLK_CLKCTRL_ID_WDT;           // Feed the GCLK2 to the WDT
      while (GCLK->STATUS.bit.SYNCBUSY);                // Wait for synchronization
    
      REG_WDT_CONFIG = WDT_CONFIG_PER_16K;              // Set the WDT reset timeout to 16384 clock cycles, 16 seconds
      while(WDT->STATUS.bit.SYNCBUSY);                  // Wait for synchronization
     
      REG_WDT_CTRL = WDT_CTRL_ENABLE;                   // Enable the WDT in normal mode
      while(WDT->STATUS.bit.SYNCBUSY);                  // Wait for synchronization
    }

    And inside loop() function notify the WDT by clearing the watchdog timer

      if (!WDT->STATUS.bit.SYNCBUSY) {              // Check if the WDT registers are synchronized  
        REG_WDT_CLEAR = WDT_CLEAR_CLEAR_KEY;        // Clear the watchdog timer
      }

    I have uploaded the changes to the Github repository

    https://github.com/javagoza/Remote-IAQ-Monitor

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • javagoza
    javagoza over 3 years ago

    Looking for information about the Arduino Nicla Sense ME I have found a reference to this project. Heart eyes

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube