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.

5. IOT Cloud

Posted April 11, 2024

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. (Alhamdollelah I have a gift code which reduced 20 % for me)

However Arduino cloud is so easy to use and very convenient for naive as the cloud will provide every thing related to the code and how to push your data to the cloud and then how to create the dashboard from scratch.

Let’s GO Ahead and Code

  • I will start very fast and code my device using the sketch the Arduino cloud will generate and then adds up my components libraries and my functions previously created in the sensor testing.

  • First of all I will create a device and set it up.

Adding Device

For more Information Please refer to this LINK on how to set up a device and also set a full working device with the IOT platform.

  • After adding the device I will add a new thing as stated in the platform.

Adding Thing

  • Now in this section I will add all the variables I want then I will add my code.

Variables

  • Here I have 11 variables added (For the free version its only 5 variables).

  • Then I will move to sketch and start adding my code if I want to choose the online compiler or I can just copy and paste on a local sketch and save it.

We have to remember to copy the header file also and name exactly the same as it in the code (You can change but remember they must match).

SKetch tab

  • Now I will only connect the codes I have previously built for each sensor.

  • I will only make sure to push the data I want to the cloud.

For more Information About how to set the code for the cloud and how to connect with it please refer to this LINK

  • Now I need to make sure that the variables I’m gonna use are the same in the header file so I can push them to the cloud.

Sometimes I create local variables within the function so its important to push this data to the global variable other wise it won’t make any difference (Reminding my self).

Code I have Used



#include "thingProperties.h"

#include <Adafruit_SCD30.h>//CO2 Sensor Library
#include "Adafruit_AGS02MA.h"//TVOC Library 

#include "Adafruit_PM25AQI.h"//PM Library 
#include <HardwareSerial.h> // The hardware serial library to use the other serial port within the Xiao esp32c3


#include <Adafruit_NeoPixel.h> // Neopixel Library 


HardwareSerial pmSerial(0); // Setting the hardware serial for the PArticulate matter sensor. 

Adafruit_PM25AQI aqi = Adafruit_PM25AQI(); // PM constructor

Adafruit_SCD30  scd30; // CO2 Sensor Constructor
Adafruit_AGS02MA ags; // TVOC sensor Constructor

Adafruit_NeoPixel zaid = Adafruit_NeoPixel(16, 3 , NEO_GRB + NEO_KHZ800); // NEOPIXEL Constructor 
int rColor ; // Variable to store the RGB color



void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(115200);
  //while (!Serial) delay(10); 
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 
  if (!scd30.begin()) {
    Serial.println("Failed to find SCD30 chip");
    while (1) { delay(10); }
  } // This function is not necessary to be used at all in the final version (I have used it for the debug only)
  Serial.println("SCD30 Found!");

  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();
  }// This function is also not necessary in the final code just used for debugging.
  Serial.print("Firmware version: 0x");
  Serial.println(ags.getFirmwareVersion(), HEX); // The firmware version of the TVOC sensor
  ags.printSensorDetails();
  
  Wire.setClock(16000); // I2C Clock speed to 16K 

  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!");} // This function is not necessary to be used in the final stage its only used in depugging. 




  zaid.begin(); // Initiallize the RGB Class (Zaid)
  zaid.setBrightness(100); // setting the brightness of the RGB to full
  zaid.show(); // Initialize all pixels to 'off'

  

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
 ArduinoCloud.update();
  // Your code here 
  PM25_AQI_Data data;// Particulate matter sensor class (Data)

   tVOC = ags.getTVOC();// pushing the TVOC sensor reading to the global variable to be pushed to the cloud
    if ( aqi.read(&data)) {// this function will check if the class data of the PM sensor is ready
    pMStatus = HIGH;  // pushing the status of the PM sensor to the cloud (HIGH)
    pM2_5 = data.pm25_standard;// Pushing the data of the PM2.5 to the global variable
    pM10 = data.pm100_standard ;//  Pushing the data of the PM10 to the global variable
    pM1_0 = data.pm10_standard; //  Pushing the data of the PM1.0 to the global variable
    
    }else{pMStatus = LOW;// If readings are not ready the status is OFF}
   scd30.setMeasurementInterval(10);// setting the reading interval of the SCD30 (CO2 Sensor) to 10 seconds {This sensor can takes reading from 2 Seconds to 180 seconds}
   if (scd30.dataReady()){if (!scd30.read()){ Serial.println("Error reading sensor data"); return; }// This function is not necessary just for debugging or we can elevate its use for status but in this case we need to create another variable for this. 
    
    temperature = scd30.temperature; // Pushing the temperature data to the global variable
    humidity = scd30.relative_humidity;// Pushing the Humidity data to the global variable
    cO2 = scd30.CO2;// Pushing the CO2 data to the global variable
    // the following are only used for debugging you can exclude them.
    Serial.print("Temperature: ");
    Serial.println(temperature);
    Serial.print("Humidity: ");
    Serial.println(humidity);
    Serial.print("CO2: ");
    Serial.println(cO2);
    Serial.print("TVOC: ");
    Serial.println(tVOC);
    Serial.print(F("PM 2.5: ")); Serial.println(data.pm25_standard);
  }
 
 onRGBChange(); // calling the RGB function
   
  
}
// This function is for the RGB ring to show only one color on the ring
void test(uint32_t c){
  for (int i =0 ;i<zaid.numPixels();i++){
    zaid.setPixelColor(i,c); // Setting the pixel color by passing the pixel number and the color of each pixel
    zaid.show(); // Turn the pixel on 
    delay(10); // delay for the function to take effect. 
  }
}

void onRGBChange() {
  // Add your code here to act upon Brightness change
  bool RGBstate = rGB.getSwitch(); // Getting the state of the RGB from the cloud 

  if(RGBstate == 1){// If the state is 1 thats mean the RGB is running and we need to take the RGB values from the cloud so the ring can hue with the same color. 
  
  uint8_t r, g, b;//local variable to stor the data coming from the cloud
  rGB.getValue().getRGB(r,g,b); // Getting the Value from the cloud 
  rColor = zaid.Color(r,g,b); // Passing the Value to the color function I have for my RGB
  if (rainbow == 1){// Taking the status from the cloud to check for the need of animation or not if satus 1 animation are going to be produced.
    if (animation_type == 1){ // ANimation case types.
    rainbowtest(5);// Moving rainbow function 
    zaid.show();// To initialize the RGB to show the last function
    }else if (animation_type == 2){
    
    zaid.rainbow();// Calling the static rainbow function
    zaid.show();
    }else if (animation_type == 3){
      
      theaterChaseRainbow(10);// calling the chasing function with 10 milli second delay 
    }else if (animation_type == 4){
      theaterChase(rColor,20);// Calling the cahsing theater function by pushing the color needed and the delay for the chase.
    }
    
    }else{test(rColor);// if the state of the animation is off just show the color normaly}
  
  //Serial.print("red");Serial.println(r);
  zaid.setBrightness(rGB.getBrightness());// Changing the brigtness of my RGB by getting the Value from the Cloud and pass it to the local function. 
  
  }else{// If status of the RGB is off from the cloud the ring will be powered off
  zaid.clear();
  zaid.show();
  }
  

  //Serial.print("IN Chabge");Serial.println(rGB.getBrightness());
}

void onRainbowChange()  {
  // Add your code here to act upon Rainbow change
}

void onAnimationTypeChange(){

}

// Neopixel functions

void rainbowtest(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    // strip.rainbow() can take a single argument (first pixel hue) or
    // optionally a few extras: number of rainbow repetitions (default 1),
    // saturation and value (brightness) (both 0-255, similar to the
    // ColorHSV() function, default 255), and a true/false flag for whether
    // to apply gamma correction to provide 'truer' colors (default true).
    zaid.rainbow(firstPixelHue);
    // Above line is equivalent to:
    // strip.rainbow(firstPixelHue, 1, 255, 255, true);
    zaid.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}
void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      zaid.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<zaid.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / zaid.numPixels();
        uint32_t color = zaid.gamma32(zaid.ColorHSV(hue)); // hue -> RGB
        zaid.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      zaid.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      zaid.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<zaid.numPixels(); c += 3) {
        zaid.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      zaid.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}
  • Now I need to set the Dashboard to push the data to it.

Dashboard

Dashboard creating

  • Now I will start adding my first widget, which is gonna be the color for the RGB (Where I can control the RGB color and brightness in addition to Switch the RGB on and off)

RGB color

RGB variable

  • NOw this Widget is ready I will just need to press link variable and then OK

RGB variable linked

RGB widget Done

  • Now the first widget is done.

first widget Done

  • Now I will Add a switch for the animation.

Animation switch Select

Animation switch variable

Animation switch DOne

  • Now the two widget are ready.

The two widget for the RGB is ready

  • Now I will add a selector for the animation.

Selector for the animation type

Selector for the animation type variable

Selector for the animation type Done

  • NOw I have all the RGB related done.

  • I will need only to sort them as I want and then I can jump to the next value I need to represent.

RGB related DOne

  • Now I will add an advanced chart to represent the important values.

Advanced Chart

Link variable with advanced chart

Advanced chart variables way of viewing

Advanced chart label y-axis

  • NOw I can say the chart is ready and I can view the data I have been collecting.

Advanced chart is ready

  • Now I will Just Add the rest of the data I want to visualize in the same way.

  • Now after some hard work and sorting here is the Dashboard is ready.

  • Now I need to move to the Hardware Part and start building my PCB so I can have a great system integration in my project.