Sometimes, a proxy for physical touch can be as powerful as a local presence. We explored this principle in the development of a system that lets remote lovers know when their partners are engaging their adorable surrogate "Lovebirds."

Created: February 10th, 2016

0
diot - creative assignment #3
Xingsuo Liu - https://vimeo.com/154952929
0

Problem Identification

Long distance relationship can be hard to manage especially between lovers. Keeping a long distance relationship means you need to bear the lonely time without the beloved one around you; you can not express your feelings easily to him/her... Nowadays, long distance relationship becomes a quite common problem and many people want to figure out some approaches to deal with this situation. 

0

Concept

Based on the problem identification, we made some brainstorm and narrowed down to our final concept. The concept is to connect the people from long distance by using the light and sound. When a person from one side tries to touch the wooden bird or tries to speak to it. On the other side, the wooden bird will light up and make some sound based on different interaction from the other side.

0

Process

Our original vision was to have two birds that would each indicate when a recorded message had been received and was queued for playback. The thinking was that, especially in a long distance relationship, it would be great to hear something spontaneously recorded along the lines of “hi, I love you,” at the beginning of a day. The bird could indicate that a loved one is thinking of you. It could offer surrogacy for affection.

This proved problematic as we discovered that .mp3 and .wav files were tough to download from the cloud. In doing research we discovered that the Arduino analog to digital (A-D) conversion has a sample rate of below 10kHz, meaning we could maybe capture low quality speech, but not music. Also, the memory (RAM) of the Arduino board is very limited, so capturing a lot of audio samples is not really possible, unless we could write them off to an SD card in a timely manner. Ultimately, the Arduino is not really equipped for audio applications; it's really not fast enough. As a result, we pivoted our method to affect this outcome within the scope of this assignment.

The hallmarks of effective relationships are intimacy and vulnerability. The inherent amplification of uncertainty in a long distance relationship heightens the need for affirmation and a sense of safety, to create moments of intimacy from afar. Our team recognized that a purposeful act of kindness and affection could communicate a lot of value in a prescribed intent, and so we felt comfortable in projecting affection in the context of an action that would say “I miss you.” To do this, a user simply needs to touch a bird in its nest. Whenever one bird is touched, the nest of the other will light up and chirp, to communicate that the lover is not really alone.

0

Persona

Mary and her boyfriend live in two different countries. They always miss each other very much and constantly crave one another’s affection. On Valentine’s Day, Mary’s boyfriend gives her a Lovebird. He explains that she should keep hers in her home while the other one will stay in his. From then on, when Mary misses her boyfriend, she can just touch the bird, and her boyfriend will see a light come form the bird and hear its adorable chip, to remind him of Mary’s smiling face.

0

Prototypes

0

Components list:

Particle Photon *2

Mic *2

LED *4

Photo sensor *4

Buzzer *2

Resistors

Jumper

Usb cable

0
int mic_pin = A0;

int lightPin1 = A4;
int lightPin2 = A5;

int  thresholdTouchMax = 800;
int thresholdTouchMin = -20;

int noise_level = 0;
const int sampleWindow = 50;

int ledPin1 = A1;
int ledPin2 = A2;
int ledPin3 = A3;
int ledPin4 = A4;

void setup(){

  pinMode(mic_pin, INPUT);
  pinMode(lightPin1, INPUT);
  pinMode(lightPin2, INPUT);


  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);

  Particle.subscribe("xingsuo/touchEvent1", touchGet);
  Particle.subscribe("xingsuo/noiseLevel1", noiseGet);

  Serial.begin(9600);
}

void loop(){

  String noise_level = noiseSensor();
  bool ifTouch = pressureSensor();
  //Serial.println(noise_level);
  //Serial.println(ifTouch);
}


void touchGet(String trigger)
{
  if(trigger == "touch")
  {

      for(int i=0;i<255;i++)
      {
        analogWrite(ledPin1, i);
        analogWrite(ledPin2, i);
        analogWrite(ledPin3, i);
        analogWrite(ledPin4, i);
        delay(100);
      }
      for(int i = 255; i>0; i--){
        analogWrite(ledPin1, i);
        analogWrite(ledPin2, i);
        analogWrite(ledPin3, i);
        analogWrite(ledPin4, i);
        delay(100);
      }

  }

}


bool pressureSensor(){

  //int buttonState = digitalRead( switchPin );
  int a1 =  analogRead(lightPin1)/4;
  int a2 =  analogRead(lightPin2)/4;


  int touch = a1-a2;
  //Serial.println(analogRead(pressure_pin));

  if(touch>=thresholdTouchMax || touch<thresholdTouchMin)
  {
    Particle.publish("xingsuo/touchEvent", "touch");
    Serial.println(a1-a2);
    return true;
  }else
  {
    return false;
  }
}

String noiseSensor(){
  unsigned long startMillis = millis(); // Start of sample window
  int highest_sample = 0;
  int lowest_sample = 1000;
  // collect data for 50 mS
  while (millis() - startMillis < sampleWindow)
  {
  int sample = analogRead( mic_pin );
  	// invert the range, and convert it to a percent
  	sample = map( sample, 0, 4095, 1000, 0 );
  	// now see if the sample is the lowest;

  	if ( sample > highest_sample ){
  	highest_sample = sample ;
  	}
  	if ( sample < lowest_sample ){
  	lowest_sample = sample;
  	}
  }
  int peakToPeak = highest_sample - lowest_sample;
  String level = String(peakToPeak);
  Particle.publish("xingsuo/noiseLevel", level);
  return level;

}

void touchGet(const char *event, const char *data)
{
  String dataStr = data;
  String test = "touch";
if(dataStr == "touch")
{

    for(int i=0;i<255;i++)
    {
      analogWrite(ledPin1, i);
      analogWrite(ledPin2, i);
      analogWrite(ledPin3, i);
      analogWrite(ledPin4, i);
      delay(100);
    }
    delay(2000);
    for(int i = 255; i>0; i--){
      analogWrite(ledPin1, i);
      analogWrite(ledPin2, i);
      analogWrite(ledPin3, i);
      analogWrite(ledPin4, i);
      delay(100);
    }

}

}

void noiseGet(const char *event, const char *data)
{

 String dataStr = data;
 int level = dataStr.toInt();
 Serial.println(level);
if(level <= noiseLevel1)
{
  playSound(0);
}
else if((level > noiseLevel1) && (level <= noiseLevel2) )
{
  playSound(1);
}
else if((level > noiseLevel2) && (level <= noiseLevel3) )
{
  playSound(2);
}
else if(level > noiseLevel3 )
{
  playSound(3);
}
}

void playSound(int level)
{
switch(level)
{
  case 0: ;
  case 1: {
            length=sizeof(tune1)/sizeof(tune1[0]);
            for(int x=0;x<length;x++)
            {
              tone(tonepin,tune1[x]);
              delay(500*durt[x]);
              noTone(tonepin);
            }
            delay(2000);
          };
  case 2: {
            length=sizeof(tune2)/sizeof(tune2[0]);
            for(int x=0;x<length;x++)
            {
              tone(tonepin,tune2[x]);
              delay(500*durt[x]);
              noTone(tonepin);
            }
            delay(2000);
          };

  case 3: {
            length=sizeof(tune3)/sizeof(tune3[0]);
            for(int x=0;x<length;x++)
            {
              tone(tonepin,tune3[x]);
              delay(200*durt[x]);
              noTone(tonepin);
            }
            delay(2000);
          };

          }

        }
Click to Expand
0
int ledPin1 = A1;
int ledPin2 = A2;
int ledPin3 = A3;
int ledPin4 = A4;

#define NTDH1 589
#define NTDH2 661
#define NTDH3 700
#define NTDH4 786
#define NTDH5 882
#define NTDH6 990
#define NTDH7 112

int tune1[]=
{
NTDH7,NTDH5,NTDH6
};

int tune2[]=
{
NTDH3,NTDH4,NTDH1
};
int tune3[]=
{
NTDH1,NTDH2,NTDH5
};

float durt[]=
{
1+1,0.5,1.5
};

int length;
int tonepin = D0;

int noiseLevel1 = 800;
int noiseLevel2 = 1000;
int noiseLevel3 = 1200;

void setup(){

Particle.subscribe("xingsuo/touchEvent", touchGet);
Particle.subscribe("xingsuo/noiseLevel", noiseGet);

pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(tonepin, OUTPUT);

pinMode(D1, OUTPUT);


Serial.begin(9600);
}

void loop(){



}

void touchGet(const char *event, const char *data)
{
  String dataStr = data;
  String test = "touch";
if(dataStr == "touch")
{

    for(int i=0;i<255;i++)
    {
      analogWrite(ledPin1, i);
      analogWrite(ledPin2, i);
      analogWrite(ledPin3, i);
      analogWrite(ledPin4, i);
      delay(100);
    }
    delay(2000);
    for(int i = 255; i>0; i--){
      analogWrite(ledPin1, i);
      analogWrite(ledPin2, i);
      analogWrite(ledPin3, i);
      analogWrite(ledPin4, i);
      delay(100);
    }

}

}

void noiseGet(const char *event, const char *data)
{

 String dataStr = data;
 int level = dataStr.toInt();
 Serial.println(level);
if(level <= noiseLevel1)
{
  playSound(0);
}
else if((level > noiseLevel1) && (level <= noiseLevel2) )
{
  playSound(1);
}
else if((level > noiseLevel2) && (level <= noiseLevel3) )
{
  playSound(2);
}
else if(level > noiseLevel3 )
{
  playSound(3);
}
}

void playSound(int level)
{
switch(level)
{
  case 0: ;
  case 1: {
            length=sizeof(tune1)/sizeof(tune1[0]);
            for(int x=0;x<length;x++)
            {
              tone(tonepin,tune1[x]);
              delay(500*durt[x]);
              noTone(tonepin);
            }
            delay(2000);
          };
  case 2: {
            length=sizeof(tune2)/sizeof(tune2[0]);
            for(int x=0;x<length;x++)
            {
              tone(tonepin,tune2[x]);
              delay(500*durt[x]);
              noTone(tonepin);
            }
            delay(2000);
          };

  case 3: {
            length=sizeof(tune3)/sizeof(tune3[0]);
            for(int x=0;x<length;x++)
            {
              tone(tonepin,tune3[x]);
              delay(200*durt[x]);
              noTone(tonepin);
            }
            delay(2000);
          };

          }

        }
Click to Expand
0

Next Steps

Should we advance this particular project further, we would enjoy exploring different conditions; sometimes, we care to know that things are being played with because we want to see them engaged, while at other times, we want to know if things are being played with precisely because we care that they be left alone. In future iterations, we might endeavor in the domain of remote cat (or dog) training with real-time feedback of whether or not the toy bird is being engaged.

x
Share this Project

Courses

49-713 Designing for the Internet of Things

· 4 members

This course charts the emergence of the now "connected world" to explore the possibilities for future products and connected spaces.


Skills
About

Sometimes, a proxy for physical touch can be as powerful as a local presence. We explored this principle in the development of a system that lets remote lovers know when their partners are engaging their adorable surrogate "Lovebirds."