Project tutorial
Faucet

Faucet

The Sink That Can Think

  • 1,415 views
  • 1 comment
  • 2 respects

Components and supplies

13285 01
PIR Motion Sensor (generic)
×1
1/8" Acrylic - Fluorescent Green
×1
Purple LED
×2
1/8 Acrylic - Translucent White
×1
Acrylic Welding Solution
×1
Speaker
×1
Cardboard Tube (for resonance chamber)
×1
Velcro
×1
Electrical Tape (for resonance chamber)
×1
Flex Resistor
×1
NPN Tip120 Power Transistor
×1
SD Card Sound Board
×1
Mfr 25frf52 10k sml
Resistor 10k ohm
×1
Wires
×18
11114 01a
SparkFun Arduino Pro Mini 328 - 3.3V/8MHz
×1

About this project

The Team

Clare Lin - Cog Sci
Yang Zhao - CS
Jose Carrillo - EECS
Alex Greenspan - CS/Cog Sci
Kelsey Brennan - Architecture

Demo Video

Warning: embedding parts within the project story has been deprecated. To edit, remove or add more parts, go to the "Hardware" tab. To remove this list from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Hardware" tab).
1/8" Acrylic - Fluorescent Green
1/8 Acrylic - Translucent White
Acrylic Welding Solution
Velcro
Warning: embedding parts within the project story has been deprecated. To edit, remove or add more parts, go to the "Hardware" tab. To remove this list from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Hardware" tab).
13285 01
PIR Motion Sensor (generic)
Purple LED
Speaker
Cardboard Tube (for resonance chamber)
Electrical Tape (for resonance chamber)
Flex Resistor
NPN Tip120 Power Transistor
SD Card Sound Board
Mfr 25frf52 10k sml
Resistor 10k ohm
Wires
Arduino Mini Pro

Images

Laser Cut File for Enclosure

Construction Diagram for Enclosure

Exploded Axon for Device

Circuit Diagrams

Code

faucet.ino
Code

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

/*
  A = motion sensing = 0000, 0001, 0009, 0011; 0013
  B = water flow
  C = hardcode
 */

/*
  Sounds and Corresponding File Names:
  SUE
  0000 = Whoa, I'm feeling a bit of rain through my pipes today!
  0001 = (A) You know, the microwave was just talking about you…
  0002 = (A) The silverware was just telling me there's a drought?!
         That can't be good.
  0003 = (C) Hey, be kind to my handles! Slow and steady now.
  0004 = (B) Oh… that looks like it could use some soap.
  0005 = (B) The water keeps talking about the Hetchy reservoir.
         Seems like it’s spent a lot of time there.
  0006 = (B) Cut back on the water! I'm in charge of it! Understand?
  0007 = (B) Did you know this water came all the way from the Sierra Nevada?
         Give it some respect please!
  0008 = (B) I'm giving you an important task. Keeping me clean.
         I want to shine like an ice cube.
  0009 = (A) I feel like you could use a nice glass of water right now.
  0010 = (B) Ah. Now isn’t thaat nice?
  0011 = (A) A sponge a day keeps the mildew away.
  
  STUART
  0012 = (C) Hey! The water’s scalding!
  0013 = (A) Hope you’re having a good day!
  0014 = (B) Here’s some Sierra Nevada...*water plays*
  0015 = (B) You know what this reminds me of? *song plays*
 */

#include <Wtv020sd16p.h>
//#include <Event.h>
//#include <Timer.h>

int resetPin = 2;  // The pin number of the reset pin.
int clockPin = 3;  // The pin number of the clock pin.
int dataPin = 4;  // The pin number of the data pin.
int busyPin = 5;  // The pin number of the busy pin.

int flexPin = A0;
int motionPin = 7;

int stuartMotionPhrases[] = {13};
int stuartWaterPhrases[] = {14,15};
int stuartSpecialPhrases[] = {12};

int sueMotionPhrases[] = {0,1,2,9,11};
int sueWaterPhrases[] = {4,5,6,7,8,10};
int sueSpecialPhrases[] = {3};

int demoPin = 12;

int count = 0;

int flexValueCenter = 770;

int pirVal;
int flexValue;
int prevFlexValue;

int motionDetected = 0;
int waterDetected = 0;

int waterFlowTotalTime = 0;
int motionTotalTime = 0;

int flexEnabled = 1;
int motionEnabled = 1;


int SUE = 0;
int STUART = 1;
int voice = 1;

int water = 0;
int motion = 1;
int special = 2;


/*
Create an instance of the Wtv020sd16p class.
 1st parameter: Reset pin number.
 2nd parameter: Clock pin number.
 3rd parameter: Data pin number.
 4th parameter: Busy pin number.
 */
Wtv020sd16p wtv020sd16p(resetPin,clockPin,dataPin,busyPin);

void setup() {
  //Initializes the module.
  Serial.begin(9600);
  wtv020sd16p.reset();
  pinMode(flexPin, INPUT);
  pinMode(motionPin, INPUT);
  pinMode(demoPin, INPUT);
  
  flexValue = analogRead(flexPin);
  prevFlexValue = flexValue;
  delay(5000);
}


void loop() {
  
  if(motionEnabled) {
    pirVal = digitalRead(motionPin);
  } else {
    pirVal = HIGH;
  }
  prevFlexValue = flexValue;
  delay(300);
  if(flexEnabled) {
    flexValue = analogRead(flexPin);
  } else {
    flexValue = prevFlexValue;
  }
  
  
  //Serial.println("FLEXV")

  if(pirVal == LOW){ //was motion detected
    Serial.println("Motion");
    if (digitalRead(demoPin)) {
      speakDemo();
    } else {
      speak(motion);
    }
   
  } else if (flexValue - prevFlexValue > 5 ) {
    Serial.println("Flex");
    Serial.println(prevFlexValue);
    Serial.println(flexValue);
    prevFlexValue = flexValue;
    if(digitalRead(demoPin)) {
      speakDemo();
    } else {
      speak(water);
    }
  } 
}


void speak(int phraseGroup) {
  if(voice == SUE) {
    if(phraseGroup == water) {
      int value = (int)random(6);
      wtv020sd16p.asyncPlayVoice(sueWaterPhrases[value]);
      
    } else if (phraseGroup == motion) {
      int value = (int) random(5);
      wtv020sd16p.asyncPlayVoice(sueMotionPhrases[value]);
      
    } else if (phraseGroup == special) {
      int value = (int) random(1);
      wtv020sd16p.asyncPlayVoice(sueSpecialPhrases[value]);
      
    }
  } else if(voice==STUART) {
    if(phraseGroup == water) {
      int value = (int)random(2);
      wtv020sd16p.asyncPlayVoice(sueWaterPhrases[value]);
      
    } else if (phraseGroup == motion) {
      int value = (int) random(1);
      wtv020sd16p.asyncPlayVoice(sueMotionPhrases[value]);
      
    } else if (phraseGroup == special) {
      int value = (int) random(1);
      wtv020sd16p.asyncPlayVoice(sueSpecialPhrases[value]);
    }
  } 
  delay(500);
  while(digitalRead(busyPin)) {
        //busy wait
  }
}

void speakDemo() {
  Serial.println("Demo");
  Serial.println(voice);
  
  if(voice == SUE) {
    if(count > 11) {
      count = 0;
    }
    
  } else if (voice == STUART) {
    if (count > 15 || count < 12) {
      count = 12;
    }
  }
  Serial.println(count);
  wtv020sd16p.asyncPlayVoice(count);
    delay(500);
    while(digitalRead(busyPin)) {
      //busy wait
    }
  count++;
  delay(2000);
}

Documentation

Video Script
Presentation PowerPoint
Sink Narrative Practice 1
Sink Narrative Practice 2

Project Statement

The kitchen is an indispensable feature of any home. In investigating our personal day-to-day experiences with our respective kitchens, each of the members of our group came to better appreciate the role of the sink. Functionally, the sink plays a prominent and important part — being an appliance which is constantly turned on and off, while at the same time often a necessity even when other devices are not in use. After all, how many times does one simply walk into the kitchen for a cup of water from the tap? Or just to wash dishes after a meal? We use our sinks all the time. As a machine of convenience, it often seems to fade as a utility into the background of our lives. With this in mind, our group was determined to better utilize the capacity of our sink, especially in light of the drought recently declared in our state of California. By anthropomorphizing our sink, imbuing it with speech, conscience, and personality, we have endeavored to bring the user a new kitchen experience: our device disrupts the normative use of the kitchen by providing a new, unique, and humanized narrative for the kitchen sink. We see such an experience as an asset not only to the residents of California, but sink users globally — all of whom could profit from the awareness we aim to foster.

Brainstorm and Design

The members of our group brainstormed extensively to come up with the concept for this project. All members partook in individual and communal brainstorming and discussion times, wherein every aspect of the project- from personal goals to specific design implementations, were put on the table and hashed out extensively. To better facilitate our process, we began with a discussion of our general goals for the project- what equipment, materials, and skills we each desired to learn or implement. In this preliminary discussion, we came to first appreciate each member's different strengths and not only allowed the team to better understand one another, but also brought everyone up to speed- aligning the team to a uniform set of objectives. 

We followed this with generalized discussion about the setting and usage of the kitchen. Each member poured out his or her thoughts, insights, problems, concerns, and questions regarding the kitchen and any related issues. Many hours thus spent proved very fruitful, according ideas ranging from water conservation to specific affordances which could improve kitchen use (e.g. easily accessible top shelving, etc.). Each member also spent time on their own, considering their respective kitchen and conducting contextual inquiry at home in order to facilitate more cognizant understanding of kitchen space and use. We were also determined to further brainstorm on our own on specific objects and functionalities before getting back together again, whereupon we continued our extensive process of critiquing and further brainstorming, eventually settling upon the utility of the kitchen sink- which we believed would best meet several concerns brought out by our members- from water conservation to simply better minding one's dirty dishes. Our team brainstorming was further enriched by consulting our instructors in the topic of Critical Making, which brought out several alternatives and improvements to our then-idea and design.

This bout of creative thinking was then followed by considerations for the actual design and implementation of our device. Each member of the team took a day to consider the specific function, look, feel, and know-how of how we envisioned the project. This, predictably, was followed by corporate consideration and constructive critique, and the ultimate shape of Faucet began to take form. We were determined from our brainstorms that our sink device would work to influence how users experienced and even considered the kitchen. We wanted the kitchen to take on a new narrative for the user- for their kitchen experience to tell a different, more conscious, story- rather than provide a device that simply did something utilitarian for the user.

The process of producing our device had finally begun. Again, each member's individual talents shone through in this process. One member contributed a well-developed knowledge of electronics and mechanics, including the practical understanding of what was required and/or possible given our own constraints (budget, time, and material), while another put forth great insight on the architectural implications of the device and what could be done with the design physically and aesthetically to afford the most function for its form. At the same time, other members worked on the many other demands of the project- from drawings and Arduino code to documentation and presentation. Every member of the team contributed much to the final project, putting in extensive time and energy to ensure the necessary work was completed, the many deadlines were met, and ultimately guaranteed that the project in its entirety would be an absolute success.

Project Process and Research Notes

Instructions for Assembly

  1. Form the acrylic sections required for the outer container by cutting the parts out of 1/8-inch acrylic or Plexiglas. Also ensure the sides have appropriate openings for the flex sensor, PIR sensor, and wires (refer to prototype images for reference), all of which must later extend outward from the inner mass of the container. These holes should be wide enough to allow passage of these projections while still providing ample coverage of the device from potential water splashes (given the nature of its anticipated environment- i.e. a sink ). Some tiny holes should also be made (where one expects the speaker to later be placed) in order to better allow for the projection of sounds emitted by the speaker. Be careful to architect these many holes such that their respective functioning components do not ultimately interfere physically with one another (e.g. don't put the speaker holes right next to the wiring holes, lest you later find that all your wires must all snake complicatedly around your speaker, or worse- that no way exists for both elements to occupy the same space, at all).
  2. Use Plexiglas welding cement to assemble the outer container as detailed in the axonometric construction diagram. Ensure the two main sections of the box slide together properly. Also attach the Velcro to the back of the device (note that this step can alternatively wait until after the rest of your project is fully assembled, in order to better facilitate the future installation and arrangement of delicate electronics).
  3. Make a resonance chamber to amplify the sound of the speaker: using a cardboard roll of similar or slightly larger diameter, shorten it as needed to fit the height of the acrylic container, then insert the speaker into one end (it should be a tight fit- the less holes there are, the better the final effect will be). Seal the other end with tape to complete the resonance chamber.
  4. Assemble the electronics according to the circuit diagram.
  5. Neatly place the flex sensor, PIR sensor, LEDs, and speaker in the enclosure. Also thread the many attached wires through the designated holes.
  6. Make sure your electronics are wired up correctly. Now enjoy meeting your faucet!

Hard at Work!

Code

faucet.inoPlain text
faucet.ino
/*
  A = motion sensing = 0000, 0001, 0009, 0011; 0013
  B = water flow
  C = hardcode
 */

/*
  Sounds and Corresponding File Names:
  SUE
  0000 = Whoa, I'm feeling a bit of rain through my pipes today!
  0001 = (A) You know, the microwave was just talking about you
  0002 = (A) The silverware was just telling me there's a drought?!
         That can't be good.
  0003 = (C) Hey, be kind to my handles! Slow and steady now.
  0004 = (B) Oh that looks like it could use some soap.
  0005 = (B) The water keeps talking about the Hetchy reservoir.
         Seems like its spent a lot of time there.
  0006 = (B) Cut back on the water! I'm in charge of it! Understand?
  0007 = (B) Did you know this water came all the way from the Sierra Nevada?
         Give it some respect please!
  0008 = (B) I'm giving you an important task. Keeping me clean.
         I want to shine like an ice cube.
  0009 = (A) I feel like you could use a nice glass of water right now.
  0010 = (B) Ah. Now isnt thaat nice?
  0011 = (A) A sponge a day keeps the mildew away.
  
  STUART
  0012 = (C) Hey! The waters scalding!
  0013 = (A) Hope youre having a good day!
  0014 = (B) Heres some Sierra Nevada...*water plays*
  0015 = (B) You know what this reminds me of? *song plays*
 */

#include <Wtv020sd16p.h>
//#include <Event.h>
//#include <Timer.h>

int resetPin = 2;  // The pin number of the reset pin.
int clockPin = 3;  // The pin number of the clock pin.
int dataPin = 4;  // The pin number of the data pin.
int busyPin = 5;  // The pin number of the busy pin.

int flexPin = A0;
int motionPin = 7;

int stuartMotionPhrases[] = {13};
int stuartWaterPhrases[] = {14,15};
int stuartSpecialPhrases[] = {12};

int sueMotionPhrases[] = {0,1,2,9,11};
int sueWaterPhrases[] = {4,5,6,7,8,10};
int sueSpecialPhrases[] = {3};

int demoPin = 12;

int count = 0;

int flexValueCenter = 770;

int pirVal;
int flexValue;
int prevFlexValue;

int motionDetected = 0;
int waterDetected = 0;

int waterFlowTotalTime = 0;
int motionTotalTime = 0;

int flexEnabled = 1;
int motionEnabled = 1;


int SUE = 0;
int STUART = 1;
int voice = 1;

int water = 0;
int motion = 1;
int special = 2;


/*
Create an instance of the Wtv020sd16p class.
 1st parameter: Reset pin number.
 2nd parameter: Clock pin number.
 3rd parameter: Data pin number.
 4th parameter: Busy pin number.
 */
Wtv020sd16p wtv020sd16p(resetPin,clockPin,dataPin,busyPin);

void setup() {
  //Initializes the module.
  Serial.begin(9600);
  wtv020sd16p.reset();
  pinMode(flexPin, INPUT);
  pinMode(motionPin, INPUT);
  pinMode(demoPin, INPUT);
  
  flexValue = analogRead(flexPin);
  prevFlexValue = flexValue;
  delay(5000);
}


void loop() {
  
  if(motionEnabled) {
    pirVal = digitalRead(motionPin);
  } else {
    pirVal = HIGH;
  }
  prevFlexValue = flexValue;
  delay(300);
  if(flexEnabled) {
    flexValue = analogRead(flexPin);
  } else {
    flexValue = prevFlexValue;
  }
  
  
  //Serial.println("FLEXV")

  if(pirVal == LOW){ //was motion detected
    Serial.println("Motion");
    if (digitalRead(demoPin)) {
      speakDemo();
    } else {
      speak(motion);
    }
   
  } else if (flexValue - prevFlexValue > 5 ) {
    Serial.println("Flex");
    Serial.println(prevFlexValue);
    Serial.println(flexValue);
    prevFlexValue = flexValue;
    if(digitalRead(demoPin)) {
      speakDemo();
    } else {
      speak(water);
    }
  } 
}


void speak(int phraseGroup) {
  if(voice == SUE) {
    if(phraseGroup == water) {
      int value = (int)random(6);
      wtv020sd16p.asyncPlayVoice(sueWaterPhrases[value]);
      
    } else if (phraseGroup == motion) {
      int value = (int) random(5);
      wtv020sd16p.asyncPlayVoice(sueMotionPhrases[value]);
      
    } else if (phraseGroup == special) {
      int value = (int) random(1);
      wtv020sd16p.asyncPlayVoice(sueSpecialPhrases[value]);
      
    }
  } else if(voice==STUART) {
    if(phraseGroup == water) {
      int value = (int)random(2);
      wtv020sd16p.asyncPlayVoice(sueWaterPhrases[value]);
      
    } else if (phraseGroup == motion) {
      int value = (int) random(1);
      wtv020sd16p.asyncPlayVoice(sueMotionPhrases[value]);
      
    } else if (phraseGroup == special) {
      int value = (int) random(1);
      wtv020sd16p.asyncPlayVoice(sueSpecialPhrases[value]);
    }
  } 
  delay(500);
  while(digitalRead(busyPin)) {
        //busy wait
  }
}

void speakDemo() {
  Serial.println("Demo");
  Serial.println(voice);
  
  if(voice == SUE) {
    if(count > 11) {
      count = 0;
    }
    
  } else if (voice == STUART) {
    if (count > 15 || count < 12) {
      count = 12;
    }
  }
  Serial.println(count);
  wtv020sd16p.asyncPlayVoice(count);
    delay(500);
    while(digitalRead(busyPin)) {
      //busy wait
    }
  count++;
  delay(2000);
}

Custom parts and enclosures

axon_20for_20arduino_20enclosure.stl

Sketchfab still processing.

Comments

Similar projects you might like

Simple FM Radio

Project tutorial by Alexander

  • 27,865 views
  • 13 comments
  • 25 respects

ST. VALENTINE’S DAY: HACKED

Project tutorial by Egor Spirin

  • 1,821 views
  • 0 comments
  • 2 respects

Magic Morse on Arduino

Project tutorial by Ray Burnette

  • 24,612 views
  • 8 comments
  • 36 respects

Ultimate Kegerator

Project tutorial by Kevin D Wolf

  • 16,486 views
  • 8 comments
  • 57 respects

Smart Home Mini Arduino - In 30 Minutes - Posting in Ubidots

Project tutorial by Andre Mendes

  • 15,150 views
  • 2 comments
  • 29 respects

Turn your RC Car to Bluetooth RC car

Project tutorial by Prajjwal Nag

  • 11,992 views
  • 1 comment
  • 11 respects
Add projectSign up / Login