Online purchases make cloud unhappy.

Made by Ruolan Xia, Joseph Johnson, prithishni sekar and Ben Smith

Our goal was to bring awareness to the relatively intangible quantity of online purchases that modern consumers make. The ambient display brings glanceable feedback to help moderate your excessive purchases.

Created: February 3rd, 2016

0
Ambient Awareness IOT Assignment 2
ruolan xia - https://youtu.be/QOzRJdH4PTs
0

Problem Statement

Due to ease of purchase and a higher willingness to pay with credit cards, online shopping can pose a significant financial issue for even casual shoppers. That being said, e-commerce often represents a cheaper and more convenient method of shopping. Consumers therefore need a visual indicator to identify when they have passed a self-imposed limit for online shopping.

0

Goal

Our team wanted to create an ambient, anthropomorphic device that provides the online shopper a quick and effective notification of their online shopping trends. If the shopper stays under their target limit within a specified timeframe, the device should appear happy (i.e., using colors and facial expressions). If the shopper goes over their limit, the device should appear sad or upset. A warning color will let the shopper know when they are close to their limit.

0

Process

Process Step 1: Controlling a Servo and RGB LEDs

First, we utilized the tutorials written on the DIoT Lab Site (http://daraghbyrne.github.io/diotlabs/6-controlling-outputs/servo/) to set up servo control. There was no issues with the implementation of the servo. Subsequently, had a need to control the RGB values of multiple RGB LEDs, so to minimize the number of GPIO pins required, we built out an RGB LED control matrix utilizing 3x NPN transistors, 3x 5mm RGB LEDs, and 9x 680 ohm resistors. This allows for PWM signals to actuate the transistors as switches powering the three LEDs R, G, and B channels simultaneously and independently.

Process Step 2: Calling a Particle.function through Gmail / IFTTT trigger

Next we generated the IFTTT rule set to call a receipt count function on the Photon whenever an email was received with “receipt” in the subject line. We utilized the onboard D7 LED flashing to indicate success of the function call. So far so good.

Process Step 3: Combining the Code Elements

Next, we brought all of the independently working code elements together. This generated a considerable amount of trouble, all associated with conflicts around PWM pins. There was some conflict in controlling PWM on D0, D1, D2, D3 simultaneously, with either D2 or D3 (red LED channel or Servo) not functioning. Ultimately, this was resolved by triggering the Green and Blue channels both from D0 (not independent) and controlling Red from D1 and the servo on A4.

Process Step 4: Calibration and Build Up

Finally, we built up the cloud structure and encased the control board and electronics within. This required mounting the servo at the front of the cloud and arranging the LED throughout the structure to create the necessary glow. Simple foam core and electrical tape were utilized for this purpose. Once built, we had to set the final calibration variables for the servo to align the smile horizontally when in the smile and frown position.

0

Outcome

Our final product, Avery™, notifies the user when they have surpassed their online shopping limit by reading online shopping receipts sent to the user's Gmail. To activate the device, the user would set an arbitrary time limit and several purchase delimiters (i.e., happy = 1 or fewer purchases, warning = 2 purchases, sad = 3 or more purchases).

For example, the user might want to make less than 3 online purchases in a week. If the user makes 1 or fewer online purchases, the cloud smiles, remaining a bright white hue. If the user makes a second purchase, the cloud would continue to smile, but the LEDs would change to a blue-green color. Finally, if the user makes a third purchase that week, the smile turns to a frown and the LEDs turn red. The device would reset after the week was up (smiling / white hue).

In terms of next steps, we'd like to build out the features of the cloud (i.e., the face and the cloud materials) and make it hang-able. We would also like to find a better way to hide the circuitry.

0

Documentation

Below is the final electrical schematic, Particle code, and screen captures from the test Gmail and IFTTT recipe.

0
//Declaring servo control variables and servo motors
int servoPin = A4;
Servo mouthServo;
int servoPos = 10;

//Status Indicator LED
int ledPin7 = D7;

//Variables for count of receipts and time of last receipt
int receiptCount = 0;
int receiptTime = 0;

//Variables for LED control
int redPin = D0;
int bluegreenPin = D1;
int redValue = 255;
int bluegreenValue = 255;

//Threshold values and decrication time variable
int highCount = 3;
int midCount = 2;
int timeLimit = 120000; //86400000 mils per day

void setup()
{
  //Pinmode for indicator LED
  pinMode(ledPin7, OUTPUT);

  //Servo control setup functions and variables, with debugging
  mouthServo.attach(A4);
  //Particle.function("ServoSet", servoControl);
  //Particle.variable("ServoPos", servoPos);

  //Particle functions and variables for interacting with email receipts
  Particle.function("Receipt", receiptReceive);
  Particle.variable("Receipts", receiptCount);

  //Functions and variables for setting the warning and high thresholds
  Particle.variable("highCount", highCount);
  Particle.variable("midCount", midCount);
  Particle.function("SetThres", setThresholds);
  Particle.variable("timeLimit", timeLimit);
  Particle.function("setTime", setTime);

  //RGB Pinmodes, variables, and initializing RGB LED outputs
  //pinMode(redPin, OUTPUT);
  pinMode(redPin, OUTPUT);
  pinMode(bluegreenPin, OUTPUT);

  //Debugging for LED values and controls
  //Particle.function("led", ledControl);
  //Particle.variable("redValue", redValue);
  //Particle.variable("bgValue", bluegreenValue);

  //Write initial values for RGB LEDs
  analogWrite(redPin, redValue);
  analogWrite(bluegreenPin, bluegreenValue);
}
void loop()
{
  checkTime(); //Check if sufficient time has passed to decrease the receiptcount variable
  checkCount(); //Check the receiptcount and set servo and LED values
  delay (100);
}

//Control function for servo
int servoControl(int command)
{
  int newPos = command;
  servoPos = constrain(newPos, 10, 170); //Adjust values for range of servo motion
  mouthServo.write(servoPos);
  return 1;
}

int receiptReceive(String command)
{
  receiptCount = receiptCount + 1;  //Incriment count if function is called by IFTTT
  receiptTime = millis();           //Overwrite receipt time with time of function call
  digitalWrite(ledPin7, HIGH);
  delay(1000);
  digitalWrite(ledPin7, LOW);
  delay(1000);
  return receiptCount;
}

int checkTime()
{
  if (receiptCount >= 1 && receiptTime+timeLimit <= millis()) //If there is a count, and if timeLimit has passed since last receipt or deprication, decrease count and reset time
  {
    receiptCount = receiptCount-1;
    receiptTime = millis();
  }
}

int checkCount()
{
  if (receiptCount >= highCount) //If count is equal to or higher than the highCount, then red and frown
  {
    servoControl(10);
    ledControl("0,255");
  }
  else if (receiptCount <= highCount && receiptCount >= midCount) //If at midCount, then pink and smile
  {
    servoControl(180);
    ledControl("128,255");
  }
  else //otherwise teal and smile
  {
    servoControl(180);
    ledControl("255,0");
  }
}

int ledControl(String command) //Receives two values as string to set LED values
{
  String colors[2];
  colors[0]="";
  colors[1]="";

  int index=0;
  for (int i=0; i<command.length(); i++)
  {
    if(index < 2)
    {
      char c= command.charAt(i);
      colors[index] += c;
      if (c == ',') index++;
    }
  }
  redValue = colors[0].toInt();
  bluegreenValue = colors[1].toInt();

  analogWrite(redPin, redValue);
  analogWrite(bluegreenPin, bluegreenValue);

  return 1;
}

int setThresholds(String command) //function for setting the threshold values. Accepts midCount then highCount
{
  String thresholds[2];
  thresholds[0]="";
  thresholds[1]="";

  int index=0;
  for (int i=0; i<command.length(); i++)
  {
    if(index < 2)
    {
      char c= command.charAt(i);
      thresholds[index] += c;
      if (c == ',') index++;
    }
  }
  midCount = thresholds[0].toInt();
  highCount = thresholds[1].toInt();

  return 1;
}

int setTime(String command) //function for setting the cooldown timing. Value in seconds
{
  timeLimit = command.toInt();
  return 1;
}
Click to Expand
0

Reflection

Development ultimately required segmentation. We did not expect every individual to participate fully in every step of the process. Accordingly, individuals volunteered to code, build the circuit, and create the aesthetic components of the device. These steps did require some coordination, but everyone understood their individual jobs and prepared accordingly.

In terms of the process, we (i) prepared individually, (ii) met as a group to discuss potential solutions and finalize our direction, (iii) met again to ensure individual progress, and (iv) conducted one build session to finish and test the device. Generally, this process—and the abovementioned segmentation—worked well. We were able to troubleshoot and correct any incompatibilities during the final build / test phase. 

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.


About

Our goal was to bring awareness to the relatively intangible quantity of online purchases that modern consumers make. The ambient display brings glanceable feedback to help moderate your excessive purchases.