Introduction: Mood Projector (Hacked Philips Hue Light With GSR) TfCD
By Laura Ahsmann & Maaike Weber
Purpose: Low moods and stress are a big part of the modern fast-paced life. It's also something that's invisible to the outside. What if we were able to both visually and acoustically project our stresslevel with a product, to be able to show how you feel. It would make it easier te communicate about these problems. Your own reaction could also be more adequate to the moment when receiving feedback on your stresslevels.
GSR, or galvanic skin resistance, a measurement taken at the fingertips of a user, is proven to be a really good predictor of stress. Since the sweatglands in the hand mostly react to stress (not only physical excercise), increased stresslevels generate a higher conductance. This variable is used in this project.
Idea: What if we could quickly detect stress or mood and represent it with coloured light and music? A GSR system could make that happen. In this Instructable, we will make an Arduino based system to do that! Operated by both Arduino Software and Processing Software, it will translate skin conductance values into a certain colour light and a certain type of music.
What do you need?
- Arduino Uno
- Wires
- Philips Hue light (Living Colors)
- Three 100 Ohm resistors (for the RGB LED)
- One 100 KOhm resistor (for the GSR sensor)
- Something to act as conductance sensors, like aluminium foil
- Arduino Software
- Processing Software (we used v2.2.1, newer ones tend to crash)
- SolidWorks, to design the housing (optional)
- Access to a CNC mill (optional)
- Green modelling foam (EPS)
Breadboard (optional, could also solder)
Step 1: Take Apart the Hue Light
This step is easy, just use some force (or a screwdriver) let lose and crack open the light. Some snap connections hold the product together, so it's easy to take apart.
Now, the light in the top can be screwed off and disconnected from the rest of the electronics. We will only need the light and the top of the housing. Save or toss the rest, it's up to you!
Step 2: Preparing the Hardware
For this project, we used a Philips Hue light, to make embodiment prettyer and faster. You could however also use a regular RGB LED, as shown in the picture with the breadboard.
To operate the RGB LED, connect the pins to three different PWM ports of the Arduino (indicated ba a ~). Use the 100Ohm resistors for this connection. Connect the longest pin to the 5V output of the Arduino. To see which pin corresponds to which colour, see the last image of this step.
For the Hue Light, the same steps go. The LED is easily connected to the Arduino by soldering wires to the designated slots, see the third picture in this step. The slots have an R, a G and a B, indicating which wire should go where. It also has a + and a - slot, to be connected to the 5V of the Arduino and the ground of the Arduino, respectively. Once you hooked up the LED, you can screw in back into the housing.
To hook up the GSR sensors, made out of aluminium foil (or use those alumium containers of tealights, which look just a bit nicer), solder or tape them to a wire and connect one to the 5V. Connect the other one to the resistor of 100KOhm and a capacitor of 0,1mF (parallel), which should then be connected to the ground and the A1 slot on the Arduino. This will give the output of the stresslevel, which will then be used as the input for the light color and music.
We stuck the sensors to the lamp, so it becomes a nice product to grab while measuring your stress. Be careful however that the sensors are not touching!
The last picture shows how it can be done without a breadboard.
Step 3: Measuring the Stresslevel
Measuring the stresslevel with just these homemade sensors will definitely not give accurate measurements on how stressed you exactly are. However, when calibrated right, it can give an approximation.
To measure the GSR levels, we will use the following piece of code, in the Arduino environment. To have a less fluctuating measurement, an avarage is taken every 10 readings.
const int numReadings = 10;<br> int readings[numReadings]; // input from A1 int index = 0; // the index of the current reading int total = 0; // the running total unsigned long average = 0; // the avg
int inputPin = A1;
void setupGSR() { // set all readings to 0:
for (int i = 0; i < numReadings; i++) readings[i] = 0; }
unsigned long runGSR() { total = total - readings[index]; // read from GSR sensor readings[index] = analogRead(inputPin); // add new reading to total total = total + readings[index]; // next position of array index = index + 1;
// test end of array if (index >= numReadings) // and start over index = 0;
// what is the avg average = total / numReadings; // send it to the computer as ASCII digits return average;
}
In another tab (to keep things organized), we will make the code to react to the measurements, see the next step!
Step 4: Managing the Lights
To manage the lights, we first have to calibrate the measurements. Check what the upperlimit is to your measurements by opening the serial monitor. For us the measurements were something in between the 150 (when we really tried to relax) and the 300 (when we tried really hard to become stressed).
Then, decide what colour should represent what stresslevel. We made it so that:
1. Low stresslevel: white light, changing into green light with increasing stress
2. Medium stresslevel: green light, changing into blue light with increasing stress
3. High stresslevel: blue light, changing into red with increasing stress
The following code was used to process the measurements and turn them into values to send to the LED:
//MASTER <br>#define DEBUG 0
//GSR = A1 int gsrVal = 0; // Variable to store the input from the sensors
// As mentioned, use the Pulse-width Modulation (PWM) pins int redPin = 9; // Red LED, connected to digital pin 9 int grnPin = 9; // Green LED, connected to digital pin 10 int bluPin = 5; // Blue LED, connected to digital pin 11
// Program variables int redVal = 0; // Variables to store the values to send to the pins int grnVal = 0; int bluVal = 0;
unsigned long gsr = 0;
void setup() { pinMode(bluPin, OUTPUT); pinMode(grnPin, OUTPUT); pinMode(redPin, OUTPUT); pinMode(A1, INPUT);
Serial.begin(9600); setupGSR(); }
void loop() { gsrVal=gsr; if (gsrVal < 150) // Lowest third of the gsr range (0-149) { gsr = (gsrVal /10) * 17; // Normalize to 0-255 redVal = gsrVal; // off to full grnVal = gsrVal; // Green from off to full bluVal = gsrVal; // Blue off to full
String SoundA = "A"; Serial.println(SoundA); //for later use in operating music } else if (gsrVal < 250) // Middle third of gsr range (150-249) { gsrVal = ( (gsrVal-250) /10) * 17; // Normalize to 0-255 redVal = 1; // Red off grnVal = gsrVal; // Green from full to off bluVal = 256 - gsrVal; // Blue from off to full String SoundB = "B"; Serial.println(SoundB); } else // Upper third of gsr range (250-300) { gsrVal = ( (gsrVal-301) /10) * 17; // Normalize to 0-255 redVal = gsrVal; // Red from off to full grnVal = 1; // Green off to full bluVal = 256 - gsrVal; // Blue from full to off String SoundC = "C"; Serial.println(SoundC); } <br>
analogWrite(redPin, redVal); // Write values to LED pins<br> analogWrite(grnPin, grnVal); analogWrite(bluPin, bluVal); gsr = runGSR(); delay(100); }
So now the LED is reacting to your stresslevel, let's add some music to represent your mood, in the next step.
Step 5: Managing the Music
We chose to represent the 3 stresslevels with the following music:
1. Low level (A): singing bowls and birds chirping, a very light sound
2. Medium level (B): a melancholic piano, a little more heavy sound
3. High stress level (C): A thunder storm, a dark sound (though quite relaxing)
The code is written in Processing, a software to provide the software feedback part of Arduino:
import processing.serial.*;<br>import ddf.minim.*;
Minim minim; AudioPlayer[] players ;
int lf = 10; // Linefeed in ASCII String myString = null; Serial myPort; // The serial port int sensorValue = 0;
void setup() { // List all the available serial ports printArray(Serial.list()); // Open the port you are using at the same rate as Arduino myPort = new Serial(this, Serial.list()[2], 9600); myPort.clear(); // clear measurements myString = myPort.readStringUntil(lf); myString = null; // we pass this to Minim so that it can load files minim = new Minim(this); players = new AudioPlayer[3]; // Change the name of the audio file here and add it to the libraries players[0] = minim.loadFile("Singing-bowls-and-birds-chirping-sleep-music.mp3"); players[1] = minim.loadFile("Melancholic-piano-music.mp3"); players[2] = minim.loadFile("Storm-sound.mp3"); }
void draw() { // check if there is a new value while (myPort.available () > 0) { // store the data in myString myString = myPort.readString(); // check if we really have something if (myString != null) { myString = myString.trim(); // check if there is something if (myString.length() > 0) { println(myString); try { sensorValue = Integer.parseInt(myString); } catch(Exception e) { } if (myString.equals("A")) //see what stresslevel it's measuring { players[0].play(); //play according music } else { players[0].pause(); //if it's not measuring low stress level, don't play the according song } if (myString.equals("B")) { players[1].play(); } else { players[1].pause(); } if (myString.equals("C")) { players[2].play(); } else { players[2].pause(); } } } } }
This code should play the music according to the stresslevel on our laptop speakers.
Step 6: Design the Embodiment
We used the upperpart of the Philips Hue Light, but cnc'd a greenfoam bottom. The SolidWorksfile is here, but it could also be fun to measure the lamp yourself and design someting to your taste!
We used a photo of the top of the lamp as an underlayer in SW, to make sure the shape of the bottom follows the curve of the top (see first photo).
To have the model cnc'd, save it as an STL file and find your local miller (at uni for instance).
Step 7: Sources
If you'd like more information on this topic, or see more extensive codes for measuring stress, see the following websites and projects: