Week 12 – Serial Communication

Exercise 1

Ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on Arduino is controlled by p5

Code 1

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);
  }
}

Exercise 2

Something that controls the LED brightness from p5

code 2

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(map(rVal, 0, 1023, 0, 255), 255, 200);

  // the other value controls the text's transparency value
  fill(255, 0, 255, map(alpha, 0, 1023, 0, 255));

  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 <= width / 2) {
      left = 1;
    } else {
      right = 1;
    }
  } else {
    left = right = 0;
  }
}

function keyPressed() {
  if (key == " ") {
    // 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 == 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);
  }
}

Video

Arduino code for 1 and 2

int leftLedPin = 2;
int rightLedPin = 5;

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);
  pinMode(rightLedPin, OUTPUT);

  // Blink them so we can check the wiring
  digitalWrite(leftLedPin, HIGH);
  digitalWrite(rightLedPin, HIGH);
  delay(200);
  digitalWrite(leftLedPin, LOW);
  digitalWrite(rightLedPin, 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();
    int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(leftLedPin, left);
      digitalWrite(rightLedPin, right);
      int sensor = analogRead(A0);
      delay(5);
      int sensor2 = analogRead(A1);
      delay(5);
      Serial.print(sensor);
      Serial.print(',');
      Serial.println(sensor2);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

Exercise 3

Bouncing ball

video

code 3

let velocity;
let gravity;
let position;
let acceleration;
let breeze;
let drag = 0.99;
let mass = 50;
let heightOfBall = 0;
function setup() {
  createCanvas(640, 360); // Create a canvas of 800x400 pixels
 
  noFill();
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  breeze = createVector(0,0); 
}
function draw() {
  background(215);
  fill(0);
  
  if (!serialActive) {
    text("Press the space bar to select the serial Port", 20, 50);
  }
  else 
  {
    text("check the light.", 20, 50);
  
  applyForce(breeze);
  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;
    
    heightOfBall = 0;
    
    } 
    else {
      heightOfBall = 1;
    }
  }
}
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 (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}
// this callback function
function readSerial(data) {
    ////////////////////////////////////
    //READ FROM ARDUINO HERE
    ////////////////////////////////////
  
     if (data != null) {
    // make sure there is actually a message
    
    let fromArduino = split(trim(data), ",");
    
       // if the right length, then proceed
    if (fromArduino.length == 1) {
//sensor value is the input from potentiometer
      let sensorVal = int(fromArduino[0]);
      
//potentiometer value ranges from 0 - 1023
//for values less than 400,wind blows to right
      if (sensorVal < 400){
        breeze.x=1
      }
//if value between 400 and 500, wind stops so ball stops
      else if(sensorVal >= 400 && sensorVal < 500){
        breeze.x = 0
      }
//if value greater than 500, wind blows to left
      else {
        breeze.x = -1
      }
          //////////////////////////////////
          //SEND TO ARDUINO HERE (handshake)
          //////////////////////////////////
    }
//height of ball sent to arduino to check if ball on floor or not
    let sendToArduino = heightOfBall  + "\n";
    writeSerial(sendToArduino);
  }
}

code 3 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);
  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() {
  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);
}

 

Arduino + p5js in class exercises (Luke and Gunjan)

For our first exercise, we used a light sensor as the analog input value for the movement of the ellipse on the p5js screen. The rVal from Arduino is used to plot the x coordinate of the ellipse.

Demo:

Circuit:

Code:

P5Js:

//Exercise 1 P5js Code
let ellipseX; // Variable to store ellipse's x-coordinate
function setup() {
  createCanvas(600, 400); // Create a canvas of 800x400 pixels
  ellipseX = width / 2; // Set initial x-coordinate of ellipse to middle of the screen
  noStroke(); // No stroke for the ellipse
}
function draw() {
  
  background(220); // Refresh background on each frame
  fill(0, 0, 255); // Set fill color to red
  ellipse(ellipseX, height / 2, 50, 50); // Draw ellipse at current x-coordinate and middle of the screen
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);}
}
function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }   
}
// 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 == 1) {
      // only store values here
      // do everything with those values in the main draw loop
//values from light sensor roughly ranged between 0 and 500,000 so map them between 0 and width of the screen
//use the mapped value as x-coordinate of the ellipse
      ellipseX = map(data,0,500000, 0,width);
    }
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
   let sendToArduino = fromArduino + "\n";
   writeSerial(sendToArduino);
  }
}

In future implementations, we may want the ball to move in a smoother fashion. We can consider adding codes that can smooth out the path of the ball’s movement. But using the photosensor to control the ball, we reinforce the knowledge about coding in Arduino and sending data from Arduino to p5.

Exercise 2:

https://drive.google.com/file/d/18aedgmMdG_DP-2rTXQYxR1kvSSRr9CIY/view

Circuit:

P5js code:

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
let slider;
function setup() {
  createCanvas(640, 480);
  textSize(18);
  slider = createSlider(0,255,0);
  slider.position(50,50);
}
function draw() {
  // one value from Arduino controls the background's red color
  background('white');
  // 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 <= width / 2) {
  //     left = 1;
  //   } else {
  //     right = 1;
  //   }
  // } else {
  //   left = right = 0;
  // }
}
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) {
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = slider.value() + "\n";
    console.log(slider.value());
    writeSerial(sendToArduino);
    
    }
}

In terms of the future improvement for this one, we may want to control multiple LEDs with only one slider, or add more sliders to control many LEDs. But it helped us think about writing the code on transferring data to Arduino.

Exercise 3:

Circuit:

p5js code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let rVal ;
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() {
  background(255);
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  fill("blue");
  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;
    }
  if (position.y == height - mass/2) {
      right = 1;
  } else {
      right = 0;
  }
  if (rVal > 522) {
    wind.x = 1;
} else if (rVal < 502) {
    wind.x = -1;
} else {
    wind.x = 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);
  // }
}
function applyForce(force){
  // Newton's 2nd law: F = M * A
  // or A = F / M
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}
// if (position.y == height - mass/2) {
    
//     //   left = 1;
//     // } else {
//       right = 1;
//     // }
//   } else {
//     // left = right = 0;
//   right = 0;
//   }
function keyPressed(){
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  // if (keyCode==LEFT_ARROW){
  //   wind.x=-1;
  // }
  // if (keyCode==RIGHT_ARROW){
  //   wind.x=1;
  // }
  if (keyCode==ENTER){
    // mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
}
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////
  if (data != null) {
    // make sure there is actually a message
    // split the me ssage
    rVal=data;
    print(rVal);
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = right + "\n";
    writeSerial(sendToArduino);
  }
}

Challenges and implementations: we had no problem making the LED blink every time the ball touches the ground. But we did face some challenges in controlling the wind with the potentiometer initially. The ball kept moving to the left and we couldn’t figure out how to control it no matter what. In the end, we figure out that the issue lies in mapping and in coding the snippets of codes we want to send from p5 into Arduino. For improvements, we want to increase the speed of the ball being controlled by the potentiometer. At the moment, it is moving rather slowly.

Final Project Proposal Draft 1

Introduction

For my final project I’ve decided to work on something which is relatable for us all students: Stress.  Drawing inspiration from some previous works, especially the one which used stress levels to create patterns, I’ve come up with a new concept. Given that it’s finals week and students are feeling highly stressed, my project will allow them to use a stress ball to gauge their stress levels, which will be represented by a stress scale in p5.js. If their stress levels reach the maximum, the p5.js sketch will display calming patterns and play soothing music to help the user feel calm.

Concept

The idea is to use a stress ball to measure stress levels. When you squeeze the ball, it tells you how stressed you are. The project then shows your stress level using a stress scale in p5, plays relaxing music and soothing patterns if you’re very stressed.

Components

  • Stress Ball
  • Flex Sensor
  • Arduino Board
  • Breadboard
  • Jumper Wires
  • Resistors
  • Speaker

How it works

  1. Stress Sensing:
    • stress ball with a sensor inside to measure how hard you’re squeezing.
  2. Arduino Interaction:
    • An Arduino board talks to the stress ball sensor.
    • The Arduino reads how hard you’re squeezing and tells the computer.
  3. p5.js Visualization:
    • The computer shows your stress level on a scale.
  4. Interactive Response:
    • If you get really, really stressed, the project shows calming patterns.
  5. Audio Feedback:
    • If you’re super stressed, it plays calming music to help you relax.

 

Week 12: Design meets disability

I really enjoyed this reading as it gave me a new insight on these products. When we think of discretion in relation to fashion, like the author mentioned, it is a bit tricky to design products for disabilities. There is always a doubt of whether the product should be designed “invisibly” or more as fashion wear. When it is designed to be unseen, it seems more like the disability is to be ashamed of.

In general, having products with good design makes it more likely that the person would enjoy using it. I also found it very interesting the idea of designing unique pieces rather than designing one thing for everyone. Even for people with disabilities, there should be a diversity of designs for a product which should also be something that makes them feel good.

Final Project Proposal Draft 1

Introduction Concept: The Crypto Locker Puzzle is an interactive project designed to challenge users with a series of code-cracking tasks under time constraints. The objective is to solve hints and enter correct codes using a custom-built interface to unlock a wooden box and win the prize inside. This game combines physical computing with digital elements to create an engaging and educational experience.


Objective:
The main goal of this project is to engage users in a fun and educational way by combining elements of cryptography and puzzle-solving. The game encourages critical thinking and problem-solving skills as players attempt to unlock the box within a specified time limit, providing an enjoyable and challenging experience.

Key Features

1) Dynamic Countdown Timer: A prominently displayed timer adds a sense of urgency and excitement to the gameplay. It counts down from a set time, pushing players to think and act quickly, which enhances the challenge and engagement of the puzzle.

2) Attempt Counter: This feature tracks the number of attempts a user makes to solve the puzzle. It’s great for adding a competitive edge, as players can challenge themselves or others to solve the puzzle in fewer attempts, promoting replayability.

3) Cryptic Hints Display: As players progress, cryptic hints are displayed on the screen to aid in decoding the puzzle. This feature helps to balance the difficulty level and ensures that the puzzle remains solvable while still challenging.

4) Thematic Interface Design: The interface’s design is sleek and modern, resembling a spy gadget, which aligns well with the thematic elements of the puzzle box. This integration of theme and function helps to immerse players in the game’s world.

5) Feedback on Input Accuracy: When players enter a code, the interface immediately provides feedback. If the code is incorrect, players are prompted to try again, and if correct, a success message is displayed, and the box unlocks. This immediate feedback loop keeps players engaged and informed.

6) Multiple Difficulty Levels: With the inclusion of three difficulty levels, the game can cater to a broad range of skill levels. Beginners can start with simpler, shorter codes and fewer hints, while advancing – the game takes the user tackle longer codes with cryptic hints.

Components

  • Arduino Uno: Serves as the main controller for input and output operations.
  • Servo Motor: Operates the locking mechanism of the box.
  • Potentiometer: Allows users to select digits for the code.
  • Button: Used for entering selected digits and navigating through the game.
  • P5.js: It acts like a digital interface that provides instructions, feedback, and manages the timer and attempt counter.

P5.js Sketch: The P5.js sketch handles the game logic and user interface. It displays hints, the countdown timer, and the number of attempts. It also receives digit inputs from the Arduino and checks them against the predetermined code. If the code is correct, it sends a command to unlock the box.

Arduino Sketch: The Arduino controls the hardware aspects of the project. It uses a servo motor to lock and unlock the box. A potentiometer is used for dialing in digits (0-9), and a button confirms the entry of each digit. The Arduino sends these inputs to the P5.js program, which processes them to determine if the entered code matches the required one.

How the Game Works

    1. Initialization: At the start of the game, the servo motor locks the box, and the Arduino awaits input from the potentiometer and button.
    2. User Interaction: Players turn the potentiometer to select digits and press the button to confirm each entry. The Arduino sends these inputs to the P5.js sketch.
    3. Feedback and Unlocking: The P5.js sketch evaluates the entered code. If incorrect, it prompts the user to try again; if correct, it sends a signal to unlock the box via the servo motor.
    4. Time and Attempts Management: The game includes a countdown timer and records the number of attempts. Players must solve the puzzle before the time runs out.

Week 12 – Serial Communication (Group Assignment)

Team Members: Yaakulya Sabbani and Muhammed Hazza

Exercise 1: ARDUINO TO P5 COMMUNICATION

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. So for this exercise we have used a potentiometer.

Arduino Code

void setup() {
  Serial.begin(9600);
  //pinMode(LED_BUILTIN, OUTPUT);

//start the handshake
  while (Serial.available() <= 0) {
    //digitalWrite(LED_BUILTIN, HIGH);
    Serial.println("0,0"); // send a starting message
    delay(300);
    //digitalWrite(LED_BUILTIN, LOW);
    delay(50);

  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
     //digitalWrite(LED_BUILTIN, HIGH);
    int isMoving = Serial.parseInt();
    if (Serial.read() == '\n') {
      int photoVal = analogRead(A0); 
      delay(5);
      Serial.println(photoVal);
   }
  }
  //digitalWrite(LED_BUILTIN, LOW);
}

P5 code

// Initialize variables to store values from Arduino
let rVal = 0; // Stores the received value from Arduino
let xPos = 0; // Stores the mapped x-position value
let rad = 50; // Radius of the ellipse to be drawn

// Setup function - runs once at the beginning
function setup() {
  // Create a canvas with dimensions 400x400
  createCanvas(400, 400);
  // Set text size to 18 pixels
  textSize(18);
}  

// Draw function - runs continuously
function draw() {
  // Set background color to white
  background(255);

  // Check if serial communication is active
  if (!serialActive) {
    // Display message to prompt user to press Space Bar to select Serial Port
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    // If serial communication is active, display "Connected" message
    text("Connected", 20, 30);
    
    // Map the received value (rVal) to the x-position within the canvas
    xPos = map(rVal, 0, 900, 0, 400);
    // Display the current received value (rVal)
    text('rVal = ' + str(rVal), 20, 50);
    // Draw an ellipse at the mapped x-position with fixed y-position (200) and radius (rad)
    ellipse(xPos, 200, rad, rad);
    // Display the mapped x-position (xPos)
    text('xPos = ' + str(xPos), 20, 70);
  }
}

// Function to handle key presses
function keyPressed() {
  // Check if Space Bar is pressed
  if (key == " ") {
    // Call setUpSerial() function to start serial connection
    setUpSerial();
  }
}

// Function to read data from Arduino
function readSerial(data) {
  // Check if data is not null
  if (data != null) {
    // Split the received data into an array using comma as delimiter
    let fromArduino = split(trim(data), ",");
    
    // Check if the array contains only one element
    if (fromArduino.length == 1) {
      // Update rVal with the received value from Arduino
      rVal = fromArduino[0];
    }
    
    // Send a handshake message to Arduino
    let sendToArduino = 1 + "\n";
    writeSerial(sendToArduino);
  }
}

Schematic

Video Demonstation

 

Exercise 2: P5 TO ARDUINO COMMUNICATION

Something that controls the LED brightness from p5. For this exercise we have created a slider to controll the brightness of the green led.

Arduino Code

//Ex-2 Arduino Code

const int ledPin =9;
int brightness = 0;
void setup() {
  Serial.begin(9600); // This will start serial communication at 9600 bps

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ledPin, OUTPUT);
// start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on blink when waiting for serial data
    Serial.println("0,0"); // sending a starting message 
    delay(300);            // waiting for the delar
  }
}
void loop() 
{
  // wait for data from p5 before doing something
    while (Serial.available()) 
    {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
    int brightness = Serial.parseInt(); //get slider value from p5
    Serial.println(brightness); //just to view the value
    
     if (Serial.read() == '\n') {
       analogWrite(ledPin, brightness); // will set brightness of LED
     
      }else
      {
        digitalWrite(LED_BUILTIN, HIGH);
      }
    }
}

P5 Code

//Exercise 2 - P5js Code
let slider;
function setup() {
   createCanvas(400, 400); // Creating canvas of 400x400 pixels
  slider = createSlider("0, 255, 0");
  slider.position(100, height/2); // Set the position of the slider
  slider.style('width', '80px'); // Set the width of the slider 
 
  
  noStroke(); // No stroke for the ellipse initially
}
function draw() {
  
  background(255); // Refresh background on each frame
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);}
}
function keyPressed() {
  if (key == " ") {
    // setting the serial connection!!
    setUpSerial();
  }   
}
// this callback function
function readSerial(data) {
    ////////////////////////////////////
    //READ FROM ARDUINO HERE
    ////////////////////////////////////
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    console.log(slider.value());
    let sendToArduino = slider.value() + "\n";
    writeSerial(sendToArduino);
  
}

Video Demonstration

Schematic

Exercise 3: BI-DIRECTIONAL COMMUNICATION

Every time the ball bounces one led lights up and then turns off, potentiometer is used as the analog sensor to control the wind.

Arduino Code

//Exercise 3 Arduino Code

const int poten_pin = A0;
const int ledPin = 2;
void setup() {
 Serial.begin(9600); // Start serial communication at 9600 bps
 pinMode(LED_BUILTIN, OUTPUT);
 pinMode(ledPin, OUTPUT);
 pinMode(poten_pin, INPUT);
 // 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);
     digitalWrite(ledPin, LOW);
//read the position of ball from p5
     int position = Serial.parseInt();
  
     if (Serial.read() == '\n') {
       // Read potentiometer value
     int sensorValue = analogRead(poten_pin);
     //send value to p5
     Serial.println(sensorValue);
     }
//if ball is touching the ground i.e. height is zero, turn LED on
     if (position == 0)
     {
       digitalWrite(ledPin, HIGH);
     }
     else{
       digitalWrite(ledPin, LOW);
     }
   }
     digitalWrite(LED_BUILTIN, LOW);
   }

p5 Code

//Exercise 3 - P5js Code

let velocity;
let gravity;
let position;
let acceleration;
let breeze;
let drag = 0.99;
let mass = 50;
let heightOfBall = 0;
function setup() {
  createCanvas(640, 360); // Create a canvas of 800x400 pixels
 
  noFill();
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  breeze = createVector(0,0); 
}
function draw() {
  background(215);
  fill(0);
  
  if (!serialActive) {
    text("Press the space bar to select the serial Port", 20, 30);
  }
  else 
  {
    text("Arduino is connected! Press b to jump.", 20, 30);
  
  applyForce(breeze);
  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;
    
    heightOfBall = 0;
    
    } 
    else {
      heightOfBall = 1;
    }
  }
}
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 (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }   
  else if (key=='b'){
    mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
}
// this callback function
function readSerial(data) {
    ////////////////////////////////////
    //READ FROM ARDUINO HERE
    ////////////////////////////////////
  
     if (data != null) {
    // make sure there is actually a message
    
    let fromArduino = split(trim(data), ",");
    
       // if the right length, then proceed
    if (fromArduino.length == 1) {
//sensor value is the input from potentiometer
      let sensorVal = int(fromArduino[0]);
      
//potentiometer value ranges from 0 - 1023
//for values less than 400,wind blows to right
      if (sensorVal < 400){
        breeze.x=1
      }
//if value between 400 and 500, wind stops so ball stops
      else if(sensorVal >= 400 && sensorVal < 500){
        breeze.x = 0
      }
//if value greater than 500, wind blows to left
      else {
        breeze.x = -1
      }
          //////////////////////////////////
          //SEND TO ARDUINO HERE (handshake)
          //////////////////////////////////
    }
//height of ball sent to arduino to check if ball on floor or not
    let sendToArduino = heightOfBall  + "\n";
    writeSerial(sendToArduino);
  }
}

Schematic

Video Demonstration

Week 12: Response on Design Meets Disability

My understanding of the reading ‘Design meets Disability’ made me conclude that the evolution of disability aids into fashionable items, and it questions the idea that these designs must prioritize invisibility over style. One of the designs in the reading, portrays the evolution of glasses from stigmatized medical aids to stylish fashion accessories, challenging the notion that design for disability must be inconspicuous. And I think we can see how the transformation of eyewear serves as a case study, showing that embracing visibility can enhance the acceptability of assistive devices. In contrast to the historical push for devices to be flesh-colored and blend in, eyewear has achieved a positive image without invisibility, becoming both a tool for vision enhancement and a fashion statement (pg. 16).

One fascinating aspect is the historical perspective that considered glasses as a symbol of social humiliation, which has dramatically shifted over time. The change in perception from medical necessity to fashion accessories reflects a societal adaptation and a broader acceptance of diversity. The transition emphasizes how designs can shift cultural narratives and the importance of integrating aesthetic considerations into functionality (pg. 15-16).

Another compelling point is the influence of the design of Charles and Ray Eames’ leg splints on modern furniture. Their approach, integrating the constraints of disability to inspire innovative design, demonstrates how limitations can spur creativity, resulting in designs that serve a broader purpose and audience. The Eames’ work illustrates that design with a focus on disability does not have to forsake style or cultural relevance.

This exploration I think reevaluates how we perceive design in the context of disability, emphasizing that functionality need not exclude aesthetic appeal. And it surely highlights the potential for designs that acknowledge the user’s desire for both utility and style, fostering a more inclusive approach to product development.

Raya Tabassum: Serial Communication Project

1. 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

For this project, I used a potentiometer connected to the Arduino to send its readings to a p5.js sketch via serial communication. The position of the ellipse on the screen will correspond to the potentiometer’s position.

Arduino Code:

#include <Arduino.h>

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

void loop() {
  int sensorValue = analogRead(A0); // Read the potentiometer
  Serial.println(sensorValue);      // Send the value to the serial port
  delay(50);                        // Delay for stability
}

p5.js Code:

let serial;          
let latestData = 0;  

function setup() {
  createCanvas(640, 360);
  serial = new p5.SerialPort();  
  serial.on('data', gotData);  
  serial.open('/dev/tty.usbmodem11101');  
}

function draw() {
  background(255);
  let sensorValue = map(latestData, 0, 1023, 0, width); 
  ellipse(sensorValue, height / 2, 50, 50); 
}

function gotData() {
  let currentString = serial.readLine(); 
  trim(currentString);                   
  if (!currentString) return;            
  latestData = parseInt(currentString);  
}

2. Make something that controls the LED brightness from p5

To control an LED’s brightness from p5.js sketch, this setup will use a graphical slider in the p5.js sketch to send brightness values to the Arduino, which in turn will adjust the brightness of the LED accordingly.

Arduino Code:

#include 

const int ledPin = 9;  

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    int brightness = Serial.parseInt();  
    if (Serial.read() == '\n') {  
      analogWrite(ledPin, brightness);  
    }
  }
}

p5.js Code:

let serial;          
let slider;          

function setup() {
  createCanvas(400, 300);
  serial = new p5.SerialPort();
  serial.on('open', onSerialOpen);  
  serial.on('error', onSerialError);  
  serial.open('/dev/tty.usbmodem11101');  

  //Create a slider from 0 to 255 (LED brightness range)
  slider = createSlider(0, 255, 127);
  slider.position(10, 10);
  slider.style('width', '380px');
}

function draw() {
  background(102);
  let val = slider.value();  
  serial.write(val + '\n');  

  fill(255);
  noStroke();
  text("LED Brightness: " + val, 10, 50);
}

function onSerialOpen() {
  console.log('Serial Port is open');
}

function onSerialError(err) {
  console.log('Something went wrong with the serial port. ' + err);
}

3. 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

For this, the wind force is controlled by a potentiometer connected to the Arduino, allowing the user to influence the ball’s horizontal movement by adjusting the potentiometer. And every time the ball bounces off the bottom of the canvas, an LED connected to the Arduino lights up briefly as a visual indicator of the bounce.

Arduino Code:

#include 

const int ledPin = 13;  
const int potPin = A0;  
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int potValue = analogRead(potPin); 
  Serial.println(potValue);          

  if (Serial.available()) {
    char command = Serial.read(); 
    if (command == '1') {
      digitalWrite(ledPin, HIGH); 
      delay(100);                 
      digitalWrite(ledPin, LOW);  
    }
  }
  delay(10); 
}

p5.js Code:

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

function setup() {
  createCanvas(640, 360);
  serial = new p5.SerialPort();
  serial.on('data', serialEvent);  
  serial.open('/dev/tty.usbmodem11101'); 

  position = createVector(width / 2, 50);
  velocity = createVector(0, 0);
  acceleration = createVector(0, 0);
  gravity = createVector(0, 0.1 * mass);
}

function draw() {
  background(220);
  applyForce(createVector(wind, 0));  
  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;  
    position.y = height - mass / 2;
    serial.write('1\n');  
  } else {
    serial.write('0\n');
  }
}

function applyForce(force) {
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function serialEvent() {
  let data = serial.readStringUntil('\n').trim();
  if (data !== '') {
    let analogVal = int(data);  // Convert the received string to an integer
    wind = map(analogVal, 0, 1023, -5, 5);  // Map the value to a suitable range for wind
  }
}

Challenges:

As I had to do this solo while other people did in groups, I had some disadvantages of course – by not having another perspective of “why’s this not working”.

The first one was rather easy, thought I’m not sure if we’re supposed to show the values on the serial monitor in the video. The second one was quite tricky for me at first – I had taken a different approach where the brightness of the LED was supposed to increase while I move the cursor horizontally on screen from left to right with a ball on screen which when white the LED would turn off and when getting filled with darker shades the brightness of the LED will also increase. But that wasn’t working well as the LED would turn on and off randomly so I took the slider approach instead which was better and clearer to see.

For the third one, as it took input from p5 to show output to Arduino and vice versa – it took a bit of understanding to implement it. First I did one where the ball bounces vertically and the LED will turn on and off with every bounce – as instructed. And you could push the ball to either left or right using the potentiometer. But the one I submitted I found it better – it can bounce towards left or right depending on which side you turn the potentiometer – even if it starts at one side you can change the way while it’s bouncing and the LED also works fine. Overall, it was a great experience doing it by myself to learn better about serial communication.

Week 12 Reading (Pi) – Graham Pullin’s Design Meets Disability

“It’s not a weapon, it’s more of a highly advanced prosthesis.” ― Tony Stark (when the court asks if his Iron Man suit is a weapon)

Reflecting upon Graham Pullin’s Design Meets Disability, I find myself musing about this quote from Tony Stark in Iron Man. The suit, while seemingly a robust piece of technology, parallels a fashionable prosthesis, both functional and aesthetically pleasing with its intricate yet discreet components. Indeed, his suit is a prosthesis. This amusing interpretation not only highlights the suit’s dual nature but also aligns with broader design principles.

Transitioning from the fictional world of Iron Man to the real-world impact of design, Charles Eames’s perspective that “design depends largely on constraints” resonates deeply with me. This principle is vividly illustrated in the creation of the Eames leg splint during wartime—a necessity that spurred innovation. The splint was not only functional but also aesthetically pleasing, subsequently influencing mainstream furniture design. This example beautifully encapsulates the dance between limitation and innovation, challenging the preconceived notion that design for disability must forsake beauty for functionality.

The juxtaposition of fashion and discretion in disability design is equally eye-opening. The evolution of eyewear from a stigmatized medical appliance to a fashion accessory exemplifies a significant shift in societal perception. However, the underlying desire for discreet devices reveals a lingering societal discomfort with visible signs of disability. Graham Pullin’s insights provoke a reevaluation of this narrative, advocating for a shift from concealing disabilities to celebrating and empowering individuals.

Pullin’s text not only expands my understanding of functional design but also reaffirms the importance of aesthetics in user-centered design. Whether it pertains to physical objects like a leg splint or digital solutions like software interfaces, the essential principle remains the same: effective design must resonate with users on both functional and aesthetic levels, thereby enhancing their interaction and experience.

Final Project Proposal

My final project idea is to create a virtual tour of the NYUAD campus. This interactive tour will serve as a unique introduction to our campus for incoming students, new students, and faculty. The project will consist of three components: a physical 3D campus map, miniature figure, and an informational page featuring photographs on p5.js.

I will create a physical 3D model of our campus based on the campus map.

Using laser cutting, I will create several layers based on the map and then assemble them to form the buildings. Each building will have an RFID sensor at the entrance.

Users will utilize a miniature figure equipped with an RFID magnet sensor to interact with these buildings. When the user places the miniature figure in front of a building, the p5.js application will display photographs and information about that specific building.

The information page on p5.js will be designed as follows:

In summary, the functions of the Arduino and p5.js in this project are as follows:

– Arduino: Manages sensor inputs located in front of each building.

– p5.js: Displays photographs and information about the building when the sensors send data.