This project connects people with their loved ones who are living at a distance by subtly augmenting objects in their natural surroundings which then become their enchanted versions and magically convey the message of being missed.

0

Introduction

In the interest of education, profession or projects, many people live far away from their loved ones. Often when caught up with life, we tend to get so busy that it seems impossible to take out any time to stay in touch. Moreover, we always think twice before making a phone call so as to not disturb others assuming that everyone is always busy. On numerous occasions, even if there's nothing to talk about, a small gesture of letting someone know that they are being missed is more than enough to communicate the love and affection for them.

Living pictures is a connected social photo frame that augments a regular photo frame placed on a desk or hanging on a wall that enables its users to touch the picture and send a simple message to the ones they love that they miss them and are thinking about them. To the other side of the interaction, a simple breathing light which is glanceable in the periphery works as a reminder that there's someone out there who is missing them.

0

Concept

The concept of this idea was to initiate some kind of social interaction between loved ones which is non-intrusive and does not require urgent attention of the actors. We wanted to create an object that not only facilitates this interaction but also fall back to function as a regular everyday object that is in the natural surrounding of its users.

We chose to augment a photo frame because it has always been an object that stimulates emotions and is associated with memories and nostalgia. It also felt like a suitable tangible medium to connect people with their loved ones whose pictures are already placed in a traditional photo frame.

0

Interaction

The interaction with the picture frame is simple yet meaningful. The user can simply touch a part of the photo frame on their desk or make a streak of touch and the same touch would be visible on the photo frame that their loved ones have bu a series of led lights that light up in the same area as the original touch. These lights then slowly fade away indicating the trail that a touch leaves behind it. To the user on the other side, the photo frame which is glanceable in their peripheral vision lights up as if someone is touching it from the other side, and they can choose to retrace the path or create their own gesture which is communicated back indicating that they are missing them and thinking about them too.



0

Proof of Concept - Connecting Input and Output

To capture the touch of the user in different areas of the frame, we are using five-point capacitive touch sensors that are attached to metal contacts on top of the frame. The sensor can detect different areas of touch and send the signal to particle cloud as input.

0
int buttonPin = D3;
int capPin = D4;
bool ananas = false; //

void setup() {
    
    pinMode(capPin, INPUT);
    pinMode(buttonPin, INPUT);
    Particle.variable("bool", ananas);
}

void loop() {

    if (digitalRead(capPin) == LOW)
    {
        ananas= !ananas;
        Particle.publish ("Capacitive Touch", "LOW");
        delay(2000);

    } else 
    {
        Particle.publish ("Capacitive Touch", "HIGH");
        delay(2000);
    }

}
Click to Expand
0

On the picture frame at the receiving user's end, a Neopixel strip is subscribed to the particle cloud that is transmitting the input signal, and the led lights up when it receives the input

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// This value will store the last time we published an event
long lastPublishedAt = 0;
// this is the time delay before we should publish a new event
// from this device
int publishAfter = 10000; //10 s

int buttonPin = D3;
    // IMPORTANT: Set pixel COUNT, PIN and TYPE
    #define PIXEL_PIN D2
    #define PIXEL_COUNT 5
    #define PIXEL_TYPE WS2812
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

String event = "css19/diot/2019/paired/";

void setup()
{

  // We'll want to subscribe to an event thats fairly unique

  // From the Particle Docs
  // A subscription works like a prefix filter.
  // If you subscribe to "foo", you will receive any event
  // whose name begins with "foo", including "foo", "fool",
  // "foobar", and "food/indian/sweet-curry-beans".

  // Basically this will match any event that starts with 'db2018/paired/'
  // This is a feature we'll useto figure out if our event comes from
  // this device or another (see publishMyEvent below)
    pinMode( buttonPin , INPUT_PULLUP);
    strip.begin();
    Particle.subscribe(  event , handleSharedEvent );

}

void loop()
{
    int buttonState = digitalRead( buttonPin );
   if( buttonState == LOW)
   {
   // turn the LED On
   publishMyEvent();
   //doSolenoid();
   }else{
   // otherwise
   // turn the LED Off
   }
   delay( 100 );

}


void publishMyEvent()
{
  // Remember that a device can publish at rate of about 1 event/sec,
  // with bursts of up to 4 allowed in 1 second.
  // Back to back burst of 4 messages will take 4 seconds to recover.
  // So we want to limit the amount of publish events that happen.

  // check that it's been 10 secondds since our last publish
  if( lastPublishedAt + publishAfter < millis() )
  {
      // Remember our subscribe is matching  "db2018/paired/"
      // We'll append the device id to get more specific
      // about where the event came from

      // System.deviceID() provides an easy way to extract the device
      // ID of your device. It returns a String object of the device ID,
      // which is used to identify your device.

      String eventName = event + System.deviceID();

      // now we have something like "diot/2019/paired/0123456789abcdef"
      // and that corresponds to this devices info

      // then we share it out
      Particle.publish( eventName, "Seema" );

      // And this will get shared out to all devices using this code

      // we just pubished so capture this.
      lastPublishedAt = millis();
  }

}

// Our event handlde requires two bits of information
// This gives us:
// A character array that consists of the event name
// A character array that contains the data published in the event we're responding to.
void handleSharedEvent(const char *event, const char *data)
{
    // Now we're getting ALL events published using "db2018/paired/"
    // This includes events from this device.
    // So we need to ignore any events that we sent.

    // Let's check the event name
    String eventName = String( event ); // convert to a string object
    // This gives us access to a bunch of built in methods
    // Like indexOf()
    // Locates a character or String within another String.
    // By default, searches from the beginning of the String,
    // but can also start from a given index,
    // allowing for the locating of all instances of the character or String.
    // It Returns: The index of val within the String, or -1 if not found.

    // We can use this to check if our event name contains the
    // id of this device

    String deviceID = System.deviceID();


    if( eventName.indexOf( deviceID ) != -1 )
    {
      // if we get anything other than -1
      // the event came from this device.
      // so stop doing stuff
      return;
    }

    // otherwise do your stuff to respond to
    // the paired device here
    uint32_t i;
    uint32_t c = strip.Color(0, 0, 255); // Blue
    uint32_t d = strip.Color(0, 0, 0); // no color
    
 // if( buttonReading == HIGH )
 //  {
   
 
    for( int i = 0; i < strip.numPixels(); i++ )
        {
        strip.setPixelColor(i, c); // set a color 
        strip.show();
        delay( 200 );
        }

//}
}
Click to Expand
0

MVP - Connecting Frames via the Internet

The two pictures frames were installed with capacitive touch sensors and for the purpose of demonstration, one was embedded with Neopixel to show the interaction with the frames.

When a user 1 touches the picture frame it lights up blue in that area, and the light on the picture frame of user 2 lights up red in the same area.

When both the users touch the frame at the same time in the same area, the lights on both frame light up purple indicating a simultaneous touch.

0

Code for user 1

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

#define PIXEL_COUNT 1
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// COLORS
int red = 0;
int blue = 0;
int green = 0;

// INPUT
int buttonPin = D3;

// PARTICLE CLOUD
long lastPublishedAt = 0;
int publishAfter = 3000;

// EVENT NAME
String event = "css19/diot/2019/paired/";

// TIME KEEPING
unsigned long pressTime = 0;

void setup() {
   pinMode(buttonPin , INPUT_PULLUP);
   pinMode( PIXEL_PIN, OUTPUT );
   Particle.subscribe(  event , handleSharedEvent );
}

void loop() {
   int buttonState = digitalRead( buttonPin );
   if( buttonState == LOW)
   {
   // turn the LED On
   publishMyEvent();
   //doSolenoid();
   }else{
   // otherwise
   // turn the LED Off
   }
   delay( 100 );
   if((millis()-pressTime) > 5000) {
   setRGBColor(0,0,0);
   } else {
     int v = int ((millis() - pressTime) / 5000);
     setRGBColor(v * red, v * blue,0);
   }
}

void setRGBColor( int r, int g, int b ){
 red = r;
 green = g;
 blue = b;
    
 strip.setPixelColor(0, red, green, blue);
 strip.show();
}

void publishMyEvent()
{
 // Remember that a device can publish at rate of about 1 event/sec,
 // with bursts of up to 4 allowed in 1 second.
 // Back to back burst of 4 messages will take 4 seconds to recover.
 // So we want to limit the amount of publish events that happen.

 // check that it’s been 10 secondds since our last publish
 if( lastPublishedAt + publishAfter < millis() )
 {
     // Remember our subscribe is matching  “db2018/paired/”
     // We’ll append the device id to get more specific
     // about where the event came from

     // System.deviceID() provides an easy way to extract the device
     // ID of your device. It returns a String object of the device ID,
     // which is used to identify your device.

     String eventName = event + System.deviceID();

     // now we have something like “diot/2019/paired/0123456789abcdef”
     // and that corresponds to this devices info

     // then we share it out
     Particle.publish( eventName, "Satyan" );

     // And this will get shared out to all devices using this code

     // we just pubished so capture this.
     lastPublishedAt = millis();
 }

}

void handleSharedEvent(const char *event, const char *data)
{
   // Now we’re getting ALL events published using “db2018/paired/”
   // This includes events from this device.
   // So we need to ignore any events that we sent.

   // Let’s check the event name
   String eventName = String( event ); // convert to a string object
   // This gives us access to a bunch of built in methods
   // Like indexOf()
   // Locates a character or String within another String.
   // By default, searches from the beginning of the String,
   // but can also start from a given index,
   // allowing for the locating of all instances of the character or String.
   // It Returns: The index of val within the String, or -1 if not found.

   // We can use this to check if our event name contains the
   // id of this device

   String deviceID = System.deviceID();

   // device id = 0123456789abcdef
   // event = “diot/2019/paired/0123456789abcdef”

   if( eventName.indexOf( deviceID ) != -1 ){
     // if we get anything other than -1
     // the event came from this device.
     // so stop doing stuff
     pressTime = millis();
     blue = 255;
     setRGBColor(red,blue,0);
     return;
   }

   // otherwise do your stuff to respond to
   // the paired device here

   //motorOn = true;
   pressTime = millis();
   red == 255;
   setRGBColor(red,blue,0);
}
Click to Expand
0

Code for user 2 with LED implemented

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>


#define PIXEL_COUNT 1
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// COLORS
int red = 0;
int blue = 0;
int green = 0;

// INPUT
int buttonPin = D3;

// PARTICLE CLOUD
long lastPublishedAt = 0;
int publishAfter = 3000;

// EVENT NAME
String event = "css19/diot/2019/paired/";

// TIME KEEPING
unsigned long pressTime = 0;

void setup() 
    {
         pinMode(buttonPin , INPUT_PULLUP);
         pinMode( PIXEL_PIN, OUTPUT );
         Particle.subscribe(  event , handleSharedEvent );
    }

void loop() 
    {
        int buttonState = digitalRead( buttonPin );
        if( buttonState == LOW)
            {
             // turn the LED On
            publishMyEvent();
            //doSolenoid();
            }
        else
            {
            // otherwise
            // turn the LED Off
            }
   
        
        if((millis()-pressTime) > 7000) 
            {
            setRGBColor(0,0,0);
            strip.setBrightness(255);
            } 
    
        unsigned long v = ((millis() - pressTime) / 7000.0);
        int k = int(255.0 * (1.0-v));
        strip.setBrightness(k);
    }

void setRGBColor( int r, int g, int b )
    {
        red = r;
        green = g;
        blue = b;
    
        strip.setPixelColor(0, red, green, blue);
        strip.show();
    }

void publishMyEvent()
    {
    // Remember that a device can publish at rate of about 1 event/sec,
    // with bursts of up to 4 allowed in 1 second.
    // Back to back burst of 4 messages will take 4 seconds to recover.
    // So we want to limit the amount of publish events that happen.

    // check that it’s been 10 secondds since our last publish
    if( lastPublishedAt + publishAfter < millis() )
        {
        // Remember our subscribe is matching  “db2018/paired/”
        // We’ll append the device id to get more specific
        // about where the event came from

        // System.deviceID() provides an easy way to extract the device
        // ID of your device. It returns a String object of the device ID,
        // which is used to identify your device.

     String eventName = event + System.deviceID();

     // now we have something like “diot/2019/paired/0123456789abcdef”
     // and that corresponds to this devices info

     // then we share it out
     Particle.publish( eventName, "Seema" );

     // And this will get shared out to all devices using this code

     // we just pubished so capture this.
     lastPublishedAt = millis();
         }

    }

void handleSharedEvent(const char *event, const char *data)
    {
     // Now we’re getting ALL events published using “db2018/paired/”
     // This includes events from this device.
     // So we need to ignore any events that we sent.

   // Let’s check the event name
   String eventName = String( event ); // convert to a string object
   // This gives us access to a bunch of built in methods
   // Like indexOf()
   // Locates a character or String within another String.
   // By default, searches from the beginning of the String,
   // but can also start from a given index,
   // allowing for the locating of all instances of the character or String.
   // It Returns: The index of val within the String, or -1 if not found.

   // We can use this to check if our event name contains the
   // id of this device

   String deviceID = System.deviceID();

   // device id = 0123456789abcdef
   // event = “diot/2019/paired/0123456789abcdef”

   if( eventName.indexOf( deviceID ) != -1 )
        {
        // if we get anything other than -1
        // the event came from this device.
        // so stop doing stuff
        pressTime = millis();
        blue = 255;
        strip.setBrightness(255);
        setRGBColor(red,0,blue);
        return;
        }

    // otherwise do your stuff to respond to
    // the paired device here

    //motorOn = true;
    pressTime = millis();
    red = 255;
    strip.setBrightness(255);
    setRGBColor(red,0,blue);

    }
Click to Expand
0
x
Share this Project

Courses

49713 Designing for the Internet of Things

· 18 members

A hands-on introductory course exploring the Internet of Things and connected product experiences.


Focused on
Tools
About

This project connects people with their loved ones who are living at a distance by subtly augmenting objects in their natural surroundings which then become their enchanted versions and magically convey the message of being missed.

Created

February 11th, 2019