An ambient photo frame which encourages users to talk to their families more often.



"Let's Catch Up" is an ambient photo frame which encourages users to talk to their families more often. It includes a photo frame, a love pointer, and a capacitive touch sensor (circuit). 

By default, the lover pointer hides behind the photo frame, and it starts to run after users' last call with their families. The longer they have not called, the faster it goes. The increasing movement leads to a hard time seeing the family photo that is been placed in the frame. The sense of urgency impels users to realize their ignorance of their families. By tapping the side of the photo frame, the family in the distance will receive a "Let's catch up" text. The initiator's pointer also stops right after because we want to remind users that planning to call does not equal to actual calling, and the pointer goes back to the default hidden location and restarts after the family responds to the text. 


As international students ourselves, we want to design a product that can connect families members who live far away from each other. We have learned from domain research that there are many products in the IoT market targeting long distance emotion/feeling sharing, and we would love to build upon those and add a call-to-action. 

Inspiration from previous works:

1. Ishii's LumiTouch photo frame
2. Proximity Lamp Using Arduino
3. IoT Location Sensing Picture Frame

Final Design


Network Diagram


Feedback from Version 1, 

"Missing U" (the initial prototype)

  • The touching/LED-lighting-up interaction is kind of strange. People think it can be scary when a photo lights up randomly.
  • The idea is really similar to Ishii's LumiTouch photo frame. 


1. The initial prototype was intrusive, and the idea has been out there for many year, so we started with another round of ideation. We still like the family connection concept, but this time we looked into how to make users take actual actions by using our product, such as sending cute messages, calling.

2. After deciding the direction (texting), we started brainstorming what the interactions should be and how we can show the interactions. Because we want users to take actions, we want to create a sense of urgency. Sijia suggested it will be interesting if the family picture gradually disappears when people have not talked to their families for a while. We tried LCD first. Though it looked fancy, it was too small compare to our frame, and its rectangle sharp shape looked intrusive. 


3. Then, we went back to a more traditional way, adding a stick in between the picture and front frame to interrupt people looking at the picture.    


4. We also wanted to incorporate the capacitor section we built before, so we quickly storyboarded how the entire interaction will be. We connected it with IFTTT to completing the responded interaction from the other party. 


 5. We tried different kinds of "love pointer" design.    


6. We also started working on the code and circuit design, exploring ways to make our ideas come alive. 


Bill of Material

  1. Argon x 1
  2. Breadboard x 1
  3. Capacitive  touch sensor x 1
  4. Servo x 1
  5. Wire Jumpers 




Servo switchServo;
// invokes the inbuilt servo function and assigns it to switchServo

int step = 20;
int speed = 0;
// step and speed are global variables used to control the current degree and speed of the servo motor

long startedAt = 0;
// It monitors the time since the last servoevent was activated
//duration is used

bool shouldDoIt = false;
bool increasing = true;

int touchSensor = D3;
// assigns capacitive sensor, that is connected to D3 to a variable named TouchSensor 
bool lastState = false;
int touchState = LOW;
// touchState is used to monitor when the cap touch was last activated 
// lastState is used to control the movement of the servo based on servo activation

bool overRide = false;
// used to turn on the loop when servoEvent is activated

int a = 1;

long lastPublishedAt = 0;
// this is the time delay before we should publish a new event
// from this device
int publishAfter = 10000;

void setup()

pinMode( touchSensor, INPUT);

// sets servo to starting position

// the devices are subscribed to a common channel and an event named servoEvent from that channel

Particle.subscribe(  "servostart", servoEvent );
// the devices are subcribed to an IFTTT trigger


void loop()

    if ( a = 1 )
        shouldDoIt = true;
        a = 2; 

touchState = digitalRead(touchSensor);
 // reads the value from touchSensor
// function checks when the touchSensor was last activated

  if(shouldDoIt == true)

   startedAt = millis();
   // records the time at which the servoEvent starts
   shouldDoIt = false;

if ( overRide == true )


   speed = speedCalculate();
   // uses a function to calculate the speed of the servo motor in respect to the time since last trigger of servoEvent
   // servo motor  is moved to a required angle based on the value on the step variable
   // controls the time between consecutive steps of a servo motor
   step = stepCalculate();
   // calculates the step value for the next loop

// void loop ends

int speedCalculate()
// the function uses the time difference between the time when the servoEvent started and the time at a given moment to calculate the time delay between two consecutive servo motions
    if ((millis () - startedAt) < 20*1000 )
    speed = 500;
     if ((millis () - startedAt) > 20*1000 && (millis () - startedAt) < 40*1000 )
    speed = 300;
    if ((millis () - startedAt) > 40*1000 )
    speed = 200;
    return speed;

int stepCalculate()
// the function uses the previous step of the servo motor to caclulate its next step or angle. The function also decides the direction of movement 
     if (step < 160 && increasing == true )
     step = step + 5;
     step = step - 5;
     increasing = false;
      if (step == 20)
         increasing = true;
         // increasing is a variable used to register the direction of motion of the servo motor
 return step;

bool checkLaststate()
// checks is capacitive touch has been activated
// stops the motor
// publishes an event to trigger IFTTT
    if ( touchState == HIGH ); 
    overRide = false;
// delay for a bit

int servoEvent(const char*event, const char*data)
// recieves an input from the channel subscribed to and restarts the servo loop
step = 20;
// sets servo angle to start point
increasing = true;
// sets servo direvtion to start point
shouldDoIt = true;
//resets the timer
overRide = true;
// starts the loop
return 1;

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 = "diot/2019/paired/sijiavedhachun" + 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, "true" );
      // And this will get shared out to all devices using this code
      // we just pubished so capture this.
      Particle.publish( "sendmessage", "done" );
      // the trigger for IFTTT sending message 
      lastPublishedAt = millis();

Click to Expand

Next Steps

1. The way of reminding people to connect with family members can be more ambient and intuitive - photos could fade off or disappear as time passes by.

2. Currently, we have only connected IFTTT and the initiator (people who reach out first). For the next step, we should connect both sides.

3. The devices are connected with only the text at the moment. We can incorporate social media into part of interactions.


Feedback from Tue. Presentation

The guests gave us some really insightful feedback in areas we have not thought about at all. Some of the things we learned:

1. Think about the design intention. What emotion do we want to bring to the users? Do we want to make them feel guilty about forgetting to talk to their families or do we want to create happiness for them?

2. Think about the target users Guests suggest us to be specific about our target groups since they see gaps between their understanding and our descriptions. It will be better for the work and presentation if we have a specific persona in mind. 

3. Think about the ethics issue the product might bring to the users. Though it is designed with good intentions, we need to be careful about the level of stress we unintentionally add to the users. 

Share this Project


49713 Designing for the Internet of Things

· 18 members

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


An ambient photo frame which encourages users to talk to their families more often.


February 18th, 2019