Avateam

Communicate your status in a playful and interactive way.

Made by Mengqi Wang, Christopher Holliday, Stephen Krotseng and jfwiddifield

Created: February 3rd, 2015

0

Goal

The goal of the Avateam connected intimacy device was to allow two people to display their statuses to each other in a way that is fun to interactive, but not too obtrusive in everyday life. The device allows the partners to display three states: available (standing), busy (sitting), and asleep (laying down). The current position of your avatar is displayed on the right of the figurine using a simple RGB led interface, with green meaning available, red meaning busy, and purple meaning asleep. The current position of your partners avatar is displayed on the left of the figurine using the same logic.  

Function

To enable the interaction between the two devices, we used two sets of infrared beam break sensors.  The sensors were positioned so that when the figurine was in the seated position, it would only break the first set of sensors, and when it was in the laying position it would break both sets of sensors.  Clearly, when the figurine is standing up, it doesn't break either of the sensor beams.

0

Process

Components Used: (1 per device)

-  Spark microcontroller

-  Breadboard

-  8 1kΩ resistors

-  2 RGB LEDs

-  2 IR transmitters and 2 IR recievers

-  Leads

-  LEGO Minifigure

-  1/4" plywood

0

Circuit

0

Code for Chris's Core

0
int legPin = A0;
int headPin = A1;
int redPin = A4;
int greenPin = D0;
int bluePin = D1;
int myredPin = A5;
int mygreenPin = A6;
int mybluePin = A7;
int legbeam;
int headbeam;
int avatarState;

void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(myredPin, OUTPUT);
  pinMode(mygreenPin, OUTPUT);
  pinMode(mybluePin, OUTPUT);

  pinMode(legPin, INPUT);
  pinMode(headPin, INPUT);

  Spark.variable("legbeam", &legbeam, INT);
  Spark.variable("headbeam", &headbeam, INT);

  Spark.subscribe("StephenKrotseng", handlePositionChange );
}

void loop()
{

  //delay( 1000 );

  legbeam = analogRead(legPin);
  headbeam = analogRead(headPin);

  //avatarState = 0;
  // State variable key
  // sit = 1
  // lay = 2
  // stand = 3

  if (legbeam>100 && headbeam<100 && avatarState != 1)
  {
      // Red
      announceSit();
      avatarState = 1;
  }else if (legbeam>100 && headbeam>100 && avatarState != 2)
  {
      // Red + Blue
      announceLay();
      avatarState = 2;
  }else if (legbeam<100 && headbeam<100 && avatarState != 3)
  {
      // Green
      announceStand();
      avatarState = 3;
  }

  delay(2500);

}

void announceSit()
{
  Spark.publish("ChrisHolliday", "SIT", 60, PUBLIC);

  // Set to red
  analogWrite(myredPin, 0);
  analogWrite(mybluePin, 255);
  analogWrite(mygreenPin, 255);
}

void announceLay()
{
  Spark.publish("ChrisHolliday", "LAY", 60, PUBLIC);

  // Set to purple
  analogWrite(myredPin, 0);
  analogWrite(mybluePin, 0);
  analogWrite(mygreenPin, 255);
}

void announceStand()
{
  Spark.publish("ChrisHolliday", "STAND", 60, PUBLIC);

  // Set to green
  analogWrite(myredPin, 255);
  analogWrite(mybluePin, 255);
  analogWrite(mygreenPin, 0);
}

void handlePositionChange( const char * event, const char *data  )
{
    if( strcmp( data, "SIT" ) == 0 ){
      RGBSIT();
      return;
    }

    if( strcmp( data, "LAY" ) == 0 ){
      RGBLAY();
      return;
    }

    if( strcmp( data, "STAND" ) == 0 ){
      RGBSTAND();
      return;
    }
}

void RGBSIT()
{
  analogWrite(redPin, 0);
  analogWrite(bluePin, 255);
  analogWrite(greenPin, 255);
}

void RGBLAY()
{
  analogWrite(redPin, 0);
  analogWrite(bluePin, 0);
  analogWrite(greenPin, 255);
}

void RGBSTAND()
{
  analogWrite(redPin, 255);
  analogWrite(bluePin, 255);
  analogWrite(greenPin, 0);
}
Click to Expand
0

Code for Stephen's Core

0
int legPin = A0;
int headPin = A1;
int redPin = A4;
int greenPin = D0;
int bluePin = D1;
int myredPin = A5;
int mygreenPin = A6;
int mybluePin = A7;
int legbeam;
int headbeam;
int avatarState;

void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(myredPin, OUTPUT);
  pinMode(mygreenPin, OUTPUT);
  pinMode(mybluePin, OUTPUT);

  pinMode(legPin, INPUT);
  pinMode(headPin, INPUT);

  Spark.variable("legbeam", &legbeam, INT);
  Spark.variable("headbeam", &headbeam, INT);

  Spark.subscribe("ChrisHolliday", handlePositionChange );
}

void loop()
{

  //delay( 1000 );

  legbeam = analogRead(legPin);
  headbeam = analogRead(headPin);

  //avatarState = 0;
  // State variable key
  // sit = 1
  // lay = 2
  // stand = 3

  if (legbeam>100 && headbeam<100 && avatarState != 1)
  {
      // Red
      announceSit();
      avatarState = 1;
  }else if (legbeam>100 && headbeam>100 && avatarState != 2)
  {
      // Red + Blue
      announceLay();
      avatarState = 2;
  }else if (legbeam<100 && headbeam<100 && avatarState != 3)
  {
      // Green
      announceStand();
      avatarState = 3;
  }

  delay(2500);

}

void announceSit()
{
  Spark.publish("StephenKrotseng", "SIT", 60, PUBLIC);

  // Set to red
  analogWrite(myredPin, 0);
  analogWrite(mybluePin, 255);
  analogWrite(mygreenPin, 255);
}

void announceLay()
{
  Spark.publish("StephenKrotseng", "LAY", 60, PUBLIC);

  // Set to purple
  analogWrite(myredPin, 0);
  analogWrite(mybluePin, 0);
  analogWrite(mygreenPin, 255);
}

void announceStand()
{
  Spark.publish("StephenKrotseng", "STAND", 60, PUBLIC);

  // Set to green
  analogWrite(myredPin, 255);
  analogWrite(mybluePin, 255);
  analogWrite(mygreenPin, 0);
}

void handlePositionChange( const char * event, const char *data  )
{
    if( strcmp( data, "SIT" ) == 0 ){
      RGBSIT();
      return;
    }

    if( strcmp( data, "LAY" ) == 0 ){
      RGBLAY();
      return;
    }

    if( strcmp( data, "STAND" ) == 0 ){
      RGBSTAND();
      return;
    }
}

void RGBSIT()
{
  analogWrite(redPin, 0);
  analogWrite(bluePin, 255);
  analogWrite(greenPin, 255);
}

void RGBLAY()
{
  analogWrite(redPin, 0);
  analogWrite(bluePin, 0);
  analogWrite(greenPin, 255);
}

void RGBSTAND()
{
  analogWrite(redPin, 255);
  analogWrite(bluePin, 255);
  analogWrite(greenPin, 0);
}
Click to Expand
0

Assembling the Display

0

Using the laser cutter at the Mechanical Engineering Department's machine shop, we created the faces for our display.

0

We assembled the box and attached the breadboard under the top surface, allowing the sensors and lights to show through.  We then attached the figurine in the correct position to trigger the sensors.

0

The happy couple.

0

Video

0
0

Challenges Encountered

The most difficult aspect of this project was getting the two cores to communicate to one another consistently.  We had many iterations of our code, each one trying to bring us closer to consistency.  Unfortunately, even our final code is a bit buggy.  Throughout the process, our devices would work, and then stopped working with no indication of why.  We also encountered some issues making our circuits fit into our box designs, which caused to improvise.  

0

Final Thoughts

When it worked, we were really happy with the Avateam.  However, it was frustrating trying to debug code whose logic seemed sound.  

x