Remote Monitoring & Control

Enter Your Electronics & Design Project for a chance to win up to a $200 Shopping Cart of Product!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll






In this project PPD42NJ particle sensor is used to measure the air quality (PM 2.5) present in the air with Particle Photon. It not only display the data on Particle console and but also indicate the air quality using RGB LED by changing its color.





  • Particle Photon ==> $ 19
  • Seeed PPD42NJ dust sensor ==> $7.20
  • RGB anode / cathode LED ==> $ 1
  • 10k Resistor ==> $ 0.04
  • 3 x 220 Ω Resistor ==> 0.06


  • Particle Web IDE

Total price is around $ 28

About PM (Particulate Matter)



Particulate matter (PM) in the atmospheric air or in any other gas cannot be expressed in terms of ppmv, volume percent or mole percent. PM is expressed as mg/m^3 or μg/m^3 of air or other gas at a specified temperature and pressure.


Note:- One volume percent = 10, 000 ppmv (parts per million by volume) with a million being defined as 10^6.


Care must be taken with the concentrations expressed as parts per billion by volume (ppbv) to differentiate between the British billion which is 10^12 and the USA billion which is 10^9.


Particulate matter is the sum of all solid and liquid particles suspended in air many of which are hazardous. This complex mixture includes both organic and inorganic particles.

Based on size, particulate matter is often divided into two groups.


1. Coarse particles (PM 10-2.5) such as those found near roadways and dusty industries range in diameter from 2.5 to 10 micrometers (or microns). The existing coarse particle standard (known as PM 10) includes all particles less than 10 microns in size.


2. "Fine particles" (or PM 2.5) are those found in smoke and haze have diameters less than 2.5 microns. PM 2.5 is referred to as "primary" if it is directly emitted into the air as solid or liquid particles, and is called "secondary" if it is formed by chemical reactions of gases in the atmosphere.


Which of PM2.5 and PM10 is more harmful?


The smaller particles or PM2.5 are lighter and go deeper into the lungs and cause greater damage longer term. They also stay in the air longer and travel farther. PM10 (big) particles can stay in the air for minutes or hours while PM2.5 (small) particles can stay in the air for days or weeks.


Note:- PM2.5 or PM10 data on online websites is represented as AQI or ug/m3. If the PM2.5 value is 100, then if it is represented as AQI then it will fall in the 'Satisfactory' category but if it is represented as ug/m3 then it will fall under the 'Poor' category.





PPD42NJ Dust Sensor


Based on the light scattering method, it detects airborne particles continuously. Pulse output that corresponds to concentration per unit volume of particles can be obtained with using an original detection method based on light scattered principle similar to the particle counter.


Front side


On the front, it has 2 pots labelled VR1 and VR3 that have been already factory-calibrated. The IR detector is covered under the metal can. Interestingly there’s a slot by the side labelled SL2 which is unused.










Back side

The circuit consists largely of passives and an op-amp. RH1 is the resistor heater which, in theory, could be removed to save power if there was some other method of air circulation.



Sensor Placement (important)



There are several points that should be observed when deciding how the sensor is placed.


  • The sensor must be placed in a vertical orientation. Any other orientation would not achieve the desired airflow.
  • The sensor should be kept in a dark condition.
  • Soft cushioning material to seal the gap between sensor and housing is necessary.


Seal the gap using foil paper as shown below



The sensor output is normally high, but goes low in proportion to the PM concentration, hence by measuring what they call Low Pulse Occupancy (LPO), the PM concentration can be determined. This LPO is recommended to be measured over a unit time of 30 seconds.




There are two kinds of RGB LEDs

  • Common anode LED

In a common anode RGB LED, the three LEDs share a positive connection (anode).

  • Common cathode LED

In a common cathode RGB LED, all three LEDs share a negative connection (cathode).




Particle Photon


Photon is a popular IOT board.The board houses STM32F205 120Mhz ARM Cortex M3 microcontroller and has 1 MB flash memory, 128 Kb RAM and 18 mixed signal general purpose input output (GPIO) pins with advanced peripherals. The module has on-board Cypress BCM43362 Wi-Fi chip for Wi-Fi connectivity and Single band 2.4GHz IEEE 802.11b/g/n for Bluetooth. The board comes equipped with 2 SPI, one I2S, one I2C, one CAN and one USB interface. It should be noted that 3V3 is a filtered output used for analog sensors. This pin is the output of the on-board regulator and is internally connected to the VDD of the Wi-Fi module. When powering the Photon via VIN or the USB port, this pin will output a voltage of 3.3VDC. This pin can also be used to power the Photon directly (max input 3.3VDC). When used as an output, the max load on 3V3 is 100mA. The PWM signals have a resolution of 8-bit and run on a frequency of 500 Hz.


Pin Diagram




Pin Description


                                                                          enables your machine and sensor data to become easily accessible through a web based RESTful API, allowing you to quickly make apps or simply share data.


1. Go to




2. Go to dweets section and create dweet for a thing.



3. You will see page like this. Enter a unique name of a thing. This name will be used in Particle photon.





Now, we are done with setup.


Particle Web IDE


For writing the program code for any Photon, developer needs to create an account on Particle website and register the Photon board with his user account. The program code then can be written on Web IDE at the Particle's website and transferred to a registered photon over the internet. If the selected Particle board, Photon here, is switched on and connected to cloud service of the Particle, the code is burnt to the selected board over the air via internet connection and the board starts operating according to the transferred code. For controlling board over the internet, a web page is designed which uses Ajax and JQuery to send data to the board using HTTP POST method. The web page identifies the board by a device ID and connects to the Particle's Cloud Service through an access token.


How to connect photon with Internet

1. Power your device

  • Plug the USB cable into your power source.
  • As soon as it is plugged in, the RGB LED on your device should begin blinking blue.If your device is not blinking blue, hold down the SETUP button.If your device is not blinking at all, or if the LED is burning a dull orange color, it may not be getting enough power. Try changing your power source or USB cable.


2. Connect your Photon to the Internet

There are two ways either you use web application or mobile app

a. Using web application

  • Step 1 Go to
  • Step 2 Click on setup a Photon
  • Step 3 After clicking on NEXT, you should be presented with a file (photonsetup.html)
  • Step 4 Open the file.
  • Step 5 After opening the file connect your PC to the Photon, by connecting to the network named PHOTON.
  • Step 6 Configure your Wi-Fi credentials.

Note:- If you mistype your credentials, the Photon will blink dark blue or green. You have to go through the process again (by refreshing the page or clicking on the retry process part)

  • Step 7 Rename your device. You will also see a confirmation if the device was claimed or not.


b. Using smartphone

  • Open the app on your phone. Log in or sign up for an account with Particle if you don't have one.
  • After login, press the plus icon and select the device you'd like to add. Then follow the instructions on the screen to connect your device to Wi-Fi. If this is your Photon's first time connecting, it will blink purple for a few minutes as it downloads updates. It may take 6-12 minutes for the updates to complete, depending on your internet connection, with the Photon restarting a few times in the process. Do not restart or unplug your Photon during this time.


Once you have connected your device. Your device can store up to five networks. To add a new network after your initial setup, you'd put your device into Listening Mode again and proceed as above. If you feel like your device has too many networks on it, you can wipe your device's memory of any Wi-Fi networks it has learned. You can do so by continuing to hold the setup button for 10 seconds until the RGB LED flashes blue quickly, signaling that all profiles have been deleted.




  • Cyan, your Photon is connected to the Internet.
  • Green, it is trying to connect to the internet.
  • Magenta, it is currently loading an app or updating its firmware. This state is triggered by a firmware update or by flashing code from the Web IDE or Desktop IDE. You might see this mode when you connect your Photon to the cloud for the first time.
  • White, the Wi-Fi module is off.



Particle Build is an Integrated Development Environment, or IDE that means that you can do software development in an easy-to-use application, which just so happens to run in your web browser.


  • To open build, login to your particle account and then click on Web IDE as shown in image.




  • Once you clicked you will see console like this.



  • To create a new create app, click on create new app.


  • To verify the program. Click on verify.


  • To upload the code, click on flash but before doing that select a device.If you have more than one device you have to make sure that you have selected which of your devices to flash code to. Click on the "Devices" icon at the bottom left side of the navigation pane, then when you hover over device name the star will appear on the left. Click on it to set the device you had like to update (it won't be visible if you have only one device). Once you have selected a device, the star associated with it will turn yellow. (If you only have one device, there is no need to select it, you can continue.






Particle Photon ==> PPD42NJ sensor (placed in vertical direction)


GND ==> Pin1(GND)

D6 ==> Pin2 (Output)

Vin ==>Pin3(5V)

GND ==> 10k resistor ==> Pin5 (Input)


Particle Photon ==> RGB LED


D1 ==> R

D2 ==> G

D3 ==> B

GND ==> Common Cathode










int SensorPin = D6;  //  reads data from the sensor
int REDled = D1; // RED
int GREENled = D2; //GREEN
int BLUEled = D3; //BLUE

unsigned long starttime;
unsigned long sampletime_ms = 30000;  //Length of sampling time before it reports. 30,000=30 sec.  You can change this
unsigned long triggerOnP2;
unsigned long triggerOffP2;
unsigned long pulseLengthP2;
unsigned long durationP2;
boolean valP2 = HIGH;
boolean triggerP2 = false;
double ratioP2 = 0;  // start the code with the ratio set to 0.  This clears any previous data
double PM25 = 0; // start the code with the PM25 set to 0.  This clears any previous data

String colour; // tells the color
String category;  // tells the category of air

//used to control the wifi if being used in an area where there is no wifi
const uint32_t msRetryTime  =   30000; // stop trying to connect to the internet after 30sec of boot up
// end of Wifi checking

TCPClient client;

#define THINGNAME "AirQualDev" // Name you give to your device on  Don't use spaces.

void setup()
  pinMode(REDled, OUTPUT);
  pinMode(GREENled, OUTPUT);
  pinMode(BLUEled, OUTPUT);
  starttime = millis();//millis() is the on chip timer that starts running when the program starts running.
  //Tells you how many milliseconds since the program started

   Particle.connect();  //if it can't connect to the internet in 30 seconds of booting up it will turn the Wifi off and keep running
     if (!waitFor(Particle.connected, msRetryTime)); // if the wifi comes back it will not turn the wifi on the photon.  You must reset it to get it back on wifi.

    delay(120000); //this delays the sensor for 2 minutes while it warms up


void loop(){ 

      valP2 = digitalRead(SensorPin);

     if(valP2 == LOW && triggerP2 == false){
    triggerP2 = true;
    triggerOnP2 = micros();

    if (valP2 == HIGH && triggerP2 == true){
      triggerOffP2 = micros();
      pulseLengthP2 = triggerOffP2 - triggerOnP2;
      durationP2 = durationP2 + pulseLengthP2;
      triggerP2 = false;
    if ((millis() - starttime) > sampletime_ms) {  //if the difference between what time it is right now and when this sample started is greater than our sample time
    //than end this sample and report the data.

    ratioP2 = durationP2/(sampletime_ms*10.0);  //  percentage 0=>100   Percent of time this pin was triggered during sampling.
    //a higher ratio tells dirtier air. 

    PM25= ratioP2 * ratioP2 * .1809 + 3.8987 * ratioP2;  //This is the calibration between the ratio and PM25 in ug/m3

    //this section controls what color the LED is at on different PM25 levels.

    if (PM25 < 10)   
        digitalWrite(REDled, LOW); 
        digitalWrite(GREENled, HIGH); 
        digitalWrite(BLUEled, LOW); 
        colour = "Green";
        category = "Good";
    if (PM25 < 20 && PM25 > 10) 
        digitalWrite(REDled, LOW); 
        digitalWrite(GREENled, HIGH); 
        digitalWrite(BLUEled, HIGH); 
        colour = "Cyan";
        category = "Satisfactory";

     if (PM25 < 30 && PM25 > 20) 
        digitalWrite(REDled, LOW); 
        digitalWrite(GREENled, LOW); 
        digitalWrite(BLUEled, HIGH); 
        colour = "Blue";
        category = "Moderately satisfactory";
     if (PM25 < 40 && PM25 > 30) 
        digitalWrite(REDled, HIGH);
        digitalWrite(GREENled, LOW);
        digitalWrite(BLUEled, HIGH);
        colour = "Magenta";
        category = "Poor";

     if (PM25 < 100 && PM25 > 40)
        digitalWrite(REDled, HIGH); 
        digitalWrite(GREENled, LOW);
        digitalWrite(BLUEled, LOW);
        colour = "Red";
        category = "Very poor";

       if (PM25 > 100)  
        digitalWrite(REDled, HIGH);
        digitalWrite(GREENled, HIGH);
        digitalWrite(BLUEled, HIGH);
        colour = "Black";
        category = "Severe";

    //ends the LED control section

    Particle.publish("colour", String(colour));
    Particle.publish("PM25", String(PM25));
    Particle.publish("ratioP2", String(ratioP2));
    Particle.publish("category", String(category));
    // Starts the section that will publish the results to DWEET
    if (client.connect("", 80))
    // Go to  to see the results in your browser. change "thingname" to your thingname in the web address.
      client.print("GET /dweet/for/");
      client.print("?ratioP2=");  // Don't use spaces for data names
      client.print("&PM25=");  // Don't use spaces for data names
      client.println(" HTTP/1.1");
      client.println("Connection: close");
           // ends publishing to DWEET

   durationP2 = 0;  //resets the lowpulseoccupancy back to zero to start the next sample
      starttime = millis(); // set the start time to what time it is now.
      // go back to the top of the loop and start sampling again