Final Project: Interactive Item Block Mood Lamp

Concept

For my final project, I made an interactive mood lamp with five push-buttons corresponding to five moods: Day, Calm, Study, Energetic, and Night. Each mood lights up with a matching color on the arduino and p5, as well as background music from p5.

Implementation

I used a total of 5 push-buttons (obtained from the IM Lab), each for one of the moods. I also used a potentiometer to control the light brightness, an RGB LED for the light itself, and some 220ohm resistors I had at home (because I lost the ones from the kit), as well as the breadboard and jumper wires.

Each button is connected to one of the arduino’s digital ports; I used the internal pullup resistors for them to reduce the amount of components needed and to make the circuit simpler. The RGB LED is connected through resistors to PWM ports to have control over the brightness. The potentiometer is connected to an analog input.

When the arduino starts, the light is set to orange as a starting color, with a matching screen on p5 prompting the user to select a mood. Whenever any of the five buttons are pressed, the light switches to that mood’s color, as well as the p5 screen, and matching music is played. Light brightness can be controlled continuously through the potentiometer.

Arduino Code
// Pin definitions for buttons
const int greenButtonPin = 2;
const int redButtonPin = 4;
const int blueButtonPin = 7;
const int whiteButtonPin = 5;
const int blackButtonPin = 6;

// Pin definitions for RGB LED
const int redLEDPin = 9;
const int greenLEDPin = 10;
const int blueLEDPin = 11;

// Pin definition for the potentiometer
const int potPin = A0;

// Variable to store the last pressed button
int lastPressedButton = 0;

// Current color variables (Default set to orange)
int currentRed = 255;
int currentGreen = 50;
int currentBlue = 0;

void setup() {
  Serial.begin(9600);

  // Initialize button pins
  pinMode(greenButtonPin, INPUT_PULLUP);
  pinMode(redButtonPin, INPUT_PULLUP);
  pinMode(blueButtonPin, INPUT_PULLUP);
  pinMode(whiteButtonPin, INPUT_PULLUP);
  pinMode(blackButtonPin, INPUT_PULLUP);

  // Initialize RGB LED pins
  pinMode(redLEDPin, OUTPUT);
  pinMode(greenLEDPin, OUTPUT);
  pinMode(blueLEDPin, OUTPUT);

  // Set initial LED color and brightness to maximum
  updateBrightness(255); // Ensure full brightness on startup
  setColor(currentRed, currentGreen, currentBlue); // Start with default mood 'Start' (Orange)
  Serial.println("Start");
}

void loop() {
  // Continuously adjust the brightness based on potentiometer reading
  int brightness = analogRead(potPin) / 4; // Scale to 0-255
  updateBrightness(brightness);

  // Check each button and change the LED color and print the mood if changed
  checkButton(greenButtonPin, "Study", 0, 255, 0);
  checkButton(redButtonPin, "Energetic", 255, 0, 0);
  checkButton(blueButtonPin, "Calm", 0, 0, 255);
  checkButton(whiteButtonPin, "Day", 255, 255, 255);
  checkButton(blackButtonPin, "Night", 128, 0, 128);
}

void setColor(int red, int green, int blue) {
  // Store the current color settings
  currentRed = red;
  currentGreen = green;
  currentBlue = blue;
}

void updateBrightness(int brightness) {
  // Adjust the PWM output to LED pins based on the current color and new brightness
  analogWrite(redLEDPin, map(currentRed, 0, 255, 0, brightness));
  analogWrite(greenLEDPin, map(currentGreen, 0, 255, 0, brightness));
  analogWrite(blueLEDPin, map(currentBlue, 0, 255, 0, brightness));
}

void checkButton(int buttonPin, String mood, int red, int green, int blue) {
  if (digitalRead(buttonPin) == LOW && lastPressedButton != buttonPin) {
    delay(50); // Debounce delay
    if (digitalRead(buttonPin) == LOW) { // Confirm the button is still pressed
      lastPressedButton = buttonPin;
      setColor(red, green, blue);
      updateBrightness(analogRead(potPin) / 4); // Update brightness immediately with new color
      Serial.println(mood);
    }
  }
}

Basically, whenever a button corresponding to a mood other than the current one is clicked, the LED color is updated to the color corresponding to the new mood and the mood name is sent to P5 over serial communication. Additionally, the LED brightness is being continuously updated based on changes to the reading from the potentiometer.

P5 Code
let bgColor = [255, 165, 0]; // Orange Starting Color
let moodText = "Mood Lamp"; // Default text to display
let mood = "Start"

// Music Variables
let dayMusic;
let calmMusic;
let studyMusic;
let energeticMusic;
let nightMusic;

// Load all audio
function preload() {
  dayMusic = loadSound('Wii Sports - Title (HQ).mp3');
  calmMusic = loadSound('Animal Crossing New Leaf Music - Main Theme.mp3');
  studyMusic = loadSound('Gusty Garden Galaxy Theme - Super Mario Galaxy.mp3');
  energeticMusic = loadSound('Title Screen - Mario Kart Wii.mp3');
  nightMusic = loadSound('Luma - Super Mario Galaxy.mp3');
}

// Setup canvas
function setup() {
  createCanvas(windowWidth, windowHeight);
  textSize(32);
  textAlign(CENTER, CENTER);
}

function draw() {
  background(bgColor);
  fill(255);
  text(moodText, width / 2, height / 2);
  
  if (!serialActive) {
    text("Click the screen to select Serial Port", width / 2, height / 2+50)
  } 
  else if (mood == "Start") {
    bgColor = [255, 165, 0];
    moodText = "Select one of the mood buttons to being...";
    dayMusic.stop();
    calmMusic.stop();
    studyMusic.stop();
    energeticMusic.stop();
    nightMusic.stop();
  }
  
  if (mood == "Day") {
    bgColor = [200, 200, 200];
    moodText = mood;
    calmMusic.stop();
    studyMusic.stop();
    energeticMusic.stop();
    nightMusic.stop();
    if (!dayMusic.isPlaying()) dayMusic.loop();
  }
  
  if (mood == "Calm") {
    bgColor = [0, 0, 255];
    moodText = mood;
    dayMusic.stop();
    studyMusic.stop();
    energeticMusic.stop();
    nightMusic.stop();
    if (!calmMusic.isPlaying()) calmMusic.loop();
  }
  
  if (mood == "Study") {
    bgColor = [0, 255, 0];
    moodText = mood;
    calmMusic.stop();
    dayMusic.stop();
    energeticMusic.stop();
    nightMusic.stop();
    if (!studyMusic.isPlaying()) studyMusic.loop();
  }
  
  if (mood == "Energetic") {
    bgColor = [255, 0, 0];
    moodText = mood;
    calmMusic.stop();
    dayMusic.stop();
    studyMusic.stop();
    nightMusic.stop();
    if (!energeticMusic.isPlaying()) energeticMusic.loop();
  }
  
  if (mood == "Night") {
    bgColor = [128, 0, 128];
    moodText = mood;
    calmMusic.stop();
    dayMusic.stop();
    studyMusic.stop();
    energeticMusic.stop();
    if (!nightMusic.isPlaying()) nightMusic.loop();
  }

}

// Serial code copied from example sketch, with some modifications

function mousePressed() {
  if (!serialActive) {
    // important to have in order to start the serial connection!!
    setUpSerial();
  } else mood = "Start";
}

function readSerial(data) {
  if (data != null) {
    // make sure there is actually a message
    // split the message
    mood = trim(data);
  }
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

Basically, after serial connection is established by the user, the canvas is updated to reflect the current mood whenever a new mood is read from the arduino on the serial connection, and the corresponding audio plays as well.

P5 Embedded

User Testing

I had each of my sisters my project to try (prior to making a case and finalizing it).

My first sister managed to figure it out without any instructions from me, surprisingly even knew which COM port to select. She did not figure out that brightness can be controlled by the potentiometer though.

IMG_7816

My other (younger) sister managed the same, but did not know which what to do when the COM port prompt came up. She also did not realize that brightness can be controlled.

IMG_7817

Project Pictures

Project Video

IM Showcase

Problems & Areas for Improvement

I had built the casing using cardboard I got from Rahaf from Student Affairs. The material is very flimsy and I should replace it with something more permanent and stable. I had to solder wires to the red button immediately before the showcase because it didn’t have any; I also used two blue buttons because I couldn’t find a white one.

Additionally, I could aim to make the project more fun and interactive, but overall it’s a nice idea that people seemed to enjoy at the showcase.

Production Assignment – Week 12

For this assignment, we were tasked to control an ellipse using sensor data from arduino.

For this, I’m using readings from a potentiometer.

Arduino Code

void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0); // Read the value from the potentiometer
  Serial.println(sensorValue); // Give P5 the value over serial
  delay(10);
}

P5 Code

let sensor = 0;

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  if (!serialActive) text("Click the screen to connect serial.", 50, 50); // display text to connect serial
  
  let x = map(sensor, 0, 1023, 0, 400); // map sensor to canvas
  ellipse(x, 200, 50, 50); // Draw the ellipse in the middle of the screen
}

// Serial code copied from example sketch, with some modifications

function mousePressed() {
  if (!serialActive) {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

function readSerial(data) {
  if (data != null) {
    // make sure there is actually a message
    // split the message
    sensor = trim(data);
  }
}

P5 Embedded

Video

Reading Reflection – Week 12

The reading dives into the fascinating history of how design intersects with disability, and of how focusing on design for disability doesn’t just solve immediate problems but can also inspire broader changes in the design world.

What’s really interesting about this is the idea that solving specific problems for disabled users can actually lead to major innovations that benefit everyone. It’s a powerful reminder that good design is about more than just looks or functionality; it’s about thoughtful innovation that considers all users. This perspective encourages us to think differently about design and its potential impact, pushing for high standards and creativity in all areas, including those designed for disability.

Reading Reflection – Week 11

This reading challenges the current trend in technology interfaces, which he criticizes as merely “Pictures Under Glass.” He argues that this approach severely underutilizes the complex capabilities of human hands, which are not only meant for touching but also for manipulating objects in rich and varied ways. This is intriguing because it prompts us to rethink how we interact with technology. Victor’s perspective is a wake-up call to consider more innovative and natural interactions beyond the confines of screens and opens up exciting possibilities for future technological developments that genuinely enhance human abilities rather than constrain them.

What I find particularly interesting is the emphasis on the need for inspired people to drive this change. It’s a reminder of the power of visionairy thinking in technology and the responsibility of creators and funders to strive for meaningful advancements, not just incremental changes, not just accepting technology as it is, but imagining and working towards what it could be to enhance human interaction.

Final Project Update: Interactive Mood Lamp

Concept

For my final project, I made an interactive mood lamp with five push-buttons corresponding to five moods: Day, Calm, Study, Energetic, and Night. Each mood lights up with a matching color on the arduino and p5, as well as background music from p5.

Implementation

I used a total of 5 push-buttons (3 from the Arduino kit and 2 I had at home), each for one of the moods. I also used a potentiometer to control the light brightness, an RGB LED for the light itself, and some 220ohm resistors I had at home (because I lost the ones from the kit), as well as the breadboard and jumper wires.

Each button is connected to one of the arduino’s digital ports; I used the internal pullup resistors for them to reduce the amount of components needed and to make the circuit simpler. The RGB LED is connected through resistors to PWM ports to have control over the brightness. The potentiometer is connected to an analog input.

When the arduino starts, the light is set to orange as a starting color, with a matching screen on p5 prompting the user to select a mood. Whenever any of the five buttons are pressed, the light switches to that mood’s color, as well as the p5 screen, and matching music is played. Light brightness can be controlled continuously through the potentiometer.

User Testing

I gave each of my sisters my project to try.

My first sister managed to figure it out without any instructions from me, surprisingly even knew which COM port to select. She did not figure out that brightness can be controlled by the potentiometer though.

IMG_7816

My other (younger) sister managed the same, but did not know which what to do when the COM port prompt came up. She also did not realize that brightness can be controlled.

IMG_7817

Areas for Improvement

I should add instructions for the brightness within the program, so that people are aware it can be adjusted.

I also have yet to make a casing for my project, which I hope to finish soon.

Reading Reflection – Week 10

Reflecting on the concepts mentioned in “Physical Computing’s Greatest Hits (and Misses),” it is clear that some project ideas appear frequently in physical computing. The different topics provide unique learning opportunities of physical interaction. makes you see the charm in revisiting old project ideas. It’s cool to think about how each student puts their spin on classic assignments like making digital instruments or smart clothing. This whole process teaches us a lot about how we interact with the tech we build, which is super handy for learning and creativity. It makes you see the charm in revisiting old project ideas. It’s interesting to think about how each student puts their own twist or spin on classic assignments like making digital instruments or wearable devices. This whole process teaches us a lot about how we interact with the tech we build, which is extremely useful for learning and creativity.

The second article, “A Public Physical Computing Service,” discusses the integration of physical computing in public spaces. By making technologies like Arduino and Raspberry Pi accessible to a broader audience, everyone gets a chance to play around and learn something new. This showcases the importance of community in technology education, and how shared resources and collaborative spaces can empower people and enhance collective creativity in the physical computing field.

Production Assignment – Week 10

For this assignment, we were tasked with using one digital sensor (on/off) and one analog sensor (variable) to control an LED each.

I used a potentiometer as my analog sensor to control and dim a blue LED based on the reading, and used a regular button as my digital sensor (switch).

I used arduino to get the readings from the potentiometer and control the blue LED, but for the switch and green LED, I just used the 5V out to keep things simple.

Materials Used:

  • Jumper Wires
  • Blue LED
  • Green LED
  • Resistor
  • Potentiometer
  • Button

Code:

const int ledPin = 10;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int sensorLevel = analogRead(A0); // Read from potentiometer
  int brightness = map(sensorLevel, 0, 1023, 0, 255); // Map sensor reading to LED brightness

  analogWrite(ledPin, brightness); // Control LED

  delay(100);
}

 

Demo:

Production Assignment – Week 9

For this assignment, we were tasked to create an unusual  switch without using our hands. I decided to create a pressure switch that can be stepped on to activate the LED.

I recycled some cardboard packaging I found to use as the casing, two sugar packets to create the spacing, two aluminum foil pads, some jumper wires, and an LED.

Demo:

Reflection:

Overall this was a fun project to work on, I could make it more durable to prevent it from falling apart.

Reading Reflection – Week 8

Reflecting on the insights from Don Norman’s essay, I find his integration of aesthetics and usability particularly thought-provoking. Attractive products aren’t merely pleasing to the eye but also functionally better due to the positive effect they provide. It’s enlightening to see the psychological and emotional layers behind product interactions; that our reactions to design are not just superficial but come from our cognitive and emotional thinking.

Norman also makes you wonder if there’s a relationship between functionality and aesthetic design, where they complement each other. This idea is not only innovative but also inspiring for anyone involved in creative design, prompting us to consider how the objects we create affect the emotional and cognitive experiences of users.

Midterm Project: Dallah & Fenyan

For our midterm project, we were tasked with creating a game using what we learned, including a shape, image, sound, text, and OOP. Sticking to my cultural theme that I’ve been using for my assignments, I decided to create an Emarati twist on the classic XO game, calling it Dallah & Fenyan.

I started off by getting the images for the players from google, as well as the background audio. I ended up resizing the images to a square in Paint.NET to make it easier to incorporate in my game. The audio I downloaded from YouTube: https://www.youtube.com/watch?v=PN1nUDx5znA

The game contains multiple components, such as:

  • Board class to handle slots on the grid and check contents during gameplay.
  • drawBoard(), displayStartScreen(), and displayGameOver() functions to manage the visible parts of the game.
  • mousePressed(), checkWinner(), getWinner(), and restartGame() containing game logic to manage gameplay.

I’m proud of the getWinner() function because it took me the longest to write properly 🙁

function getWinner() {
  // Check rows, columns, and diagonals for a win
  for (let i = 0; i < 3; i++) {
    // Rows
    if (board.cells[i][0] === board.cells[i][1] && board.cells[i][1] === board.cells[i][2] && board.cells[i][0] !== '') {
      return board.cells[i][0];
    }
    // Columns
    if (board.cells[0][i] === board.cells[1][i] && board.cells[1][i] === board.cells[2][i] && board.cells[0][i] !== '') {
      return board.cells[0][i];
    }
  }
  // Diagonals
  if (board.cells[0][0] === board.cells[1][1] && board.cells[1][1] === board.cells[2][2] && board.cells[0][0] !== '') {
    return board.cells[0][0];
  }
  if (board.cells[0][2] === board.cells[1][1] && board.cells[1][1] === board.cells[2][0] && board.cells[0][2] !== '') {
    return board.cells[0][2];
  }
  return null; // No winner yet
}

Overall, this is the final outcome:

Looking to the future, I could definitely make it look more appealing, have some better design and animations, as well as audio during gameplay. I could also add a score counter to see how many times each player won the game.