AirCasting Particle Monitor Bill of Materials Shinyei PPD42NS Seeed http://www.seeedstudio.com/depot/grove- dust- sensor- p- 1050.html?cPath=25_27 JY- MCU HC- 06 Bluetooth Wireless Serial Port Module FastTech http://www.fasttech.com/products/1005/10001791/1129201 DHT22/AM2302 Digital Temperature Humidity Sensor Ebay http://www.ebay.com/itm/new- DHT22- AM2302- Digital- Temperature- Humidity- Sensor- Replace- SHT11- SHT15- Logger- /271175728425?pt=LH_DefaultDomain_0&hash=item3f23553d29 Copal F16EA- 03LLC Arduino Uno R3 Rev3 Development Board Digi- Key FastTech http://www.digikey.com/product- search/en?x=10&y=18&lang=en&site=us&keywords=copal+f16ea- 03LLC http://www.fasttech.com/products/0/10000015/1001700- arduino- uno- r3- rev3- development- board Adjustable Voltage Booster Regulator JST Right- Angle Connector http://www.jayconsystems.com/adjustable- boost- regulator- 4-25v.html Jayconsystems Jayconsystems http://www.jayconsystems.com/jst- right- angle- connector.html Lipo Charger Basic (Micro- USB) Jayconsystems http://www.jayconsystems.com/micro- usb- lipo- charger- mcp73831.html http://www.jayconsystems.com/3-7- volt- rechargeable- lithium- battery- 2000- Li- on Battery 2000 mah Jayconsystems mah.html SPDT Slide Switch Sparkfun https://www.sparkfun.com/products/9609 Mini- Breadboard Sparkfun https://www.sparkfun.com/products/11658 Resistors Sparkfun https://www.sparkfun.com/products/11508 http://www.amazon.com/breadboard- jumper- wire- 75pcs- pack/dp/b0040dei9m/ref=sr_1_1?s=electronics&ie=utf8&qid=1380996915&sr=1- Jumper Cables Amazon 1&keywords=jumper+cables+electronics
- + 3.7 Polymer Lithium Ion Battery 2000mAh Micro Fan Iem Heng and Raymond Yap Electrical/Computer Engineering Department Manhattan College Riverdale, NY 5V Booster Regulator (DC to DC) Vin GND Vout Bluetooth Mate Silver DHT22 Digital Humidity/ Temperature Sensor 3V3 5V Vin D13 D13 Power RST D12 AREF IO REF NC Arduino Uno D11 D10 D9 PWM PWM PWM CTS Vcc GND Tx Rx RTS This extra pin is not connected to anything. A0 A1 Digital Input/Output D8 D7 D6 D5 D4 D3 PWM PWM PWM 10K Ohm Brown Black Orange A2 A3 A4 Analog Input D2 D1 D0 Tx Rx A5 SCL Vcc GND Sig GND SDA Seeed Grove Dust Sensor - Shinyei Model PPD42NS
//AirCasting Particle Monitor Code, by Iem Heng & Raymond Yap #include <SoftwareSerial.h> #include <FlexiTimer2.h> #include <DHT.h> SoftwareSerial myserial(2, 3); #define DHTPIN 9 #define DHTTYPE DHT22 DHT dht(dhtpin, DHTTYPE); int pin = 8; int humi, cel, fah; //kelv; volatile double rawparticalcount; volatile double totalparticles = 0; volatile double particlecounttodisplay = 0; volatile double ratio = 0; volatile uint16_t timecounter = 0; #define numberofpeaksrecording 5 volatile uint32_t previouspeaks[numberofpeaksrecording]; volatile uint32_t sumofpreviouspeaks = 0; volatile uint32_t instantgoal = 0; volatile int32_t delta = 0; volatile uint32_t slowmovingaverage = 0; volatile boolean readytosenddata = false; void setup() { Serial.begin(115200); myserial.begin(115200); pinmode(8,input); FlexiTimer2::set(1,1.0/10000,readPin); FlexiTimer2::start(); } void loop() { humi = dht.readhumidity(); cel = dht.readtemperature();
//kelv = cel + 273.15; fah = ((cel * 9)/5) + 32; delay(1); if(readytosenddata){ Serial.print(fah); Serial.print("F "); Serial.print(cel); Serial.print("C "); //Serial.print(kelv); //Serial.print("K "); Serial.print(humi); Serial.print("RH "); Serial.print(rawParticalCount, DEC); Serial.print(" Raw Particle Count (0-10000) "); Serial.print(ratio, DEC); Serial.print(" Ratio (0-100%) "); Serial.print(particleCountToDisplay, DEC); Serial.print(" Particle Count"); Serial.println(""); myserial.print(particlecounttodisplay, DEC); myserial.print(";insertsensorpackagename;ppd42ns;particulate Matter;PM;hundreds of particles per cubic foot;hppcf;0;4000;8000;1200;16000"); myserial.print("\n"); myserial.print(fah); myserial.print(";insertsensorpackagename;dht22- F;Temperature;F;degrees Fahrenheit;F;0;25;50;75;100"); myserial.print("\n"); myserial.print(cel); myserial.print(";insertsensorpackagename;dht22- C;Temperature;C;degrees Celsius;C;0;10;20;30;40"); myserial.print("\n"); //myserial.print(kelv); //myserial.print(";insertsensorpackagename;dht22- K;Temperature;K;kelvin;K;273;300;400;500;600"); //myserial.print("\n"); myserial.print(humi); myserial.print(";insertsensorpackagename;dht22- RH;Relative Humidity;RH;percent;%;0;25;50;75;100"); myserial.print("\n");
} readytosenddata = false; } void readpin(){ if(digitalread(pin) == LOW){ rawparticalcount++; } timecounter++; if (timecounter == 10000) { timecounter=0; //Changes are made here based on Chris Nafis's code: http://www.howmuchsnow.com/arduino/airquality/grovedust/ ratio = rawparticalcount/100.0; //Convert to percentage, the shinyei reads 10milliseconds to 90milliseconds duration for particles. Basing on 10milliseconds, smallest particle assumingly from specification sheet. //FlexiTimer2, reads 10,000 readings per second, which would be 1 reading per 100 microseconds. 100 readings would be 10 milliseconds. Since Shinyei runs at minimal 10 millisecond range. I divided 10,000 readings by 100 to get 100. //Good example would be rawparticalcount is 5000 half of the 10,000 readings were active. 5000/100 would be 50 which translate to 50% low pulse occupancy. totalparticles = (1.1*pow(ratio,3)- 3.8*pow(ratio,2)+520*ratio+0.62); rawparticalcount = 0; // shift counters over, code adapted from template provided by Mike Taylor and Joshua Schapiro from Carnegie Mellon University's CREATE Lab for (uint8_t i = 0; i < (numberofpeaksrecording- 1); i++) { previouspeaks[i] = previouspeaks[i+1]; } previouspeaks[numberofpeaksrecording - 1] = totalparticles; sumofpreviouspeaks = 0; for (uint8_t i = 0; i < numberofpeaksrecording; i++) { sumofpreviouspeaks += previouspeaks[i]; }
instantgoal = 2*sumOfPreviousPeaks; delta = instantgoal - slowmovingaverage; if (delta < - 5000){ slowmovingaverage = slowmovingaverage - 250; } else if (delta < - 2500){ slowmovingaverage = slowmovingaverage - 120; } else if(delta < - 1200){ slowmovingaverage = slowmovingaverage - 60; } else if(delta < - 500){ slowmovingaverage = slowmovingaverage - 25; } else if(delta < - 5){ slowmovingaverage = slowmovingaverage - 5; } else if(delta < - 1){ slowmovingaverage = slowmovingaverage - 1; } else if(delta > 5000) { slowmovingaverage = slowmovingaverage + 500; } else if(delta > 2500){ slowmovingaverage = slowmovingaverage + 250; } else if(delta > 1200){ slowmovingaverage = slowmovingaverage + 120; } else if(delta > 500){ slowmovingaverage = slowmovingaverage + 50; } else if(delta > 5){ slowmovingaverage = slowmovingaverage + 5; } else if(delta > 1){ slowmovingaverage = slowmovingaverage + 1; } particlecounttodisplay = slowmovingaverage; readytosenddata = true; } }