Air Quality Monitoring System with Particle Sensors and Arduino boards

During the last holidays period I started to build an air quality monitoring system, an old personal project. I selected the particle sensor PPD42NS, Shinyei, due to its low cost and easy integration with Arduino boards. I also used a HUZZAH ESP8266 wifi module to send captured data to the cloud so I can monitor air quality remotely.

Next, I briefly present the tests and main challenges after the integration of two PPD42NS units with an Arduino DUE and the wifi module. You can download the code and a short report on my downloads.

Each sensor provides two digital outputs that are indicative of the number of particles larger than 1 µm or 2.5 µm. The information is coded in the Low Pulse Occupancy (LPO) time of the digital outputs. To build the monitoring system, the sensors were integrated with an Arduino Due that acquired the sensor outputs, and a HUZZAH ESP8266 wifi module that sent the data to the cloud. The Arduino Due measured the LPO time of the digital pulses by means of interrupt services and communicated with the HUZZAH ESP8266 using I2C protocol. The test consisted on the continuous acquisition of two sensor units for a couple of weeks, while the system was placed in my home terrace. Results show that both sensors provide similar outputs and can be used to detect activities in their vicinity. However, sensitivity to larger particles is quite low and outputs may be averaged over time to decrease noise.

PPD42NS Sensor

The PPD42NS dust sensor requires +5V and it provides two digital outputs that oscillate between HIGH (voltage higher than 4.0V) and LOW (voltage lower than 0.7V) that are indicative of the number of particles in air. The outputs account for the number of particles larger than 1 µm and 2.5 µm respectively. The outputs are provided in digital ports that, in normal background, only go to LOW state occasionally for short periods of time (10 ms to 90 ms). It seems that the outputs are non-periodic and the suggested measuring protocol is to measure LPO time in periods of 30 s.

The datasheet provided by the manufacturer lacks of technical detail, but one can find reverse engineering showing more detail on the circuits and the sensors. After a simple visual inspection of the captured signals, I spotted that acquired data was very noisy so I added stiff paper over the opening to reduce ambient light that reaches the sensor and to ensure the proper airflow pattern induced by the heating element, as suggested before.

Reading with Arduino

On the Internet one can find several approaches implemented in Arduino Uno to measure LPO during a defined time interval (usually 30 s). They even provide a digitalization of the curve included in the datasheet to convert the sensor readings to concentration. However, these approaches are based on the built-in function PulseIn(pin,LOW). This function waits until the pin is LOW, starts timing and waits for the pin to go HIGH and stops timing. It returns the duration of the pulse in microseconds. Therefore, the approaches based on PulseIn(pin,LOW) need the microprocessor dedicated to the measure of the LPO. Several LPO times could only be measured sequentially.

I adapted the acquisition routine with interrupts to allow parallel processes in the Arduino while counting the duration of the pulses.


I have two dust sensors so I could test them putting one next to the other. Hence, I needed to measure the duration of four pulses simultaneously. Arduino Uno only features two hardware interrupts. Fortunately, I have an Arduino Due at hand, which has powerful interrupt capabilities that allows to attach an interrupt function on all available pins.

In order to save the acquired values and send the data to the cloud, I found very convenient the use of Adafruit HUZZAH ESP8266. It is a low-cost wifi microcontroller that can communicate very easily to the Arduino board by means of I2C protocol. To supply both devices, I used a quite cheap power supply (MB102, Sodial) that outputs 3.3 V and 5.0 V .

The result is a relatively cost-efficient hardware based on:

Circuit design

The dust sensor outputs voltage levels higher than 4.0V. This requires some attention for Arduino Due since the maximum voltage that the I/O pins can tolerate is 3.3 V. I simply added four voltage dividers with resistors to reduce the voltage levels.

The rest of the circuit is shown below. I chose pins #2 and #14 from the wifi module to exchange data with the Arduino Due. In the Arduino Due, to measure LPO times, interrupt services are configured in pins #2, #3, #5 and #6.

Circuit design to acquire sensor outputs and send data to the cloud

Software implementation

Basically, I implemented a master (ESP8266) – slave (Arduino Due) communication protocol. The slave keeps counting the duration of the pulses until the master asks for the LPO times. The slave responds with four values (10.000 x LPO) and sets the counters to zero. Every time the master receives data, it uploads the four values to the cloud ( ). The master requests data periodically. In my case, I set up the timer at 30 s.


I placed the two sensing units in a home terrace for two weeks while daily routines were performed as usual. Luckily, I have a simple log that details the activities and times carried out in the terrace.

To ensure that the sensing units were in dark condition and not affected by winds or air streams, I placed both units in a cardboard box with large apertures. The units were in vertical position to ensure the generated flow by the heater follows the expected path.


The acquisition system and data transmission protocol proved to be robust as I did not identify any missed data after two weeks of data acquisition. Figure below shows a portion of the acquired signals. After an initial visual inspection, one can confirm that the sensors of the different units behave similarly. In particular, the captured signals for the 1 µm particle sensors present higher oscillations and larger values approximately from 11:25 to 11:40. This corresponds to activity being performed in the terrace: clothes were hung out to dry during that time interval. However, 2.5 µm particle sensors are not sensitive to that activity.

Both units respond similarly. 1 µm sensors are sensitive to activities performed in their vicinity (at 11:25, and for about 15 minutes, clothes were hung out to dry in the terrace)



The two tested PPD42NS sensors provided similar responses, confirming the reliability of the responses. However, sensor outputs were quite noisy. Special care on the sensor placement and housing seemed imperative to reduce noise. Adding stiff paper on the apertures and placing the sensors in dark conditions helped to improve the quality of the signals. Beyond those considerations, noise could be reduced by digital filtering at later stage, or by increasing the measuring time for the LPO. Actually, this has been done by others before (basically, averaging consecutive points), but, on the flip side, this yields to larger time constants.

I did not implement any digital filter and measuring time was set to 30 s. During tests, different activities were performed in the vicinity of the sensors to test system sensitivity. 1 µm particle sensors were sensitive to certain level of activity that increased the number of particles in air. On the other hand, 2.5 µm particle sensors showed lower sensitivity, although it can be tuned by means of a resistor in the dust sensor.

I the future, I may study more deeply the signals and implement algorithms for data processing, and explore signal conditioning circuits to increase the sensitivity of 2.5 µm particle sensors.

All in all, PPD42NS Shinyei represent a cheap option to measure the concentration of particles in air.


One thought on “Air Quality Monitoring System with Particle Sensors and Arduino boards

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s