HOW

Do Couples Exchange Feelings?

Human beings rely on the five senses to communicate emotions

SIGHT | HEARING | TOUCH | SMELL | TASTE

What's in your vision provides context, while hearing acquires exact information when people chat.
Touch, smell or even taste render chemical reactions, which is the so called atmosphere.

WHAT IF

They Are in Long Distance?

SIGHT | HEARING | TOUCH | SMELL | TASTE

Limited sight makes tiny body languages invisible;
The absence of touch, smell and taste disables the perception of atmosphere;
Interactions without physical contact can hardly establish intimacy.

WHEN WE EXCHANGE OUR FEELINGS,
IT IS NOT THE CONTENT THAT MATTERS,
IT IS THE WAY WE DELIVER IT.

DESIGN CONCEPT

Wearable Device with Tactile Interactions

/POKEMO is a tactile interactive communication device designed for long distance couples. It not only senses your mood with embedded sensors, but gets to know you and your emotion over time as well, which makes it much easier to share your emotion with your partner. Wearable and convenient, it provides better interaction experience and could strengthen emotion bond between long ditance couples.

INTERACTION SYSTEM: PROACTIVE + REACTIVE INTERACTIONS

The two rings communicate with each other through talking to the owner’s smart phone using BLE. The smartphone, which is connected to the Internet, will sync data to the cloud service. Complicated calculations are processed on the smartphone instead of the /POKEMO ring in order to save battery. 

      Message Coder

        Physically interact with your partner with unique tactile message by poking and twisting the /POKEMO ring; a customizable message coding menu is provided in the App, which is synced by both parties’ smartphones.

      Bad Mood Alert

        /POKEMO’s inner layer tights up to alert you on your partner’s bad mood; this function is achieved based on analysis of GSR readings and other body characteristics.

      Health Indicator

        The opacity of upper ring layer (LCD material controlled by voltage change) reflects your partner’s health status. It turns foggy and opaque when biological signals indicate illness.

HARDWARES

MOBILE APPLICATION

VIDEO

Persona + Use Scenario

PROTOTYPING

Form Protytpe + Interactive Prototype

CONTROL PROGRAM

						
import processing.serial.*;
import cc.arduino.*;
Arduino arduino;  // main device

// poke variables
int touchSensorReading = 0;
static final int pokeTouchDigitalPin = 2;
static final int pokeViberatorDigitalPin = 13;
int touchingCounter = 0;

// badMoodAlert variables
static final int badMoodAnalogPin = 0;
static final int badMoodServoMotorPin = 10;
int miniServoOutput = 0;
float gsrThreshold = 0;
int gsrSensorInput = 0;
int servoMotorResumingTime = -1;
ServoMotorStatus servoMotorStatus = ServoMotorStatus.IDLE;

// twist variables
static final int twistAnalogPin = 5  ;
static final int twistServoMotorPin = 11;
int servo995Output = 0;
int twistInput = 0;
int previousTwistInput = 0;
int twistThreshold = 8;


void setup(){
  println("starting up the system...\n==========");
  
  // poke module initialization
  println("initializing poke function... ");
  arduino = new Arduino(this, Arduino.list()[5], 57600);
  arduino.pinMode(pokeTouchDigitalPin, Arduino.INPUT);
  arduino.pinMode(pokeViberatorDigitalPin, Arduino.OUTPUT);
  println("poke function initialization done\n==========");
  
  // badMoodAlert
  println("initializing bad mood detection... ");
  long sum = 0;
  arduino.pinMode(badMoodAnalogPin, Arduino.INPUT); //declare gsr into pin
  arduino.pinMode(badMoodServoMotorPin, Arduino.SERVO); //D11 control mini servo
  miniServoOutput = 0;
  arduino.servoWrite(badMoodServoMotorPin, miniServoOutput);//setup ring in relax mode
  delay(1000);  // wait for the miniServo to reset
  for(int i=0;i<1000;i++){
    gsrSensorInput=arduino.analogRead(badMoodAnalogPin);
    sum += gsrSensorInput;
    delay(5);
  }
  gsrThreshold = sum/1000;
  print("gsrThreshold = ");
  println(gsrThreshold);
  println("bad moon detection initialization done\n==========");

  // twist
  println("initializing twist detection... ");
  arduino.pinMode(twistAnalogPin, Arduino.INPUT); //declare potentiometer input pin
  arduino.pinMode(twistServoMotorPin, Arduino.SERVO); //D10 control servo 995
  servo995Output = 95; // adjusted value for servo 995 
  arduino.servoWrite(twistServoMotorPin, servo995Output);//setup ring upper mark pointing middle
  println("bad moon detection initialization done\n==========");



void draw(){
  // poke logic
  touchSensorReading = arduino.digitalRead(pokeTouchDigitalPin);
  if (touchSensorReading > 0){
    if(touchingCounter > 5){
      println("touched, touchSensor reading : " + touchSensorReading);
      arduino.digitalWrite(pokeViberatorDigitalPin, Arduino.HIGH);
    }
    touchingCounter++;
  }
  else{
    touchingCounter = 0;
    arduino.digitalWrite(pokeViberatorDigitalPin, Arduino.LOW);
  }
  
  // badMoodAlert logic
  switch (servoMotorStatus){
    case IDLE:  
      gsrSensorInput = arduino.analogRead(badMoodAnalogPin);
      println("GSR threshold : " + gsrThreshold + "GSR Sensor Value = " + gsrSensorInput );
      miniServoOutput = (int)abs(gsrThreshold - gsrSensorInput);  
      if(miniServoOutput > 120){  // if current value differes from threshold by 50 check again to reduce noise
        gsrSensorInput = arduino.analogRead(badMoodAnalogPin);
        miniServoOutput = (int)abs(gsrThreshold - gsrSensorInput);
        if(miniServoOutput > 120){ // if it's still larger than 50
          servoMotorStatus = ServoMotorStatus.OPERATING;
          servoMotorResumingTime = (second() + 3) % 60; // 3 seconds for motor to rotate          
          arduino.servoWrite(badMoodServoMotorPin, 0);          
          println("bad mood detected");
        }
      }
      break;
    case OPERATING: // OPERATING
//      println("operating");
      if(second() == servoMotorResumingTime){
        arduino.servoWrite(badMoodServoMotorPin, 10); // reset the motor position
        servoMotorResumingTime = (second() + 1) % 60; // 1 second to reset            
        servoMotorStatus = ServoMotorStatus.RESETTING;
      }
      break;
    case RESETTING: // RESETTING
//      println("resetting");
      if(second() == servoMotorResumingTime){
        servoMotorStatus = ServoMotorStatus.IDLE;
      }
    break;
  }
 
  // twist logic
  twistInput = arduino.analogRead(twistAnalogPin);
  if(abs(twistInput - previousTwistInput) > twistThreshold){ 
    if(twistInput <= 505){
      if(twistInput > 145){
        servo995Output = 172 - (int)((twistInput - 145)/4.235);
      }
      else{
        servo995Output = 172;
      }  
    }
    else{
      if(twistInput < 853){
        servo995Output = 172 - (int)((twistInput - 505)/4.5 + 95);
      }
      else {
        servo995Output = 10;
      }
    }
    println(servo995Output);
    arduino.servoWrite(twistServoMotorPin, servo995Output);
  }
  previousTwistInput = twistInput;
  
}
						
					

USER TESTING

12 Participants in Pairs | 44min/pair

      Evaluation

      Almost all test users responded possitively on the designed interactions and they showed specific interests in customizing their own tactile messages using the tap/vibration mechanism. Some reflected if an emergency alarm is added, this design will be able to expand its use scenario to elderly care.

      IMI Analysis