User Tools

Site Tools


Action disabled: source
projects:lasercutterfilterpdmonitor

Laser Cutter Exhaust Filter Pressure Drop Monitor

Purpose

  • Monitor the performance and effectiveness of filters
  • Determine end of life for filter media
  • Help determine when to order new filters

History

  • Built/tested 11/25/18
  • Installed 12/09/18
  • Removed ???
  • Revamped 7/27/23

Readings

Date Stage 1 PD Stage 2 PD Stage 3 PD Comments
12/12/18 0.40 2.15 0.90
12/15/18 0.17 1.18 0.56
12/29/18 0.19 1.25 0.54
01/02/19 0.22 1.20 0.62
01/12/19 0.28 1.16 0.32 Markus changed out the Stage 1 filter
01/15/19 0.31 1.12 0.78
01/20/19 0.18 1.15 0.32
01/23/19 0.44 1.12 0.31
02/07/19 0.66 1.13 0.34
03/02/19 1.37 1.13 0.32
03/08/19 1.45 1.16 0.30
03/10/19 0.96 1.20 0.23 Brant changed out the Stage 1 filter
03/14/19 0.98 1.16 0.31
03/22/19 1.07 1.17 0.35
03/22/19 1.01 1.25 0.22 Markus replaced the Stage 1 filter with a 12“ deep model
05/10/19 1.14 1.22 0.32
07/11/19 1.78 0.00 0.32 Stage 2 removed?
07/21/19 1.80 0.00 0.30
08/25/19 1.85 0.00 0.30
10/27/19 1.99 0.28 0.60
01/26/20 2.15 0.27 2.59 Wood floor installed, room rearranged
? ? ? ? Removed
07/27/23 0.25 0.03 0.00 Revamped, no can filter
08/13/23 0.27 0.06 0.00
09/02/23 0.17 0.01 0.01 Before leaks in flex ducts were found
09/02/23 0.18 0.01 0.24 After leaks fixed
09/09/23 0.27 0.27 0.30 All new filters installed
09/10/23 0.27 0.28 0.35
10/07/23 0.27 0.27 0.05 Can filter removed
10/15/23 0.41 0.28 0.15 New can filter with cloth cover
12/09/23 1.32 0.28 0.25 Tubing swapped incorrectly, now fixed
12/28/23 1.25 0.28 0.25
01/05/24 1.22 0.28 0.25
01/07/24 0.05 0.28 0.25 Raymond cleaned the filters during SID, Brant connected new ductwork

All values measured in inches of water column (in.w.c.)
The signals used to read this when no air was flowing (Stg1=-0.26, Stg2=-0.28, Stg3=-0.24)
Signal calibration factors are now included in the programming

Design/Construction

  • Designed/built by BrantH
  • Uses three differential pressure transducers, 5 VDC, 20 mA
  • Custom shield (a very crappy perforated board with several wire/solder connections)
  • Scrap metal enclosure box is a salvaged air conditioner relay box from Brant's attic
  • Arduino Uno v.3 with code borrowed from various sources ( Smoothing by David A. Mellis, LCD Library by Limor Fried and Tom Igoe )
  • Arduino takes 10 readings from each sensor, averages them, then displays the average, updates once every second
/*
  LiquidCrystal Library - display() and noDisplay()
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD and uses the 
 display() and noDisplay() functions to turn on and off
 the display.
 
 The circuit:
 * LCD RS pin 4 to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe 
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://arduino.cc/en/Tutorial/LiquidCrystalDisplay

 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 9,8,7,6,5,4,3,2);

int sensorAPin = A1;    
int sensorBPin = A2;    
int sensorCPin = A3;    
double PDA = 0;
double PDB = 0;
double PDC = 0;

int lifeA = 0;
int lifeB = 0;
int lifeC = 0;


const int numReadingsA = 10;
int readingsA[numReadingsA];      // the readings from the analog inputs
int readIndexA = 0;              // the index of the current readings
int totalA = 0;                  // the running total
int averageA = 0;                // the average

const int numReadingsB = 10;
int readingsB[numReadingsB];      // the readings from the analog inputs
int readIndexB = 0;              // the index of the current readings
int totalB = 0;                  // the running total
int averageB = 0;                // the average

const int numReadingsC = 10;
int readingsC[numReadingsC];      // the readings from the analog inputs
int readIndexC = 0;              // the index of the current readings
int totalC = 0;                  // the running total
int averageC = 0;                // the average

void setup() {

  for (int thisReading = 0; thisReading < numReadingsA; thisReading++) {
  readingsA[thisReading] = 0;
 
}

}

void loop() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 4);
  // Print a message to the LCD.
  
  lcd.setCursor(0, 0);
  lcd.print("Filter Life Monitor");

  lcd.setCursor(0, 1);
  lcd.print("Base:");
  lcd.print(PDA);
  lcd.print(" ");
  lcd.print(lifeA);
  lcd.print("% loaded");
  
  lcd.setCursor(0, 2);
  lcd.print("HEPA:");
  lcd.print(PDB);
  lcd.print(" ");
  lcd.print(lifeB);
  lcd.print("% loaded");
  
  lcd.setCursor(0, 3);
  lcd.print("Can:");
  lcd.print(PDC);
  lcd.print(" ");
  lcd.print(lifeC);
  lcd.print("% loaded");

  //adjust for sensor calibration
  PDA = abs((averageA / 1023.00 * 5.00) - 0.27);
  PDB = abs((averageB / 1023.00 * 5.00) - 0.28);
  PDC = abs((averageC / 1023.00 * 5.00) - 0.25);
 
  // SENSOR A
  // subtract the last reading:
  totalA = totalA - readingsA[readIndexA];
  // read from the sensor:
  readingsA[readIndexA] = analogRead(sensorAPin);
  // add the reading to the total:
  totalA = totalA + readingsA[readIndexA];
  // advance to the next position in the array:
  readIndexA = readIndexA + 1;
  // if we're at the end of the array...
  if (readIndexA >= numReadingsA) {
    // ...wrap around to the beginning:
    readIndexA = 0;}
  // calculate the average:
  averageA = totalA / numReadingsA;


  // SENSOR B
  // subtract the last reading:
  totalB = totalB - readingsB[readIndexB];
  // read from the sensor:
  readingsB[readIndexB] = analogRead(sensorBPin);
  // add the reading to the total:
  totalB = totalB + readingsB[readIndexB];
  // advance to the next position in the array:
  readIndexB = readIndexB + 1;
  // if we're at the end of the array...
  if (readIndexB >= numReadingsB) {
    // ...wrap around to the beginning:
    readIndexB = 0;}
  // calculate the average:
  averageB = totalB / numReadingsB;
  // send it to the computer as ASCII digits


    // SENSOR C
  // subtract the last reading:
  totalC = totalC - readingsC[readIndexC];
  // read from the sensor:
  readingsC[readIndexC] = analogRead(sensorCPin);
  // add the reading to the total:
  totalC = totalC + readingsC[readIndexC];
  // advance to the next position in the array:
  readIndexC = readIndexC + 1;
  // if we're at the end of the array...
  if (readIndexC >= numReadingsC) {
    // ...wrap around to the beginning:
    readIndexC = 0;}
  // calculate the average:
  averageC = totalC / numReadingsC;
  // send it to the computer as ASCII digits

  //end of life filter section pressure drops
int deadA = 200; //can filter
int deadB = 150; //HEPA
int deadC = 80; //entry

  // estimate remaining life
  lifeA = (PDA*100 / deadA) * 100;
  lifeB = (PDB*100 / deadB) * 100;
  lifeC = (PDC*100 / deadC) * 100;


  delay(1000);

}

Old photos:

projects/lasercutterfilterpdmonitor.txt · Last modified: 2024/01/08 13:35 by branth