Rise and Shine reflects the mood of the user based on previous day's input and wakes him or her up while motivaing them. It uses color and sound to enable the user to awake and to reflect on the emotions and stress that they have been subject to.

0

Overview

This device enables the user to wake up and reflect on the emotions and stress from yesterday, and encourages him or her to take time in the morning to notice how this makes them feel.

0
Inspiration & Reference
Picture2
0

Concept Description

 This alarm clock device utilizes light and sound to output data received from 'Mood Mobile' and 'Off-Your-Mind Jar'. It receives 1 of 3 emotions from 'Mood Mobile' and outputs color via LED to reflect emotions. It receives 1 of 2 stress levels from the 'Off-Your-Mind Jar' and outputs sounds via speaker to reflect stress level through different types of music. 

Challenges:

  • Concept Iterations: Disco Ball vs. Net
    As you can see in the sketch below, this device began as a disco-ball shaped device. We iterated and updated our design, inspired by mosquito nets surrounding a bed. We felt that this netting would serve to represent mood very well, and the user must physically 'exit' the mood they are in (the netting) in order to interact with the mobile and change their mood. 
0
Initial Sketching
Emoclock
0

Bill of Materials

0
Item #Description
1LED Individual Lights
2Speaker
3String/Wire
6Wires
7Resistors
8Particle Photon
9Power Source
10Audio Amplifier
11Audio Cable
12MP3 Module
0

Storyboard


0

Process

We started our design process around a disco ball idea. The initial idea was to design a disco ball-like device hanging from the ceiling reflecting user's mood based on previous day's information, which would come from Mood Mobile and Off-Your-Mind Jar. Our idea evolved into a hanging device, composed of fabric and Mood Mobile components, above the bed in order to enable user to interact just after he/she wakes up in the morning.  

Below are some photographs as our design process progressed.

0

Fabrics: Our first decision was between different types of fabrics for the netting. The first of these two fabrics was more net-like and possibly more sturdy. The second material was more fluid and was found to diffuse LED lights better from within. We chose to prototype with the second material. 

0

Fritzing Diagram

0

LEDs: Our initial vision for this prototype included individual LEDs, spread throughout the netting. This strategy, we hoped, would create an etherial effect, with the netting glowing in a lovely way above the bed that it hangs over. 

We struggled with these LEDs, which were difficult to wire, solder, and attach to the netting. In this process, they lost their seamless and ethereal nature that we were shooting for. We made a decision to switch the single LEDs out for the LED strips. 

0
Attaching LED lights to the fabric
Img 3925
0
Fabric with LED lights attached and metal holder on the top
Img 3924
0
/*
 * Project: EmoClock
 * Revision: B
 * Description: IoT Spring 2018 Final Project
 * Author: Corey Williams
 * Team: Home-wreckers
 * Date: 2/28/2018
 */

//Add libraries.
#include <neopixel.h>
#include "application.h"
#include "neopixel/neopixel.h"
#include "DFRobotDFPlayerMini.h"

//Define variables.
#define PIXEL_COUNT 7
#define PIXEL_PIN D6
#define PIXEL_PIN_B D5
#define PIXEL_TYPE WS2811

//Assign global variables.
long lastPublishedAt = 0; // This value will store the last time we published an event.
int publishAfter = 10000; // This is the time delay before we should publish a new event.

int mobileState = 0;
int mindCount = 0;
bool pressed = FALSE;

Adafruit_NeoPixel pixelsA = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE); //Initiate first neopixel strand.
Adafruit_NeoPixel pixelsB = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN_B, PIXEL_TYPE); //Initiate first neopixel strand.

DFRobotDFPlayerMini myDFPlayer; //Initiate .mp3 player.

 //Assign pins.
int buttonPin = D4;

//For testing purposes.
int testPinA = D3;
int testPinB = D2;
int testPinC = D1;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  //Assign inputs.
  pinMode(buttonPin, INPUT_PULLUP);

  //Assign outputs.
  //Initiates the NeoPixel connection.
  pixelsA.begin();
  pixelsB.begin();
  for(int i=0; i < PIXEL_COUNT; i++)
  {
    pixelsA.setPixelColor(i, 0,0,0);
    pixelsA.show();
    pixelsB.setPixelColor(i, 0,0,0);
    pixelsB.show();
  }
  //Initiates the DFPlayer.
  if (!myDFPlayer.begin(Serial1))
  {  //Use Serial1 to communicate with player.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true){
      delay(0);
    }
  }
  Serial.println("DFPlayer Initialized");
  myDFPlayer.volume(30);

  //Subscribe to particle events.
  Particle.subscribe("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEA", handleMobileA); //Subscribe to event that is published by mood mobile A.
  Particle.subscribe("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEB", handleMobileB); //Subscribe to event that is published by mood mobile B.
  Particle.subscribe("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEC", handleMobileC); //Subscribe to event that is published by mood mobile C.
  Particle.subscribe("DIOT-2018-DARA-TEAM-HOME-WRECKERS-PLAY", handlePlay); //Subscribe to event that is published by mood mobile for music playing.
  Particle.subscribe("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MIND", handleMind); //Subscribe to event that is published by mind jar.

  //For testing.
  pinMode(testPinA, INPUT_PULLUP);
  pinMode(testPinB, INPUT_PULLUP);
  pinMode(testPinC, INPUT_PULLUP);

  Particle.function("Sun", publishA);
  Particle.function("Bolt", publishB);
  Particle.function("Cloud", publishC);
  Particle.function("Jar", publishJar);
}

void loop()
{
  int buttonState = digitalRead (buttonPin); //See if button is pushed or not.
  int testStateA = digitalRead (testPinA); //For testing purposes.
  int testStateB = digitalRead (testPinB); //For testing purposes.
  int testStateC = digitalRead (testPinC); //For testing purposes.

  if (buttonState == LOW && pressed == FALSE) //If button is pressed...
  {
    pressed = TRUE;
    publishMyEvent(); //Publish reset event.
  }

  if (buttonState == HIGH) //If button is not pressed...
  {
    pressed = FALSE;
  }

  //For testing purposes.
  if (testStateA == LOW)
  {
    publishTestA();
  }

  if (testStateB == LOW)
  {
    publishTestB();
  }

  if (testStateC == LOW)
  {
    publishTestC();
  }
}

void publishMyEvent() //When button is pushed, publish an event to reset the inputs.
{
  if(lastPublishedAt + publishAfter < millis())
  {
    Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-RESET");
    lastPublishedAt = millis();
    Serial.println(mindCount);
    //Determine music output based on jar inputs.
    if (mindCount <= 2)
    {
      myDFPlayer.play(1);
    }
    if (mindCount > 2)
    {
      myDFPlayer.play(2);
    }
    //Determine light output based on mobile inputs.
    if (mobileState == 3) //If cloud (sad) mobile was hit last.
    {
      for(int i=0; i < PIXEL_COUNT; i++) //Light up neopixel based on Mood Mobile inputs.
      {
        pixelsA.setPixelColor(i, 30,29,236); //Blue.
        pixelsA.show();
        pixelsB.setPixelColor(i, 30,29,236); //Blue.
        pixelsB.show();
      }
      for(int z=0; z < 5; z++) //Add breathing effect.
      {
        for (int j=1; j<200; j++)
        {
          pixelsA.setBrightness(j);
          pixelsA.show();
          pixelsB.setBrightness(j);
          pixelsB.show();
          delay(15);
        }
        for (int j=200; j>1; j--)
        {
          pixelsA.setBrightness(j);
          pixelsA.show();
          pixelsB.setBrightness(j);
          pixelsB.show();
          delay(15);
        }
      }

      pixelsA.setBrightness(200);
      pixelsA.show();
      pixelsB.setBrightness(200);
      pixelsB.show();
    }

    if (mobileState == 2) //If bolt mobile (angry) was hit last.
    {
      for (int b=0; b < 10; b++) //Blinking effect.
      {
        for(int i=0; i < PIXEL_COUNT; i++) //Light up neopixel based on Mood Mobile inputs.
        {
          pixelsA.setPixelColor(i, 35,236,29); //Red on
          pixelsA.show();
          pixelsB.setPixelColor(i, 35,236,29); //Red on
          pixelsB.show();
        }
        delay(500);
        for(int i=0; i < PIXEL_COUNT; i++) //Light up neopixel based on Mood Mobile inputs.
        {
          pixelsA.setPixelColor(i, 0,0,0); //Off
          pixelsA.show();
          pixelsB.setPixelColor(i, 0,0,0); //Off
          pixelsB.show();
        }

        delay(500);
      }

      for(int i=0; i < PIXEL_COUNT; i++) //Light up neopixel based on Mood Mobile inputs.
      {
        pixelsA.setPixelColor(i, 35,236,29); //Red
        pixelsA.show();
        pixelsB.setPixelColor(i, 35,236,29); //Red
        pixelsB.show();
      }
    }

    if (mobileState == 1) //If mood moblie (happy) was hit last.
    {
      for(int i=0; i < PIXEL_COUNT; i++) //Light up neopixel based on Mood Mobile inputs
      {
        pixelsA.setPixelColor(i, 245,237,48); //Yellow
        pixelsA.show();
        pixelsB.setPixelColor(i, 245,237,48); //Yellow
        pixelsB.show();
      }

      delay(10000);
    }

    delay(10000);

    for(int i=0; i < PIXEL_COUNT; i++) //Turn off neopixels.
    {
      pixelsA.setPixelColor(i, 0,0,0);
      pixelsA.show();
      pixelsB.setPixelColor(i, 0,0,0);
      pixelsB.show();
    }

    mindCount = 0;//Reset jar count.
    myDFPlayer.pause();//Turn off music.
  }
}

//Create functions update input data from Mood Mobiles and Mind Jar.
void handleMobileA(const char *event, const char *data)
{
    mobileState = 1;
}

void handleMobileB(const char *event, const char *data)
{
    mobileState = 2;
}

void handleMobileC(const char *event, const char *data)
{
    mobileState = 3;
}

void handlePlay(const char *event, const char *data)
{
  if (String(data) == "MA")
  {
    myDFPlayer.play(5);
    delay(10000);
    myDFPlayer.pause();
  }

  if (String(data) == "MB")
  {
    myDFPlayer.play(4);
    delay(10000);
    myDFPlayer.pause();
  }

  if (String(data) == "MC")
  {
    myDFPlayer.play(6);
    delay(10000);
    myDFPlayer.pause();
  }
}

void handleMind(const char *event, const char *data)
{
    mindCount++;
    myDFPlayer.play(6);
    delay(10000);
    myDFPlayer.pause();
}

void publishTestA()
{
  if(lastPublishedAt + publishAfter < millis())
  {
      Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEA", "6");
      Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MIND", "1");
      lastPublishedAt = millis();
  }
}

void publishTestB()
{
  if(lastPublishedAt + publishAfter < millis())
  {
      Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEB", "6");
      Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MIND", "6");
      lastPublishedAt = millis();
  }
}

void publishTestC()
{
  if(lastPublishedAt + publishAfter < millis())
  {
      Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEC", "6");
      lastPublishedAt = millis();
  }
}

int publishA(String command)
{
  Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEA");
  Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-PLAY", "MA");
  lastPublishedAt = millis();
  return 1;
}

int publishB(String command)
{
  Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEB");
  Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-PLAY", "MB");
  lastPublishedAt = millis();
  return 1;
}

int publishC(String command)
{
  Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-MOBILE-MOBILEC");
  Particle.publish("DIOT-2018-DARA-TEAM-HOME-WRECKERS-PLAY", "MC");
  lastPublishedAt = millis();
  return 1;
}

int publishJar(String command)
{
  mindCount = atoi(command);
  myDFPlayer.play(3);
  delay(8000);
  myDFPlayer.pause();
  return mindCount;
}
Click to Expand
0

Reflection

Overall, we felt that this concept (despite it's occasional frustrations with creation and linking to the other devices) was a successful component of the larger IoT Product System, R.E.M. It serves its purpose as a reflection of mood and stress level in connection with the other two devices. 

We feel that, with further iterations, we can improve the connectivity between devices, the LED placement on the fabric, and the connection between this device and the Mood Mobile hanging in the same physical space. 

x
Share this Project

Courses

49713 Designing for the Internet of Things

· 25 members

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


About

Rise and Shine reflects the mood of the user based on previous day's input and wakes him or her up while motivaing them. It uses color and sound to enable the user to awake and to reflect on the emotions and stress that they have been subject to.

Created

March 7th, 2018