Omer MucahitKatie Millican
Published © GPL3+

Automated Room Light

Automated light that allows you control your room light with a motion sensor and Amazon Alexa while logging the light level every minute.

IntermediateFull instructions provided1 hour693
Automated Room Light

Things used in this project

Hardware components

Photon
Particle Photon
This project can be completed by one photon. Because of the assignment requirements we are using two photons.
×2
PIR Motion Sensor (generic)
PIR Motion Sensor (generic)
You might need to play with sensitivity settings depends on how big you room is.
×1
LED (generic)
LED (generic)
×1
Resistor 10k ohm
Resistor 10k ohm
×1
Resistor 1k ohm
Resistor 1k ohm
This resistor for the LED. Smaller value can be used. Smaller the resistance higher the brightness
×1
Particle Photon I²C 2-Channel SPDT 1-Amp Signal Relay
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
Photo resistor
Photo resistor
×1
15 A/125 V Power strip
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Amazon Alexa service
IFTTT Amazon Alexa service
ThingSpeak API
ThingSpeak API
Mobicle
ControlEverything.com Mobicle

Hand tools and fabrication machines

flat head screwdriver

Story

Read more

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 reading

C/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 Code

C/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 Code

JSON
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

Omer Mucahit

Omer Mucahit

1 project • 2 followers
Contact
Katie Millican

Katie Millican

1 project • 1 follower
Contact

Comments