Abstract

   We hope to develop a way that allows us to know precisely when our laundry is finished and receive a notification when that should happen. Instead of setting a timer or using an app, this product will easily send a simple notification to our smartphone telling us our laundry is finished. To accomplish this task, we plan to implant an accelerometer onto a washing or drying machine and detect the vibrations from the respective machine. Here, we naturally assume that all laundry machines experience such vibrations during their washing/drying cycles. When these vibrations stop completely, the accelerometer will catch this long-term cessation of motion and duly send a message via Ethernet and/or Bluetooth to our smartphone notifying us that our laundry has finished washing or drying. During this process, the accelerometer must necessarily experience changes in motion due to the laundry machine vibrations, so to accommodate such movement, we plan to create a mechanistic boundary over which the accelerometer can move. Most importantly, the accelerometer will begin detecting changes in motion automatically, thereby making the use of an alarm or stopwatch completely unnecessary. Moreover, we believe that our method of retrieving laundry immediately after it has finished is much more efficient than using a stopwatch or fumbling with a smartphone app. 

Promotional Video Link

https://www.youtube.com/watch?v=hdYroLqx7Nw

The Problem

Many things can go wrong when you're trying to do laundry in college. You can forget your laundry in the dryer, the dryer might not be working, or someone might move your laundry so they can get a machine. Worst of all, you can become a victim of laundry theft. We hope to solve these problems with the LaundroMeter.

Our Approach

In order to solve these problems, we attached an accelerometer to the door of the laundry machine in order to determine when the door was opened based on the acceleration of the door as well as to tell whether the machine was on, based on the vibrations of the machine. We also added a temperature sensor to the inside of the dryer so we could figure out if the laundry was actually being heated or not. We then enabled Bluetooth communication between the Arduino with the sensors and an Arduino connected to an Ethernet port to allow the Arduino connected to Ethernet to send messages to the user's phone.

What We Accomplished

After much data analysis through MATLAB, we were able to find the thresholds to determine when the door was opened, when the machine was on or off, and when the temperature of the machine was going up. To figure out when the dryer had started, we used the temperature sensor and sent a notification to the user. That is, if the user did not receive the message that the dryer had begun a load of laundry, they would immediately realize that the dryer was defective and would be able to switch dryers.
In order to ascertain when the door of the laundry machine had opened, we experimentally determined thresholds by opening the laundry machine door multiple times. We found that we got the most consistent results when we measured jerk, the derivative of acceleration, because there was a great deal of distortion and noise in the acceleration graphs. Then, we added code such that whenever jerk exceeded a certain threshold value, the user would be notified that the door had been opened.
Finally, to determine when the laundry was finished and tell the user that it has finished, we used a threshold for acceleration. Because laundry machines tend to vibrate when they are on, we were able to measure the magnitude of these vibrations with acceleration values from the accelerometer. When the acceleration values were below the thresholds we found experimentally, we sent a message to the user to let them know that their laundry was done. Additionally, because the vibrations of the laundry machine weren't always consistent or could be modified by the vibrations of other laundry machines nearby, we set an internal timer in the LaundroMeter that would send a notification to the user after a certain period of time after the laundry had started. These two methods ensured that the LaundroMeter would notify the user when the laundry had finished.
To message the user, we used a combination of Bluetooth and Ethernet communication. The Arduino on the laundry machine would communicate with an Arduino connected to Ethernet that would send a certain message to thingspeak.com, which, in turn, would send an SMS to the user. Each function of the LaundroMeter corresponded to a different text message that would be sent to the user, letting the user quickly know the status of their laundry.
In the end, after conducting a large amount of research as well as gathering and analyzing data, we created a LaundroMeter that was able to solve many of problems that students doing laundry tend to face.

Code for Arduino on the Laundry Machine

#include < SoftwareSerial.h >
SoftwareSerial BTSerial(2, 3); 

//CONSTANTS
const int DRIER_TIME = 45*60; //seconds it takes to dry clothes, approx. 45 minutes
//Threshold values used to determine events for the dryer.
const int X_DOOR_THRESHOLD = 30;
const int Y_DOOR_THRESHOLD = 30;
const int Z_DOOR_THRESHOLD = 70;
const double OFF_THRESHOLD = 5;
const int ON_TEMP_THRESHOLD = 3;
//constant used to convert temperature to degrees F
const double TEMP_MULTIPLIER = 500/1024.0;

//Setup values for Arduino pins
const int xPin = 2;
const int yPin = 3;
const int zPin = 4;
const int tPin = 0;

//INITIALIZED VALUES FOR PROGRAM
//Calibration array: initialized at the beginning so both setup() and loop() can access the values
int CalVal[] = {0, 0, 0, 0}; //Stores calibrated values for x, y, and z accelerations and temperature, in that order
                              //Since jerk is calculated with calibrated accelerations, it does not need to have its own calibration.
boolean dryerstarted = false; //boolean representing whether the dryer has started. Initial condition assumes the dryer is off.
boolean dooropen = false; //boolean representing whether the dryer door is open.Initiial condition assumes door is closed. 

void setup() {
  //Begin communication with bluetooth and serial monitor.
  BTSerial.begin(9600); 
  Serial.begin(9600);

  //Calibrates Machine before beginning
  Serial.println("Hold Steady for Calibration...");
  int i = 0; 
  int xcRead = 0;
  int ycRead = 0;
  int zcRead = 0;
  int temp = 0;
  //Adds together values for each variable for 5 seconds
  while(i < 50){
    xcRead = xcRead + analogRead(xPin);
    ycRead = ycRead + analogRead(yPin);
    zcRead = zcRead + analogRead(zPin);

    temp += analogRead(tPin) * TEMP_MULTIPLIER;
    
    i = i + 1;
    delay(100);
  }
  //Stores average value for each variable into the CalVal array so they can be accessed in the loop
  CalVal[0] = xcRead / 50; //Calibrated accelerations
  CalVal[1] = ycRead / 50;
  CalVal[2] = zcRead / 50;
  CalVal[3] = temp / 50;
  Serial.println("Temperature Calibration: " + (String) CalVal[3]);
  Serial.println("x calibration: " + (String) CalVal[0] + "y calibration: " + (String)CalVal[1] + "z calibration: " + (String)CalVal[2]);
  Serial.println("Calibration done!");

}


//Initializes arrays to store acceleration values for two consecutive calculations  
int xRead[] ={0, 0};
int yRead[] ={0, 0};
int zRead[] ={0, 0};

//Starts a count of how long the dryer has been on
int halfsecondspassed = 0;

void loop() {

  //Stores previous value of acceleration in Read[0] and the current value in Read[1], so jerk can be calculated later
  xRead[0] = xRead[1]; xRead[1] = analogRead(xPin) - CalVal[0];
  yRead[0] = yRead[1]; yRead[1] = analogRead(yPin) - CalVal[1];
  zRead[0] = zRead[1]; zRead[1] = analogRead(zPin) - CalVal[2];

  //Uses these consecutive values to calculate jerk.
  int xjRead = (xRead[1] - xRead[0]);
  int yjRead = (yRead[1] - yRead[0]);
  int zjRead = (zRead[1] - zRead[0]);

  //stores difference in temperature from calculated value
  int dTemp = analogRead(tPin) * TEMP_MULTIPLIER - CalVal[3];
  
  //Print to serial monitor for debugging
  Serial.println("x: " + (String) xRead[1] + " y: " + (String) yRead[1] + "z: " + (String) zRead[1]);
  Serial.println("xjerk: " + (String) xjRead + " yjerk: " + (String) yjRead + " zjerk: " + (String) zjRead);
  Serial.println("Temp: " + (String) dTemp);
  
  //The following code determines when to send a message to the other Arduino:
  
  //Door Opened: Occurs when the accelerations reach a certain value and the door is not already open.
  if(((abs(xjRead) > X_DOOR_THRESHOLD || abs(yjRead) > Y_DOOR_THRESHOLD) && (abs(zjRead) > Z_DOOR_THRESHOLD) && !dooropen)){
    Serial.println("D");
    BTSerial.println("D");
    dooropen = true;
  }
  //Machine off: Occurs when all the accelerations are below a certain threshold (representing the machine's natural vibration)
  //and the dryer has already been started. Could also occur if the drier has been running for long enough.
  else if (((abs(xRead[1]) < OFF_THRESHOLD) && (abs(yRead[1]) < OFF_THRESHOLD) && (abs(zRead[1]) < OFF_THRESHOLD) && dryerstarted) 
             || (halfsecondspassed > DRIER_TIME * 2)){
    Serial.println("O");
    BTSerial.println("O");
    dryerstarted = false;
  } 
  //Machine on: Should occur if the laudry machine is hot enough and it isn't already on
  else if (abs(dTemp) > ON_TEMP_THRESHOLD  && !dryerstarted){
    Serial.println("N");
    BTSerial.println("N");
    dryerstarted = true;
  } else{
    Serial.println("");
    BTSerial.println("");
  } 
  delay(500); // delay so we can read the values more clearly

  //Code to keep track of time
  if(dryerstarted){
  halfsecondspassed +=1; //keeps track of the time, since each loop is approximately half a second
  } else {
    halfsecondspassed = 0; //if the dryer hasn't started, the time should be 0
  }
} 

Code for Ethernet Arduino

#include < SPI.h >
#include < Ethernet.h >
#include < SoftwareSerial.h >
SoftwareSerial  BTSerial(2, 3); 
 
// MAC address, specific to the Ethernet shield we used
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0x07, 0xCC };  
// IP address of our specific station
IPAddress ip(165, 123, 130, 208);
 
char server[] = "api.thingspeak.com";

//API key for the Thingspeak ThingHTTP already configured
const String apiKey = "OCRTSL6FYQAXW47D";

//the number the message should be sent to
const String sendNumber = "XXXXXXXXXXX";
 
EthernetClient client;
 
void setup() {
  //Begin communication with serial monitor and our other Arduino
  BTSerial.begin(9600);
  Serial.begin(9600);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);
  Ethernet.begin(mac, ip);
  delay(2000);
  Serial.println("Ready to send");
}

void loop() {
  if(BTSerial.available()){
    char inRead = (char) BTSerial.read();
    
    //Send a notification when the door is opened
    if(inRead == 'D'){
      Serial.println("Try to send door open text");
      sendSMS(sendNumber, "Your laundry door has been opened, hope that was you!");
    }
    
    //Send a notification when the machine turns off
    if(inRead == 'O'){
      Serial.println("Try to send machine off text");
      sendSMS(sendNumber, "Your laundry machine has turned off, come and get your clothes!");
    }
    
    //Send notification when machine turns on
    if(inRead == 'N'){
      Serial.println("Try to send machine on textl");
      sendSMS(sendNumber, "Looks like you've started a new load! We'll tell you when its done.");
    }
  } 
}

//Code for sending an SMS, mostly from instructables.com
void sendSMS(String number,String message)
{
  // Make a TCP connection to remote host
  if (client.connect(server, 80))
  {

    //should look like this...
    //api.thingspeak.com/apps/thinghttp/send_request?api_key={api key}&number={send to number}&message={text body}

    client.print("GET /apps/thinghttp/send_request?api_key=");
    client.print(apiKey);
    client.print("&number=");
    client.print(number);
    client.print("&message=");
    client.print(message);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  }
  else
  {
    Serial.println(F("Connection failed"));
  } 

  // Check for a response from the server, and route it
  // out the serial port.
  while (client.connected())
  {
    if ( client.available() )
    {
      char c = client.read();
      Serial.print(c);
    }      
  }
  Serial.println();
  client.stop();
}

//Code used to encode messages so they actually send
String URLEncode(const char* msg)
{
  const char *hex = "0123456789abcdef";
  String encodedMsg = "";

  while (*msg!='\0'){
    if( ('a' <= *msg && *msg <= 'z')
      || ('A' <= *msg && *msg <= 'Z')
      || ('0' <= *msg && *msg <= '9') ) {
      encodedMsg += *msg;
    } 
    else {
      encodedMsg += '%';
      encodedMsg += hex[*msg >> 4];
      encodedMsg += hex[*msg & 15];
    }
    msg++;
  }
  return encodedMsg;
} 
Share this project:
×

Updates