DIY Smart Home Air Cleaner

By Staff

Air filtration devices can help remove unwanted odors, particles, and more. The simplest of such units typically incorporate a fan and one or multiple filters. Depending on the filter you use, you can achieve different effects. This article discusses a homemade air filtration device that uses a readily available and cheap 12V computer fan and an activated charcoal filter. This filter traps dust particles and also filters smells that linger in the air. In addition, the device incorporates an air-quality sensor. An additional Arduino board controls the fan speed depending on the air quality in the room.


The finished device. Note that because of the natural imperfection of 3D printing, the case doesn’t fit together perfectly. You can, however, improve the fit with some sanding.

Components and Tools You’ll Need

You’ll need the following components if you want to build this project:

Item/Where to buy/Amount

In addition to these materials, you’ll need a soldering iron and the other items that go along with it, a 3D printer and filament or access to a 3D printing service, and tools for cutting and stripping wires.

Assembling the Case

This project features a fairly large and complex custom 3D-printed case that houses all the electronic components. I designed this case to be as easy to print as possible. Hence, I split the enclosure into four relatively similar parts. Doing so should reduce the effort when you print the shell pieces, and it should also reduce the chance of parts warping or prints failing late in the manufacturing process.

Either way, I designed the case parts around a standard 120mm computer fan. The fan gives the finished product stability. The case pieces themselves aren’t connected. Instead, you mount the shell to the computer fan using the supplied screws. Here, make sure that the holes in the printed plastic parts are large enough so that the screws don’t create a thread. Use a drill to widen the holes if necessary. Start the assembly process by attaching two of the case parts to one side of the computer fan. The other side of the fan should contain a finger guard:


The finger guard on the inside of the device prevents wires and electronic components from coming in contact with the fan blades.


After you’ve attached two of the case pieces to the computer fan, make sure that you connect the electronic components as shown in the following schematic diagram.


The schematic diagram of this project. 

At first glance, the diagram might look more complicated than it is. Most of the wires supply power to the individual electronic components. First, the positive supply rail goes through the rocker switch that you need to snap into one of the case pieces. Then, the positive and negative supply lines go to the motor control breakout board’s screw terminal.

The screw terminal supply pins are directly connected to the pins on the other side of the board (labeled VM and GND). In this project, I used the VM and GND pins to supply power to the Arduino. Doing so reduces the complexity of the wiring. The Arduino Nano 33 IoT comes with an onboard voltage regulator that steps the 12V input down to the 3.3V that the Arduino requires to operate as well as supplies the CCS811 sensor module with 3.3V.

Next, connect two digital I/O lines of the Arduino to the IN1 and IN2 inputs of the motor controller board. Doing so allows the Arduino to control the RPM of the fan via pulse width modulation. Then, connect the SCL and SDA lines of the Arduino to the CCS811 sensor board. You can look at this guide for more details.

The hole next to the rocker switch is where the power supply wire goes. Don’t forget to tie a knot at the end of the wire to act as a strain relief. This prevents a user from accidentally yanking the cable out of the device:


Tie a knot at the end of the power supply cable. The knot acts as a strain relief.

Once you’ve connected the components according to the schematic diagram, mount all the electronic parts on the bottom piece of the 3D-printed case. I added small pegs to the plastic plate that allow you to mount the breakout boards. Unfortunately, the Arduino’s mounting holes are too small for mounting the development boards on pegs. Therefore, you’ll have to use some double-sided tape or a small amount of hot glue to hold the Arduino in place. However, make sure to upload the project’s firmware to the Arduino before proceeding with the build.


Connect all electronic components before you close the case. Note that the Arduino just sits between the bottom case piece and the fan. You can use some hot glue or double-sided tape to hold it in place.

The Final Assembly

Slide the bottom piece into the two parts you attached to the fan earlier. The bottom piece has four pins that should slide into the two cutouts of the already attached pieces:


These tabs hold the bottom case piece in place.

Next, mount the remaining two pieces to the computer fan. Due to the natural imprecision of 3D printing, your case pieces might not fit together at first. You can use sandpaper or a file to smooth out any rough edges that prevent the parts from coupling accurately.


The assembled device with one corner removed. You can see the individual layers of the device.

Trim down the edges of the carbon filter to make it fit in the pocket on top of the device. Trim away a bit of the filter on each corner as well to make room for the screw posts:


Cut the carbon filter so that it neatly fits in the enclosure. Make sure to cut away the edges to make space for the screw posts.

Last, place the top grid on top of the filter and use four screws to hold it in place:


The finished device with the carbon filter in place.

The Software

The hardware is the most complicated part of this project. Note that you need to install the Adafruit CCS811 library before you can compile and upload the Arduino sketch. You can refer to this guide if you’re not sure how to do this. The firmware only consists of a few lines of code:

Copy Code
#include "Adafruit_CCS811.h"

#define BUFFER_SIZE 60
#define M_1 3 // Motor Breakout IN1
#define M_2 2 // Motor Breakout IN2

Adafruit_CCS811 ccs_sensor; // CCS811 sensor object

unsigned long lastSpeedUpdate = 0UL;
unsigned long lastSensorUpdate = 0UL;
unsigned voc_co2_index = 0;
float co2[BUFFER_SIZE];
float voc[BUFFER_SIZE];

bool initializeCCS811(void)
// The program couldn't initialize the sensor
return false;

// Wait for the sensor to be ready
while(!ccs_sensor.available()) { }

return true;

void getAirQualityData(void)
if(voc_co2_index >= BUFFER_SIZE)
voc_co2_index = 0;

co2[voc_co2_index] = ccs_sensor.geteCO2();
voc[voc_co2_index] = ccs_sensor.getTVOC();
voc_co2_index += 1;

float getAverage(float* arr, unsigned len)
float sum = 0.0f;

for(int i = 0; i < len; i++)
sum += arr[i];

return sum / len;

void changeMotorSpeed(byte desiredSpeedValue)
digitalWrite(M_1, LOW);
analogWrite(M_2, desiredSpeedValue);

void setup()
// Initialize the digital I/O pins
pinMode(M_1, OUTPUT);
pinMode(M_2, OUTPUT);

// Initialize the Air Quality sensor
// Halt the program if an error occurs
while(!initializeCCS811()) { }

void loop()
if(millis() - lastSpeedUpdate > SPEED_UPDATE_INTERVAL)
float averageVOC = getAverage(&voc[0], BUFFER_SIZE);

if(averageVOC < 100) // perfect air quality
changeMotorSpeed(64); // 25% speed
else if(averageVOC < 250) // good air quality
changeMotorSpeed(128); // 50% speed
else if(averageVOC < 500) // fair air quality
changeMotorSpeed(192); // 75% speed
else // low air quality
changeMotorSpeed(255); // max speed

lastSpeedUpdate = millis();

if(millis() - lastSensorUpdate > SENSOR_UPDATE_INTERVAL)
lastSensorUpdate = millis();

First, the sketch defines a few variables and macros that control how quickly the air cleaner reacts to changes in the air quality. Then, I created an object for the sensor board and a few arrays that hold the measured air quality values of the last minute. I decided to collect a few samples over time and then make the program calculate the average value. Doing so prevents the fan from constantly speeding up and stopping due to sudden changes in the air quality, for example, when you exhale near the air intake.

The setup method initializes the digital I/O pins and the CCS811 breakout board. This article discusses the initialization process in more detail. The loop method periodically requests the current air quality from the sensor. It also checks whether it’s necessary to update the fan speed. For this purpose, the update function calls a helper method that calculates the average value of the last 60 sensor readings. The getAverage helper function sums up all entries in the array and then divides the sum by the number of elements in the array. Then, the loop method updates the fan speed depending on the calculated average VOC level.

Make sure to upload the code to the Arduino board before you finish assembling the case. In addition, I recommend that you test the electronics with the case open. This way, you can ensure that the fan spins the right way around. If your fan spins the wrong way around, you can try swapping the IN1 and IN2 lines. Furthermore, you can test whether the device correctly measures the air quality by placing some alcoholic hand sanitizer near the device’s air intake. After a few seconds, you should hear the fan spin up. Upon removing the sanitizer, the device should lower the fan speed after a short delay.


This article explained how to build a simple air filtration device at home. Due to its simplicity, this project is perfect for beginners and classroom environments. In the end, you’ll have a practical device that automatically detects poor air quality in a room and cleans the air. For this, the finished product uses an Arduino and a CCS811 sensor to measure the VOC level in the environment. If the level exceeds a certain threshold, the Arduino instructs the motor controller breakout board to increase the fan speed. The fan pulls in air through the side vents and pushes it through a carbon filter located on the top of the case.

Download the Case Design Files

You can download the case design files here:

Key Parts and Components

Add all Digi-Key Parts to Cart
  • 1528-1719-ND
  • 1528-2356-ND
  • 1050-ABX00027-ND
  • EG5618-ND
  • 243-1364-ND
  • 1053-1357-ND
  • 993-1332-ND