top of page

Sensor Code

//This section tells the computer the name of all the variables that I am going to use in this program
//and what they are going to do
// Anything written after two slashes is a comment to be read by people not by the computer
int SensorPin = D6;  // this pin is the pin that reads from the sensor
int REDled = D1;
int GREENled = D2;
int BLUEled = D3;
int LEDpower = D0; //this pin will power the LED
unsigned long starttime;
unsigned long sampletime_ms = 30000;  //Length of sampling time before it reports. 30,000=30 sec.  You can change this
unsigned long triggerOnP2;
unsigned long triggerOffP2;
unsigned long pulseLengthP2;
unsigned long durationP2;
boolean valP2 = HIGH;
boolean triggerP2 = false;
float ratioP2 = 0;  // start the code with the ratio set to 0.  This clears any previous data
float PM25 = 0; // start the code with the PM25 set to 0.  This clears any previous data
float brightness = 125;  // this is how bright you want the LED.  0 is off, 255 is full brightness.  You can change this

//used to control the wifi if being used in an area where there is no wifi
const uint32_t msRetryTime  =   30000; // stop trying to connect to the internet after 30sec of boot up
SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)
// end of Wifi checking

TCPClient client; 

#define THINGNAME "SJEQ-D-1" //change the name in the " " can be anything.  "upstairsbath"  This is for naming your device on dweet.io
// I use the name that is given to the photon.  Don't use spaces. Go to  http://dweet.io/follow/thingname  to see the results in your browser. change "thingname" to your thingname


void setup()
{
  // This section of code only runs once.  Right after the photon is turned on or code is loaded.
  // Serial.begin(9600);
   pinMode(REDled, OUTPUT);
   pinMode(GREENled, OUTPUT);
   pinMode(BLUEled, OUTPUT);
   pinMode(LEDpower, OUTPUT);
  pinMode(SensorPin,INPUT); // this tells my program that pin 6 is an input pin.  Meaning I will read or listen to this pin
  starttime = millis();//millis() is the on chip timer that starts running when the program starts running.  
  //Tells you how many milliseconds since the program started
   
   Particle.connect();  //if it can't connect to the internet in 30 seconds of booting up it will turn the Wifi off and keep running
     if (!waitFor(Particle.connected, msRetryTime))  
    WiFi.off(); // if the wifi comes back it will not turn the wifi on the photon.  You must reset it to get it back on wifi.
    
    analogWrite(LEDpower, brightness); //turns on the LEDpower pin to whatever brightness power you have choosen.  It will stay on.
     
    digitalWrite(REDled, HIGH); // turn the Red LED on while waiting for the sensor to warmup
    digitalWrite(GREENled, LOW);
    digitalWrite(BLUEled, LOW);
    delay(120000); //this delays the sensor for 2 minutes while it warms up.  You can change this.
    
}

void loop(){ // Sensor reading code written by Matthew Schroyer, MentalMunition.com
      valP2 = digitalRead(SensorPin); //Now I am listening to pin 6.  It has two options "high" or "low"
 
     if(valP2 == LOW && triggerP2 == false){
    triggerP2 = true;
    triggerOnP2 = micros();
  }
 
    if (valP2 == HIGH && triggerP2 == true){
      triggerOffP2 = micros();
      pulseLengthP2 = triggerOffP2 - triggerOnP2;
      durationP2 = durationP2 + pulseLengthP2;
      triggerP2 = false;
  }
    if ((millis() - starttime) > sampletime_ms) {  //if the difference between what time it is right now and when this sample started is greater than our sample time
    //than end this sample and report the data.  
    
    ratioP2 = durationP2/(sampletime_ms*10.0);  //  percentage 0=>100   Percent of time this pin was triggered during sampling. 
    //a higher ratio is dirtier air.
   
    PM25= ratioP2 * ratioP2 * .1809 + 3.8987 * ratioP2; // +2.5003;   //This is the calibration between the ratio and PM25.  Change this to calibrate the PM25 reading in ug/m3
    
    //this section controls what color the LED is at on different PM25 levels. HIGH = off  LOW = on  Feel free to change the cutoff numbers.
    if (PM25 < 10) //green
    {
        digitalWrite(REDled, LOW);
        digitalWrite(GREENled, HIGH);
        digitalWrite(BLUEled, LOW);
        
    }
    if (PM25 < 20 && PM25 > 10)  // cyan
{
        digitalWrite(REDled, LOW);
        digitalWrite(GREENled, HIGH);
        digitalWrite(BLUEled, HIGH);
    }
     if (PM25 < 30 && PM25 > 20) // blue
{
        digitalWrite(REDled, LOW);
        digitalWrite(GREENled, LOW);
        digitalWrite(BLUEled, HIGH);
    }
     if (PM25 < 40 && PM25 > 30) // magenta
{
        digitalWrite(REDled, HIGH);
        digitalWrite(GREENled, LOW);
        digitalWrite(BLUEled, HIGH);
    }
     if (PM25 < 100 && PM25 > 40)// red
{
        digitalWrite(REDled, HIGH);
        digitalWrite(GREENled, LOW);
        digitalWrite(BLUEled, LOW);
    }
       if (PM25 > 100)  // white
{
        digitalWrite(REDled, HIGH);
        digitalWrite(GREENled, HIGH);
        digitalWrite(BLUEled, HIGH);
    }
    //ends the LED control section
    
    // Starts the section that will publish the results to DWEET, like twitter for devices
    if (client.connect("dweet.io", 80))  
    // Go to  http://dweet.io/follow/thingname  to see the results in your browser. change "thingname" to your thingname in the web address.
    {
 
      client.print("GET /dweet/for/");
      client.print(THINGNAME);
      client.print("?ratioP2=");  // Don't use spaces for data names
      client.print(ratioP2);
      client.print("&PM25=");  // Don't use spaces for data names
      client.print(PM25);
      client.println(" HTTP/1.1");
      client.println("Host: dweet.io");
      client.println("Connection: close");
      client.println();
           } 
           // ends publishing to DWEET
           
           
    
 
   durationP2 = 0;  //resets the lowpulseoccupancy back to zero to start the next sample
      starttime = millis(); // set the start time to what time it is now.  
      // go back to the top of the loop and start sampling again
    
}
    
    }

bottom of page