49-713 Designing for the Internet of Things
· 26 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Found in Connected Cuisine
The goal of our project was to enhance the social interaction among customers during their time spent in a Chinese brunch with a global context. This was to be achieved by the use of IoT devices enabled by basic inputs and outputs controlled via the internet.
Dim Sum restaurants are a traditional place for Chinese elder people to spend hours hanging out with friends or families and are thus spaces for social interaction. We envision a future in which these restaurants are popular among the younger generation, as well as outside of China.
In this situation, how can we use ambient devices to ensure that the social environment is maintained and is not taken over by people checking their smartphones?
How might we motivate people to stay away from their smart devices and interact more with others? The key to this question is to establish a positive reinforcement, or a reward, for staying away from their smart phone while dining at the table.
We achieved the above by rewarding patrons with a painting inspired by Chinese art. An IoT device senses whether or not each person has placed their phones on the phone tray. If they have, an electronic painter starts creating a painting. The painting will get interrupted if they pick up their phone, but will resume painting if the phone is replaced. This motivates them to stay away from their phones and interact with friends.
1) A peristaltic pump to drop the paint. it is reliable as the pump is exterior and we would get paint to drip slowly enough for our purpose.
2) Motor with belt drive to achieve the linear motion from Left to Right, back and again as a cycle.
3) Switch with extended arm to act as the phone sensor.
4)Potentiometer to denote the time spent at the table which would determine the finishing time of the painting.
INPUT: phone in phone tray (press down switch) and the timer being set (potentiometer)
OUTPUT: Painting (movement of the pump and the motor)
Our challenge was to transform this action to be done electronically. We identified the following actions that need to be done electronically:-
1) A pump to drop the ink over the static paper and an ink container as source.The required codes were plugged in and flashed to check the basic working of the devices which were found to be perfect. The following modifications were to be achieved:-
1)The motor should turn clockwise for X sec and then stay still for Y sec and do the cycle again. The values of X and Y could be changed to ensure that the total time taken was variable
2)The belt drive seemed to slipping a bit. Would need to keep the belt at tension for a perfect drive.
3)The pump outlet needs to be connected to the pressure switch via internet. If the switch is on, pump should be working and otherwise not.
Positioning - Against the initial idea of having a phone stand in the center of table and a canvas holder at the end of table, we decided to use the canvas holder as a representation of Chinese culture and keep the phone rack subtle and below the table. This is due to the fact that the sight of phone itself could be a distraction on the table.
Reward/Censure - We had a few different ideas in mind for the reward mechanism, and tested these out with users. Initially, we wanted to stop the painting completely if any diner lifted their phones. however, this was found to be too harsh and severe of a punishment, and also would have resulted in a very bad experience (say, in case of emergencies which required diners to use their phones).
We settled on pausing the painting if a phone was not in place, but continuing the painting process while all were phones were placed in their holders. This also gave more meaning and relevance to a diner deciding to keep their phone in the holder.
First concern for the architecture was to determine a perfect housing for the motors as they would be under load and need to maintain good tension for a perfect belt drive. Foam Core was used to prototype the idea. For the canvas holder, Chinese architecture was used as an inspiration. This would also give us the flexibility to contain the ink tank within the housing design. The construction was designed into two levels, the top level containing the motors and the belt drive and the bottom level containing the peristaltic pump, tubes and the canvas.
The switch was incorporated within a case meant to house an iphone 5 such that inserting the phone into the case fixed under the table would activate the switch. This was programmed to turn ON the pump via internet.
int buttonPin = D0; //button to start the project
int ledPin = D3; //LED indicating start and end of project
int projectStatus = 0; // 0 = off, 1 = on
int buttonState;
int brushPin1 = D1; //represents brush movement for diner1
int brushPin2 = D5; //represents brush movement for diner2
//int fsrPin = A0; //pressure sensor
//int fsrReading;
//int phoneOn = 3000; //pressure with phone
//int phoneOff = 1500; //pressure without phone
int switchPin1 = D2; //switch as an alternative to pressure sensor for diner1
int switchState1;
int switchPin2 = D4; //switch to show phone down for diner2
int switchState2;
int drip1 = 0; // 0 = no dripping, 1 = dripping
int drip2 = 0;
int potPin = A1; //time input
int potReading = 0;
int duration = 1; // duration in minutes
int starttime,endtime; // start and end time of the project
void setup(){
Serial.begin(9600);
pinMode( buttonPin , INPUT_PULLUP);
//pinMode( fsrPin, INPUT);
pinMode( switchPin1, INPUT_PULLUP);
pinMode( switchPin2, INPUT_PULLUP);
pinMode( brushPin1, OUTPUT );
pinMode( brushPin2, OUTPUT );
pinMode( ledPin, OUTPUT);
//Particle.variable("pressure",&fsrReading,INT);
Particle.variable("pot", &potReading, INT);
}
void loop(){
buttonState = digitalRead( buttonPin );
//fsrReading = analogRead(fsrPin);
switchState1 = digitalRead( switchPin1);
switchState2 = digitalRead( switchPin2);
potReading = analogRead(potPin);
//Serial.println(potReading);
if ( buttonState == LOW && projectStatus == 0){
//project begin
digitalWrite(ledPin, HIGH);
projectStatus = 1;
delay(1000);
//setup starttime and endtime
starttime=millis();
Serial.println(starttime);
if (potReading<=575){
duration = 1;
}else if (potReading>575 && potReading<=1150){
duration = 2;
}else if (potReading>1150 && potReading<=1725){
duration = 3;
}else if (potReading>1725 && potReading<=2300){
duration = 4;
}else if (potReading>2300){
duration = 5;
}
duration = duration * 60000;
endtime = starttime + duration;
}else if ( (buttonState == LOW || endtime == millis() ) && projectStatus == 1 ){ // if button is pressed again or time is up
// project end
digitalWrite( ledPin, LOW);
projectStatus = 0;
delay(1000);
}
if (projectStatus == 1){ // project is on
project(); //run project
}else if(projectStatus == 0){ // project is low
// stop brush or drippter
digitalWrite(brushPin1, LOW);
digitalWrite(brushPin2, LOW);
Particle.publish("diotDimSum1Off");
Particle.publish("diotDimSum2Off");
}
}
void project(){
if (switchState1 == LOW){ // put phone on switch
// move brush or drippter
digitalWrite(brushPin1, HIGH);
if(drip1 == 0) // if it's not dripping now
{
Particle.publish("diotDimSum1On");
drip1=1; // let it drip
}
}else if (switchState1 == HIGH){ // lift up phone from switch
// stop brush or drippter
digitalWrite(brushPin1, LOW);
if(drip1==1) // if it's dripping now
{
Particle.publish("diotDimSum1Off");
drip1 = 0; // stop dripping
}
}
if (switchState2 == LOW){
// move brush or drippter
digitalWrite(brushPin2, HIGH);
if(drip2 == 0)
{
Particle.publish("diotDimSum2On");
drip2 = 1;
}
}else if (switchState2 == HIGH){
// stop brush or drippter
digitalWrite(brushPin2, LOW);
if(drip2 == 1)
{
Particle.publish("diotDimSum2Off");
drip2 = 0;
}
}
}
//Controls for the H bridge
int c1 = D0;
int c2 = D1;
int c3 = D2;
int c4 = D3;
//a speed of 1 indicates that painting should be taking place, and 0 that it should not
int diner1speed = 1;
int diner2speed = 0;
//These variables control the movement of the slider that moves the pipe pf the pump slowly across the painting
int movetime = 100;
int stoptime = 6000;
void setup()
{
pinMode(c1, OUTPUT);
pinMode(c2, OUTPUT);
pinMode(c3, OUTPUT);
pinMode(c4, OUTPUT);
Particle.subscribe("diotDimSum1On", diner1paint);
Particle.subscribe("diotDimSum1Off", diner1stop);
//Uncomment these in order to have the second painting also work
//Particle.subscribe("diotDimSum2On", diner2paint);
//Particle.subscribe("diotDimSum2Off", diner2stop);
Particle.variable("paint", &diner1speed, INT);
}
int diner1paint(const char * event, const char * data)
{
diner1speed = 1;
return 1;
}
int diner1stop(const char * event, const char * data)
{
diner1speed = 0;
return 1;
}
//Uncomment the following two function if there is a second diner
/*int diner2paint(const char * event, const char * data)
{
diner2speed = 1;
return 1;
}
int diner2stop(const char * event, const char * data)
{
diner2speed = 0;
return 1;
}*/
void loop()
{
if(diner1speed==1)
{
if(millis())
//Moves the pump
digitalWrite(c3, LOW);
digitalWrite(c4, HIGH);
//Moves the motor for movetime amount of time
digitalWrite(c1, LOW);
digitalWrite(c2, HIGH);
delay(movetime);
//Makes the motor stay still for stoptime amount of time
digitalWrite(c1, LOW);
digitalWrite(c2, LOW);
delay(stoptime);
}
else if (diner1speed ==0)
{
digitalWrite(c1, LOW);
digitalWrite(c2, LOW);
digitalWrite(c3, LOW);
digitalWrite(c4, LOW);
delay(100);
}
}
The project was a great learning process as we indulged in a scenario completely new to us as a team and our greatest challenge was to achieve ubiquitous computing to the maximum. Though the prototype design had a long way to go to be a good example of ubiquitous computing, we were sure how to make it work better. The current mechanical design was not efficient enough to achieve what we thought of. So as a next step we would be thinking of a downsizing the whole housing and achieve the mechanism with a well thought out construction.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
~
March 6th, 2017