The Lonely Lamp
Made by Dillon Shu
Made by Dillon Shu
What would it feel like to use tech that cares more about what it needs more that it cares about what you need? Well, the Lonely Lamp needs your companionship to work. Spend more time with it and it shines brighter, but leave it alone for too long and it might start misbehaving!
Created: February 17th, 2023
I wanted to capture the idea of how our relationship with technology is based on functionality. It feels pointless to have a lamp that doesn’t work when you need it to, all because it feels lonely. My goal was to make something that can still be useful, but only on its own terms, so the lamp will still work, especially if you spend time around it. I also wanted to add a level of free-will and unpredictability to it - a very human characteristic is emotion, and sometimes people will get angry for no reason.
Addicted Products by Simon Rebaudengo
Link - http://www.simonerebaudengo.com/project/addictedproducts
I was inspired by the idea that the toasters needed to be kept happy by being used. I wanted to capture the same idea where the technology we are using has its own needs that need to be met that is more important than your needs.
I wanted to capture the spirit of animism in my project. The lamp has its own desires, and also “feels”. I also wanted it to be unpredictable - people get angry for no reason too. I really wanted to imbue as many “human” characteristics into the lamp as I could.
I also initially started with the AIBO (https://us.aibo.com) in mind, which is where the friendship aspect came from. I wanted to explore where people draw the line for friendship and treating things as "alive". If we program it to have feelings, does that change how we treat it?
Bill of materials -
1x breadboard
1x lamp
1x Arduino
1x LED strip (cut down into smaller strips later)
3x male to male wires
Wire
Hot Glue
Libraries used - Adafruit Neopixel by Adafruit and APDS9960 by Arduino
My first prototype had me cut the LED strip so that I only had 10 LEDs, but afterwards I decided to separate the indicator LEDs and lighting LEDs. I had to solder the two strips together, and did so like the picture below.
Final Product (Demo)-
The lamp gets dimmer (until the lights are off) or brighter depending on if you are in proximity or not. The happiness decrease speed has been sped up in the demo.
There mood is indicated on a scale of 3 LEDs, with 3 green being the best happiness and 3 red being the worst.
When the lamp is "angry", it will either turn off for a few seconds as it did in the demo, or flash red.
Product Flow -
My process was extremely messed up because the Arduino and my computer(s) simply did not want to cooperate. As a result, there were very few iterations. I didn’t have a first project log since I missed the class where everything was assigned. The time covered in my second and third project logs were both mostly just me trying to figure why the Arduino wouldn’t work. In essence everything was done during and after the fourth log, which was not ideal.
My design process was mainly brainstorming how to imbue human characteristics on the lamp using the features of the proximity sensor and LED strip that I explored. For example, the pulsing red lights was something I had done while just exploring the technology, and I thought it would be a good way for the lamp to convey anger/frustration.
I had to simplify the “lamp that wants to be your friend” that I was going for initially, but I think that it’s very doable to add more complexity to the lamp’s happiness to make it more “human”. The proximity sensor on the Arduino is a bit too limited in range, so a proximity sensor with more range would work better. I also think that having other sensors, like something sound related, can also help capture the experience better. For example, talking to the lamp would increase happiness.
I’m still unsure about the place that animistic technology has in our society. It was weird for me to try to not focus on the functionality of something I was trying to make, and to actively try to sabotage its usefulness.
I’m happy with what I got done under the circumstances; I definitely didn’t meet my ambitions but given how frustrating the entire project was, having created a functional final product that captures the essence of animism I was going for is a success, even if it’s quite rough around the edges.
That said, I definitely didn’t have the time to do a great job; the first few project logs being most spent troubleshooting wasn’t very productive. Going forward, I’ll be borrowing from lending or going to a computer lab at school, which, while inconvenient, is still more convenient than what I went through during this project.
I also didn’t really think about the appearance of my lamp that much as opposed to the functionality. I didn’t get to see too many other projects since I missed the demo session, but I saw what some of my peers had created that added added life to their object using visuals, and I should keep that in mind in the future.
Using Sample Code from:
Code:
//By: Dillon Shu
#include <Arduino_APDS9960.h>
#include <Adafruit_NeoPixel.h>
#define PIXEL_PIN D2
#define PIXEL_COUNT 13
#define PIXEL_TYPE NEO_GRB + NEO_KHZ800
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
void setup() {
while (!Serial);
if (!APDS.begin()) {
Serial.println("Error initializing APDS-9960 sensor!");
}
strip.begin();
strip.show(); // Initialize all pixels to 'off'
APDS.setGestureSensitivity(90);
}
//color palette
uint32_t green = strip.Color(0, 255, 0);
uint32_t light_green = strip.Color(0, 127, 0);
uint32_t light_red = strip.Color(127, 0, 0);
uint32_t red = strip.Color(255, 0, 0);
uint32_t off = strip.Color(0, 0, 0);
float happiness = 0.85; //happiness multiplier that determines brightness of light source
//led setting variables w/ default values
uint32_t led_color = strip.Color(255, 255, 255); //light source led color
uint32_t friendship_indicator_color = strip.Color(255, 255, 255);//indicator led color
int num_indicator_leds = 3;
int friendship_indicator_led = PIXEL_COUNT - num_indicator_leds;//first indicator led position
int lit_indicator_leds = 3;
//unpredictability meter
float disruptive = 0.01;//0 = not angry, 1 = angry. multiplier, used as (1-disruptive)
int max_predictability = 500;//real_predictability = disruptive_multiplier * predictability, used to randomly make the lamp do things
//variable conformity
float happiness_upper_req = 0.75; // value > upper == very happy
float happiness_lower_req = 0.25; // upper > value > lower == happy, lower > value == angry
int proximity_bound = 250; // above value == happiness + 0.01, below equal == happiness - 0.01
bool on = false;
int brightness = 0; //not in use
void configureLEDs()//sets led variables for indicator and lighting
{
random_disruptive();
if((happiness <= 0.99) && (happiness >= 0.79))
{
lit_indicator_leds = 3;
friendship_indicator_color = green;
more_angry(false);
}
else if ((happiness < 0.79) && (happiness >= 0.59))
{
lit_indicator_leds = 2;
friendship_indicator_color = green;
more_angry(false);
}
else if((happiness < 0.59) && (happiness >= 0.39))
{
lit_indicator_leds = 1;
friendship_indicator_color = green;
more_angry(false);
}
else if((happiness < 0.39) && (happiness >= 0.25))
{
lit_indicator_leds = 1;
friendship_indicator_color = red;
if (happiness)
more_angry(true);
}
else if((happiness < 0.25) && (happiness >= 0.10))
{
lit_indicator_leds = 2;
friendship_indicator_color = red;
more_angry(true);
}
else if((happiness < 0.10) && (happiness >= 0.01))
{
lit_indicator_leds = 3;
friendship_indicator_color = red;
more_angry(true);
}
int color = 255 * happiness;
led_color = strip.Color(color, color, color);
Serial.print("Color - ");
Serial.println(color);
}
void set_indicator_leds()//set indicator leds
{
int num_to_light = num_indicator_leds - lit_indicator_leds;
for(int i=friendship_indicator_led; i < strip.numPixels() - num_to_light; i++) {
strip.setPixelColor(i, friendship_indicator_color);
}
}
void pulse_red(int start, int amount, int iterations)
{
int pulse = start;
uint32_t led_config = led_color;
for(int i = 1; i <= iterations; i++)
{
led_color = strip.Color(pulse, 0, 0);
for(int i=0; i < strip.numPixels() - num_indicator_leds; i++) {
strip.setPixelColor(i, led_color);
}
strip.show();
wait(50);
pulse = pulse + amount;
}
set_indicator_leds();
led_color = led_config;
}
void angry_red_lights()//pulsing red lights for 10 seconds
{
for(int i = 0; i < 10; i++)
{
pulse_red(55, 40, 5);
pulse_red(255, -40, 5);
}
strip.clear();
}
void animism()//have the lamp act unpredictably
{
int predictability_value = max_predictability - max_predictability * disruptive;
int rand = random(max_predictability);
/*
Serial.print("Random Predictability Value - ");
Serial.println(rand);
Serial.print("Predictability Value - ");
Serial.println(predictability_value);
*/
Serial.print("disruptive Multiplier - ");
Serial.println(disruptive);
if (rand > predictability_value)
{
rand = random(1,5);
if (rand < 2)
{
angry_red_lights();
}
else if (rand >= 2)
{
for(int i=0; i < strip.numPixels() - num_indicator_leds; i++) {
strip.setPixelColor(i, off);
}
set_indicator_leds();
strip.show();
wait(5000);
Serial.println("off");
}
}
}
void random_disruptive()//sometimes people just get mad for no reason...
{
int rand = random(100);
int count = 1;
/*
Serial.print("Random disruptive Value - ");
Serial.println(rand);
*/
if(rand < 10)
{
while (count < rand)//increment disruptive X times
{
more_angry(true);
count++;
}
}
}
void more_angry(bool more)//more == true then increase increase the disruptive
{
//Serial.println("a");
if(more && disruptive < 0.99)
{
//Serial.println("more");
disruptive = disruptive + 0.0025;
}
else if (!more && disruptive > 0.01)
{
//Serial.println("less");
disruptive = disruptive - 0.01;
}
}
void adjustHappiness(int proximity)
{
if((proximity <= proximity_bound) && (happiness < 0.98))
{
happiness = happiness + 0.01;
}
else if ((proximity > proximity_bound) && happiness > 0.01)
{
happiness = happiness - 0.01;
}
//Serial.print("Happiness - ");
//Serial.println(happiness);
}
unsigned long time_now = 0;
void wait(int duration)//using instead of delay to try to keep gesture sensor running
{
time_now = millis();
while(time_now + duration > millis())
{
detectGesture();
}
}
void detectGesture()//on/off mechanism
{
if(APDS.gestureAvailable())
{
int gesture = APDS.readGesture();
Serial.print("Gesture - ");
Serial.println(gesture);
if(gesture == GESTURE_RIGHT)
{
if(!on)
{
disruptive = 0.01;
happiness = 0.85;
on = true;
Serial.println("Right");
}
}
else if(gesture == GESTURE_LEFT)
{
on = false;
Serial.println("Left");
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, off);
}
strip.show();
}
else if(gesture == GESTURE_UP)
{
on = false;
Serial.println("Up");
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, off);
}
strip.show();
}
else if(gesture == GESTURE_DOWN)
{
on = false;
Serial.println("Down");
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, off);
}
strip.show();
}
}
}
void loop() {
Serial.println("---------");
//detectGesture();
if(APDS.gestureAvailable())
{
int gesture = APDS.readGesture();
Serial.print("Gesture - ");
Serial.println(gesture);
if(gesture == GESTURE_RIGHT)
{
if(!on)
{
disruptive = 0.01;
happiness = 0.5;
on = true;
Serial.println("Right");
}
}
else if(gesture == GESTURE_LEFT)
{
on = false;
Serial.println("Left");
for(int i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, off);
}
strip.show();
}
else{
Serial.println(gesture);
}
}
if (on && APDS.proximityAvailable()) {
// read the proximity
// - 0 => close
// - 255 => far
// - -1 => error
int proximity = APDS.readProximity();
Serial.print("Proximity - ");
Serial.println(proximity);
adjustHappiness(proximity);
configureLEDs2();
animism();
for(int i=0; i < strip.numPixels() - num_indicator_leds; i++) {
strip.setPixelColor(i, led_color);
}
set_indicator_leds();
strip.show();
strip.clear();
}
wait(350);
}
Click to Expand
What would it feel like to use tech that cares more about what it needs more that it cares about what you need? Well, the Lonely Lamp needs your companionship to work. Spend more time with it and it shines brighter, but leave it alone for too long and it might start misbehaving!