DIY Smart Drink Coaster

Assignment: Sensing PART II: Force Sensitive Resistors and Photocells

Collaborators:

Description

For this assignment, I designed a Smart Drink Coaster that measures how full or empty your glass is and gives a visual feedback of the levels with flashing lights. This DIY Smart Coaster can be used to indicate when you need to get a coffee refill, or signal to a bartender when your drink is dangerously close to empty.

Here, I have integrated both the Processing and the Mechanical parts of the assignment. For the Mechanical component, I extended the FSR circuit that we designed in class and attached it to a coaster. For the visualization, I made Processing receive serial input from the FSR connected to the Arduino. The visualization shows seven images of a bottle with varying levels of liquid in it. Initially, they are all grayed out (Actually, because the program is still running, the first image, which is that of an empty bottle alone is highlighted). When a mug is placed on it, the image corresponding to the liquid level in it lights up, and a flashing red lights points to it.

Components Used

Arduino

Force Sensitive Resistor (FSR)

Resistor

Coaster and a Cardboard support

Drink Mug

Wires

Code

Arduino Code

/*

* Resistive Sensor Input

* Takes the input from a resistive sensor, e.g., FSR or photocell

* Dims the LED accordingly, and sends the value (0-255) to the serial port

*/

int sensorPin = 0;  // select the input pin for the sensor

int ledPin = 11;    // select the output pin for the LED

int val = 0;        // variable to store the value coming from the sensor

void setup() {

Serial.begin(9600);

}

void loop() {

val = analogRead(sensorPin); // read the value from the sensor, 0-1023

analogWrite(ledPin, val/4);  // analogWrite (dimming the LED) can be between 0-255

delay(250);

Serial.println(val/4);       // writing the value to the PC via serial connection

delay(50);                   // rest a little...

}

Processing Code

/*Created by Janani Vasudev

September 27,2009 */

import processing.serial.*;

String portname = "/dev/tty.usbserial-A70061pj";
Serial port;
String buf="";
int cr = 13;  // ASCII return   == 13
int lf = 10;  // ASCII linefeed == 10
int val = 127;
int barWidth =6;

int xVal = 200;
int yVal = 420;
PImage img1;
PImage img2;
PImage img3;
PImage img4;
PImage img5;
PImage img6;
PImage img7;
PImage ball;

int prevFlag = 1;
int prevX = 82;

void setup()
{
//initialize canvas:
size(1245,700);
frameRate(10);
smooth();
background(40,40,40);
noStroke();
port = new Serial(this, portname, 9600);

//initialize the bottle images
img1 = loadImage("img1.gif");
img2 = loadImage("img2.gif");
img3 = loadImage("img3.gif");
img4 = loadImage("img4.gif");
img5 = loadImage("img5.gif");
img6 = loadImage("img6.gif");
img7 = loadImage("img7.gif");
ball = loadImage("ball.gif");
}

void draw()
{

/*image(img2,180,0);

image(img3,360,0);
image(img4,540,0);
image(img5,720,0);
image(img6,900,0);  
image(img7,1080,0); */

}

// called whenever serial data arrives
void serialEvent(Serial p)
{
int c = port.read();
int x = 0;

int flag = 0;
if (c != lf && c != cr)
{
buf += char(c);
}
if (c == lf)
{
int val = int(buf);
println("val="+val);
buf = "";

if(val >= 0 && val< 10)
{
noTint();
image(img1,0,0);

tint(70,50);
image(img2,180,0);
image(img3,360,0);
image(img4,540,0);
image(img5,720,0);
image(img6,900,0);  
image(img7,1080,0);

float m = millis();
fill(m % 180, 0, 0);
//fill(40,40,40);
noStroke();
ellipse(82,400,50,50);
x = 82;
flag = 1;

else if(val >= 10 && val <45)
{
noTint();
image(img2,180,0);

tint(70,50);
image(img1,0,0);
image(img3,360,0);
image(img4,540,0);
image(img5,720,0);
image(img6,900,0);  
image(img7,1080,0);

float m = millis();
fill(m % 180,0,0);
//fill(40,40,40);
noStroke();
ellipse(260,400,50,50);
x = 260; 
flag = 2;

else if(val >=45 && val<80)
{
noTint();
image(img3,360,0);

tint(70,50);
image(img1,0,0);
image(img2,180,0);
image(img4,540,0);
image(img5,720,0);
image(img6,900,0);  
image(img7,1080,0);  

float m = millis();
fill(m % 180,0,0);
//fill(40,40,40);
noStroke();
ellipse(440,400,50,50);
x = 440; 
flag = 3;
}

else if(val >= 80 && val<90)
{
noTint();
image(img4,540,0);

tint(70,50);
image(img1,0,0);
image(img2,180,0);
image(img3,360,0);
image(img5,720,0);
image(img6,900,0);  
image(img7,1080,0);

float m = millis();
fill(m % 180,0,0);
//fill(40,40,40);
ellipse(620,400,50,50);
//tint(255,255);
noStroke();     
x = 620;
flag = 4;

}

else if(val >= 90 && val<110)
{
noTint();
image(img5,720,0);

tint(70,50);
image(img1,0,0);
image(img2,180,0);
image(img3,360,0);
image(img4,540,0);
image(img6,900,0);  
image(img7,1080,0);

float m = millis();
fill(m % 180,0,0);
//fill(40,40,40);
noStroke();
ellipse(800,400,50,50);
x=800;
flag = 5;
}

else if(val >= 110 && val<= 120)
{
noTint();
image(img6,900,0);

tint(70,50);
image(img1,0,0);
image(img2,180,0);
image(img3,360,0);
image(img4,540,0);
image(img5,720,0);
image(img7,1080,0);
delay(1000);     

float m = millis();
fill(m % 180,0,0);
noStroke();
//fill(40,40,40);
ellipse(980,400,50,50);
x=980;
flag = 6;
}

else if(val > 120)
{
noTint();
image(img7,1080,0);

tint(70,50);
image(img1,0,0);
image(img2,180,0);
image(img3,360,0);
image(img4,540,0);
image(img5,720,0);
image(img6,900,0);

float m = millis();
fill(m % 180,0,0);
//fill(40,40,40);
noStroke();
ellipse(1160,400,50,50);
x=1160;
flag = 7;
}

if (flag != prevFlag) {
fill(40, 40, 40);
noStroke();     
ellipse(prevX, 400, 50, 50);
}

prevFlag = flag;
prevX = x;
// prevY = y;

}

}

Images