Fruit Ninja final project Documentation

Concept:

The Fruit Ninja project recreates the classic fruit-slicing game using hand tracking and an accelerometer. Players slice virtual fruits displayed on the screen by moving their hands, which are tracked by a camera and the ml5 handpose model. The vertical movement of the virtual knife is controlled by an accelerometer connected to an Arduino.

Implementation

      • Hand Tracking: The p5.js sketch utilizes the ml5 handpose model to track the user’s hand movements through the camera. By calculating the average position of hand landmarks, it determines the x-axis position of the virtual knife.
      • Accelerometer Input: The Arduino reads the y-axis values from the accelerometer and transmits them to the p5.js sketch via serial communication. This data controls the vertical movement of the virtual knife on the screen.
      • Fruit and Bomb Generation: The p5.js sketch generates fruits and bombs at the bottom of the screen, propelling them upwards in a projectile motion.
      • Collision/slicing Detection: The sketch detects collisions between the virtual knife and the fruits/bombs. When a fruit is sliced successfully, it splits in two, the player’s score increases, and a slicing line appears. Hitting a bomb results in a penalty, a visual effect (like a flashbang), and the loss of a life.

Interaction Design

      • Hand Movements: Players use slicing motions with their hands to control the virtual knife and slice the fruits.

      • Visual Feedback: The game provides visual cues like slicing lines, explosion effects, and score updates to enhance player feedback.

      • Score and Lives: The score increases with each fruit sliced, and players have a limited number of lives, represented by hearts.

      • Game Over: The game ends when the player loses all lives by hitting bombs. The final score is displayed, and a restart option is offered.

User testing

Schematic

Arduino Code

The Arduino code reads the accelerometers yaxis values and transmits them to the p5.js sketch through serial communication. It also includes a button to reset the base position of the accelerometer for calibration (if needed for debugging reasons if the user was too far away from the screen).

const int buttonPin = 2;    // Button pin
const int xPin = A0;        // X-axis analog pin (unused)
const int yPin = A1;        // Y-axis analog pin connected to ADXL335

// Calibration values
const float xZero = 512.0;  // Raw ADC value at 0g for X (unused)
const float yZero = 512.0;  // Raw ADC value at 0g for Y

// Variables 
float baseX = 0, baseY = 0;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);  // internal pull-up resistor

  // Read initial values
  baseX = analogRead(xPin); 
  baseY = analogRead(yPin);
}

void loop() {
  // Read the button state
  static bool lastButtonState = HIGH;
  bool currentButtonState = digitalRead(buttonPin);

  // Check for button press to reset the base position
  if (lastButtonState == HIGH && currentButtonState == LOW) {
    baseX = analogRead(xPin);  // Unused
    baseY = analogRead(yPin);
  }
  lastButtonState = currentButtonState;

  // Read current accelerometer value for Y-axis
  float yVal = analogRead(yPin);

  float yG = (yVal - baseY); 

  // Send data to p5 through serial
  Serial.println(yG, 3);  // Using 3 decimal places for precision

  delay(100);  // Reduce data rate
}

p5.js Code

 

Communication between Arduino and p5.js

The Arduino sends the accelerometers yaxis data to the p5.js sketch via serial communication, which is then used to control the vertical movement of the virtual knife in the game.

Areas of Pride

      • Integration of Hand Tracking and Accelerometer: The project successfully combines hand tracking for horizontal movement and accelerometer data for vertical movement, creating a more interactive and engaging gameplay experience.

      • Visual Effects and Gameplay: The visual elements, including fruit slicing,  and bomb explosions, enhance the gameplay experience and provide satisfying feedback to the player.

Future Improvements

      • Variety of Fruits and Challenges: Introduce more fruit types, obstacles, and challenges to increase gameplay complexity and engagement.

      • Calibration and Optimization: Improve the calibration process for the accelerometer and optimize the code for smoother performance.

      • Sound Effects and Music: Implement sound effects for slicing, and explosions.

IM SHOWCASE



Final project proposal update – fruit ninja

Finalized concept:
My finalized concept is still Fruit Ninja XR, but the only change is that I am currently using an accelerometer instead of a flex sensor, The program uses the camera to get the user’s hands x position using the ml5 hand pose model, and then while rotating the Arduino the y axis changes.

The Arduino will be moved in a knife motion and will send the y value of the accelerometer to change the y value of the cutter in the p5 sketch.

The p5 will not send any data to the Arduino. The p5 sketch captures the camera input from the device and detects the user’s hand. Also, the p5 sketch generates fruits and bombs from the bottom of the screen and throws them in a projectile motion. After the user slices through a fruit a line with an angle of slicing appears, the fruit gets sliced into two halves, and then the score increases by one. If the user slices a bomb, the bomb explodes, he loses a life, and the screen goes white for a couple of seconds.

reading response – Design meets disability

Reading “Design Meets Disability” felt like a light bulb turning on in my head. I’d never really thought about disability as something created by society, you know? It made me realize how much design impacts people’s lives, either by opening doors or putting up walls.
The part about universal design really stuck with me. It’s like, why wouldn’t we want to make things that everyone can use and enjoy? It just makes sense! It’s like that curb cut example – it helps so many people, not just those in wheelchairs. It shows how good design can be helpful and just plain smart.
The book also reminded me of the saying, “Nothing About Us Without Us,” which is all about giving disabled people a voice. It made me think about how important it is for designers to actually listen to the people they’re designing for, especially when it comes to accessibility. Their experiences are what matters most, and they can help create designs that truly work for everyone.
This book really got me thinking. How can we get more designers on board with inclusive design? How can we work together to make sure accessibility isn’t just an afterthought? These are big questions, but I think finding answers is super important for creating a world where everyone feels welcome and valued.

Week 12 Assignment – Exercises done in class by Marcos Hernández and Marwan AbdElhameed

Introduction

During class, we were asked to complete, in pairs, three exercises in order to get more familiar with the serial communication between Arduino and p5.js. The exercises asked the following:

EXERCISE 01: ARDUINO TO P5 COMMUNICATION

Make something that uses only one sensor on Arduino and makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on Arduino is controlled by p5.

EXERCISE 02: P5 TO ARDUINO COMMUNICATION

Make something that controls the LED brightness from p5.

EXERCISE 03: BI-DIRECTIONAL COMMUNICATION

Take the gravity wind example and make it so:

    • Every time the ball bounces, one LED lights up and then turns off
    • And you can control the wind from one analog sensor

Therefore, in order to complete the assignment effectively, we split it respectively, and we communicated along the execution, since we needed to make sure we were not only following instructions adequately, but that we could finish on time.

Exercise #1 and #2  –  Marcos Hernández

For this assignment, there was not any tweaking of the code done in the file provided (W11_01_Bidirectional_Com.ino) alongside the class presentation in Week 12.

So, for the set-up, I just prepared the Arduino in a way that it functions with the code without being modified, since it already did everything needed for these two exercises. Although, in p5.js, I duplicated the example that we were provided on class to work with. Likewise, I did make changes since it would not replicate what was needed for exercise #1 and #2.

After setting up the Arduino, we have the following:

And with this code in p5.js that is modified so as every time the circle is clicked, the red LED gets turn on as well as having the possibility of moving it horizontally with a potentiometer via analog values:

let rVal = 0;
let alpha = 255;
let left = 0; // True (1) if mouse is being clicked on left side of screen
let right = 0; // True (1) if mouse is being clicked on right side of screen

function setup() {
  createCanvas(640, 480);
  textSize(18);
}

function draw() {
  // one value from Arduino controls the background's red color
  background(255)

  // the other value controls the text's transparency value
  fill(255, 0,0)

  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
    // Print the current values
    text('rVal = ' + str(rVal), 20, 50);
    text('alpha = ' + str(alpha), 20, 70);
  }

  // click on one side of the screen, one LED will light up
  // click on the other side, the other LED will light up
  if (mouseIsPressed) {
    if (mouseX > rVal-50 && mouseX < rVal+50 && mouseY > height/2-50 && mouseY < height/2+50) {
      right = 1;
    } 
  } else {
    right = 0;
  }
  ellipse(rVal, height/2, 50,50)
}

function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

// This function will be called by the web-serial library
// with each new line of data. The serial library reads
// the data until the newline and then gives it to us through
// this callback function
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    // split the message
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 2) {
      // only store values here
      // do everything with those values in the main draw loop
      
      // We take the string we get from Arduino and explicitly
      // convert it to a number by using int()
      // e.g. "103" becomes 103
      rVal = int(fromArduino[0]);
      alpha = int(fromArduino[1]);
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = left + "," + right + "\n";
    writeSerial(sendToArduino);
  }
}

We have the following result observed in the video:

After completing these exercises, I started to feel more confident as to how I will work on my final project.

Exercise #3  –  Marwan AbdElhameed

This one is particular was challenging. Basically, the sensor data is sent to Arduino after mapping it to -1,1, then the Y position of the ball is sent to the Arduino and checked if it was >330. If it is, the LED at is switched to HIGH.

The code found in p5.js:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  wind = createVector(0,0);
}

function draw() {
    if (!serialActive) {
    text("Press s to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
    // Print the current values
    text('rVal = ' + str(rVal), 20, 50);
    text('alpha = ' + str(alpha), 20, 70);
  }
  
  background(255);
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  if (position.y > height-mass/2) {
      velocity.y *= -0.9;  // A little dampening when hitting the bottom
      position.y = height-mass/2;
    }
}

function applyForce(force){
  // Newton's 2nd law: F = M * A
  // or A = F / M
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function keyPressed(){
  if (keyCode==LEFT_ARROW){
    wind.x=-1;
  }
  if (keyCode==RIGHT_ARROW){
    wind.x=1;
  }
  if (key==' '){
    mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
   if (key == 's') {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    // split the message
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 1) {
      
      wind = int(fromArduino[0]);
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = position.y + "\n";
    writeSerial(sendToArduino);
  }
}

The code sent to the Arduino:

int leftLedPin = 2;

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  // We'll use the builtin LED as a status output.
  // We can't use the serial monitor since the serial connection is
  // used to communicate to p5js and only one application on the computer
  // can use a serial port at once.
  pinMode(LED_BUILTIN, OUTPUT);

  // Outputs on these pins
  pinMode(leftLedPin, OUTPUT);

  // Blink them so we can check the wiring
  digitalWrite(leftLedPin, HIGH);
  delay(200);
  digitalWrite(leftLedPin, LOW);



  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

    int left = Serial.parseInt();
    if(left>=330){
       digitalWrite(leftLedPin, HIGH);
}
  
    if (Serial.read() == '\n') {
      digitalWrite(leftLedPin, left);
      int sensor = analogRead(A0);
      sensor = map(sensor,0,1023,-1,1);
      Serial.println(sensor);

    }
  }
  digitalWrite(leftLedPin, LOW);
}

After sending the setting up the Arduino, sending the code and using the one that was written in p5.js, we have the following result:

Conclusion

Working on Arduino, at first sight, might appear scary and too technical. But with these exercises, both my teammate and I feel more comfortable with the Arduino world. As they say, the hardest step will always be the first, and the rest, should be left to curiousness.

 

Final Project Concept: Fruit Ninja with Gesture Recognition

Concept: This project aims to create a physically interactive version of the popular game Fruit Ninja using Arduino and P5.js. Instead of swiping on a touchscreen, players will use a glove equipped with flex sensors to control the game through hand gestures.

Components:
Arduino: An Arduino board will be used to read data from the flex sensors on the glove.
Flex Sensors: These sensors will be attached to the glove’s fingers, detecting the bending motion when the player performs slicing gestures.
P5.js: P5.js will be used to create the game environment, display the fruits, and detect collisions between the virtual sword (player’s hand) and the fruits.

Gameplay:
Calibration: The player will initially calibrate the system by performing various hand gestures, allowing the Arduino to establish a baseline for each sensor and determine the range of motion.
Fruit Slicing: Fruits will appear on the screen, similar to the original game. The player will slice through the air with their hand, and the flex sensors will detect the bending of the fingers.
Data Transmission: The Arduino will send data from the flex sensors to P5.js via serial communication.
Collision Detection: P5.js will analyze the sensor data and determine if the player’s “virtual sword” (hand movement) intersects with a fruit on the screen.

Feedback: Successful slices will result in visual and auditory feedback, such as the fruit splitting apart and a slicing sound effect.
Scoring: The game will keep track of the player’s score based on the number of fruits sliced and the accuracy of their movements.

Challenges:
Sensor Calibration: Ensuring accurate and consistent readings from the flex sensors will be crucial for responsive gameplay.
Gesture Recognition: Developing an algorithm in P5.js to reliably translate sensor data into slicing actions will require careful design and testing.
Latency: Minimizing lag between the player’s movements and the game’s response is essential for a smooth and enjoyable experience.

Potential Enhancements:
Haptic Feedback: Integrating vibration motors into the glove could provide physical feedback when the player slices a fruit, further enhancing immersion.

Reading response – Interaction Design

Reading Bret Victor’s passionate critique of interaction design felt like he was voicing my own frustrations. Why do so many interfaces feel clunky and unnatural, forcing us to think like computers instead of them adapting to us? His call for a future where technology interacts with us as seamlessly as human speech resonated deeply.
The comparison he draws between current interfaces and the early days of written language is particularly powerful. It highlights the vast potential for improvement and reminds us that we’re still in the infancy of designing truly intuitive and human-centered interactions.
Victor’s vision connects with projects like the Tangible Media Group’s shape-shifting displays, where the digital and physical blend seamlessly. It’s exciting to imagine a future where interacting with technology is as natural as speaking or gesturing.
This rant is a powerful call to action. It challenges us to break free from limitations and create technology that empowers and inspires. It’s a future I’m eager to contribute to, where technology enhances our lives instead of holding us back.

Musical Instrument

This project provided valuable insights into the potential of technology in musical expression and exploration. Despite its seemingly simple design, utilizing two push buttons for sound generation and an ultrasound sensor for frequency modulation, the project unveiled a range of creative possibilities and highlighted areas for further development.

The incorporation of the ultrasound sensor was particularly intriguing. By translating physical distance into audible frequencies, the sensor effectively transformed space into a controllable musical parameter. This interaction proved to be a captivating demonstration of how technology can facilitate new forms of musical interaction and expression. The concept invites further exploration, prompting questions about the potential for incorporating additional sensors to create a multi-dimensional instrument responsive to a wider range of environmental stimuli.

// Check if distance is within range for playing sound
if (distance < 200 && distance > 2) {
   // Map distance to frequency
   int frequency = map(distance, 2, 200, 200, 2000);
   tone(buzzerPin, frequency); // Play sound at calculated frequency
 } else {
   noTone(buzzerPin); // Stop sound if distance is out of range
 }

 

While the project successfully demonstrated the feasibility of generating sound through Arduino, the limitations of pre-programmed sounds became evident. The lack of nuance and complexity inherent in such sounds presents a challenge for creating truly expressive and dynamic musical experiences. This observation underscores the need for further exploration into sound generation techniques, potentially involving machine learning or other advanced algorithms, to expand the sonic palette and introduce more organic and evolving soundscapes.

production assignment week 10

This project allows us to control the brightness of two LEDs – one red and one green – using a potentiometer and a push button.

Here’s what you’ll see in the video:
An Arduino Uno board.
A potentiometer, acting as a dimmer switch.
A push button for an instant override.
Two LEDs, red and green, responding to our commands.

How does it work?
Let’s dive into the details:
The Potentiometer: As you turn the knob, it sends varying voltage values to the Arduino. The code interprets these values and maps them to control the brightness of the LEDs. Turning one way brightens the green LED while dimming the red, and vice versa.
The Push Button: This acts as an override switch. No matter what the potentiometer setting is, pressing the button instantly turns the red LED on to full brightness.

Technical Insights:
The project utilizes the Arduino’s analog input capabilities to read the potentiometer values and its PWM (Pulse Width Modulation) functionality to control the LED brightness.
The push button is connected to a digital input pin, allowing the Arduino to detect button presses and trigger the override function.

void loop() {
  int sensorValue = analogRead(A0);
  buttonState = digitalRead(btn);
    brightness = map(sensorValue,0,1023,0,255);

  brightness2 = map(sensorValue,0,1023,255,0);

  analogWrite(led,brightness);
    analogWrite(led2, brightness2);

  if (buttonState == HIGH) {
      analogWrite(led,255);
  }

  Serial.println(sensorValue);

}

 

reading response Making Interactive Art/Physical Computing’s

Reading about interactive art in “Physical Computing’s Greatest Hits and Misses” and “Making Interactive Art: Set the Stage, Then Shut Up and Listen” felt like peeking behind the curtain of a magic show. It made me ponder the fascinating dance between the artist, the artwork, and us, the audience, especially when technology joins the party.
One big question that popped into my head was: can an artist ever truly be the puppet master in this interactive playground? I mean, the moment you invite participation, you’re kind of handing over the reins, right? It’s like setting up a stage for improv – you provide the props and the backdrop, but the actors, well, they bring the story to life in their own unique way. And that’s pretty darn exciting, this unpredictability that makes each experience unique.
“Making Interactive Art” really struck a chord with me when it talked about setting the stage and then taking a step back. It’s like the artist is saying, “Here’s the world I’ve built, now come explore and make it your own.” This reminds me of those cool performance art pieces or happenings, where the lines between performer and audience blur, and everyone becomes part of the art. It’s all about embracing the unexpected, the happy accidents that make life (and art) so interesting.
There was this one bit in “Physical Computing’s Greatest Hits and Misses” that made me pause. It talked about how getting lost in fancy technology can actually be a trap. It reminded me that the heart of interactive art isn’t about gadgets and gizmos, it’s about the human connection, the emotions and thoughts it evokes. Like, a cool light show is fun and all, but if it doesn’t make you feel something, think something, then is it really art?
These readings have made me realize that the artist in interactive art is more like a gardener than a dictator. They plant the seeds, nurture the soil, but ultimately, it’s up to us, the audience, to help the garden grow. And that’s the beauty of it, this collaborative spirit that makes interactive art feel so alive, so human.
Now, I’m curious to see how artists can create these interactive worlds without being too controlling. It’s like finding that sweet spot where the artist’s vision meets the audience’s imagination, and together, they create something truly magical.

Water switch

Just using basic chemistry you know that salt is an ionic compound which, when dissolved in water, breaks up completely into ions. Add ions are what moves in a circuit, and what produces energy. So I dissolved some salt in water and used that as a switch. All you have to do is put the wire in the cup and the electricity goes from the board to the water, then from the water to the circuit.