My concept of Energy Saving Emily focuses around monitoring light usage within the home. In particular, the device is to be placed within a room within the house and will monitor and measure the light exposure outside and recognise the lights that are on in the house. This version of Emily is designed to be placed within an adult household, based on research identifying a vast number of adults being less aware of their energy consumption and its impact on the environment. Additionally, Emily is targeted towards adult households due to the level of discomfort that Emily provides through having control over the lights (which may not be appropriate for younger aged children).
Energy Saving Emily is a device that places the user in annoying and uncomfortable situations in order to encourage the user to make an effort to improve their energy efficiency around the home. Emily does this through recognising the exposure of light outside and comparing it to the amount of light that is present inside. If Emily recognises a moderate or large amount of sunlight outside while lights are being used unnecessarily inside, she will alert the user through flashing lights and alarming beeps in order to induce discomfort to the user to notify them turn off unnecessary lights. If the user decides not to respond to Emily's alerts after a period of time, Emily will turn off some, if not all the lights within the room on her own accord and will restrict access the users ability to turn them back on for a period of time, inducing further discomfort in the user. For the full breakdown of the states of Emily shown below, please refer to the Interaction Plan outlined HERE (pages 4-5).
1. Minimal Sunlight State
2. Moderate Sunlight State
3. Maximum Sunlight State
4. Optimal Efficiency State
5. Moderate Efficiency State
6. Successful Progress State
For purposes of displaying the functionality of Emily, the following prompts
were simulated:
- SUNLIGHT: Varying light levels were simulated by a torch to represent sunlight exposure.
- HOUSE LIGHTS: External lights were connected to represent lighting within a room, as it
was not within my scope to connect the device directly to house lighting.
The final concept that I created does differ from the ideal concept that I had proposed,
as my final product places focus on just one element of energy, being lighting.
However, by being able to focus on one aspect of energy saving, it meant that I was
able to explore more regarding user interaction and discomforting techniques. Additionally,
elements of personality were somewhat lacking in the final output, but I think the use of varying
frequencies of sound is suitable as a method to give Emily that personality.
Overall, I believe the final concept of Energy Saving Emily
captures the essence of 'Change Through Discomfort' and incorporates all the
main elements that I intended to implement, such as creating discomfort to the user
through annoying sounds, flashing lights and restriction of light usuage, as well as
allowing for user interaction and influencing the user to make improvements in
their behaviour. Although user interaction was implemented, I feel as though the
interaction with Emily is not exactly novel or exciting, so if I were to build it again
I would explore more exciting ways for the user to interact with her.
In addition, I would have loved to develop Emily's personality further for the user
to play around with so that Emily is more tolerable and interactive, and perhaps explore
a more futuristic form to encapsulate Emily.
Despite the differences, Emily has truly been both a challenge and a joy to create as
well as reflect back on the development of her growth. I'm very proud of what I've created
as well as how far I've come regarding my confidence in physical and code building, but am
definitely relieved for this chapter to finally come to an end.
const int sensorPin = A0;
const float baseLightLevel = 130.0; //imitates no sunlight
int SwitchState = 0;
int counter = 0;
int greencounter = 0;
int frequency = 0;
int duration = 0;
int randNumber = 0;
#include <Adafruit_NeoPixel.h>
int LEDPIN = 8;
int NUMPIXELS = 8;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
int delayval = 100;
void setup() {
strip.begin(); // Initialises pixel library
strip.show(); // Initialises all pixels to 'off'
pinMode(12, INPUT);
Serial.begin(9600); // Open a serial port
for(int pinNumber = 2; pinNumber<7; pinNumber++){
pinMode(pinNumber,OUTPUT);
digitalWrite(pinNumber, LOW);
}
}
void loop() {
int sensorVal = analogRead(sensorPin);
float light = sensorVal;
SwitchState = digitalRead(12);
uint32_t red = strip.Color(150, 0, 0); // Define red colour
uint32_t yellow = strip.Color(150, 150, 0); // Define yellow colour
uint32_t green = strip.Color(0, 150, 0); // Define green colour
uint32_t blue = strip.Color(0, 0, 150); // Define blue colour
uint32_t orange = strip.Color(255, 69, 0); // Define orange colour
//BLUE LIGHT - both lights on, no sunlight
if(light < baseLightLevel && SwitchState == LOW && SwitchState == LOW && greencounter < 3){
digitalWrite(2, LOW); // Light is on
digitalWrite(3, LOW); // Light is on
for(int a=0; a<2; a++) { // Repeat 4 times...
for(int b=0; b<2; b++) { // 'b' counts from 0 to 1...
strip.clear(); // Set all pixels in RAM to 0 (off)
for(int c=b; c<strip.numPixels(); c += 2) { // 'c' counts up from 'b' to end of strip in steps of 2...
strip.setPixelColor(c, blue); // Set pixel 'c' to value 'color'
}
strip.show(); // Update strip with new contents
delay(1000); // Adjusts delay of flashing LEDs
}
}
}
//YELLOW LIGHT - one light turns off, some sunlight , Switch is not pushed and counting.
else if(light > baseLightLevel+20 && light <= baseLightLevel+470 && SwitchState == LOW && counter <10 && greencounter < 3){
Serial.println(counter);
digitalWrite(2, LOW); // Light is on
digitalWrite(3, LOW); // Light is on
frequency = 500;
duration = 50;
for(int a=0; a<2; a++) { // Repeat 4 times...
for(int b=0; b<3; b++) { // 'b' counts from 0 to 1...
strip.clear(); // Set all pixels in RAM to 0 (off)
for(int c=b; c<strip.numPixels(); c += 4) { // 'c' counts up from 'b' to end of strip in steps of 2...
strip.setPixelColor(c, yellow); // Set pixel 'c' to value 'color'
}
strip.show(); // Update strip with new contents
{
delay(700); // Adjusts delay of flashing LEDs
}
}
tone(10, frequency, duration);
frequency = frequency+100;
duration = duration+50;
}
counter=counter+1; //increase the counter by 1
}
//RED LIGHT - all lights off, lots of sunlight switch is not pushed and counting
else if(light > baseLightLevel+470 && SwitchState == LOW && SwitchState == LOW && counter <10 && greencounter < 3){
Serial.println(counter);
digitalWrite(2, LOW); // Light is on
digitalWrite(3, LOW); // Light is on
for(int a=0; a<10; a++) { // Repeat 10 times...
for(int b=0; b<2; b++) { // 'b' counts from 0 to 1...
strip.clear(); // Set all pixels in RAM to 0 (off)
for(int c=b; c<strip.numPixels(); c += 2) { // 'c' counts up from 'b' to end of strip in steps of 2...
strip.setPixelColor(c, red); // Set pixel 'c' to value 'color'
}
strip.show(); // Update strip with new contents
{ // Alarm sounds
delay(180); // Adjusts delay of flashing LEDs
}
}
randNumber = random(1,20);
tone(10, frequency, duration);
frequency = randNumber*200;
duration = randNumber*50;
}
counter=counter+1; //increase the counter by 1
}
//ORANGE LIGHT - counter reached - One light turns off
else if(light > baseLightLevel+20 && light <= baseLightLevel+470 && SwitchState == LOW && counter >=10 && greencounter < 3) {
digitalWrite(2, LOW); //Light is on
digitalWrite(3, HIGH); //Light is off
strip.clear();
for(int a=0; a<4; a++) { // Repeat 4 times...
for(int b=0; b<3; b++) { // 'b' counts from 0 to 1...
strip.clear(); // Set all pixels in RAM to 0 (off)
for(int c=b; c<strip.numPixels(); c += 4) { // 'c' counts up from 'b' to end of strip in steps of 2...
strip.setPixelColor(c, orange); // Set pixel 'c' to value 'color'
}
strip.show(); // Update strip with new contents
delay(500); // Adjusts delay of flashing LEDs
}
}
counter=0;
delay(3000);
}
//GREEN LIGHT - Counter reached - Both lights turn off
else if(light > baseLightLevel+470 && SwitchState == LOW && counter >=10) {
digitalWrite(2, HIGH); //Light is off
digitalWrite(3, HIGH); //Light is off
strip.clear();
for(int c=1; c<strip.numPixels(); c += 1) { // 'c' counts up from 'b' to end of strip in steps of 1...
strip.setPixelColor(c,green);
strip.show();
counter=0;
delay(3000);
}
}
//ANY LIGHT - Switch pushed - Both lights turn off
else if(SwitchState == HIGH) {
digitalWrite(2, HIGH); //Light is off
digitalWrite(3, HIGH); //Light is off
strip.clear();
greencounter = greencounter+1;
for(int c=1; c<strip.numPixels(); c += 1) { // 'c' counts up from 'b' to end of strip in steps of 1...
strip.setPixelColor(c,green);
strip.show();
counter=0;
delay(3000);
}
}
else if(greencounter >= 3){
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
strip.clear();
frequency = 500;
duration = 100;
int firstPixelHue = 0; // First pixel starts at red (hue 0)
for(int a=0; a<15; a++) { // Repeat 30 times...
for(int b=0; b<3; b++) { // 'b' counts from 0 to 2...
strip.clear(); // Set all pixels in RAM to 0 (off)
// 'c' counts up from 'b' to end of strip in increments of 3...
for(int c=b; c<strip.numPixels(); c += 3) {
// hue of pixel 'c' is offset by an amount to make one full
// revolution of the color wheel (range 65536) along the length
// of the strip (strip.numPixels() steps):
int hue = firstPixelHue + c * 65536L / strip.numPixels();
uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
}
strip.show(); // Update strip with new contents
delay(100); // Pause for a moment
firstPixelHue += 65536 / 50; // One cycle of color wheel over 90 frames
greencounter = 0;
}
tone(10, frequency, duration);
frequency = frequency+20;
duration = duration+50;
}
}
}