Things used in this project

Hardware components:
Photon new
Particle Photon
This project can be completed by one photon. Because of the assignment requirements we are using two photons.
×2
13285 01
PIR Motion Sensor (generic)
You might need to play with sensitivity settings depends on how big you room is.
×1
09590 01
LED (generic)
×1
Mfr 25frf52 10k sml
Resistor 10k ohm
×1
Mfr 25frf52 1k sml
Resistor 1k ohm
This resistor for the LED. Smaller value can be used. Smaller the resistance higher the brightness
×1
Mcp23008 scio6r2g5v1 a 1
ControlEverything.com Particle Photon I²C 2-Channel SPDT 1-Amp Signal Relay
Any relay that can handle 110v AC and 60W (Assuming you are using regular 60W light) can be used. We used this one, because it was just easier to make a cable connections.
×1
Adafruit industries ada161 image 75px
Photo resistor
×1
15 A/125 V Power strip
×1
11026 02
Jumper wires (generic)
×1
Software apps and online services:
Gawd2jnp51w1h1ccsulo
IFTTT Amazon Alexa service
Hackster
ThingSpeak API
Mobicle 1024
ControlEverything.com Mobicle
Hand tools and fabrication machines:
flat head screwdriver

Schematics

PIR and Photo resistor setup
Breadboard Configuration
Breadboard 2fyhwyxycs
PIR and Photo resistor setup
Circuit Diagram
Circuit diagram d994iogbub
Relay Connections
Just connect the relay as shown to the photon and upload the program. This code makes all relays turn off or on at the same time. If you want to control more things than editing the code is necessary. The relay is attached to the power strip to be used with multiple devices. You can directly connect the light cable to it.
Relay1 hhjo1ys6zo
Connection of Relay Shield to Power Strip
The power strip is connected to the NO and COM ports on the relay shield.
Relay2 3kdqdejb6m
Zoomed In
Relay3 dft3fotsam

Code

PIR and Photo resistor readingC/C++
This is for the photon that has PIR Sensor and Photo resistor connection. The photon reads the values of each and decides if lights needs to be on or off and then publishes it to the cloud to change the relay status connected to 2nd particle. Towards the end of the code there is a part with a bunch of X's, this part needs to change according to your thingspeak information.
// This code is edited by Omer Mucahit And Katie Millican
//Original author of the code: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at


int calibrationTime = 20;   
#define publish_delay 60000
unsigned int lastPublish = 0;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause =180000;  

boolean lockLow = true;
boolean counter = true;
boolean takeLowTime;  
int i = 0;
int z=0;

int pirPin = D4;    //the digital pin connected to the PIR sensor's output PIR Sensor (Rev B) 555-28027
int ledPin = D0;
int lightPin = A1;  //Photoresistor - VT935G-B  350-00009
int lightVal = analogRead(lightPin);

/////////////////////////////
//SETUP
//Setup also activates the serial communication to diagnose the problem with the code.
void setup(){
    Particle.variable("LightValue" , lightVal);
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);
  pinMode(lightPin, INPUT);
  //give the sensor some time to calibrate and give some time to connect serial port
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(500);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    Serial.print("Light Value ==> ");
    Serial.println(lightVal);
    delay(50);
    
  }

////////////////////////////
//LOOP
void loop(){
    
    

       lightVal = analogRead(lightPin);
     
       
      
      
       
  
     if(digitalRead(pirPin) == HIGH && lightVal < 1300){
       digitalWrite(ledPin, HIGH);
      if (counter){
      i++;
     
       Serial.print("Number of state change ==> ");
       Serial.println(i);
      }
      counter=false; //This counter counts the state change of pid sensor. It can be used to determine the light on and off state and can be used to calculate if somebody is in the room or not. 
       //the led visualizes the sensors output pin state
       if(lockLow){  
           
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec"); 
         Serial.print("Light Value ==> ");
         Serial.println(lightVal);
         Particle.publish("Motion-Detected", "Someone is in the room" );
         delay(50);
         }         
         takeLowTime = true;
       }
      

     if(digitalRead(pirPin) == LOW){       
       digitalWrite(ledPin, LOW); 
       counter=true;
        
   

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false; 
        Serial.println(lightVal);//make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           Serial.println(lightVal);
           Particle.publish("Motion-STOPPED", "Room is empty");
           i=0;
           delay(50);
           }
       }
         unsigned long now = millis();
    if ((now - lastPublish) < publish_delay) {
        return;
    }
//Thing speak integration
    int value = analogRead(A0);
    Particle.publish("thingSpeakWrite_A1", "{ \"1\": \"" + String(lightVal) + "\", \"k\": \"XXXXXXXXXXXXXXXX\" }", 60, PRIVATE);
    lastPublish = now;

     
  }
Relay Controller CodeC/C++
This code goes to photon connected to relay. XXXXXXXXXXX part needs to be replaced with the access token of photon with PID controller.
/* Includes ------------------------------------------------------------------*/
#include "NCD2Relay.h"

NCD2Relay relayController;

SYSTEM_MODE(AUTOMATIC);

int triggerRelay(String command);

bool tripped[6];

int debugTrips[6];

int minTrips = 5;

/* This function is called once at start up ----------------------------------*/
void setup()
{
	Particle.function("controlRelay", triggerRelay);
	Serial.begin(115200);
	relayController.setAddress(0,0,0);

  Particle.subscribe("Motion-Detected", relayfunction3, "XXXXXXXXXXXXXXXXXXXXXXXX");///  Instead of X paste the access token for particle with the motion sensor
  Particle.subscribe("Motion-STOPPED", relayfunction2, "XXXXXXXXXXXXXXXXXXXXXXXX");///  Instead of X paste the access token for particle with the motion sensor
 
}

// loop() runs over and over again, as quickly as it can execute.
void relayfunction3(const char *event, const char *data)
{
 relayController.turnOnAllRelays();
  delay(1000);
}
void relayfunction2(const char *event, const char *data)
{
 	relayController.turnOffAllRelays();
}

/* This function loops forever --------------------------------------------*/
void loop()
{
  
	int status = relayController.readAllInputs();
	int a = 0;
	for(int i = 1; i < 33; i*=2){
		if(status & i){
			debugTrips[a]++;
			if(debugTrips[a] >= minTrips){
				if(!tripped[a]){
					tripped[a] = true;
					//set input trip event to true
					String eventName = "Input_";
					eventName+=(a+1);
					Particle.publish(eventName, "ON");
					Serial.print("eventName: ");
					Serial.println(eventName);
					Serial.print("eventContents: ");
					Serial.println("ON");
				}
			}
		}else{
			debugTrips[a] = 0;
			if(tripped[a]){
				tripped[a] = false;
				//set input trip event to false
				String eventName = "Input_";
				eventName+=(a+1);
				Particle.publish(eventName, "OFF");
				Serial.print("eventName: ");
				Serial.println(eventName);
				Serial.print("eventContents: ");
				Serial.println("OFF");
			}
		}
		a++;
	}
}

int triggerRelay(String command){
	if(command.equalsIgnoreCase("turnonallrelays")){
		relayController.turnOnAllRelays();
		return 1;
	}
	if(command.equalsIgnoreCase("turnoffallrelays")){
		relayController.turnOffAllRelays();
		return 1;
	}
	if(command.startsWith("setBankStatus:")){
		int status = command.substring(14).toInt();
		if(status < 0 || status > 255){
			return 0;
		}
		Serial.print("Setting bank status to: ");
		Serial.println(status);
		relayController.setBankStatus(status);
		Serial.println("done");
		return 1;
	}
	//Relay Specific Command
	int relayNumber = command.substring(0,1).toInt();
	Serial.print("relayNumber: ");
	Serial.println(relayNumber);
	String relayCommand = command.substring(1);
	Serial.print("relayCommand:");
	Serial.print(relayCommand);
	Serial.println(".");
	if(relayCommand.equalsIgnoreCase("on")){
		Serial.println("Turning on relay");
		relayController.turnOnRelay(relayNumber);
		Serial.println("returning");
		return 1;
	}
	if(relayCommand.equalsIgnoreCase("off")){
		relayController.turnOffRelay(relayNumber);
		return 1;
	}
	if(relayCommand.equalsIgnoreCase("toggle")){
		relayController.toggleRelay(relayNumber);
		return 1;
	}
	if(relayCommand.equalsIgnoreCase("momentary")){
		relayController.turnOnRelay(relayNumber);
		delay(300);
		relayController.turnOffRelay(relayNumber);
		return 1;
	}
	return 0;
}
Thingspeak Integration Webhook CodeJSON
This code is for creating Thingspeak Webhook on particle cloud. Go tohttps://console.particle.io/integrations and click new integration and paste the code.
{
    "event": "thingSpeakWrite_",
    "url": "https://api.thingspeak.com/update",
    "requestType": "POST",
    "form": {
        "api_key": "{{k}}",
        "field1": "{{1}}",
        "field2": "{{2}}",
        "field3": "{{3}}",
        "field4": "{{4}}",
        "field5": "{{5}}",
        "field6": "{{6}}",
        "field7": "{{7}}",
        "field8": "{{8}}",
        "lat": "{{a}}",
        "long": "{{o}}",
        "elevation": "{{e}}",
        "status": "{{s}}"
    },
    "mydevices": true,
    "noDefaults": true
}

Credits

Replications

Did you replicate this project? Share it!

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

AquaNiner Pet Hydration Monitor
Intermediate
  • 382
  • 14

Full instructions

Using two Photons, IFTTT and ThingSpeak, get notifications for when your furry friend needs water and monitor how much they're drinking.

Hot Shot Hoops
Intermediate
  • 530
  • 13

Full instructions

No need to keep track of the number of baskets you make when shooting hoops. Hot Shot Hoops does the work for you.

Hot Shot Hoops

Team IOT Basketball

Temperature Mirror
Intermediate
  • 381
  • 8

Full instructions

The Temperature Mirror incorporates a digital display to allow its user to readily view time, temperature, humidity, and light.

Temperature Mirror

MEGR3171 Team 49

Pet Feeder
Intermediate
  • 414
  • 7

Full instructions

Automated pet food dispenser to feed our pets when we are not at home by using an IoT device.

Teacher Tracker
Intermediate
  • 176
  • 4

Full instructions

If you want to know when a professor comes back to his/her office so you can ask annoying questions then this an option

LightAlert
Intermediate
  • 138
  • 4

Full instructions

As the great Terry Crews once said "that's 49 cents of milk spilt over the table! Somebody's gonna drink that!" But instead... electricity.

Add projectSign up / Login
Respect project