Flipper
Made by Travis Chambers
Made by Travis Chambers
The main goal for this project was to create a device that could turn on and off a light based on the amount of light in a room.
Created: February 2nd, 2017
I designed this device for one room in my house that has the light switch outside of the actual room. This room is a converted closet so it is smaller than the others and has a few other quirks with the light switch being one of them. As you can imagine this can be an annoyance to have go into the hallway to turn off the lights at night. I chose this problem because it is a small thing that is easy to deal with but it is an example of a type of problem that IoT can be used to solve. It is just making someone life a little bit easier.
The solution I wanted to create is very similar to the clapper light switch. In this case a clapper may not be the best solution because of the barrier between the switch and the person so I wanted to create something that allowed you to use a phone to turn off the light with the added benefit of turning the lights off when it was bright outside.
My first iteration was to be able to turn the light on and off with the photo resistor and I was able to accomplish this very early. I then moved on to adding the iOS app where I began with simply turning a light on and off and dimming a light without the photo resistor. Once these two separate parts were completed I moved on combining the two. After combining my first two parts, I found that they did not mesh well together. Specifically because the photo resistor is in the loop method it would crush the message saying to turn off or on the light from the app. To solve this problem I created the switch so that when the user wanted to control the light themselves, they would flip the switch in the iOS app.
The “final” product that is complete right now is a very basic model of what I wanted to create. It has basic the basic functionality of being able to turn on and off the light from the app as well as the light turning on when it is darker in a room. I also added a dimmer on the app so that you could dim the light. There is a switch in the app to turn the photo resistor on and off. This was necessary because the dimmer was not working as well when the light was being turned on and off. In the future it would be nice to fix this problem and do away with the switch. Beyond that I wanted to be able to display when the light was on and off in the app but that is not working as I wanted. I am able to tell when the light is on and off in the actual app code but the display is not updating right now. It would also be nice to be able to incorporate a motion sensor with the photo resistor so that the light could turn off when there is no one in the room. Finally I think an device like this could be used to help conserve energy by notifying the user when the lights have been on for too long.
I learned a lot about communicating with the particle device from an iOS platform, which I believe would be similar with other platforms, and also communicating from the device to other platforms. I think if I were to re-do this project I would incorporate a physical switch earlier. I have a physical switch but it does not interact with the code, by this I mean I am not able to tell when the light is switched off physically because there is no data being passed from the switch. Finally if I were to do this again or had more time, I would clean up the code on both iOS app and microcontroller. I did not get exactly where I wanted but I definitely think the device is in a workable place right now and I was able to learn a lot about the device through this project.
int led1 = D0;
int led2 = D1;
int isOn = 0;
int pResistor = A0;
int value;
int dimmerVal = 100;
String userControlled = "false";
void slide(const char *event, const char *data) {
int convertedData = atoi(data);
dimmerVal = convertedData;
analogWrite(led1,dimmerVal);
}
void switchedCalled(const char *event, const char *data) {
userControlled = data;
if(userControlled == "true") {
Serial.println("1");
}
if(userControlled == "false") {
Serial.println("2");
}
}
void setup()
{
// Here's the pin configuration, same as last time
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(pResistor, INPUT);
Serial.begin(9600);
// We are also going to declare a Particle.function so that we can turn the LED on and off from the cloud.
Particle.function("led",ledToggle);
Particle.function("connected",connectedLed);
Particle.variable("isOn",isOn);
// For good measure, let's also make sure both LEDs are off when we start:
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
Particle.subscribe("slider", slide);
Particle.subscribe("switch",switchedCalled);
}
void loop()
{
value = analogRead(pResistor);
Serial.println(userControlled);
if(userControlled == "false") {
if (value > 600){
digitalWrite(led1, LOW); //Turn led off
} else {
// digitalWrite(ledPin, HIGH); //Turn led on
analogWrite(led1, dimmerVal);
}
delay(500); //Small delay
}
}
int connectedLed(String command) {
digitalWrite(led2,HIGH);
delay(500);
digitalWrite(led2,LOW);
delay(500);
digitalWrite(led2,HIGH);
delay(500);
digitalWrite(led2,LOW);
Particle.variable("isOn",isOn);
}
int ledToggle(String command) {
if (command=="on") {
analogWrite(led1,dimmerVal);
// digitalWrite(led2,HIGH);
isOn = 1;
Particle.variable("isOn", isOn );
Particle.publish("test-lightOn","23456");
return isOn;
}
else if (command=="off") {
digitalWrite(led1,LOW);
// digitalWrite(led2,LOW);
isOn = 0;
Particle.variable("isOn", isOn);
Particle.publish("test-lightOn","9000000");
return 0;
}
else {
return -1;
}
}
Click to Expand
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var isControlled: UILabel!
var myPhoton : SparkDevice?
var toggleString = "on"
var lightOn = false
@IBOutlet weak var isOnLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
isControlled.text = "Not User Controlled"
SparkCloud.sharedInstance().login(withUser: "tjchambe@andrew.cmu.edu", password: "kmk123") { (error:Error?) -> Void in
if let _ = error {
print("Wrong credentials or no internet connectivity, please try again")
}
else {
print("Logged in")
SparkCloud.sharedInstance().getDevices { (sparkDevices: [Any]?, error: Error?) -> Void in
if error != nil {
print("Check your internet connectivity")
}
else {
if let devices = sparkDevices as? [SparkDevice] {
for device in devices {
if device.name == "tcham" {
self.myPhoton = device
self.myPhoton!.callFunction("connected", withArguments: ["on"], completion: { (resultCode : NSNumber?, error : Error?) -> Void in
if (error == nil) {
self.isOn()
SparkCloud.sharedInstance().subscribeToAllEvents(withPrefix: "test-", handler: self.subscribeHandler)
}
})
}
}
}
}
}
}
}
}
@IBAction func switchFlipped(_ sender: UISwitch) {
SparkCloud.sharedInstance().publishEvent(withName: "switch", data: String(sender.isOn), isPrivate: false, ttl: 60, completion: { (error:Error?) -> Void in
if error != nil
{
print("Error publishing event \(error?.localizedDescription)")
self.isControlled.text = "Currently User Controlled"
} else {
print("Error \(error?.localizedDescription)")
}
})
}
@IBAction func sliderChanged(_ sender: UISlider) {
SparkCloud.sharedInstance().publishEvent(withName: "slider", data: String(sender.value), isPrivate: false, ttl: 60, completion: { (error:Error?) -> Void in
if error != nil
{
print("Error publishing event \(error?.localizedDescription)")
}
})
}
func subscribeHandler(event: SparkEvent?, error: Error?)->() {
if (error == nil)
{
DispatchQueue.main.async(execute: {
print("Got: \(event?.event) and data: \(event?.data)")
})
} else {
NSLog("Error occured:\(error?.localizedDescription)")
}
}
func isOn() {
self.myPhoton?.getVariable("isOn", completion: {(_ result: Any?, _ error: Error?) -> Void in
if(error == nil) {
self.lightOn = (result! as! Int == 1) ? true : false
print(self.lightOn)
self.toggleString = (self.lightOn) ? "on" : "off"
self.isOnLabel.text = (self.lightOn) ? "Light is On" : "Light is Off"
} else {
print(error)
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func toggle(_ sender: Any) {
if(toggleString == "on") {
toggleString = "off"
} else {
toggleString = "on"
}
let funcArgs = [toggleString]
let task = myPhoton!.callFunction("led", withArguments: funcArgs) { (resultCode : NSNumber?, error : Error?) -> Void in
if (error == nil) {
print("LED on D7 successfully turned on")
}
}
// _; : Int64 = task.countOfBytesExpectedToReceive
}
}
Click to Expand
The main goal for this project was to create a device that could turn on and off a light based on the amount of light in a room.