49-713 Designing for the Internet of Things
· 26 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Music & Lights makes you Never miss your loved one emotion on twitter!
Tweet melody is an ambient device that let's the user know about how their close ones are feeling based on their twitter feed. Tweet Melody maps the user's emotion via hashtags on twitter such as #glad, #sad and #mad. These emotion filled tweets are represented as a melody as well as an array of lights which have the emotions color coded as: sad - blue, glad - yellow and mad - red.
From the beginning, the team knew they wanted to work with gauging and translating emotion in some way. The team brainstormed ideas in the space and found that the most compelling way to translate these emotions would be through light. The team initially also wanted to create a caricature of each team member for each board in order to be able to put them all side by side and have them each represent each member tweeting. The second part of this idea was not continued with as it was too obvious and alternates were brainstormed.
The team first spent their time configuring the Neo-Pixel to flash the desired color. Initially the team worked on just making the entire ring light up as the desired color. From there, the team learned how to to code the Neo-Pixel to flash each color five times when that piece of the function was called upon.
After the Neo-Pixel was configured the team worked on integrating the Particle with Twitter feed by using IFTTT. The code for Neo-Pixels was broken up into functions that represented three emotions: sad, glad and mad. These functions were then made available online by using the code Spark.function(). The functions were called using IFTTT where the Particle would listen for an event (tweet) which involved one of the following hashtags: #sad, #mad or #glad. Based on the respective hashtag the appropriate function was called.
Additionally, the team worked to make the system alert the user if their loved one had tweeted multiple times in a row with the same hashtag - indicating extreme happiness/distress/anger. Below you can see the response one tweet is sent and when two tweets are sent, respectively.
Different motors and the Piezo speaker were explored as possible ambient ways to map physical and audio cues to emotions.
The team worked with a Solenoid and a transistor to play around with the stroke frequency of the solenoid shaft. The team decided to map different frequencies for each emotion. It was decided to drop the use of Solenoid as the emotions are not coherently conveyed to the user of ambient device.
Servo
The team then decided to adopt the servo to map the different emotions, but then realized that a tune or music would more coherently convey the appropriate emotion.
A Piezo was chosen as the output device along with the Neo-pixel since tunes best convey emotion. The following tunes were used to map the emotions for the prototype.
In a real life ambient device, more subtle audio would have been chosen for each emotion tune.
//FINAL CODE
//pulls neopixel and math libraries
#include "neopixel.h"
#include <math.h>
// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D0
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812
//configures neopixel
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
int pixel_position = 0;
int blinkNum = 5; //begins number of blinks at 5 for all emotions first tweet
int blinkSpeed = 5; //sets speed of blinks
int countS = 0; //counter for how many sad tweets have been sent in a row
int countM = 0; //counter for how many mad tweets have been sent in a row
int countG = 0; //counter for how many sad tweets have been sent in a row
int speaker = D1;
int melodyS[] = {1568,0,1976, 0, 2794,0,2794,0,2794,2637, 2349, 2093};
int melodyM[] = {2637,2637,2637,2093,0,2349,2349,2349,1976};
int melodyG[] = {1568,2093,2349,2637,2637,0, 2637,2349,2637, 2093, 2093,0,2093,2349,2637, 2794, 3520,0, 3520, 3136,2794,2637};
int noteDurationsS[] = {4,8,8,8,8,16,8,16,8,8,8,4 };
int noteDurationsM[] = {8,8,8,2,8,8,8,8,2};
int noteDurationsG[] = {8,8,8,4,4,8,8,8,8,4,4,8,8,8,8,4,4,8,8,8,8,4 };
void setup() {
Serial.begin(9600);
strip.begin();
strip.show(); //Initialize all pixels to 'off'
Spark.function("sad", sadtweet); //if #sad is tweeted, run this
Spark.function("mad", madtweet); //if #mad is tweeted, run this
Spark.function("glad", gladtweet); //if #glad is tweeted, run this
pinMode(speaker, OUTPUT);
}
int sadtweet(String cmd) {
countS++; //increase sad count
countG = 0; //returns other functions to 0
countM = 0; //returns other functions to 0
int blinkNumS = blinkNum*countS; //sets number of blinks for sad to correlate to the number of sad tweets were send in a row
for (int thisNote = 0; thisNote < 12; thisNote++) {
int noteDuration = 1000/noteDurationsS[thisNote];
tone(speaker, melodyS[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(speaker);
}
//runs the program twice as many times as we want the light to blink (one for on, one for off)
for(int j = 0; j < blinkNumS*2; j++){
//lights on for even numbers
if(j % 2 == 0) {
for(int i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 0, 0, 255);
strip.show();
}
delay(1000/blinkSpeed);
}
//lights off for odd numbers
else {
for(int i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 0, 0, 0);
strip.show();
}
delay(1000/blinkSpeed);
}
}
}
int madtweet(String cmd) {
countM++; //increase mad count
countG = 0; //returns other functions to 0
countS = 0; //returns other functions to 0
int blinkNumM = blinkNum*countM;
for (int thisNote = 0; thisNote < 9; thisNote++) {
int noteDuration = 1000/noteDurationsM[thisNote];
tone(speaker, melodyM[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(speaker);
}
for(int j = 0; j < blinkNumM*2; j++){
if(j % 2 == 0) {
for(int i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 255, 0, 0);
strip.show();
}
delay(1000/blinkSpeed);
}
else {
for(int i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 0, 0, 0);
strip.show();
}
delay(1000/blinkSpeed);
}
}
}
int gladtweet(String cmd){
countG++; //increase glad count
countG = 0; //returns other functions to 0
countS = 0; //returns other functions to 0
int blinkNumG = blinkNum*countG;
for (int thisNote = 0; thisNote < 22; thisNote++) {
int noteDuration = 1000/noteDurationsG[thisNote];
tone(speaker, melodyG[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(speaker);
}
for(int j = 0; j < blinkNum*2; j++){
if(j % 2 == 0) {
for(int i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 255, 215, 0);
strip.show();
}
delay(1000/blinkSpeed);
}
else {
for(int i = 0; i < strip.numPixels(); i++){
strip.setPixelColor(i, 0, 0, 0);
strip.show();
}
delay(1000/blinkSpeed);
}
}
}
Click to Expand
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Music & Lights makes you Never miss your loved one emotion on twitter!
February 5th, 2017