IoT'ing an Air Filter

Felix Kohlhas • GitHub: [AirFilter]
Tags: Embedded Systems Microcontrollers IoT
Making an air filter “smart” by installing an ESP8266 to monitor particle concentration and control fan speed. [Incomplete article]

I recently bought an air filter, because pollen season was approaching and it was heavily discounted on Amazon. When it arrived I was pleasantly surprised by its high build quality and the fact that it has a build-in particle sensor to dynamically adjust its fan speed.

Photo of the air filter
The air filter

Name of the air filter: Taotronics

When I started using it, I always enjoyed checking the current particle count every time I walked past it. Sometimes the value was high and I tried to figure out what had caused it. Usually these were things such as vacuuming or cooking, but sometimes I could not explain why the value had gone up. After wondering about these events and about how the particle count in the air behaved while I was gone or asleep, I decided that it would be a fun project to build a system that would log these values automatically, so they could be plotted and analysed on demand.

Opening the device

Opening the device proved to be quite difficult, owing to the fact that it seems to be held together by hundreds of screws and clips. (This is probably why it feels so sturdy and high quality.) Once I found the right places to apply force to, I was able to open it without any permanent damages. I have attached a photo of the most important clips for anyone interested in replicating this.



After taking prying off the plastic panel at the top I got a first proper look at the PCB that takes the user and sensor input and controls the fan speed.

Photo of the PCB front side
Front side

Photo of the PCB back side
Back side

The connectors are from left to right:

The metal discs on springs are part of the the touch controls of the air filter. They appear to be capacitive touch buttons that work through the housing.

The particle sensor

The second part I immediately looked for is of course the particle sensor. I found it in the front of the device, where it used the airflow of the main fan to ingest air. According to the label this appears to be a PM1006M sensor by Cubic. While I could not find any information or datasheets for the PM1006M, I found that a very similar sensor, the PM1006K, is well documented by the smart home community, because it is included in an easily hackable IKEA air quality monitor (IKEA VINDRIKTNING).

Photo of the particle sensor

Photo of the particle sensor

Reading data

I captured some communication between the air filter and the sensor, which fortunately seemed to use the same protocol as described in the PM1006K datasheet. Only at the beginning were there some undocumented packages, that seemed to contain information about the sensor. Because of this, I assume that the pm1006 library by bertrik would work for this sensor too. I did not test it, because I ended up writing my own code to add the functionality described below.

A capture of the communication between the sensor and the MCU. (top: from MCU; bottom: from sensor)

The output looks much like the one described in the manufacturers datasheet, where it is described like this.

Response: 16 11 0B DF1-DF4 DF5-DF8 DF9-DF12 DF13-DF16[CS]
Note: PM2.5(μg/m3)= DF3*256+DF4

Controlling the fan speed

Emulating touch?

One feature that I really wanted to add, now that I had already taken apart the filter and was about to put in a wifi-enabled chip anyways, was to have the ability to control the fan speed of the air filter. I first looked into how I could interact with the “touch” controls using the ESP8266, but upon further research found out, that emulating presses on these capacitive touch buttons is much harder than expected. The only method that I could find would involve adding a relay with a tinfoil attached to one side, in order to allow increasing the capacitance on demand.

After getting frustrated from researching ways to emulate button presses, I suddenly had a great idea. If I was to read the PM25 values from the sensor, I should easily be able to create fake sensor output too. This way I could just set the air filter to auto mode and control the fan speed by sending manipulated values to the air filters MCU. But for this I would have to really understand the communication protocol and could not rely on an preexisting library.


Having seen that the serial protocol is very similar I first had a look the the code of the pm1006 library by bertrik . In contrast to the documentation by the manufacturer, the library actually made use of the checksum at the end of each packet, which is important, as the air filter would not accept packets without the correct checksum. From the library I reconstructed this more detailed description of the packets.

      16 11 0b 00000061 0000050d 00000071 02000014 d4
     /   |   \    '--------'--------'--------'     |

All the data plus the checksum should add up to zero, so the checksum can be calculated by adding up all bytes of the message and XOR’ing it with 0xFF and incrementing it by one. I found this online checksum calculator that really helped test and debug my checksumming code. In my code I used the following snippet to calculate the checksum:

checksum = (checksum^0xFF);
outgoing_byte = checksum;

After understanding the protocol, writing the code was as simple as passing through all data except for the bytes containing the particle count value and the checksum at the end.

Summary of the code handeling the sensor data


Photo of the wiring

Wiring it up was straight-forward. I ended up wiring it up like this:

Filter  TX -> RX Sensor
Sensor  TX -> RX ESP8266
ESP8266 TX -> RX Filter

Go get power, I used an ADS1117 LDO to convert 5v that I found on the air filters PCB to 3.3v for the ESP8266. The line marked 3.3V to the particle sensor seemed to be varyiing around 4.5V most of the time and therefore unsuited to be used as the power source for the ESP8266.

This article is not completed yet. I will integrate the resources below soon™.

The overall code

Main loop

  1. Read data from serial
  2. Intercept and modify bytes representing PM data and checksum
  3. Output data to serial

Interval (default 10s)

On MQTT message received


Photo of the air filter
Real particle count

Photo of the air filter
Particle count overriden to 750

Adding a temperature sensor

Photo of the temperature sensor

Photo of the air filter


This blog does not currently have a comment function. You can send me an email to [email protected] instead and I will add it here.