Final Project

X-Breath

X-Breath

X-Breath is a sleek decorative piece equipped with air-sensing capabilities for CO2, TVOC, particulate matter, temperature, and humidity in its ambient environment. Your browser does not support the video tag. License This project is shared under the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) license. Overview What will it Do? I will develop a device capable of measuring CO2 Levels of the surrounding in addition to (Temperature, Humidity, TVOC, and Particulate Matter) then the device will push these Information to an online platform for monitoring.

1. Ideation

Research and Motivation Crafting a project emerges as a straightforward endeavor when guided by a well-defined plan and meticulous breakdown. However, translating this simplicity into reality proves to be a nuanced challenge, commencing with the inception of an idea – a point where my creative journey encounters a stumbling block. Since the beginning of December 2023, I’ve embarked on a quest to crystallize a concept that resonates with my aspirations. Regrettably, my progress has been impeded by the persistent emergence of technical hurdles, casting shadows on the potential realization of my envisioned accomplishment.

2. Plan

Plan My plan focus on 5 different stages Stage 1 (Spiral 1) Collecting Data AIR -- O2 .-- Co2 .-- Other air particles Small to mid size Made of wood Stage 2 (Spiral 2) Full of RGB’s Having a Screen Try changing the MCU Stage 3 (Spiral 3) Enhance the Shape and the quality of the packaging Build an app or just link it to blynk IOT ESP32 Stage 4 (Spiral 4) Add Speaker “Amplifier circuit is needed” Try make the size smaller Try making the device rechargeable “Stand alone” Charging circuit is required Stage 5 (Spiral 5) Build it using 3D printer Small rounded shape Easy to carry RGB, No Screen, IOT Connected Project Sketch System Diagram Schedule

3. Research

As planned I’m looking to create a device able to monitor the Surrounding air and check the quality of it. Air Quality Is a phrase refers to how clean the Air is and the amount of particles this air carry. When air quality is good, the air is clear and contains only small amounts of solid particle and chemical pollutants. Poor air quality, which contains high levels of pollutants, is often hazy and dangerous to health and the environment.

4. Sensors

As per My previous research I have to collect (CO2 , Particulate Matter (PM), Volatile organic compounds (VOC), Temperature, and Humidity) to obtain the quality of the indoor AIR so below I will list the needed sensors to collect the required data and their primary test. List of sensors. ID Sensor Measured Value LINK Price Datasheet 1 SCD30 CO2, Temp, Hum LINK $51.4 LINK 2 PMS5003 PM1, PM2.5, PM10 LINK $39.

5. IOT Cloud

As for the platform I want to use, I have previously tested two platform in the Interface and Application Programming week and I have decided to use thinger.io because it have more options in terms of data monitoring and data analysis after the data reaches the platform, But unfortunately this platform is not cheap if I want to expand the sensor data im collecting, So I decided to go with Arduino cloud and buy the maker plan So I can push all my data to the cloud and have 90 days of data retention.

6. Embedded Design and Fabrication

I have previously finished all testing for the hardware and the circuit is ready but it’s built using a breadboard now I need to design a new PCB board and make sure all my circuit is fully integrated on this board. As I have shown before my circuit is working 100% as I want and it is pushing data to the IOT platform as I want but I need now to make this complected messy looking circuit to a sleek lovely board with no complication when looking to it.

7. Housing Design and Fabrication

After finalizing all the Electrical requirement and the Board fabrication which the core of my project I need now a good representation for this core which can be a sleek piece on the corner or in the middle of the setting area which can’t go wrong when the person eye come to it and it attract the others attention. Previously I have decided to use ARABISC look on the front of the piece.

8. Wood processing and assembling

NOw After I have finalized the process of fabrication I need to assemble the housing all together with the PCB, But before that I need to make sure that this wood will stay in great shape as long as possible so i decided to give this wood some process to increase its life span and also to protect it from the Humidity and other weather conditions. This Process is the coating process as I will put a chemical liquid on the wood to protect it (This chemical is called Sanding Sealer)

9. Stand Design And Fabrication

After finalizing all the Housing Part and the needed to have every thing working as needed, Now I need to design and fabricate the stand for the housing to sit on and also enclosure for the PM2.5 Sensor –> This Is why I have decided to build this part. This part needs to be simple and compact, able to carry the housing piece and contain the PM2.5 sensor without any complications.

10. Final Product

Alhamdulillah, all our previous efforts have culminated in outstanding results. Every component is meticulously designed and functioning flawlessly. Moreover, the Electronics component, the core of our product, seamlessly transmits data to the Cloud as required. Now I will show Up the final assembly for all the parts together and a brief about what next in the future. This Is the final look of the project To know More about this in a brief LINK.

4. Sensors

Posted April 11, 2024

As per My previous research I have to collect (CO2 , Particulate Matter (PM), Volatile organic compounds (VOC), Temperature, and Humidity) to obtain the quality of the indoor AIR so below I will list the needed sensors to collect the required data and their primary test.

List of sensors.

ID Sensor Measured Value LINK Price Datasheet
1 SCD30 CO2, Temp, Hum LINK $51.4 LINK
2 PMS5003 PM1, PM2.5, PM10 LINK $39.95 LINK
3 AGS02MA TVOC LINK $4.95 LINK
4 AM2302 Temp and Humidity LINK $7.42 LINK

These are the sensors I want to use to build this project.

Now I will test each sensor alone.

SCD30

The SCD30 is a highly accurate CO2 sensor module based on CMOSens® Technology for IR detection that includes a best-in-class humidity and temperature sensor.

This is NDIR (non-dispersive infrared) Sensor which work by using an infrared (IR) lamp to direct waves of light through a tube filled with a sample of air. –> This air moves toward an optical filter in front of an IR light detector. The IR light detector measures the amount of IR light that passes through the optical filter.

NDIR Sensor working

Working principle

In an NDIR CO2 sensor, the band of IR radiation also produced by the lamp is very close to the 4.26-micron absorption band of CO2. Because the IR spectrum of CO2 is unique, matching the light source wavelength serves as a signature or “fingerprint” to identify the CO2 molecule.

As the IR light passes through the sample tube of air, the CO2 gas molecules absorb the specific band of IR light while letting other wavelengths of light pass through. At the detector end, the remaining light hits an optical filter that absorbs every wavelength of light except the wavelength absorbed by CO2 molecules in the sample tube.

Finally, an IR detector reads the remaining amount of light that was not absorbed by the CO2 molecules or the optical filter.

For more information about the sensor please refer to links below:

NDIR Sensors SCD30

Testing

  • I will test the sensor by connecting it to my previously built board.

SCD30 and My board

SCD30 Pinout

Connection with Xiao esp32c3

  • Then I will Use Arduino IDE to code.

  • I will start by downloading the library (Adafruit SCD30 with its dependency) then I will use the example code to check the sensor and its data.

Downloading the adafruit SCD30 library

Dependencies of the library

  • The example I will use is (adafruit_scd30_test).

Example used

  • Then I will just upload the code and test how it works.

Output

Great I have a good CO2 percentage.

Code I have used


// Basic demo for readings from Adafruit SCD30
#include <Adafruit_SCD30.h>

Adafruit_SCD30  scd30;


void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit SCD30 test!");

  // Try to initialize!
  if (!scd30.begin()) {
    Serial.println("Failed to find SCD30 chip");
    while (1) { delay(10); }
  }
  Serial.println("SCD30 Found!");


  // if (!scd30.setMeasurementInterval(10)){
  //   Serial.println("Failed to set measurement interval");
  //   while(1){ delay(10);}
  // }
  Serial.print("Measurement Interval: "); 
  Serial.print(scd30.getMeasurementInterval()); 
  Serial.println(" seconds");
}

void loop() {
  if (scd30.dataReady()){
    Serial.println("Data available!");

    if (!scd30.read()){ Serial.println("Error reading sensor data"); return; }

    Serial.print("Temperature: ");
    Serial.print(scd30.temperature);
    Serial.println(" degrees C");
    
    Serial.print("Relative Humidity: ");
    Serial.print(scd30.relative_humidity);
    Serial.println(" %");
    
    Serial.print("CO2: ");
    Serial.print(scd30.CO2, 3);
    Serial.println(" ppm");
    Serial.println("");
  } else {
    //Serial.println("No data");
  }

  delay(100);
}
  • Now I will compare the temperature and humidity from DHT22 and this sensor.

DHT and SCD30 comparison

  • Both are close to each other and gives almost the same values.

I have to re-consider having the DHT on my board.

According to this documentation

There is no wide difference between the integrated temperature & Humidity sensors on the SCD30 and the DHT22 but DHT22 lacks the integrated technology that SCD30 offers.

So I will drop the DHT22 from my list (80%)–> I will do it

Code I have Used


// Basic demo for readings from Adafruit SCD30
#include <Adafruit_SCD30.h>
#include <DHT.h>

// Where the DHT data pin is connected
#define PIN 8 
// DHT sensor Type.
#define TYPE DHT22 

DHT zaid(PIN,TYPE); // Constructor

Adafruit_SCD30  scd30;


void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit SCD30 test!");

  // Try to initialize!
  if (!scd30.begin()) {
    Serial.println("Failed to find SCD30 chip");
    while (1) { delay(10); }
  }
  Serial.println("SCD30 Found!");


  // if (!scd30.setMeasurementInterval(10)){
  //   Serial.println("Failed to set measurement interval");
  //   while(1){ delay(10);}
  // }
  Serial.print("Measurement Interval: "); 
  Serial.print(scd30.getMeasurementInterval()); 
  Serial.println(" seconds");

  zaid.begin(); // DHT sensor with zaid name started.


}

void loop() {
  
  float temp = zaid.readTemperature();
  float hum = zaid.readHumidity();
  
  Serial.println("DHT22 Data : ");
  Serial.print("Temperature = ");Serial.println(temp);
  Serial.print("Humidity = ");Serial.println(hum);
  delay(1000);

  Serial.println("SCD30 DATA");
  if (scd30.dataReady()){
    Serial.println("Data available!");

    if (!scd30.read()){ Serial.println("Error reading sensor data"); return; }

    Serial.print("Temperature: ");
    Serial.print(scd30.temperature);
    Serial.println(" degrees C");
    
    Serial.print("Relative Humidity: ");
    Serial.print(scd30.relative_humidity);
    Serial.println(" %");
    
    Serial.print("CO2: ");
    Serial.print(scd30.CO2, 3);
    Serial.println(" ppm");
    Serial.println("");
  } else {
    //Serial.println("No data");
  }

  delay(100);
}

Reflection

  • This sensor is very sensitive as if someone blow to the sensor from a distance it will affect the reading.

  • This sensor have a sampling rate of 0.5 Hz.

PMS5003

PMS5003 is a kind of digital and universal particle concentration sensor, which can be used to obtain the number of suspended particles in the air.

The Sensor uses a Laser Scattering principle where a laser beam hit a light diffuser so the light scatter and hit the air particles then this goes to a receiver to be analyzed.

Working principle

Working Principle

The Laser pm 2.5 air quality sensor can assess air quality by measuring the concentration of suspended particulate matter (PM2.5) in the air. It works as follows:

  1. Laser Emitter: First, the laser sensor generates a laser beam through a laser emitter.
  2. High-efficiency scatterer: The laser beam is directed to a high-efficiency scatterer (also known as a diffuser), which allows the laser beam to scatter with airborne particles.
  3. Receiver: During the scattering process, the scattered light enters a receiver inside the sensor, which converts the received light signal into an electrical signal for processing.
  4. Light scattering signal analysis: the received light signal will be analyzed to determine the concentration of particulate matter in the air by measuring the angle and intensity of light scattering.
  5. PM2.5 Concentration Calculation: By estimating the size of the particulate matter based on the angle and intensity of scattering, the PM2.5 concentration is then calculated.

Testing

I will connect it now with the Board I have made.

  • This sensor uses serial communication to send its data.

PM2.5 Pin out

PM2.5 datasheet Pin out

  • For the connection with the XIAOESP32C3. –> The Sensor return data in TTL (3.3) so I don’t have to worry (Because the sensor is taking 5V).

PM2.5 with Xiao

PM2.5 with Xiao

  • Now I will use the Arduino IDE to code it.

  • I will Install the Library (Adafruit_PM25AQI).

PM2.5 library

  • Then I will use the example code coming with the library.

PM2.5 example

  • As for this code it uses software serial library which comes with all the Arduino boards but for the ESP32 This is not achievable so I have to use Hardware serial library.

I will clarify it more in the code file.

  • Now I will Upload the code and check the values.

PM2.5 data

These data shocked me (I thought i may have more dust particles) but this is good I’m within the recommended values from the World health Organization.

Please refer to this Article for more information.

Code USED


#include "Adafruit_PM25AQI.h"
#include <HardwareSerial.h>

HardwareSerial pmSerial(0);

Adafruit_PM25AQI aqi = Adafruit_PM25AQI();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial) delay(10);

  delay(1000);
  pmSerial.begin(9600,SERIAL_8N1, -1, -1);// hardware serial default for tx 6 and rx 7 in xiaoesp32c3
   if (! aqi.begin_UART(&pmSerial)) {
    Serial.println("Could not find PM 2.5 sensor!");
    while (1) delay(10);
  }else {Serial.println("PM25 found!");}
}

void loop() {
  // put your main code here, to run repeatedly:
   PM25_AQI_Data data;
  
  if (! aqi.read(&data)) {
    Serial.println("Could not read from AQI");
    delay(500);  // try again in a bit!
    return;
  }
  Serial.println("AQI reading success");

  Serial.println();
  Serial.println(F("---------------------------------------"));
  Serial.println(F("Concentration Units (standard)"));
  Serial.println(F("---------------------------------------"));
  Serial.print(F("PM 1.0: ")); Serial.print(data.pm10_standard);
  Serial.print(F("\t\tPM 2.5: ")); Serial.print(data.pm25_standard);
  Serial.print(F("\t\tPM 10: ")); Serial.println(data.pm100_standard);
  Serial.println(F("Concentration Units (environmental)"));
  Serial.println(F("---------------------------------------"));
  Serial.print(F("PM 1.0: ")); Serial.print(data.pm10_env);
  Serial.print(F("\t\tPM 2.5: ")); Serial.print(data.pm25_env);
  Serial.print(F("\t\tPM 10: ")); Serial.println(data.pm100_env);
  Serial.println(F("---------------------------------------"));
  Serial.print(F("Particles > 0.3um / 0.1L air:")); Serial.println(data.particles_03um);
  Serial.print(F("Particles > 0.5um / 0.1L air:")); Serial.println(data.particles_05um);
  Serial.print(F("Particles > 1.0um / 0.1L air:")); Serial.println(data.particles_10um);
  Serial.print(F("Particles > 2.5um / 0.1L air:")); Serial.println(data.particles_25um);
  Serial.print(F("Particles > 5.0um / 0.1L air:")); Serial.println(data.particles_50um);
  Serial.print(F("Particles > 10 um / 0.1L air:")); Serial.println(data.particles_100um);
  Serial.println(F("---------------------------------------"));
  

  delay(1000);
}

So Among all of these data I will Only need 3 DATA (PM1.0, PM2.5, and PM10)

  • Now Let me try to trigger the sensor by using a lighter.

It took the sensor a couple of seconds to respond but the change was very big.

Reflection

  • The sensor is very easy to use and connect.

  • The coding are very simple just a few things to know about the XIAO hardware serial.

  • The sensor is big in size so there is no way to fit in what i would like to build so I need to have alternative solution for this.

AGS02MA (TVOC)

AGS02MA is a high-performance TVOC sensor which is equipped with a dedicated ASIC chip, which detect and monitor variety of organic volatile gases, such as ethanol, ammonia, sulfide, benzene steam, smoke.

Working Principle

When the sensor works in air environment, the conductivity of the gas-sensitive material changes with the concentration of the gas being detected in the air. The higher the concentration of the gas being detected, the higher the conductivity of the gas-sensitive material will be. Based on this principle, a special integrated circuit is adopted to convert the change in conductivity into an output signal corresponding to the concentration of the gas.

Working principle

So in brief there is a sensitive substance on the top of the sensor its resistivity changes according to the VOC in the air, –> the more the VOC the conductivity increases which means the resistivity decrease.

Testing

This sensor is very simple sensor and Have to be connected using I2C, The sensor is analog but there is a chip inside change the data to digital and then communicate it by I2C to the MCU.

Note this sensor needs pull ups on the I2C lines and the speed of communication has not to exceed 30KHz.

I have to keep an Eye on the speed and check how to manage two different clocking sensors on the same MCU.

Pinout

  • I will connect and test this sensor using the Arduino UNO first.

With UNO

UNO connected

Note : The Sensor operate from 3.3 to 5V

  • Now I will code it starting by downloading the Library (Adafruit_AGS02MA), With its dependencies.

Library

Library Dependencies

  • Then I will use the library example.

Library example

  • Then I will just upload it.

Data

  • Now as seen the data locks unrealistic.

the sensor needs to to be powered on for stabilization –> As per the data sheet the stabilization for the first time takes between 12 hours to 96 hours depends on the storage period.

Stabilization

I will leave it for 12 hours then I will check back if the data are still unrealistic I will leave it for 72 hours.

  • So these are the data after leaving the sensor for almost 40 hours plugged.

Data after 40 hours

I can tell the sensor needs more until I see stability in the reading for a while.

According to Kaiterra the (a good TVOC amount is under 220 ppb)

For more information Please check this LINK

  • Now this sensor is bothering me with the I2C bus speed ( The sensor can’t operate above 30K bus speed).

  • So I need to find a way to manage SCD30 to work on this level as it by default it works on (100K bus speed).

  • I will try now to connect both sensors on the Arduino for testing then I will jump to the XIAO.

I’m Worried of one thing the SCD30 has internal 45K pull-up resister to 3.3v on the I2C bus and the TVOC sensor needs between 1k to 10k.

I think I can come over this as long as the current is not exceeding 3mA on the bus (I=V/R –> 3.3/10K = 0.33mA even if the Resister is 1K –> I = 3.3mA which is acceptable)

So I will connect a 10K pull-up on the I2C bus and connect both sensors and check if they will work.

Connected with SCD30

  • Uploading the code I will try now to combine both codes together.

  • Unfortunately it did not work.

TVOC not working

  • I will bypass this argument in the code and check how it will act.

Bypass the argument

  • So as seen the same problem still appearing but at least the SCD30 works very fine.

  • Now I will try to set the clock bus to 20K by using the ( Wire.setClock(20000); ).

Setting the speed to 20k

  • Nice both sensors are giving the needed data –> However I’m unable to read the TVOC sensor resistance but as long as the value of the TVOC is correct that is fine for now.

The code USED


/* Note this sensor is very very picky about I2C speed - it wants maximum 20KHz which is way 
 *  below the standard 100KHz. Not all Arduino-compatible platforms successfully set the clock
 *  speed that low. We've tested this library with Atmega328 (Arduino UNO etc) and ESP32 sucessfully!
 */

#include "Adafruit_AGS02MA.h"
#include <Adafruit_SCD30.h>

Adafruit_AGS02MA ags;
Adafruit_SCD30  scd30;


void setup() {
  Serial.begin(115200);
  Serial.println(F("Adafruit AGS20MA Test"));

  if (! ags.begin(&Wire, 0x1A)) {
//  if (! ags.begin(&Wire1, 0x1A)) { // or use Wire1 instead!
    Serial.println("Couldn't find AGS20MA sensor, check your wiring and pullup resistors!");
    while (1) yield();
  }
  if (!scd30.begin()) {
    Serial.println("Failed to find SCD30 chip");
    while (1) { delay(10); }
  }
  Serial.println("SCD30 Found!");

  /*if (ags.getFirmwareVersion() == 0) {
    Serial.println(F("Could not read firmware, I2C communications issue?"));
    while (1) yield();
  }*/

  Serial.print("Firmware version: 0x");
  Serial.println(ags.getFirmwareVersion(), HEX);
  ags.printSensorDetails();

 Serial.print("Measurement Interval: "); 
  Serial.print(scd30.getMeasurementInterval()); 
  Serial.println(" seconds");
  Wire.setClock(20000);
  // uncomment to change address, will need to restart and update the begin() argument!
  //ags.setAddress(0x1A); while (1);
}

void loop() {

  uint32_t resistance = ags.getGasResistance();
  uint32_t tvoc = ags.getTVOC();
  
  if (resistance == 0) {
    Serial.println(F("Failure reading resistance, I2C communications issue?"));
  } else {
    float kohm = resistance / 1000.0;
    Serial.print(F("Gas resistance: "));
    Serial.print(kohm);
    Serial.println(" Kohms");
  }

  if (tvoc == 0) {
    Serial.println(F("Failure reading TVOC, I2C communications issue?"));
  } else {
    Serial.print(F("TVOC: "));
    Serial.print(tvoc);
    Serial.println(" ppb");
  }

  delay(2000);

  s30();
}

void s30 (){

  if (scd30.dataReady()){
    Serial.println("Data available!");

    if (!scd30.read()){ Serial.println("Error reading sensor data"); return; }

    Serial.print("Temperature: ");
    Serial.print(scd30.temperature);
    Serial.println(" degrees C");
    
    Serial.print("Relative Humidity: ");
    Serial.print(scd30.relative_humidity);
    Serial.println(" %");
    
    Serial.print("CO2: ");
    Serial.print(scd30.CO2, 3);
    Serial.println(" ppm");
    Serial.println("");
  } else {
    //Serial.println("No data");
  }

  delay(100);
}
  • Great News I kept trying different bus speeds until the resistance worked.

I have set the bus to 16k speed.

Setting the speed to 16K

Great at this point I have them both working together, –> Now is the moment of truth ; I have to build all of this on the XIAO.

I will do it all as it is but changing the UNO to My XIAO board and check.

  • I will start by uploading the code first then I will change the connection.

I used the exact same code.

Alhamdollelah XIAO worked perfectly.

Alhamdollelah, All the sensors are tested and they are working as I want.

Now I will prepare the code to be then linked with one of the Platforms.