KyleSamuel Bultman
Published © GPL3+

Washing Machine Monitor MEGR 3171

This is an IoT project that uses two Particle Argons to detect when the washing machine cycle is finished and notify the user.

BeginnerFull instructions provided2 hours1,228
Washing Machine Monitor MEGR 3171

Things used in this project

Hardware components

Argon
Particle Argon
×2
Photo resistor
Photo resistor
×1
Solderless Breadboard Half Size
Solderless Breadboard Half Size
×1

Software apps and online services

Maker service
IFTTT Maker service
Google Sheets
Google Sheets

Story

Read more

Schematics

Argon 1 Schematic

Connect photo resistor to A0 and A5 on your Particle Argon. Connect WiFi antenna and power as normal.

Argon 2 Schematic

No connections to this board, just WiFi antenna and power.

Code

Argon 1 Code

C/C++
Particle Web IDE Code for Argon 1 (in laundry room)
// -------------------------------------------------------------
// Publish and Subscribe with photoresistors or phototransistors
/* -------------------------------------------------------------

Go find a buddy who also has a Particle device.
Each of you will pick a unique event name
   (make it weird so that no one else will have it)
   (no more that 63 ASCII characters, and no spaces)

In the following code, replace "your_unique_event_name" with your chosen name.
Replace "buddy_unique_event_name" with your buddy's chosen name.

Have your buddy do the same on his or her IDE.

Then, each of you should flash the code to your device.

Breaking the beam on one device will turn on the D0 LED on the second device.

But how does this magic work? Through the miracle of publish and subscribe.

We are going to Particle.publish a public event to the cloud.
That means that everyone can see you event and anyone can subscribe to it.
You and your buddy will both publish an event, and listen for each others events.

------------------------------------------*/


int led = D0;
int boardLed = D7;
int photosensor = A0;

int intactValue;
int brokenValue;
int beamThreshold;

bool beamBroken = false;

void myHandler(const char *event, const char *data); // forward declaration

// We start with the setup function.

void setup() {
    // This part is mostly the same:
    pinMode(led,OUTPUT); // Our LED pin is output (lighting up the LED)
    pinMode(boardLed,OUTPUT); // Our on-board LED is output as well

    // Here we are going to subscribe to your buddy's event using Particle.subscribe
    Particle.subscribe("LaundryStatus4", myHandler);
    // Subscribe will listen for the event buddy_unique_event_name and, when it finds it, will run the function myHandler()
    // (Remember to replace buddy_unique_event_name with your buddy's actual unique event name that they have in their firmware.)
    // myHandler() is declared later in this app.

    // Since everyone sets up their LEDs differently, we are also going to start by calibrating our photosensor.
    // This one is going to require some input from the user!

    // Calibrate:
    // First, the D7 LED will go on to tell you to put your hand in front of the beam.
    digitalWrite(boardLed,HIGH);
    delay(2000);

    // Then, the D7 LED will go off and the LED will turn on.
    digitalWrite(boardLed,LOW);
    digitalWrite(led,HIGH);
    delay(500);

    // Now we'll take some readings...
    int off_1 = analogRead(photosensor); // read photosensor
    delay(200); // wait 200 milliseconds
    int off_2 = analogRead(photosensor); // read photosensor
    delay(1000); // wait 1 second

    // Now flash to let us know that you've taken the readings...
    digitalWrite(boardLed,HIGH);
    delay(100);
    digitalWrite(boardLed,LOW);
    delay(100);
    digitalWrite(boardLed,HIGH);
    delay(100);
    digitalWrite(boardLed,LOW);
    delay(100);

    // Now the D7 LED will go on to tell you to remove your hand...
    digitalWrite(boardLed,HIGH);
    delay(2000);

    // The D7 LED will turn off...
    digitalWrite(boardLed,LOW);

    // ...And we will take two more readings.
    int on_1 = analogRead(photosensor); // read photosensor
    delay(200); // wait 200 milliseconds
    int on_2 = analogRead(photosensor); // read photosensor
    delay(300); // wait 300 milliseconds

    // Now flash the D7 LED on and off three times to let us know that we're ready to go!
    digitalWrite(boardLed,HIGH);
    delay(100);
    digitalWrite(boardLed,LOW);
    delay(100);
    digitalWrite(boardLed,HIGH);
    delay(100);
    digitalWrite(boardLed,LOW);
    delay(100);
    digitalWrite(boardLed,HIGH);
    delay(100);
    digitalWrite(boardLed,LOW);

    intactValue = (on_1+on_2)/2;
    brokenValue = (off_1+off_2)/2;
    beamThreshold = (intactValue+brokenValue)/2;

}


void loop() {
    // This loop sends a publish when the beam is broken.
    if (analogRead(photosensor)>beamThreshold) {
       // if (beamBroken==true) {
            Particle.publish("LaundryNotifier4", "intact", PUBLIC); // publish this public event
            // rename your_unique_event_name with your actual unique event name. No spaces, 63 ASCII characters.
            // give your event name to your buddy and have them put it in their app.

            // Set the flag to reflect the current status of the beam.
           beamBroken=false;
            delay(1000);
       // }
    }

    else {
       // if (beamBroken==false) {
            // Same deal as before...
            Particle.publish("LaundryNotifier4", "broken", PUBLIC);
           beamBroken=true;
            delay(1000);
      //  }
    }
}


// Now for the myHandler function, which is called when the cloud tells us that our buddy's event is published.
void myHandler(const char *event, const char *data)
{
    /* Particle.subscribe handlers are void functions, which means they don't return anything.
      They take two variables-- the name of your event, and any data that goes along with your event.
      In this case, the event will be "buddy_unique_event_name" and the data will be "intact" or "broken"

      Since the input here is a char, we can't do
         data=="intact"
        or
         data=="broken"

      chars just don't play that way. Instead we're going to strcmp(), which compares two chars.
      If they are the same, strcmp will return 0.
     */

    //if (strcmp(data,"intact")==0) {
         // if your buddy's beam is intact, then turn your board LED off
       // digitalWrite(boardLed,LOW);
    //}
   // else if (strcmp(data,"broken")==0) {
         // if your buddy's beam is broken, turn your board LED off
      //  digitalWrite(boardLed,LOW);
   // }
      if (strcmp(data,"finished")==0) {
        // if the laundry is finished, turn on the board LED on
        digitalWrite(boardLed, HIGH);
        delay(30000);
    }
    else {
        // if the data is something else, don't do anything.
        // Really the data shouldn't be anything but those two listed above.
    }
    
    }

Argon 2 Code

C/C++
Particle Web IDE Code for Argon 2
/* -------------------------------------------------------------

Code for Argon two in IOT Project. 

Argon 2 subscribes to the event published by Argon 1. When Argon 2  is notified of a change in the status of the light from on to off it publishes "finished". 
IFTTT applets are configured to send a GroupMe message and log data to Google Sheets when it sees Argon 2 publish "finished".
Argon 1 is subscribed to Argon 2. Argon 1 illuminates the on board LED when it receives the "finished" event to indicate data has been sent via Argon 2 and IFTTT 
and that the cycle is complete to anyone standing in the laundry room (since the last indicator light is now partially covered). This achieve bi-directional communication. 

------------------------------------------*/

//Initialize variables

bool oldValue;

bool beamBroken = false;

void myHandler(const char *event, const char *data); // forward declaration

// Setup function.

void setup() {

    // Subscribe to Argon 1 with Particle.subscribe
    Particle.subscribe("LaundryNotifier4", myHandler);
    // Subscribe will run the function myHandler() when recieves the evnt 
}

// myHandler called when the cloud tells us that event is published.
void myHandler(const char *event, const char *data) 
{
    oldValue=beamBroken; //old value tells us what the last state was
    
    if (strcmp(data,"intact")==0) { 
        
        //if light on, publish intact
         Particle.publish("LaundryStatus4", "intact", PUBLIC);
            // publish this public event
            
            // Set the flag to reflect the current status of the beam.
            beamBroken=false;
            delay(2000); //delay 2 seconds
    }
    else if (strcmp(data,"broken")==0) {
        // if told that the beam is broken
         
         // We only want to be notified when the cycle is done, so with this "if" statement it only publishes "finished" when it goes from intact to broken. 
         //Otherwise it would constantly notify us if the light is off, but that does not mean the cycle is complete. 
        if (oldValue==false) {
            
           Particle.publish("LaundryStatus4", "finished", PUBLIC);
            beamBroken=true;
            delay(2000);
        }
        //if last value was also broken, just continue publishing broken. 
        else {
            Particle.publish("LaundryStatus4", "broken", PUBLIC);
            beamBroken=true;
            delay(2000);
        }
            
    }
    else {
        // if the data is something else, don't do anything.
    }
}

Credits

Kyle

Kyle

1 project • 1 follower
Samuel Bultman

Samuel Bultman

1 project • 0 followers

Comments