Week 13 User Testing

User Testing Video

For user testing, I told my test user to start the game without giving any instructions. The user immediately figured out that the controller was not an ordinary one because it’s just a piece of plastic with nothing on the outside. Luckily the first thing he tried was to tilt the controller, which made the character move, allowing him to complete the first level of the game.

One aspect of the experience that worked surprisingly well was that all my test users somehow knew that that the goal was to move upwards even though I didn’t indicate that the finish line was there. It then became clear that because the bottom boundary of the maze is showing, the users assumed that the finish line was in the other direction.

The biggest area that can and will be improved is the robustness of the controller. It’s currently an accelerometer and vibration motor taped to the controller case, which makes it weak and sometimes makes it fall apart. I plan to use the glue gun to fix this. Another issue is the amount of wires going out of the controller. There are currently 5 wires for the accelerometer and 3 for the vibration motor. While these are essential to make the game work, I can make them less annoying by using tie cables to clamp them all into one single wire.

I didn’t need to explain anything to my test users, however, the game might not be as intuitive for other users. I plan on adding an instruction page in the beginning and some text under the controllers on the box that tells users they’re supposed to tilt them to move.

 

Final Project Proposal

Finalized Concept For my final project, I am building a competitive 2-player game inspired by “Tomb of the Mask,” except physical steadiness determines who wins. Two players will race against each other to navigate a digital maze on the screen. Instead of using a keyboard, each player will hold a custom physical controller that detects tilt.

By tilting their controller forward, backward, left, or right, the players will steer their avatars on the screen. The game will require steady hands and precise movements to avoid crashing into walls while trying to beat the opponent to the finish line.

Arduino Design & Logic The Arduino will  translate physical movements into data.

Inputs: I will use two separate Accelerometers connected to a single Arduino board. One sensor is for Player 1, and the other is for Player 2.

Processing: The Arduino program will constantly read the X, Y, and Z tilt angles from both sensors to understand exactly how each player is holding their controller.

Communication (Sending): It will package these four values (Player 1 X/Y/Z and Player 2 X/Y/Z) and send them continuously to the computer via the USB cable.

P5.js Design & Logic P5.js will act as the “brain” and “display” of the game.

Visuals: The program will draw the maze walls, the start/finish zones, and the two player avatars.

Communication (Receiving): P5.js will continuously listen for the tilt numbers coming from the Arduino.

Game Logic:

    • It takes the tilt numbers and uses them to change the speed and direction of the player dots. (e.g., Tilt left = Move left).

    • It checks for collisions. If a player hits a wall, they stop or bounce back.

    • P5 checks for the winner and notifies the Arduino to reward the winner.

Project Roadmap To complete this project, I will follow these steps:

  1. Wiring: Connect both accelerometers to the Arduino and confirm I can get readings from both at the same time.

  2. Connection: Write the code to successfully send the sensor numbers from Arduino to P5.js.

  3. Gameplay: Create the maze graphics in P5 and program the physics so the dots move smoothly with the sensors.

  4. Building: Construct two simple handheld boxes (or 3D printed shells) to house the sensors so they are easy to hold and tilt.

Final Project Idea

My project idea is to make a game or maybe some kind of art tool that uses a tilt controller I’m going to build myself. I might use an Adafruit Circuit Playground to be the controller, since it has an accelerometer inside to sense which way you’re tilting it. I plan to use the Arduino IDE to program the Circuit Playground and get the accelerometer data. Then, I want to send that data to my computer and use p5.js to make the actual game or art program. I’m not totally sure what the final thing will be, but it could be a maze game where you tilt to move the character, a simple pilot game, or a cool art program where the tilt moves the brush around instead of using arrow keys.

Week 11 Reading Reflection

This week’s article made me see things in a new way. It used eyeglasses as its main example. Glasses are a medical tool, but they are also fashion items. The article asks why other aids, like hearing aids, can’t be the same. I had never really thought about it before, but it’s true. It feels like a failure that we treat these items so differently.

This made me think about how design makes people feel. When a device looks cold and medical, it can make a person feel like they are just a “patient” or that their needs are something to hide. The article shows that making these items beautiful or cool is not silly. It’s actually very important for giving people dignity and choice. It changes the focus from “fixing a problem” to just “living a life.”

Finally, the most interesting point was that this is a two-way street. Designing for disability can actually spark amazing new ideas for everyone. When designers have to solve a specific problem, it can lead to a brand new way of thinking. This means design for disability isn’t a small or separate thing; it’s a source of creativity that can make all design better.

Week 11: Serial Communication (Mariam and Mohammed)

Exercise 1: Arduino to P5 Communication

For this exercise, we used a potentiometer as the analog sensor. The potentiometer controls the ellipse’s position on the horizontal axis in the P5 sketch. When you turn it one way, the ellipse moves to the right, turning it the other way causes it to move left.

We added a little text at the top of the sketch that displays the sensor value. As the value increases, the ellipse moves to the right, and vice versa.

Demo

Full Code

Schematic

Arduino:
void loop() {

  potentiometerValue = analogRead(potentiometerPin);  // reads sensor value (0–1023)


  // Send value to p5 via serial as a line of text

  Serial.println(potentiometerValue);

  delay(20);

}
P5:
// read sensor value from Arduino
 let data = port.readUntil("\n");
 if (data.length > 0) {
   sensorValue = int(trim(data)); // convert from string to number
 }

 // map potentiometer range (0–1023) to screen width
 let x = map(sensorValue, 0, 1023, 0, width);
 let y = height / 2;

 //draws ellipse
 ellipse(x, y, 50, 50);
Exercise 2: P5 to Arduino Communication

Here, we used the keyboard arrow keys to change the LED brightness. Pressing the right arrow increases the brightness, and the left arrow decreases it.

Demo

Full Code

Schematic

Arduino:
void loop() {
  if (Serial.available() >= 0) {
    brightness = Serial.parseInt(); 
    brightness = constrain(brightness, 0, 255);
    analogWrite(ledPin, brightness); 
  }
}
P5:
function draw() {
  background(240);

  if (!port.opened()) {
    text("Disconnected - press button to connect", 20, 80);
  } else {
    text("Connected - use arrow keys to adjust brightness", 20, 80);
    text("Brightness: " + sendToArduino, 20, 120);

    // Send the brightness value to Arduino
    port.write(sendToArduino + "\n");
  }
}

function keyPressed() {
  if (keyCode === LEFT_ARROW) {
    sendToArduino -= 10;
  } else if (keyCode === RIGHT_ARROW) {
    sendToArduino += 10;
  }

  sendToArduino = constrain(sendToArduino, 0, 255);
}
Exercise 3: Bi-directional Communication

For the Arduino to P5 communication, the potentiometer acts like the “wind” in the gravity/wind example. As you turn it, the ball gets pushed left or right depending on the mapped value.

For the P5 to Arduino communication, every time the ball hits the bottom and bounces, it triggers the LED to briefly turn on and then off, so the LED flashes in sync with each bounce.

Demo

Full Code

Schematic

Arduino:
void loop() {
  // Read analog sensor
  sensorValue = analogRead(sensorPin);
  // Send sensor value to P5
  Serial.println(sensorValue);
  
  // Check for bounce signal from P5
  if (Serial.available() > 0) {
    int bounce = Serial.read();
    if (bounce == 1) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
  }

  delay(50);
}
P5:
// Read analog sensor value from Arduino
 if (port.available() > 0) {
   sensorValue = int(port.read());
   wind.x = map(sensorValue, 0, 1023, -2, 2); // Map sensor to wind strength
 }

 

Week 10 Reading Response

This reading made me rethink what “future technology” really means. I used to think of futuristic interfaces as things like touchscreens or holograms, but the author argues that these are actually limiting, that “Pictures Under Glass” remove the tactile richness that makes human interaction powerful. The way he describes how our hands feel and manipulate objects made me realize how much design has ignored our most natural abilities. We’ve gotten so used to flat screens that we’ve forgotten how much more expressive and intuitive touch and movement can be.

What stood out most to me was the idea that technology should amplify human capabilities, not replace or dull them. The examples about picking up a book or tying your shoes really drove this home. Those actions are effortless because they’re built on feedback, texture, and motion. It made me think about how most digital interfaces feel numb and disconnected by comparison.

I also liked how the author ended with a kind of challenge that the future is a choice. It made me see that innovation shouldn’t just be about what’s new, but about what’s better for human experience. As someone interested in design and tech, this made me want to think beyond screens and imagine tools that respond to our hands, our bodies, and the way we naturally move through the world.

Week 10: Group Project “NYUAD DJ Kit”

Main Concept:

The main concept for our group project is a DJ, since we wanted to experience what it feels like to be one. A DJ needs to handle many sounds and instruments using their unique artistic skills to create music that makes people happy and excited. Thus, we crafted this device called “NYUAD DJ Kit.” By using it, you can choose different kinds of songs with various speeds and a base sound produced by a wooden stick. This is a unique way to compose new kinds of songs as a DJ.

Demonstration Video

Schematic:

Code we’re particularly proud of:

The parts of the code we’re most proud of are the one shown below. The if else statement allows us to move to the next song and play it. When the button is pressed, meaning the pin is low, we set buttonPressed to true and noteIndex to 0 so that the song plays from the beginning. We also used the modulo operator to ensure that we always go back to the first song after the last one. The else if statement resets the buttonPressed state to false, so that the next time we press the button, it plays the next song

//handle music switching using modulo
if (digitalRead(BUTTON_PIN) == LOW && !buttonPressed) {
    buttonPressed = true;
    //move to the next song
    currentSong = (currentSong + 1) % 3; 
    //set note to 0 so that a song plays from the beginning
    noteIndex = 0; 
    isPlaying = false;
    noTone(BUZZER_PIN);
    delay(250); //delay for 250 milliseconds
  } else if (digitalRead(BUTTON_PIN) == HIGH) {
    //set buttonPressed to false to play next song 
    buttonPressed = false;
  }

The second snippet of code allows the servo to move every servoDelay milliseconds, controlling its speed and angle. We applied the concept we learned in class called “non-blocking” to ensure that this operation does not affect the rest of the program. Inside the if statement, we use the write() function from the Servo library to change the servo’s angle each time it runs. This way, the servo continues changing its angle until it reaches either 180° or 0°, incrementing by a step each time servoDelay milliseconds have passed. We’re happy that we were able to apply multiple concepts we learned in class, such as non-blocking and modulo, to our DJ project. As references, we used the example file ToneMelody from the Digital section and the Knob example from the Servo library. We also used ChatGPT to help us figure out how to apply the non-blocking concept so that the melody can move to the next one without affecting the rest of the program, which allows the servo to continue moving smoothly.

//Use non-blocking to not affect the rest of the program
if (currentTime - lastServoUpdate >= servoDelay) { //if servoDelay mills has passed
    lastServoUpdate = currentTime;
    //Change the angle of the servo by servoPos 
    myservo.write(servoPos);
    servoPos += servoStep;
    //Start decrementing if servo reaches 0 or 180 degrees
    if (servoPos >= 180 || servoPos <= 0) servoStep = -servoStep;
  }

Reflections & Future Improvements:

In terms of reflections, we struggled a lot to make the base work because we needed to attach the wooden stick to the servo and it was not stable at all at first. The way we attached it was by using tape, which was the primary cause of why it was unstable. As a result, every time we ran the servo fast, the stick fell off or the servo stopped working for some reason. We eventually managed to make the stick and servo stable by placing some weight on top of the setup so that no matter how fast the servo moved, the stick remained stable.

As for future improvements, we want to enhance the quality of the base because right now we’re just using a wooden stick, and it doesn’t produce a loud enough sound for a party situation. Furthermore, as the stick swings faster, its swing range becomes smaller, so we need to move the bottle manually to allow the stick to reach it. We believe this happens because the servoDelay becomes too small, reaching about 1 ms, so the servo can’t physically keep up. Therefore, next time we should use constrain() on the mapped value to prevent electrical noise from going out of range. This way, we can allow the servo to catch up with the speed that we want.

Week 9 Assignment

Concept

This project uses one digital sensor (a toggle switch) and one analog sensor (an LDR) to control two LEDs. The toggle switch turns a green LED fully on or off, and the LDR controls the brightness of a yellow LED. The darker it gets, the brighter the LED becomes.

Demo

Schematic

Code Snippet
void loop() {
  // Switch controls green LED
  int switchState = digitalRead(switchPin);
  if (switchState == LOW) {
    digitalWrite(greenLED, HIGH);
  } else {
    digitalWrite(greenLED, LOW);
  }

  // Analog part: light sensor controls yellow LED brightness
  int lightVal = analogRead(ldrPin);
  int brightness = map(lightVal, 0, 1023, 255, 0); // darker room = brighter LED
  Serial.println(brightness);
  analogWrite(yellowLED, brightness);
}
Reflection and Future Improvements

This project helped me clearly see the difference between analog and digital inputs: the LDR smoothly controls LED brightness while the switch simply turns the other LED on or off.  Moving forward, I’d like to try adding more outputs, like a buzzer or an RGB LED, to make the reactions more expressive.

Week 9 Reading Reflections

Physical Computing’s Greatest Hits and Misses

Reading “Physical Computing’s Greatest Hits” made me realize that I don’t always have to invent something completely new. I learned that common projects are “hits” for a good reason. They are popular because they create a very clear and intuitive link between what a person does and what happens next. It showed me that these projects are powerful building blocks for learning, not just simple exercises to be done once and forgotten.

This article changed how I think about my own creative work. I used to worry a lot about being totally original, but now I see it’s more important to focus on the feeling or experience I’m creating. It’s okay to use a familiar idea, like a glove that senses movement, as long as I use it in a way that feels surprising or meaningful. It’s a relief to know that the human experience is more important than the technology itself.

Making Interactive Art: Set the Stage, Then Shut Up and Listen

The main lesson I learned from “Making Interactive Art” is that my job isn’t to tell the audience what to think or do. My first instinct is usually to explain everything so people “get it,” but this reading showed me that’s the wrong way. Instead, my role is to “set the stage” and to provide the space, the objects, and maybe a few hints. The real art isn’t just the thing I built. It’s the experience that people have when they explore it for themselves.

This approach means I have to “shut up and listen,” which requires a lot of trust. I have to trust that my design gives enough clues and trust that the audience will be creative. It helped me see that when people use my project in a way I didn’t expect, it’s not a failure, it’s a discovery. This makes the audience a partner in the art.

Unusual Switch

Concept

For my unusual switch, I wanted to use a light sensor to create a simple “password” that isn’t typed or pressed in the usual way. Instead of a button, the user has to shine a flashlight on the sensor in a specific pattern to activate the LED. The idea is inspired by a morse-code style signal: the user must turn the light on for a set amount of time, then off for a set amount of time, and repeat this sequence to successfully trigger the switch. This makes the interaction more playful and unusual, relying on timing and attention rather than direct contact.

How it works

The project uses an LDR to detect light intensity and an LED as the output indicator. The Arduino reads the LDR value and compares it to a threshold to decide if the light is “on” or “off.” The user must follow the correct timing sequence: light on for three seconds, then off for three seconds, repeated three times. If the pattern is completed correctly, the green LED turns on for a few seconds to indicate success.

Github https://github.com/MohdAlkhatib/introtoim/blob/main/sketch.c

void loop() {
  int success = 0;

  for (int i = 0; i < 3; i++) {
    if (analogRead(ldrPin) > lightThreshold) {
      delay(3000); // light on for 3 seconds
      if (analogRead(ldrPin) < lightThreshold) {
        success++;
        delay(3000); // light off for 3 seconds
      }
    }
    delay(500); // brief pause between attempts
  }

  // if the user does the signal correctly 3 times in a row, turn on the LED
  if (success == 3) {
    digitalWrite(greenLED, HIGH);
    delay(3000);
    digitalWrite(greenLED, LOW);
  }

  delay(1000); // short pause before restarting
}
Future Improvements

In the future, I could make the switch more flexible by allowing different light patterns as “passwords” or adjusting the timing for each sequence. I could also add multiple LEDs or even a small sound to give feedback for each correct or incorrect step.