Chris Munz
Published © GPL3+

Test the Effectiveness of Your DIY Face Mask

Build an affordable device that tests how well a face mask can protect from particulates. Record quantitative data (PM 1.0, 2.5 and 10.0).

IntermediateFull instructions provided8 hours5,159
Test the Effectiveness of Your DIY Face Mask

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
Arduino Due or Arduino Mega are preferable because they have multiple serial ports.
×1
Plantower PMS5003 Particulate Sensor (With Breakout Board)
×1
Plastic Mannequin Head
×1
Plastic Tupperware Container
×1
Caulk/Sealant
×1
Duct Tape
×1
Epoxy or Super Glue
×1
Large Plastic Bin
×1
Candle
×1
Small Zip-ties
×6
General Purpose Transistor NPN
General Purpose Transistor NPN
×2
1N4007 – High Voltage, High Current Rated Diode
1N4007 – High Voltage, High Current Rated Diode
×2
5V DC Fan, 40mm
×4
5 mm LED: Green
5 mm LED: Green
×1
Resistor 220 ohm
Resistor 220 ohm
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
This is a rough estimate of the amount.
×30
USB-A to B Cable
USB-A to B Cable
×1
9V 1A Switching Wall Power Supply
9V 1A Switching Wall Power Supply
×1
Velcro
×1

Software apps and online services

Arduino IDE
Arduino IDE
Microsoft Data Streamer
Microsoft Data Streamer

Hand tools and fabrication machines

Scissor, Electrician
Scissor, Electrician

Story

Read more

Custom parts and enclosures

Excel File for Recording PM Data

You need to use Data Streamer with Excel for this to work.

Schematics

Schematic

Wiring Diagram

Code

Project Code (Main)

Arduino
This is the main code used for this project. It is written for the Arduino Uno and to be used with Microsoft Data Streamer in Excel.
#include "PMS.h"
#include <AltSoftSerial.h>

// NOTE: If using an Arduino with an extra hardware serial port like the Mega or Due,
// use that port instead of the AltSoftSerial library (Serial1 for example).

AltSoftSerial softSerial; // On the Arduino UNO: (Pin 8: RX), (Pin 9: TX), (Pin 10: unusable).
PMS pms(softSerial);
PMS::DATA data;

int endLED = 13; // Built-in LED to turn on when program is done.
int inFan = 6;   // Fans that pull air into the enclosure.
int outFan = 5;  // Fans that push air out of enclosure.

void setup(){
  softSerial.begin(9600); // Software serial port: communicates w/ PMS sensor via pms() library.
  Serial.begin(9600);     // Hardware serial port: sends data to PC.

  pinMode(endLED, OUTPUT);
  pinMode(inFan, OUTPUT);
  pinMode(outFan, OUTPUT);

  pms.passiveMode();   // Set the PMS sensor to passive mode which only takes readings when prompted with 'pms.requestRead()'.
  delay(30000);   //The sensor has to run for about 30 seconds before putting out stable data.
}

void loop(){
  if (millis() <= 360000) {  // Test terminates at 6 minutes
    cycleFan(inFan, true);        // Cycle power of intake fan.
    getSensorReading();           // Get reading from PMS sensor.
    cycleFan(outFan, false);      // Cycle power of exhaust fan.
  } else {
    digitalWrite(endLED, HIGH);   // Turn on green LED (program is over).
  }
}

void getSensorReading(){
  pms.requestRead();
  
  if (pms.readUntil(data)) {
    Serial.print("PM 1.0,");
    Serial.print(data.PM_AE_UG_1_0);
    Serial.print(",");

    Serial.print("PM 2.5,");
    Serial.print(data.PM_AE_UG_2_5);
    Serial.print(",");

    Serial.print("PM 10.0,");
    Serial.print(data.PM_AE_UG_10_0);
    Serial.println();
  } else {
    Serial.print("No data.");
  }
  delay(100);
}

void cycleFan(int fanPin, bool flowDirection_In){
  int fanSpeed;
  
  for (fanSpeed = 0; fanSpeed <= 255; fanSpeed += 5) {  // Gradually increase PWM to get fan up to full speed.
    analogWrite(fanPin, fanSpeed);
    delay(30);
  }
  if (flowDirection_In == true) {  // Amount of time to leave fan at full speed depending on which flow direction.
      delay(10000); //'in' fans -> stay on 10 seconds
  } else {
      delay(5000);  //'out' fans -> stay on 5 seconds
  }

  for (fanSpeed = 255; fanSpeed >= 0; fanSpeed -= 5) {   // Gradually reduce PWM until fan stops.
    analogWrite(fanPin, fanSpeed);
    delay(30);
  }
  delay(1000);
}

Debugging Code

Arduino
I used this code when I was debugging and trying to get the fans and PMS sensor to work properly. This code works with the serial monitor.
#include "PMS.h"
#include <AltSoftSerial.h>

int endLED = 13; // 'Built-in' LED to turn on when program is done
int inFan = 6;
int outFan = 5;
int fanSpeed;

// If using an Arduino with an extra hardware serial port like the Mega or Due,
// use that instead of the AltSoftSerial library
AltSoftSerial softSerial; //(Pin 8: RX), (Pin 9: TX), (Pin 10: used to keep time)
PMS pms(softSerial);
PMS::DATA data;

void setup(){
  softSerial.begin(9600); // Software serial port: communicates w/ PMS5003 sensor via pms() library
  Serial.begin(9600);     // Hardware serial port: prints data

  //Initialize the digital pins for the both fans and LED as output
  pinMode(endLED, OUTPUT);
  pinMode(inFan, OUTPUT);
  pinMode(outFan, OUTPUT);

  // Set the sensor to passive mode which only takes readings when prompted with 'pms.requestRead()'
  pms.passiveMode();
  Serial.println("Warming up PMS sensor, wait 30 seconds for stable readings...");
  delay(30000);
}

void loop(){
  if (millis() <= 120000) {
    cycleFan(inFan);    // Cycle power of intake fan
    getSensorReading(); // Get reading from PMS sensor
    cycleFan(outFan);   // Cycle power of exhaust fan
  } else {
    digitalWrite(endLED, HIGH); //Turn on green LED
  }
}

void getSensorReading(){
  Serial.println("Send read request...");
  pms.requestRead();
  Serial.println("Reading data...");
  
  if (pms.readUntil(data)) {
    Serial.print("PM 1.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_1_0);

    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data.PM_AE_UG_2_5);

    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_10_0);
  } else {
    Serial.println("No data.");
  }
  delay(100);
}

void cycleFan(int fanPin){
  //Gradually increase PWM to get fan up to full speed
  Serial.println("Fan on...");
  for (fanSpeed = 0 ; fanSpeed <= 255; fanSpeed += 5) {
    analogWrite(fanPin, fanSpeed);
    delay(30);
  }
  delay(5000);

  //Gradually reduce PWM until fan stops
  Serial.println("Fan off...");
  for (fanSpeed = 255 ; fanSpeed >= 0; fanSpeed -= 5) {
    analogWrite(fanPin, fanSpeed);
    delay(30);
  }
  delay(1000);
}

Credits

Chris Munz

Chris Munz

1 project • 1 follower
Thanks to fu-hsi.

Comments