As computing becomes more ubiquitous in our objects, designers need to be more aware of how to design meaningful interactions into electronically enhanced objects. At the University of Washington, a class of junior Interaction Design majors is exploring this question. These pages chronicle their efforts.

Saturday, December 14, 2019

Smart Bench mock up



In order to figure out how's our smart bench work and how are we going to build it. We first built some mockups. The first picture is a smaller mock up that we built to test out how our bench rotate. Then we take the idea further and built a actual size model to figure out the length and angle of each individual pieces. 

Friday, December 13, 2019

FLO










Ciana Yi Sandra Yao



Video:


https://vimeo.com/379402870




Overview:

FLO is for people who work full time, remotely from home. It is a lamp that lives in one's workspaces and acts as a gentle helper to track how long you are working and tell you when to take break during work sessions. We found that taking adequate breaks is important in a productive work session.

FLO detects the presence of your body and the pressure of your cell phone. When you are ready to start your work session, place your phone on the base of the lamp. This starts two timers tracking duration of time you have been at the desk and how long your phone has been on the plate.
FLO will tell you to take a break every 50 minutes. If your phone has been down on the plate for 80% or more of the time your body has been there, FLO considers you to be productive and will continue breaks in normal intervals.


Components:

Arduino Uno Reconstructed Lamp External speaker with AUX wiring Adafruit Square Force-Sensitive Resistor (FSR) - Interlink Model 406 Adafruit PIR (Passive Infrared) motion sensor YX5300 Serial MP3 Player (Catelex Module)




Input:

PIR sensor detects motion in front of lamp (starts tracking only when a person is there workspace) FSR sensor detects pressure at base of lamp (sense the weight of the phone)


Output:

Speaker outputs mp3 audio message


Reference Links:





Code:

//mp3 define setup code//code rearranged by Javier Muñoz 10/11/2016 ask me at javimusama@hotmail.com
#include <SoftwareSerial.h>


#define ARDUINO_RX 5//should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6//connect to RX of the module
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);//init the serial protocol, tell to myserial wich pins are TX and RX


////////////////////////////////////////////////////////////////////////////////////
//all the commands needed in the datasheet(http://geekmatic.in.ua/pdf/Catalex_MP3_board.pdf)
static int8_t Send_buf[8] = {0} ;//The MP3 player undestands orders in a 8 int string
                                 //0X7E FF 06 command 00 00 00 EF;(if command =01 next song order) 
#define NEXT_SONG 0X01 
#define PREV_SONG 0X02 


#define CMD_PLAY_W_INDEX 0X03 //DATA IS REQUIRED (number of song)


#define VOLUME_UP_ONE 0X04
#define VOLUME_DOWN_ONE 0X05
#define CMD_SET_VOLUME 0X06//DATA IS REQUIRED (number of volume from 0 up to 30(0x1E))
#define SET_DAC 0X17
#define CMD_PLAY_WITHVOLUME 0X22 //data is needed  0x7E 06 22 00 xx yy EF;(xx volume)(yy number of song)


#define CMD_SEL_DEV 0X09 //SELECT STORAGE DEVICE, DATA IS REQUIRED
                #define DEV_TF 0X02 //HELLO,IM THE DATA REQUIRED
                
#define SLEEP_MODE_START 0X0A
#define SLEEP_MODE_WAKEUP 0X0B


#define CMD_RESET 0X0C//CHIP RESET
#define CMD_PLAY 0X0D //RESUME PLAYBACK
#define CMD_PAUSE 0X0E //PLAYBACK IS PAUSED


#define CMD_PLAY_WITHFOLDER 0X0F//DATA IS NEEDED, 0x7E 06 0F 00 01 02 EF;(play the song with the directory \01\002xxxxxx.mp3


#define STOP_PLAY 0X16


#define PLAY_FOLDER 0X17// data is needed 0x7E 06 17 00 01 XX EF;(play the 01 folder)(value xx we dont care)


#define SET_CYCLEPLAY 0X19//data is needed 00 start; 01 close


#define SET_DAC 0X17//data is needed 00 start DAC OUTPUT;01 DAC no output
////////////////////////////////////////////////////////////////////////////////////


int sitDown = 0;                    //set variable for first time sitting down


//timers
#include  <Chrono.h>              //include Chrono stopwatch library
Chrono totalBodyTimer;            //define all our timer variables
Chrono noMotionTimer;     
Chrono totalPhoneTimer;
Chrono currentPhoneTimer;
Chrono breakTimer;


int totalBodyInt = totalBodyTimer.elapsed();


//pir motion              
int inputPinPir = 2;               // choose the input pin (for PIR sensor)
int bodyStatus = LOW;              // we start, assuming no body 
int val = 0;   


//fsr pressure
int fsrAnalogPin = 0;              // FSR is connected to analog 0
int fsrReading;                    // the analog reading from the FSR resistor divider


void setup(void) {


  //pir
  pinMode(inputPinPir, INPUT);         // declare PIR sensor as input
  Serial.begin(9600);


  mySerial.begin(9600);               //Start our Serial coms for THE MP3
  delay(500);                         //Wait chip initialization is complete
  sendCommand(CMD_SEL_DEV, DEV_TF);   //select the TF card  
  delay(200);                         //wait for 200ms
  
}


void loop(void) {


  //FSR
  fsrReading = analogRead(fsrAnalogPin);       // read input value of FSR pin


  if (fsrReading > 30) {                       // read input value of FSR pin
    totalPhoneTimer.restart(); 
    Serial.print(fsrReading);
  }
  
  //PIR
  val = digitalRead(inputPinPir);              // read input value of PIR pin
  
  if (val == HIGH) {                   // means motion detected, input PIR pin is HIGH
    if (bodyStatus == LOW) {           // check if our bodyStatus variable says theres no motion
      bodyStatus = HIGH;               // set our variable to say body is moving
      if (sitDown == 0) {    
        totalBodyTimer.restart();      //person just sat down, timer starts
        Serial.println("work session timer has started!");
        sitDown = 1; 
      }           
      noMotionTimer.restart();         //timer for "no movement" resets, because motion detected
    }
  } else {                             // means motion has stopped, input PIR pin is LOW 
     if (bodyStatus == HIGH) {         // check if our bodyStatus variable still says theres motion
      bodyStatus = LOW;                // set our variable to say body is no motion
      noMotionTimer.restart();         // no motion timer starts 
     } else if (((totalBodyInt%50)==0) && (totalPhoneTimer>(totalBodyInt*0.8)))  { //every 50 minutes, and if your phone has been on the plate for more than 80% of your time at the desk THEN take break
         sendCommand(CMD_PLAY_WITHVOLUME, 0x1E01);            //play the first song with volume 15 class
         delay(1000000);                                      //the program will send the play option each 100 seconds to the catalex chip
         Serial.print("take a break!");
         breakTimer.restart();                                    // break timer starts
     } else if ((totalBodyInt%50==0) && (totalPhoneTimer<(totalBodyTimer*0.8)) {       //if 50 minutes have been reached but they have been using their phone, break is delayed by 10 minutes
         delay(600000);                                      // wait ten minutes
         sendCommand(CMD_PLAY_WITHVOLUME, 0x1E01);            //play the first song with volume 15 class
         delay(1000000);                                      //the program will send the play option each 100 seconds to the catalex chip
         Serial.print("take a break!");
     } else if (noMotionTimer.hasPassed(180000) == true) {       //if they haven't moved in 3 mins and no phone detected, work session is over    
          totalBodyTimer.stop();
     } else if (breakTimer.elapsed() > 10000) {                  // if 10min break is up
          totalBodyTimer.stop();
     } 
  }
}


//send command method for mp3
void sendCommand(int8_t command, int16_t dat)
{
 delay(20);
 Send_buf[0] = 0x7e; //starting byte
 Send_buf[1] = 0xff; //version
 Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
 Send_buf[3] = command; //
 Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
 Send_buf[5] = (int8_t)(dat >> 8);//datah
 Send_buf[6] = (int8_t)(dat); //datal
 Send_buf[7] = 0xef; //ending byte
 for(uint8_t i=0; i<8; i++)//
 {
   mySerial.write(Send_buf[i]) ;//send bit to serial mp3
   Serial.print(Send_buf[i],HEX);//send bit to serial monitor in pc
 }
 Serial.println();
}


Photos:








detail: curved wood lid to allow FSR to sense pressure

detail: PIR sensor exposed to detect motion










Thank you for reading!










































LED Concert Jacket - Alvin Tran, Annie Xu, and Devansh Gandhi

LED Concert Jacket by Annie Xu, Alvin Tran, and Devansh Gandhi 


Our project is a light jacket that visualizes how excited and engaged you are at a concert. We wanted the jacket to reflect the movement and energy of the wearer, which could signal to the artist or the people around exactly how involved they were during the concert. We hoped the jacket could create competition between friends, immerse experiences for concert goers, and create unspoken relationships between artists and their fans. 


The jacket has 3 tiers each with its own set color. In the beginning, you start on a silvery pink color. For every jump you make, the jacket will turn to that specific color. If you do not move, then the jacket will not light up. In order to reach the next their which blinks yellow, you need to surpass a threshold. If you jump more than a designated amount of time, your jacket will turn yellow every time you jump. In addition, if you scream or make noise, the microphone will pick that up and override the jacket with red lights. The people around you can visually see that you are yelling. When and if you pass the 2nd threshold, your jacket will blink rainbow lights, indicating that you have reached the last tier. At this point, you and the people around you will be able to see your overall activity and engagement during the concert. If one reaches rainbow, that means they were extremely engaged and had many jumps and screams throughout the concert. 

The jacket has an accelerometer that measures acceleration of movement. Therefore, not only does the wearer have to jump, they have to jump fast.  For our project, we set the code so that it only detects movement in the Z direction. The jacket will only respond to jumps or movements up and down. The jacket is programmed so that after a specific number of jumps, the LED will change colors. As for the sound, there is a sound detector that signals the LED to turn red when a certain threshold is reached.

Components
Arduino uno
Rain jacket 
Led strip 
Sound detector LM 393
ADXL335 3-Axis accelerometer 
330 ohm resistor
Electrical tape 
Portable battery 


Libraries:
Fast LED library link: http://fastled.io


 Photos:







CODE:
#include <FastLED.h>
#define LED_PIN     8
#define NUM_LEDS    60


const int xpin = A0; // x-axis of the accelerometer
const int ypin = A1; // y-axis
const int zpin = A2; // z-axis


CRGB leds[NUM_LEDS];


int zTimes = 0;


int soundDetectedPin = 10; // Use Pin 10 as our Input
boolean bAlarm = false;
int soundDetectedVal = HIGH; // This is where we record our Sound Measurement
unsigned long lastSoundDetectTime; // Record the time that we measured a sound
int soundAlarmTime = 100; // Number of milli seconds to keep the sound alarm high


void setup()
{
  Serial.begin(9600);  
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  pinMode(soundDetectedPin, INPUT); // input from the Sound Detection Module
}


void loop() {
  int x = analogRead(xpin); //read from xpin
  Serial.print(x);
  Serial.print("\t");


  
  checkX(x);
  Serial.println(soundDetectedVal);


  soundDetectedVal = digitalRead (soundDetectedPin) ; // read the sound alarm time
  Serial.println(soundDetectedVal);
  Serial.println("checking...");
  if (soundDetectedVal == LOW) // If we hear a sound
  {
    Serial.println("LOW...");
    lastSoundDetectTime = millis(); // record the time of the sound alarm
    // The following is so you don't scroll on the output screen
    if (!bAlarm){
      Serial.println("LOUD, LOUD");
      bAlarm = true;
      for (int i = 0; i <= NUM_LEDS; i++) {
        leds[i] = CRGB::Red;
        FastLED.show();
        delay(10);
      }
    }
  }
  else
  {
    Serial.println("ELSE...");
    if((millis()-lastSoundDetectTime) > soundAlarmTime  && bAlarm){
      Serial.println("quiet");
      bAlarm = false;
      for (int i = 0; i <= NUM_LEDS; i++) {
        leds[i] = CRGB::Black;
        FastLED.show();
        delay(1);
      }
    }
    bAlarm = false;
  }
  
}

void checkX(int x) 
{
if ((x > 300 && x < 400)) {
    for (int i = 0; i <= NUM_LEDS; i++) {
    leds[i] = CRGB::Black;
    FastLED.show();
    delay(1);
    }
    delay(100);
  } else {
    Serial.print("X moving");
    zTimes++;
    Serial.print(zTimes);
    Serial.print("times");
    if(zTimes <= 20){
      for (int i = 0; i <= NUM_LEDS/2; i++) {
        leds[i] = CRGB::Silver;
        leds[NUM_LEDS - i] = CRGB::Silver;
        FastLED.show();
        delay(10);
      }
    } else if (zTimes <= 40) {
      for (int i = 0; i <= NUM_LEDS; i++) {
      leds[i] = CRGB::Yellow;
      FastLED.show();
      delay(10);
      }
    } else {
      for (int i = 0; i <= NUM_LEDS; i++) {
      leds[i] = CRGB(random(0, 255), random(0, 255), random(0, 255));
      FastLED.show();
      delay(10);
      }
    }
    
  }
}