Tyler HarrellOscar Zelaya
Published © GPL3+

Windowmatic

This project uses two photons in a car to allow you to control your windows from your phone and automatically rolling them up once its dark.

IntermediateFull instructions provided8 hours1,180

Things used in this project

Hardware components

Photon
Particle Photon
×2
8 Relay Relay board
×1
Nissan 240 door with automated windows
×1
Jumper wires (generic)
Jumper wires (generic)
×1
12v Car Battery
×1
Resistor 221 ohm
Resistor 221 ohm
×1
Photo resistor
Photo resistor
×1

Software apps and online services

Mobicle
ControlEverything.com Mobicle
Google Sheets
Google Sheets
Maker service
IFTTT Maker service

Story

Read more

Schematics

Windowmatic

This is the Circuit Diagram for the window portion of the Windowmatic

Photon 2

Code

Windowmatic Control

C/C++
This code is used primarily for the window motor control
int MAIN_POWER_RELAY = D4; // This is the primary relay that controls 12V+ // This relay must be on for the circuit to have 12V+

int RELAY_WIND_1 = D3; // Relay 1 for window

int RELAY_WIND_2 = D2; // Relay 2 for window

int wind_run_t = 4175; // The amount of time the motors will run

//Both RELAY_WIND_1 and RELAY_WIND_2 off will make the windows go
//Both RELAY_WIND_1 and RELAY_WIND_2 on will make the windows go



void myClose(const char *event,const char *data) {
    
        digitalWrite(MAIN_POWER_RELAY, LOW);
        digitalWrite(RELAY_WIND_1, LOW);
        digitalWrite(RELAY_WIND_2, LOW);
        
        delay(wind_run_t);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        digitalWrite(RELAY_WIND_1, HIGH);
        digitalWrite(RELAY_WIND_2, HIGH);
        
        Particle.publish("Window-Activity","100", 60, PUBLIC);
}




void setup() {
    

    
    Particle.subscribe("OZELAYA-RAIN", myClose); //Listens for OZELAYA RAIN event will put the windows up in the event of rain
    Particle.subscribe("OZELAYA-DARK", myClose); //Listens for OZELAYA DARK event will put the windows up if it gets dark

    
    Particle.function("Window-Cuzz",windowToggle); //Function used in mobicle to have remote window control
    
    

    
    // MAIN_POWER_RELAY, RELAY_WIND_1, RELAY_WIND_2 ======> OUTPUT pins (send voltage)
    
    pinMode(MAIN_POWER_RELAY, OUTPUT);
    pinMode(RELAY_WIND_1, OUTPUT);
    pinMode(RELAY_WIND_2, OUTPUT);
    
    // Makes sure that the relays are off
    digitalWrite(MAIN_POWER_RELAY, HIGH);
    digitalWrite(RELAY_WIND_1, HIGH);
    digitalWrite(RELAY_WIND_2, HIGH);

}



void loop() {
       

}



int windowToggle(String command) {

    if (command=="DOWN 100") { // if then statements for buttons on mobicle 
        
        digitalWrite(MAIN_POWER_RELAY, LOW); //Turn main relay on 

        delay(wind_run_t); //run for x amount of time

        digitalWrite(MAIN_POWER_RELAY, HIGH); //Turn main relay off
        
        Particle.publish("Window-Activity","-100", 60, PUBLIC); //Publish window position to google drive sheet

        return 7;
    }
    if (command=="DOWN 75") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);

        
        delay(wind_run_t*.75);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        
        Particle.publish("Window-Activity","-75", 60, PUBLIC);

        return 6;
    }
    if (command=="DOWN 50") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);

        
        delay(wind_run_t*.50);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        
        Particle.publish("Window-Activity","-50", 60, PUBLIC);

        return 5;
    }
    if (command=="DOWN 25") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);

        
        delay(wind_run_t*.25);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        
        Particle.publish("Window-Activity","-25", 60, PUBLIC);

        return 4;
    }
    else if (command=="UP 100") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);
        digitalWrite(RELAY_WIND_1, LOW);
        digitalWrite(RELAY_WIND_2, LOW);
        
        delay(wind_run_t);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        digitalWrite(RELAY_WIND_1, HIGH);
        digitalWrite(RELAY_WIND_2, HIGH);
        
        Particle.publish("Window-Activity","100", 60, PUBLIC);
        
        return 3;
    }
        else if (command=="UP 75") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);
        digitalWrite(RELAY_WIND_1, LOW);
        digitalWrite(RELAY_WIND_2, LOW);
        
        delay(wind_run_t*.75);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        digitalWrite(RELAY_WIND_1, HIGH);
        digitalWrite(RELAY_WIND_2, HIGH);
        
        Particle.publish("Window-Activity","75", 60, PUBLIC);
        
        return 2;
    }
        else if (command=="UP 50") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);
        digitalWrite(RELAY_WIND_1, LOW);
        digitalWrite(RELAY_WIND_2, LOW);
        
        delay(wind_run_t*.50);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        digitalWrite(RELAY_WIND_1, HIGH);
        digitalWrite(RELAY_WIND_2, HIGH);
        
        Particle.publish("Window-Activity","50", 60, PUBLIC);
        
        return 1;
    }
        else if (command=="UP 25") {
        
        digitalWrite(MAIN_POWER_RELAY, LOW);
        digitalWrite(RELAY_WIND_1, LOW);
        digitalWrite(RELAY_WIND_2, LOW);
        
        delay(wind_run_t*.25);
        
        digitalWrite(MAIN_POWER_RELAY, HIGH);
        digitalWrite(RELAY_WIND_1, HIGH);
        digitalWrite(RELAY_WIND_2, HIGH);
        
        Particle.publish("Window-Activity","25", 60, PUBLIC);
        
        return 0;
    }
    else {
        return -1;
    }

}

Dark Event

C/C++
This code is used to publish an event if it becomes dark to close the windows
int photoresistor = A0; // This is where your photoresistor is plugged in. The other side goes to the "power" pin (below).

int pwr = A5; // This is the other end of your photoresistor. The other side is plugged into the "photoresistor" pin (above).
// The reason we have plugged one side into an analog pin instead of to "power" is because we want a very steady voltage to be sent to the photoresistor.
// That way, when we read the value from the other side of the photoresistor, we can accurately calculate a voltage drop.

int analogvalue; // Here we are declaring the integer variable analogvalue, which we will use later to store the value of the photoresistor.

int darkThreshold = 50;


// Next we go into the setup function.

void setup() {
    pinMode(photoresistor,INPUT);  // Our photoresistor pin is input (reading the photoresistor)
    pinMode(pwr,OUTPUT); // The pin powering the photoresistor is output (sending out consistent power)

    // Next, write one pin of the photoresistor to be the maximum possible, so that we can use this for power.
    digitalWrite(pwr,HIGH);

    // We are going to declare a Particle.variable() here so that we can access the value of the photoresistor from the cloud.
    Particle.variable("analogvalue", &analogvalue, INT);
    // This is saying that when we ask the cloud for "analogvalue", this will reference the variable analogvalue in this app, which is an integer variable.

}


void loop() {

    analogvalue = analogRead(photoresistor);
    delay(100);
    
    if (analogvalue < darkThreshold) {
        Particle.publish("OZELAYA-DARK","IT-IS-DARK",60,PUBLIC); //Publishes event to the other photon to let it know that it is dark and closes the window
        delay(5000);
    }
    else {
        delay(5000);
    }
}

Credits

Tyler Harrell

Tyler Harrell

1 project • 0 followers
Oscar Zelaya

Oscar Zelaya

1 project • 0 followers

Comments