Ben CohenMatthew AndersonVincent Tran
Published

Lane of Things Group 408

Sensors run by a Photon are mounted in the main office of Lane Tech High School to measure the humidity, motion, and sound of the room.

AdvancedFull instructions provided3 hours600
Lane of Things Group 408

Things used in this project

Hardware components

DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
SparkFun ESP8266 Thing - Dev Board
SparkFun ESP8266 Thing - Dev Board
×1
PIR Motion Sensor (generic)
PIR Motion Sensor (generic)
×1
Photon
Particle Photon
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Male/Male Jumper Wires
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×1

Software apps and online services

Particle.io

Story

Read more

Schematics

Fritzing Diagram

This is the fritzing diagram for the photon that we used. The breadboard contains circuits for DHT sensor, motion sensor, and sound sensor

Mounting

The sensors mounted by an outlet on the wall

Temperature

Results of the temperature data that we had collected

Humidity

Results for the humidity data that we had collected

Motion Graph 3/30 Thursday

Point values of 1 are true
Point values of 0 are false

Sound Graph

Graph of the sound data

Code

Code for Photon

C/C++
We used a DHT sensor, a motion sensor, and a sound sensor
// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_DHT.h>


//DHT
#define DHTPIN 5            // what pin we're connected to
#define DHTTYPE DHT22       // DHT 22 (AM2302)

DHT dht(DHTPIN, DHTTYPE);

double hum;                 // current hum
double temp;                // current temp

unsigned long dht_interval = 3000;
unsigned long last_dht = 0;




//PIR MOTION SENSOR 
int pirPin = D0; // PIR is connected to D3
bool motion = false;
bool motionLastMin[21] = {};
bool motionAvg = false;
String motionAvgStr = "";

unsigned long motion_interval = 3000;
unsigned long last_motion = 0;




//SOUND DETECTOR
const long sample_rate = 50; // time between samples (in miliseconds)
const int array_size = 1200; // 1000/50=20 * 60=1200
int snd_array[array_size] = {};
int snd_max, prev_max = 0;
int snd_min, prev_min = 4096;
double snd_avg = 2048;
double sound_avg=0;

const int blink_thresh = 2048;

unsigned long broadcast_interval = 50;
unsigned long last_broadcast = 0;

int loudestSound = 0;



void checkDHT() {
    unsigned long now = millis();
    if ((now - last_dht) > dht_interval){
        
        double checkHum = dht.getHumidity();
        double checkTemp = dht.getTempFarenheit();
    
        if (checkHum > 0 && checkHum < 100)
            hum = checkHum;
        
        if (checkTemp > 32 && checkTemp < 100)
            temp = checkTemp;
    
        //Serial.println("Temp: " + String(checkTemp));
        //Serial.println("Hum: " + String(checkHum));
        last_dht = now;
    }
   
}


void addMotionVal(bool val) {
    for (int i = 0; i < 21 ; i++) {   //add all motion into array
            motionLastMin[i] = motionLastMin[i+1];
        }
        motionLastMin[17] = val;       //add current motion value into the 18th value
}

void setArray() {
    for (int i = 0; i < 20; i++) {      //initialize array with all "no motion"
            motionLastMin[i] = false;
        }
}

void checkMotion() {             //check if there is motion in the past 60
    
    unsigned long now = millis();
    if ((now - last_motion) > motion_interval) {
        motionAvg = false;
        
        int pirValState;
        pirValState = digitalRead(pirPin);

        if(pirValState == LOW) // Was motion detected
        {     
            Serial.println("Motion detected");
            motion = true;
        
        //delay(2000);  //Wait 1-2 seconds for the sensor to get a snapshot of the still room
        }
        else
        {
            motion = false;
        }
        addMotionVal(motion);
    
    
    
        for (int i = 0; i < 20 && motionAvg == false ; i++) {
                if (motionLastMin[i]) {
                    motionAvg = true;
                }
        }
        
        if (motionAvg)
            motionAvgStr = "True";
        else 
            motionAvgStr = "False";
        
        Serial.println("MotionAvg: " + motionAvgStr);
        motionLastMin[21] = {};
        last_motion = now;
    }
    
}






void checkLoudest() {  //checks for largest amplitude
    int bigVal = snd_array[0];
    
    for (int i = 0; i < array_size; i++) {
        if(bigVal < snd_array[i]) {
            bigVal = snd_array[i];
        }
    }
    loudestSound = bigVal;
    
}

void averageReading(int value) {
    // Shift all the values right by 1
    for(int i = array_size - 1; i > 0; i--) 
    {
        int moved_val = snd_array[i-1]; 
        snd_array[i] = moved_val;
    }
    snd_array[0] = value; // add new value to the first position in the array
    // Average array
    double avg_sum = 0; 
    for (int a=0; a < array_size; a++) {
        avg_sum  = avg_sum + snd_array[a];
    }
    snd_avg = avg_sum / array_size;
    sound_avg = snd_avg;
}

void minReading(int value) {
    if(value < prev_min) { 
        snd_min = prev_min = value;
    }
}

void maxReading(int value) {
    if(value > prev_max) { 
        snd_max = prev_max = value;
    }
}

void blinkMic(int reading) {
    if(reading > blink_thresh) {
        digitalWrite(D7, HIGH);
    } else {
        digitalWrite(D7, LOW);
    }
}

void checkBrodcast() {
    unsigned long now = millis();
    if((now - last_broadcast) > broadcast_interval) {
        //Serial.print("Avg: "); Serial.println(snd_avg);
        //Serial.print("Min: "); Serial.println(snd_min);
        //Serial.print("Max: "); Serial.println(snd_max);
        //Serial.println("Loudest: " + (String)loudestSound);
        snd_avg = 0;
        snd_min = 4096;
        snd_max = 0;
        snd_array[array_size] = {};
        //Serial.println((String)mic_reading);
        last_broadcast = now;
    }
}

void setup()
{
    Serial.begin(9600);
    //PIR MOTION SENSOR
    pinMode(pirPin, INPUT_PULLUP); // Initialize D3 pin as input with an internal pull-up resistor
    Particle.variable("motionAvg", motionAvgStr);
    
    
    //SOUND DETECTOR
    pinMode(A0, INPUT); // mic AUD connected to Analog pin 0
    pinMode(D7, OUTPUT); // flash on-board LED
    Particle.variable("snd_avg", sound_avg);
    Particle.variable("snd_min", snd_min);
    Particle.variable("snd_max", snd_max);
    Particle.variable("loudestSound", loudestSound);
    setArray();
    

    
    //DHT SENSOR
    pinMode(DHTPIN, INPUT);
    
    Particle.variable("hum", hum);
    Particle.variable("temp", temp);
}

void loop()
{
    
    //PIR MOTION SENSOR
    
    checkMotion();
    
    
    //SOUND SENSOR
    int mic_reading = analogRead(0);
    

    blinkMic(mic_reading);
    minReading(mic_reading);
    averageReading(mic_reading); 
    checkLoudest();
        
    
    checkBrodcast();
        
    //DHT SENSOR
    checkDHT();

    delay(sample_rate);
}

Google Spreadsheet Data Pull

JavaScript
Code pulls data into Google Spreadsheet
Trigger set every minute.
function collectCurrent() {
  "use strict";
  try
  {
    //Replace the device ID below with your Photon's unique device ID
    var deviceID = "34003f001347343432313031";
    
    //Replace the access token below with your Photon's unique access token
    var accessToken = "bffc6cacac82e9fd247a9fc12e28142930b851f0";
    
    //Replace the value below with you group ID
    var groupID = 408;
    
    //Replace the room number below with location of the Photon
    var room = "Main Office";
    
    var sheet = SpreadsheetApp.getActiveSheet();

    // Fetch the value of the testValue variable from the Spark Cloud API.
    // The name of your variable in Particle's cloud must match the variable in the URL below.
    var response = UrlFetchApp.fetch("https://api.spark.io/v1/devices/" + deviceID + "/hum?access_token=" + accessToken);

    // Parse the JSON and extract the testValue.
    var jsonResponse = JSON.parse(response.getContentText());
    var hum = jsonResponse.result;

    response = UrlFetchApp.fetch("https://api.spark.io/v1/devices/" + deviceID + "/temp?access_token=" + accessToken);
    jsonResponse = JSON.parse(response.getContentText());
    var temp = jsonResponse.result;    
    
    response = UrlFetchApp.fetch("https://api.spark.io/v1/devices/" + deviceID + "/snd_avg?access_token=" + accessToken);
    jsonResponse = JSON.parse(response.getContentText());
    var snd_avg = jsonResponse.result; 
    
    response = UrlFetchApp.fetch("https://api.spark.io/v1/devices/" + deviceID + "/motionAvg?access_token=" + accessToken);
    jsonResponse = JSON.parse(response.getContentText());
    var motionAvg = jsonResponse.result; 
    
    response = UrlFetchApp.fetch("https://api.spark.io/v1/devices/" + deviceID + "/snd_max?access_token=" + accessToken);
    jsonResponse = JSON.parse(response.getContentText());
    var snd_max = jsonResponse.result; 

    response = UrlFetchApp.fetch("https://api.spark.io/v1/devices/" + deviceID + "/snd_min?access_token=" + accessToken);
    jsonResponse = JSON.parse(response.getContentText());
    var snd_min = jsonResponse.result; 

    
    // Create a timestamp.
    var timeStamp = new Date();

    // Append the timestamp and the temperature to the sheet.
    sheet.appendRow([timeStamp, groupID, room, temp, hum, snd_avg, motionAvg, snd_max, snd_min]);
  } catch (e)
  {	
    // If something doesn't work, log it, then rethrow the error.
	Logger.log(e.name + ": " + e.message);
	throw (e);
  }
}

Credits

Ben Cohen

Ben Cohen

1 project • 0 followers
Matthew Anderson

Matthew Anderson

1 project • 0 followers
Vincent Tran

Vincent Tran

1 project • 0 followers

Comments