loading
In this Instructables we will walk through how we connected an Intel Perceptual Computing Camera, an Arduino Uno, and a submersible water pump so that the water pump transfers water from one vessel to another when nobody is sitting in front of the camera.

We created this project as an example of Critical Making: making activities that invoke reflection in their observers. It is a design that is intended to highlight and encourage debate surrounding the experiences of blame, shame, guilt, and anxiety that can accompany the use of personal data tracking devices. By building these ideas into a design, we hope to aid people in recognizing and expressing their feelings about these ideas.

Here's how it works: This project takes note of when a computer user walks away from her computer and assumes that the time she is away from the computer is spent using the restroom. If she is gone for too long, it publicly shames her by announcing on Twitter how long she has been away from her computer. At the same time, it records how long she has been gone by pumping water into a small receptacle on her desk, as if the computer itself is urinating. When she returns to her desk, she must dump that water back into the originating receptacle, or risk an overflow that could ruin her desk and the things on it.

The quantified self movement (www.quantifiedself.com) focuses on people collecting, managing, and analyzing data that they collect through technology. When doing this, it is important to keep in mind the side effects of these devices that are not being recorded, but still have an impact on one's physical, emotional, and psychological wellbeing. For example: when tracking hours or minutes of work through a time-tracking application, it can become easier to experience guilt while not working. This may seem like a good thing, because one should be working, and tracking work can benefit efficiency. However, this can have detrimental side effects such as anxiety or feelings of guilt. With the project we describe here, we aim to illuminate those side effects as a means of starting conversations about these complex issues.

One potential source of unnecessary guilt can come from taking necessary breaks, such as using the restroom. Should you track the time you are peeing as work time or break time? Should it only be limited to a standard minimum to maximize efficiency? On the one hand you are not working, but on the other you are completing a task that is necessary for work to continue. This concept is intentionally hyperbolic, with the hope that anyone actually using it will eventually realize "No, this is ridiculous, I should be allowed to pee without feeling bad about it" and then extend that idea to other areas of their lives. Such as "I should be allowed to take time off from work to spend time with my children without feeling guilty," "I should be allowed to read a trashy novel during my break without feeling like I should be working," and, eventually, "I should not feel guilty for making reasonable decisions." By playing with the ideas of work and the quantified self in a playful way we hope to open up a conversation about the nature of work, breaks, and the quantified self.

The rest of this document will be about the process involved in connecting the various technologies we used for this concept. The basic components of which include:
  • Twitter integration with Processing
  • Connecting a Processing application to an Arduino through a serial connection
  • Connecting an Arduino to a water pump through a PowerSwitch Tail

Step 1: Materials and Tools

The materials we used for this project are:

Step 2: Programming

In this step we will cover the programming aspects required for this project. The program is split into two parts:
  • Processing
    • The processing side of the program runs in the 32 bit Processing environment for Windows.
    • It connects to the Intel Perceptual Computing Camera and tracks when the user is sitting in front of the laptop or when the user has left through the face detection built into the camera.
    • It communicates these changes to the Arduino through a serial connection.
    • It also posts "randomized" messages to Twitter, using the Twitter API. These randomized messages are pulled from collections of messages that target specific situations or events, triggered throughout the code. In our particular project, we're using the example of a program that tracks how many times a user gets up to use the restroom, and then chastises the user if they are gone too long.
      • To work through connecting Processing to Twitter, we used this guide: http://blog.blprnt.com/blog/blprnt/updated-quick-t...
      • You will likely find it useful, as it walks you through the process of setting up the application on Twitter, generating authentication keys, etc.
  • Arduino
    • The Arduino side of the program takes the information of when the user leaves and returns to their laptop, and uses it to decide when to turn on the water pump.
    • It also manages the water pump: the particular pump we have actually pumps water too quickly for what we want it to do, so the Arduino program strategically turns the water pump on and off so that we can more easily control the flow of the water without needing to worry about modifying the submersible pump itself.
      • Since we have the water pump plugged into the PowerSwitch Tail, we turn the water pump on and off by turning the PowerSwitch Tail on and off.

The code for both of these applications is provided below. I have included comments throughout the code to help you figure out what is happening for each section, and where you will need to make your own changes. In my opinion, the code is quite difficult to read in the Instructables format, especially since it likes to remove the tabs. If you copy and paste it to Processing or Arduino, it will automatically color-code where appropriate, and make it easier to navigate.

Processing
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
/**
// PeeTracker32
// Developed by Austin Toombs (email: altoombs indiana edu)
// Concept by Austin Toombs and Shad Gross
// January 2014
**/

/** import libraries etc **/
import intel.pcsdk.*;
import processing.serial.*;

/** Initialize variables **/
/** Intel Perceptual Computing Variables **/
PXCUPipeline session;
PImage rgbTex;

int[] faceLabels = {PXCMFaceAnalysis.Landmark.LABEL_LEFT_EYE_OUTER_CORNER,
PXCMFaceAnalysis.Landmark.LABEL_LEFT_EYE_INNER_CORNER,
PXCMFaceAnalysis.Landmark.LABEL_RIGHT_EYE_OUTER_CORNER,
PXCMFaceAnalysis.Landmark.LABEL_RIGHT_EYE_INNER_CORNER,
PXCMFaceAnalysis.Landmark.LABEL_MOUTH_LEFT_CORNER,
PXCMFaceAnalysis.Landmark.LABEL_MOUTH_RIGHT_CORNER};

ArrayList facePts = new ArrayList();
ArrayList faceBoxes = new ArrayList();

/** Collections of potential tweets for verious situations
// If you create your own collections of Strings to pull from, this is where you can initialize them
**/
ArrayList returnTweets = new ArrayList();
ArrayList firstThresholdTweets = new ArrayList();
ArrayList secondThresholdTweets = new ArrayList();
ArrayList thirdThresholdTweets = new ArrayList();

/** booleans for state logic within the program **/
boolean faceState = false; //whether or not a face is seen
boolean prevFaceState = false; //whether or not a face was seen in the previous

/** variables for integrating with Twitter **/
Twitter twitter;

/** variables for monitoring how long the user has been gone
// we set up various "milestones" for while the user s gone. We have 3 here, but you can
// changes these easily by adding more here and throughout the code where these milestones
// are referenced
**/
long savedTime;
int minimumTime = 6000; //minimum time limit before sending a message
int firstMilestone = 30000; //first milestone for sending shameing messages
boolean firstMilestoneMessageSent = false; //keeping track of if we sent the first milestone message
int secondMilestone = 60000; //second milestone for sending shameing messages
boolean secondMilestoneMessageSent = false; //keeping track of if we sent the second milestone message
int thirdMilestone = 90000; //third milestone for sending shaming messages
boolean thirdMilestoneMessageSent = false; //keeping track of if we sent the third milestone message

/** variables for serial connection **/
Serial myPort; //the Serial port object


void setup()
{
//set the size of the canvas
size(640,480);

//create image from camera information (not necessary)
rgbTex = createImage(640,480,RGB);

//the session information for the Intel Perceptual Computing Camera
session = new PXCUPipeline(this);
session.Init(PXCUPipeline.COLOR_VGA|PXCUPipeline.FACE_LOCATION|PXCUPipeline.FACE_LANDMARK);

//initializing the connection to Twitter *complete with authentication!
// You will need to generate your own Twitter application keys and include them here
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXX");
cb.setOAuthConsumerSecret("YYYYYYYYYYYYYYYYYYYYYY");
cb.setOAuthAccessToken("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
cb.setOAuthAccessTokenSecret("XYZYXYZXYZYXYZXZXYZYXYZYXYZYXYZ");

//initialize twitter object
twitter = new TwitterFactory(cb.build()).getInstance();

//this doesn't have to be called at all, but is fun to see
//commented out for now: getPreviousTweets();

//initialize serial port and set baud rate to 9600
myPort = new Serial(this, Serial.list()[0], 9600);

//initialize the collections of tweets
initializeTweets();
}

//default draw function in every processing program
void draw()
{
/////// Getting data from the camera and drawing to the canvas ////////
// before playing with perceptual computing camera, we have to make sure that
// it can actually see things. Everything in this if statement should
// remain as-is for now. We use it to determine if a face is even within
// view. There is likely an easier way to do this, but we like to see the face
// boxes so we can tell what it sees as a face and what it does not
if(session.AcquireFrame(false))
{
session.QueryRGB(rgbTex);
facePts.clear();
faceBoxes.clear();

for(int i=0;;++i)
{
long[] ft = new long[2];
if(!session.QueryFaceID(i,ft))
break;

PXCMFaceAnalysis.Detection.Data fdata = new PXCMFaceAnalysis.Detection.Data();
if(session.QueryFaceLocationData((int)ft[0], fdata))
{
faceBoxes.add(fdata.rectangle);

PXCMFaceAnalysis.Landmark.LandmarkData lmark = new PXCMFaceAnalysis.Landmark.LandmarkData();
for(int f=0;f {
if(session.QueryFaceLandmarkData((int)ft[0],faceLabels[f], 0, lmark))
{
facePts.add(lmark.position);
}
}
}
}
session.ReleaseFrame();
} //end of face detection if statement

//displays what the camera sees on the canvas
image(rgbTex,0,0);
pushStyle();
stroke(255);
noFill();

//draws the face boxes on the screen
for(int f=0;f {
PXCMRectU32 faceLoc = (PXCMRectU32)faceBoxes.get(f);
rect(faceLoc.x,faceLoc.y,faceLoc.w,faceLoc.h);
}
fill(0,255,0);
for(int g=0;g {
PXCMPoint3DF32 facePt = (PXCMPoint3DF32)facePts.get(g);
ellipse(facePt.x,facePt.y,5,5);
}
popStyle();

////// That's the end of the drawing stuff ////////

//save the previous face state (for tracking purposes)
prevFaceState = faceState;

//if we can't even see a face at all
if(faceBoxes.size()==0){
faceState = false; //we can't see the face, so the user isn't there

//if they were there a moment ago, and they just now left
if(prevFaceState == true){
//output that camera no longer sees a face
System.out.println("Can't see a face, starting timer");

//start tracking time. millis() measure the time in milliseconds
// since the start of the program
savedTime = millis();

//send signal to serial that we cannot see a face
myPort.write('2');
}

//the time the user has been gone is the current time in milliseconds
// since the start of the program minus the time in milliseconds since
// the start of the program when the user left.
long timeAway = millis() - savedTime;

//use the timeAway information to determine when to send message
processAwayAlerts(timeAway);
}
else {
//if we see faces, we aren't timing them
faceState = true;

//if we see a face where we previously didn't, then we know
// they just got back
if(prevFaceState == false){
//calculate how long the user has been gone total
long timeAway = millis() - savedTime;

processJustReturnedAlerts(timeAway);


resetMessageBooleans();
}
}
//////// end of the draw method /////////
}

//set up each of the collections of tweets that can be used for
// specific situations
void initializeTweets(){
returnTweets.add("@altoombs was away from his desk for XXX seconds");
returnTweets.add("@altoombs peed for XXX seconds");
returnTweets.add("@altoombs was unproductive for XXX seconds");
returnTweets.add("@altoombs managed to procrastinate for XXX seconds");
returnTweets.add("@altoombs slacked off for XXX seconds");
returnTweets.add("@altoombs was completely useless for XXX seconds");

firstThresholdTweets.add("@altoombs is probably peeing right now, so if you need something check back soon");
firstThresholdTweets.add("@altoombs has been away from his desk for some time now. Don’t make a habit of this");
firstThresholdTweets.add("@altoombs will be back soon. Or he better be.");
firstThresholdTweets.add("@altoombs can’t come to the phone right now. Unless he has it with him. In the bathroom.");

secondThresholdTweets.add("@altoombs … where are you? Why have you been away for so long?");
secondThresholdTweets.add("@altoombs whatever you’re doing right now better be freaking important.");
secondThresholdTweets.add("@altoombs if you aren’t going to work today you might as well just go home");
secondThresholdTweets.add("@altoombs might have a medical problem. It should not take this long to pee.");

thirdThresholdTweets.add("@altoombs takes forever to pee. He better finish up quick or risk wasting his life away");
thirdThresholdTweets.add("@altoombs is wasting his time. Everyone should pressure him to get back to his desk");
thirdThresholdTweets.add("@altoombs we’re sending out the search party. You have been gone too long.");
thirdThresholdTweets.add("@altoombs is not a model for how you should behave at work.");
}

//determine which messages to send and when while the user is gone
// based on the time they have been away
void processAwayAlerts(long timeAway){
//if the time they have been gone is longer than the minimum
// time we are concerned about, then turn on the LED
if(timeAway > minimumTime){
myPort.write('1');
}

//if the time they have been gone is longer than the first
// milestone time, then take appropriate measures
if(timeAway > firstMilestone && !firstMilestoneMessageSent){
//send the message (either over twitter or to console)
sendMessage(randomTweet(firstThresholdTweets));

//mark that the first milestone message has been sent
firstMilestoneMessageSent = true;
}

//if the time they have been gone is longer than the second
// milestone time, then take appropriate measures
if(timeAway > secondMilestone && !secondMilestoneMessageSent){
//send the message (either over twitter or to console)
sendMessage(randomTweet(secondThresholdTweets));

//mark that the second milestone message has been sent
secondMilestoneMessageSent = true;
}

//if the time they have been gone is longer than the third
// milestone time, then take appropriate measures
if(timeAway > thirdMilestone && !thirdMilestoneMessageSent){
//send the message (either over twitter or to console)
sendMessage(randomTweet(thirdThresholdTweets));

//mark that the second milestone message has been sent
thirdMilestoneMessageSent = true;
}
}

//determine what to do when the user returns
void processJustReturnedAlerts(long timeAway){
//only display message if they were gone the minimum amount of
// time. Otherwise they were probably just looking away or scratching
// their face or fixing their hair or... you get it
if(timeAway > minimumTime){
//report to console how long the user was gone
System.out.println("User just returned after: " + timeAway + " miliseconds.");

//send message either over twitter or over console
sendMessage(randomTweet(returnTweets).replace("XXX", ""+timeAway/1000));
}

//send a signal over serial to tell the Arduino that the user
// is in front of the computer
myPort.write('0');
}

//choose a random tweet from the given tweet collection and
// return that message as a String
String randomTweet(ArrayList tweetList){
//choose a random number based on the length of the collection
int tweetIndex = (int) random(tweetList.size());

//return the String at that location
return tweetList.get(tweetIndex);
}

//send a message either over twitter or to console
void sendMessage(String message){
//send the message over twitter (comment out while testing)
/**try{
twitter.updateStatus(message);
}
catch (TwitterException te) {
println("Couldn't connect: " + te);
};**/

//send the message to console
System.out.println(message);
}

//reset the message booleans. Otherwise the threshold messages could only
// be sent once during each run of the program
void resetMessageBooleans() {
firstMilestoneMessageSent = false;
secondMilestoneMessageSent = false;
thirdMilestoneMessageSent = false;
}

/**
* This method just finds the previous tweets made by this device and
* prints them out to the console. It can be removed and simply not
* called and won't change any other functionality of this program
**/
void getPreviousTweets() {
Query query = new Query("#peeTimer");
//query.setRpp(100); //doesn't work w/most recent Twitter4j

//Try making the query request.
try {
//the following line updates the twitter status
QueryResult result = twitter.search(query);
ArrayList tweets = (ArrayList) result.getTweets();

for (int i = 0; i < tweets.size(); i++) {
Status t = (Status) tweets.get(i);
User u = (User) t.getUser();
String user = u.getName();
String msg = t.getText();
println("Tweet by " + user + ": " + msg);
};
}
catch (TwitterException te) {
println("Couldn't connect: " + te);
};
}
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------


Arduino
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
/**
// peetimerArduinoSketch
// Developed by Austin Toombs (email: altoombs indiana edu)
// Concept by Austin Toombs and Shad Gross
// January 2014
**/

//variables for reading to and from serial
char val; // Data received from the serial port

//pin assignments
int ledPin = 13; // Set the pin to digital I/O 13
int waterPumpPin = 10; // This pin actually controls the PowerSwitch Tail, turning it on and off

//time tracking for water pump
long previousMillis = 0;
long offInterval = 4000; //how long we need it off per interval
long onInterval = 2000; //how long we need it on per interval
boolean timeStarted = false;

//tracking the state of the water pump
int waterPumpState = LOW;

void setup()
{
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
pinMode(waterPumpPin, OUTPUT); // set pin as OUTPUT
//initialize serial communications at a 9600 baud rate
Serial.begin(9600);
}

void loop() {
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if (val == '1')
{ // If 1 was received
digitalWrite(ledPin, HIGH); // turn the LED on

// if the timer has not started yet, start it
if(!timeStarted) { timeStarted = true; }

// decide what to do with the water pump, based on time
manageWaterPump();
} else { // if anything other than a 1 is received
digitalWrite(ledPin, LOW); // turn off the LED
digitalWrite(waterPumpPin, LOW); //turn off the water pump
timeStarted = false; // turn off the timer
}
delay(10); // Wait 10 milliseconds for next reading
}

//decide how to manage the water pump
void manageWaterPump(){
//the current amount of time that has passed since we received the 1 in serial
unsigned long currentMillis = millis();

//if the water pump is already off
if(waterPumpState == LOW){
//and it has been off long enough, then turn it on
if(currentMillis - previousMillis > offInterval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
waterPumpState = HIGH;

// set the LED with the ledState of the variable:
digitalWrite(waterPumpPin, waterPumpState);
}
}
else { //if the water pump is already on
// and it has been on long enough, then turn it off
if(currentMillis - previousMillis > onInterval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
waterPumpState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(waterPumpPin, waterPumpState);
}
}
}
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------

Step 3: Setup and Testing

Intel Perceptual Computing Camera
Setting up the Intel Perceptual Computing Camera (or the Intel Real Sense 3D Camera) is fairly straightforward and the process is described pretty well here: http://software.intel.com/en-us/vcsource/tools/per...

When you download the SDK, it comes with a lot of great examples that you can pull from to help you get started. Our program uses some simple face detection, which we stripped from the face tracking example "FaceTracking.pde"

PowerSwitch Tail II
The PowerSwitch tail takes a signal from the Arduino when it needs to be switched on and off. So we have to connect it to the Arduino. For our project we did this by first opening the ports for "in +" and "in -" with a 3.0 mm flat head screwdriver. (Do NOT use the "ground" port.) Then we stuck a jumper wire into each port and tightened them to hold the end of the jumper wire in place. These jumper wires then need to be plugged into the Arduino. According to the Arduino code, we use pin 10 to control the PowerSwitch Tail II, so the wire plugged into the "in +" port of the PowerSwitch Tail II needs to plug into pin 10, and the wire from the "in -" port should connect to one of the Arduino's ground pins.

Water Pump
We are controlling the water pump through the PowerSwitch Tail II by giving and taking away power when the Arduino signals it, so setting up the water pump is remarkably easy. First, set the water pump to the lowest setting if you are using the same pump as we did, otherwise it pumps water too quickly. Then, plug it into the PowerSwitch Tail II and attach the plastic tube, making sure the tube can reach the receiving receptacle. Finally, place the water pump into the holding receptacle with the water.

Arduino
Connecting the Arduino to Windows through Parallels on a Mac can be a little bit tricky, but is mostly very similar to connecting it to a PC. If you are also using Windows on a Mac through Parallels, make sure that you connect the Arduino AFTER you start up Parallels and Windows, so that you can choose to connect it to the Windows virtual machine, allowing it to communicate with it so that Processing can see it as a potential serial communication partner.

Step 4: Finished!

After all of the code is uploaded to the Arduino, all you have to do is run the Processing sketch and watch as the Intel Perceptual Computing Camera tracks your face and determines when you get up from your computer. After being away from the computer for around 6 seconds (a buffer we built into the program so that it wouldn't activate every time you scratched your forehead), the water pump will kick on. The current program is set so that the water pump runs for 2 seconds and pauses for 4 seconds. This is to keep the pump from pumping too quickly, but these variables can be changed around in the Arduino code.

We would like to acknowledge the following people for their funding, support, help or inspiration for this project: Intel ISCT Social Computing, NSF Creative IT grant, Shaowen Bardzell, Jeffrey Bardzell, Indiana University School of Informatics and Computing, Critical Making Hackathon: Situated Hacking, Surveillance and Big Data workshop organizers (Karen Tanenbaum, Josh Tanenbaum, Amanda Williams, Matt Ratto, Gabriel Resch, and Antonio Gamba Bar), The Intel Perceptual Computing Group, Derek Whitley, and Bloominglabs.

We hope you found this useful! Thanks for reading along.

Austin Toombs and Shad Gross
<p>Some companies already use computer monitoring of EVERYTHING you do all day long. I worked at a company that rhymes with A.T&amp;Pee, and they use a system called six sigma. You would be horrified if you watched some of the examples on youtube about this subject. More and more companies are doing this type of thing and it is a sort of degrading, slavish, inhuman way to be treated. They microscope, and needle-pick, and scrutinize down to the n-th degree! Then theyt compare YOUR numbers to other employees... compare you to your numbers last month... and they scrutinize about 30 different paramaters of your performance. That's why I quit there several years ago. I don't want to be treated like a number... robot... or slave. Thank you for this instructable.</p>
<p>Sounds Horrifying. Sure makes me glad I quit working For Hate Tea and Tree long ago myself.</p>
<p>I too worked for this contractor as technical support only because I was desperate for a job. Things happened in my life and I had to leave the position. I noted, while working there that the employee turnover rate was approaching astronomical figures. Two things became immediately obvious. 1. That treating people the way framistan describes is not the way to keep good workers, and 2. the only people they could get to work for them, for the most part, were on the lower end of the scale for intellectual, social, and skill abilities. There were some there, their personal situations unkown to me, who were well above average in any measure. Why the continued to work there was beyond my comprehension.</p><p>Nevertheless, I do appreciate altoombs bringing this to our attention. It is paramount that all of us humans remain aware of the stress and humiliation that corporations are willing to impose upon their workers all in the name of greed. Where or not this type of tech should be used at all is, indeed, the question. Just because we can does not mean we should.</p>
<p>I have to agree with you. It is paramount that companies realise what a negative impact this course of action has on employees. I was initially horrified when I was reading it, then realised the final case arguments.<br><br>I hope that some good comes from this study.</p>
<p>While I am a HUGE nerd and lover of all things tech, the potential for governmant and employers to &quot;watch&quot; their employees is frightening. Public shame of a human spawned by a machine is a harbinger of much, much, more sinister uses of the technology we love. </p><p>I do not wish to make light of the efforts put into this project and the congratulate you on accomplishing your goal, however I would ask that you use your powers for &quot;good&quot; and not evil. Einstein never imagined that his theories and work would one day be used to kill people. Imagine how great you might feel when some dictator executes a person for staying too long in the the bathroom</p>
<p>Ideas that exist... </p><p>Those ideas will take the form of whatever vessel that contains it...Like water. </p><p>You can't stop that idea from existing except through madly destructive means. </p><p>(war, murder, massive brainwashing, mass suicide, genocide, union busting)</p><p>So... your choices are:</p><p>1. keep it quiet so that you can hope that it's not abused by the abusive.</p><p>2. Tell everyone, so that the public discussion will create a democratic decision.</p><p>It's not the idea that propagates an outcome, it's who can conceive and implement it.</p><p>This is not a universal &quot;rule&quot;. There are situations where a person can become influenced by the environment that they exist within because they need to survive there. This is an example of a person being saturated by an idea that they exist within. And environments ... being invisible ... can cause a non-perceptible change to people who are not sensitive to those environmental situations. </p><p>&quot;The flesh that forms the world that forms the flesh&quot;</p><p>It's not just one or the other....</p>
Getting people to think about that potential direction of technology is one of the reasons we created this project. It is certainly not a project we think anyone should actually use, but one that we hope starts discussions about exactly the kinds of privacy concerns you have raised. We also think that the potential for the government and employers to watch their employees is frightening. <br><br>I understand and appreciate your concern that we might be introducing new ways for people to be spied on, but that's not really the case here. All of the technology and capabilities presented in this project have been available to the government and to everyday people for years. We simply packaged it up in an intentionally exaggerated way to create a conversation.
<p>I'm fairly sure there is a problem with the links in this page. Though the links seem to be pointing to the right place when clicked, they all show &quot;<a href="http://software.intel.com/en-us/vcsource/tools/perceptual-computing-sdk" rel="nofollow">http://software.intel.com/en-us/vcsource/tools/pe..</a>.&quot; </p><p>And that, in all but the first, has nothing to do with the actual link.</p>
<p>Thanks for pointing that out! That is really strange that they look like that. I will look into them. I'm glad they all point to the right places though.</p>
<p>Want to see what happens with an excess of surveillance? watch the great documentary &quot;We live in public&quot;... </p>
<p>Great Instructable! My only suggestion: A bit of yellow food coloring in the water. Adds to the shame responce by a factor of ~3</p>
<p>3.14 actually!</p>
<p>One caveat... *Never substitute Pi for Pee. (or pee for pie, it tastes disgusting)</p>
<p>This is highly valuable research. It worked in a call-center where such strict monitoring of employees was illegally used. Records were kept of how long we were glued to phone. The routing of phone calls was ludicrous. On a reasonably quiet day when most of us could stand around so that we could ask our &quot;Team Leader&quot; more detailed information regarding the crappo product we were supporting, we were consistently interrupted by those few calls being directed to said Team Leader. After this frustrating episode I actually asked management could they arrange the phone queue such that instead of having one's phone suddenly start ringing while finishing notes from the previous call or rebuilding and re-installing one's own computer (frequently), why not allow people to &quot;bid&quot; from their phone to take the next call when each was ready to take the call. Such heresy saw me dismissed.</p><p>Toilet breaks were almost forbidden and a cartoon quickly appeared in the office where chairs had been replaced with toilet bowls so that one could stay on the phone while doing a &quot;big job&quot;.</p>
<p>*I worked in a call-center&quot;, not &quot;It worked in a call-center&quot;.</p>
<p>Long ago in the early days of industry. The workers were on a large open floor and the foreman was on a raised platform. What passed as a bathroom was also on the floor in the open. There was no need for high tech or computers for the foreman to see who was P'ng excessively and not working:)</p>
<p>I don't feel guilty when I'm in a public bathroom that has automatic flushers and I lean to one side while peeing (without missing) and cause the toilet to flush while I'm still using it... Can your machine fix my malady?</p>
<p>Interessting setup. Have we beaten cancer already?</p>
I had tears in my eyes while reading the intro. This is brilliant and hilarious. FOR SHAME!
<p>I was relieved to see your half paragraph that starts with &quot;This concept is intentionally hyperbolic....&quot; I tend to run a bit literal, so by the time I got to that section, I was getting a little hot under the collar at the implied message that someone should have to feel guilty about taking a break to pee! Really interesting instructable; the hookup of these elements is something I'd like to try for some other purpose, say squirting my cat if she jumps up on the kitchen counter.</p>
I'm glad we were able to clear it up for you! I think a lot of people really do think we are presenting this as a legitimate product idea, but I really don't mind because it's creating some interesting conversations.<br><br>And squirting your cat when she's on the counter sounds like a fantastic, actually useful use for something like this! As long as you don't accidentally end up squirting yourself every time you try to chop vegetables :)
<p>LOL.</p><p>&quot;important safety tip, thanks Egon&quot;</p>
<p>I initially thought if there were two canisters of liquid, and if you sat down to use the computer and the liquid was in the wrong container, then you would realize that the webcam had seen activity too recently, and you feel shame and regret for being at your computer.</p><p>Then you would go play PS4 in the living room.</p>
Your machine does a wee when procrastination is detected? You should see what my machine does when it detects irony!
This is really interesting, especially since I'm a huge procrastinator. It's interesting to think about, just the whole guilt thing and the possible &quot;punishment&quot; that may come from procrastinating.
<p>I see a legit use for this, install this in a truck stop urinal, that way the toilet will get flushed when someone is done urinating. </p>
<p>&quot;I approve.&quot; <em> Howard Hughes</em></p><p>Is this for art or a master's thesis?</p><p><em><br></em></p>
<p>This is a project concept for a workshop on critical making. http://criticalmaking.com/chi-workshop/</p>

About This Instructable

39,580views

121favorites

More by altoombs:Repair a capacitive touch screen stylus with conductive thread The Pee Timer: Connecting the Arduino, the Intel Perceptual Computing Camera, and a Submersible Water Pump 
Add instructable to: