Final project proposal

For my final project I propose to transform the conventional game ‘The Mole’ by incorporating force sensors into an Arduino setup. My goal is to enhance gameplay by introducing a tangible, hands-on interaction using force-sensitive sensors. I envision players engaging with a physical setup, detecting and responding to varying force levels to navigate through game challenges. By fusing classic gameplay with sensor technology, I aim to create an immersive and innovative gaming experience that redefines interaction in gaming environments. This project represents my aspiration to merge traditional entertainment with modern tech, offering players a novel way to engage with ‘The Mole.

I am excited

week 11 – reading reflection

I enjoyed this week’s reading because accessibility is a point that is always brought up when we speak of design and interactivity, whether it was last week’s readings about pictures-under-glass or a broader discussion about the simplicity of design. In this day and age, technological advancements are designed to be so simple that even a toddler could use them. I think instead of simplicity, the foremost thought should be accessibility. In modern design, accessibility is always an afterthought, a sort of ‘add-on’ to an existing design, that often looks unwieldy and takes away from the appearance of the original design. Another reason I strongly believe in everything being accessible instead of simply having accessible alternatives is that I have seen many disabled voices online speak of how having to use ‘alternatives’ is one of the many ways they feel other-ed by society. If everyone, abled or disabled, used the same interfaces and designs, we would be one step closer to a truly inclusive community.

I also love the discussion about the intersection of fashion and accessibility. I, personally, am unsure where I stand on this – I agree in the sense that good design is simple, and that simplicity goes hand-in-hand with universality. However, as someone who is fond of all things camp, a part of me doesn’t agree that all design should direct towards being simple. In fact, I believe that d in design can still be for disability, whilst still exploring aesthetics to their fullest potential.

week 11- reading reflectiom – design meets disability

This book about the collaboration between the Eameses and their creation of leg splints for veterans is a profound exploration of how design transcends its conventional boundaries. What’s truly fascinating is their approach—they didn’t just aim for practicality in their design; they sought to blend functionality with aesthetic appeal.

What’s really interesting is how deeply they considered the human aspect. The Eameses didn’t limit their focus to the technicalities; they delved into the emotional and experiential dimensions of their design. They wanted these splints to not only serve their purpose but also uplift the users’ spirits, ensuring comfort and a sense of dignity.

Their emphasis on inclusive design is remarkable. They didn’t want these splints to be exclusive; they envisioned them as tools accessible to all, irrespective of abilities. It’s a profound statement about the importance of ensuring good design is available universally.

The core message resonating here is that design isn’t just about appearances; it’s about functionality and the impact it has on people’s lives. The Eameses’ venture with these leg splints is a testament to how empathetic design can significantly enhance lives and contribute to a more equitable and inclusive society.

Series Connection

overview:

In this assignment, I worked with Fady John to achieve the three exercises in class

Exercise 1:

p5 js

let left = 0;

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

function draw() {
  background(220);
  fill("red");
  ellipse(left, 50, 50, 50);
}

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

function readSerial(data) {
  left = map(data, 0, 1023, 0, 400);
}

Arduino:

//// Arduino Code
/*

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  int sensor = analogRead(A0);
  delay(5);
  Serial.println(sensor);

}

*/

Exercise 2:

P5 js

let brightnessSlider;
let brightnessValue = 0;

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

  // Create a brightness slider
  brightnessSlider = createSlider(0, 255, 128);
  brightnessSlider.position(width/2-50, height/2);
  brightnessSlider.style('width', '100px');
}

function draw() {
  background(255);

  // Get the brightness value from the slider
  brightnessValue = brightnessSlider.value();
}

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

function readSerial(data) {
  console.log(data);
    let dataToSend = brightnessValue + ", \n";
    writeSerial(dataToSend);  
}

Arduino:

///Arduino COde
/*

const int ledPin = 9;  // Digital output pin for the LED

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

  // Start serial communication
  Serial.begin(9600);
}

void loop() {
  Serial.println("sensor");
  // Check if data is available from p5.js
  if (Serial.available() > 0) {
    // Read the brightness value from p5.js
    int brightness = Serial.parseInt();

    // Map the received value to the LED brightness range
    brightness = constrain(brightness, 0, 255);

    // Set the LED brightness
    analogWrite(ledPin, brightness);
  }
}

*/

Exercise 3:

P5 js

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

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);
  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 && (velocity.y > 0.5 || velocity.y < -0.5)){ 
    led = 1;
  }else{
    led = 0;
  }
}

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 == "n") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  if (key==' '){
    mass=random(15, 80);
    position.y=-mass;
    velocity.mult(0);
  }
}

function readSerial(data) {

  if (data != null) {
    // make sure there is actually a message
    // split the message
    wind.x = data;

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

Arduino:

///Arduino COde

/*

int ledPin = 9;

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

void loop() {
  int sensor = analogRead(A0);
  int wind = map(sensor, 0, 1023, -2, 2);
  Serial.println(wind);
  delay(10);
  if (Serial.available() > 0) {
    // Read the brightness value from p5.js
    int touch = Serial.parseInt();
    // Set the LED brightness
    digitalWrite(ledPin, touch);
  }
}
*/

BOUNCING BALL VIDEO

exercise3 week11

final project proposal

I was building the 3D printer for the lab and noticed how the extruder moves across the X and Y axes. There are two motors, each moving the extruder in one or the other axis. By working both motors together, the extruder can be moved to any X or Y position. This is where I got my final project idea from. I’m going to make a raised tray and fill it with sand, and place one metal ball bearing on the sand surface, like in this picture:

There’s going to be a magnet underneath the table, which attracts the ball, and by moving the magnet, I’ll be able to move the ball on the sand and draw patterns. The magnet is going to be moved across the X and Y axes using two motors, like in the 3D printer. There are a bunch of belts in the IM lab storage, just like the ones that are used in the 3D printer, and I’m hoping that I get to use those for my purposes. If not, I would probably have to order them myself.

This is where p5 comes in: the Arduino controls the motors, but the Arduino is controlled by user input from p5. Users can maybe use keyboard arrows to move a virtual ball on the canvas, and that motion will be replicated by the real ball. I haven’t really pinned down what the user interaction would look like: it could also be users painting with their finger on a touch screen, but the issue with that might be that users might just move their fingers faster than the motors are able to move the ball, so that wouldn’t work. One simple way to tackle this would be to just reduce the frame rate on p5, so that users can’t draw that fast, and the motors are able to keep up.

I would also want to program a “default” mode, so that when there’s no users, the ball draws nice, symmetric shapes on its own. That way, the project could be a nice, standalone art installation, but also interactive.

Coding Assignment – Week #11

Exercise 1:

To move the ellipse in the middle of the screen, I used the example from class with small changes. Here is the sketch:

The ellipse moving part:

let x = map(alpha, 0, 1023, 0, width);
  ellipse(x, height/2, 40, 40)
Exercise 2:

I wanted the brightness level of an LED to be matched with the falling of the ellipse on P5.js. The LED is the brightest when the ellipse is at the bottom of the canvas, thus making the LED brighter as the ellipse falls. Here is the sketch:

P5 code:

let y = 0;

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

function draw() {
  
  background(0);

  // the other value controls the text's transparency value
  fill(255);
  ellipse(width/2, y, 40, 40);
  y+=1;
  
  if (y>height){
    y=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);

  }
  
  print(y)
  

}

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 = y + "\n";
    writeSerial(sendToArduino);
  }
}

Arduino code:

int ledPin = 11;  // LED connected to pin 11

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

  // Blink the LED to indicate setup
  digitalWrite(ledPin, HIGH);
  delay(200);
  digitalWrite(ledPin, LOW);

  // Start the handshake
  while (!Serial.available()) {
    Serial.println("0");  // Send a starting message
    delay(300);
  }
}

void loop() {
  // Wait for data from p5.js before doing something
  while (Serial.available()) {
    int y = Serial.parseInt();
    if (Serial.read() == '\n') {
      // Map the y value to the LED brightness (0-255)
      int brightness = map(y, 0, 240, 0, 255);
      analogWrite(ledPin, brightness);

      // Print the received y value for debugging
      Serial.println(y);
    }
  }
}
Exercise 3:

I made the gravity weaker so that the LED blinking is more clearly visible.

P5 code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let alpha = 0; // Initialize alpha

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

function draw() {
  background(255);

  // Update wind based on alpha
  wind.x = alpha;

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

  print(int(position.y), alpha);
}

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 readSerial(data) {
  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
      alpha = int(fromArduino[1]);
    }

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

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

Arduino code:

const int potPin = A0;  
const int ledPin = 13;  

int potValue;  
int ballPosition;  
bool isBouncing = false;  

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

void loop() {
  // Read the value from the potentiometer
  potValue = analogRead(potPin);

  // Map the potentiometer value to the range of wind force
  int mappedWind = map(potValue, 0, 1023, -1, 1);

  // Send the mapped wind force value to the computer through serial
  Serial.print("0,");
  Serial.println(mappedWind);

  // Read the ball's position from p5.js
  if (Serial.available() > 0) {
    ballPosition = Serial.parseInt();
  }

  // Check if the ball bounces
  if (ballBouncesCondition()) {
    if (!isBouncing) {
      // Turn on the LED when the ball starts bouncing
      digitalWrite(ledPin, HIGH);
      isBouncing = true;
    }
  } else {
    // Turn off the LED if the ball is not bouncing
    digitalWrite(ledPin, LOW);
    isBouncing = false;
  }

  
}

bool ballBouncesCondition() {
  return ballPosition >= 320;
}

 

 

Week 11 | Exercises

Exercise 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

I used an Arduino potentiometer to change the horizontal position of the ellipse in the p5js sketch. The values read from the potentiometer are mapped to the x coordinates of the ellipse, moving it across the horizontal axis in the middle of the screen.

Video of implementation:

Code:

let left = 0;

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

function draw() {
  background(220);
  fill("red");
  ellipse(left, 50, 50, 50);
}

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

function readSerial(data) {
  left = map(data, 0, 1023, 0, 400);
}

//// Arduino Code
/*

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  int sensor = analogRead(A0);
  delay(5);
  Serial.println(sensor);

}

*/

 

Exercise 2: make something that controls the LED brightness from p5

To control the led brightness through P5JS, I created a brightness slider similar to that in our smartphones. The value of the slider is sent to Arduino to be the value of the analog write of the led and change its brightness.

Video of implementation:

Code:

let brightnessSlider;
let brightnessValue = 0;

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

  // Create a brightness slider
  brightnessSlider = createSlider(0, 255, 128);
  brightnessSlider.position(width/2-50, height/2);
  brightnessSlider.style('width', '100px');
}

function draw() {
  background(255);

  // Get the brightness value from the slider
  brightnessValue = brightnessSlider.value();
}

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

function readSerial(data) {
  console.log(data);
    let dataToSend = brightnessValue + ", \n";
    writeSerial(dataToSend);  
}

///Arduino COde
/*

const int ledPin = 9;  // Digital output pin for the LED

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

  // Start serial communication
  Serial.begin(9600);
}

void loop() {
  Serial.println("sensor");
  // Check if data is available from p5.js
  if (Serial.available() > 0) {
    // Read the brightness value from p5.js
    int brightness = Serial.parseInt();

    // Map the received value to the LED brightness range
    brightness = constrain(brightness, 0, 255);

    // Set the LED brightness
    analogWrite(ledPin, brightness);
  }
}

*/

Exercise 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

When the ball touches the ground, the value of the variable Led changes accordingly (either 0 or 1) and then sent to the Arduino to toggle the led at pin 9. For the wind effect, I used a potentiometer where its values are mapped to values between -2 and 2, making a smooth wind effect moving the ball horizontally.

Video of implementation:

Code:

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

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);
  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 && (velocity.y > 0.5 || velocity.y < -0.5)){ 
    led = 1;
  }else{
    led = 0;
  }
}

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 == "n") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  if (key==' '){
    mass=random(15, 80);
    position.y=-mass;
    velocity.mult(0);
  }
}

function readSerial(data) {

  if (data != null) {
    // make sure there is actually a message
    // split the message
    wind.x = data;

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

///Arduino COde
/*

int ledPin = 9;

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

void loop() {
  int sensor = analogRead(A0);
  int wind = map(sensor, 0, 1023, -2, 2);
  Serial.println(wind);
  delay(10);
  if (Serial.available() > 0) {
    // Read the brightness value from p5.js
    int touch = Serial.parseInt();
    // Set the LED brightness
    digitalWrite(ledPin, touch);
  }
}
*/

 

week 11: exercises

1:

For this exercise, I just repurposed the code from class. I kept the Arduino IDE code the same. I used the alpha value (which was the reading from the photoresistor) and added these three lines of code to move the ellipse along the horizontal axis.

let x = map(alpha, 0, 1023, 0, width);
fill(0, 0, 0);
ellipse(x, height/2, 20, 20);

2:

For this, I modified the Arduino code slightly.

 

// Week 11.2 Example of bidirectional serial communication

// Inputs:
// - A0 - sensor connected as voltage divider (e.g. potentiometer or light sensor)
// - A1 - sensor connect
  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') {
      brightness = map(left, 0, 1023, 255, 0);
      analogWrite(rightLedPin, brightness);
      int sensor = analogRead(A0);
      delay(5); // delay bc consecutive analog reads might make some noise 
      int sensor2 = analogRead(A1);
      delay(5);
      Serial.print(sensor);
      Serial.print(',');
      Serial.println(sensor2);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

And here is the p5.js 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);
}

function draw() {
  // one value from Arduino controls the background's red color
  background(map(rVal, 0, 1023, 0, 255), 255, 255);

  // 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);
    text('brightness = ' + str(slider.value()), 20, 90)
   

  }

}

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)
    //////////////////////////////////
    left = slider.value();
    right = slider.value();
    let sendToArduino = left + "," + right + "\n";
    writeSerial(sendToArduino);
  }
}

I created a slide that when the user moves back and forth, they can adjust the brightness of the blue LED (I used the blue LED because I used the exact same schematic, and the blue LED was connected to the digital PWM).

3:

The Arduino code I used for the third exercise was also very similar to the initial one provided:

// Week 11.2 Example of bidirectional serial communication

// Inputs:
// - A0 - sensor connected as voltage divider (e.g. potentiometer or light sensor)
// - A1 - sensor connected as voltage divider 
//
// Outputs:
// - 2 - LED
// - 5 - LED

int leftLedPin = 2;
int rightLedPin = 5;
int brightness = 0; 
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') {
      // brightness = map(left, 0, 1023, 255, 0);
      digitalWrite(leftLedPin, left);
      digitalWrite(rightLedPin, right);
      // if (right == )
      int sensor = analogRead(A0);
      delay(5); // delay bc consecutive analog reads might make some noise 
      int sensor2 = analogRead(A1);
      delay(5);
      Serial.print(sensor);
      Serial.print(',');
      Serial.println(sensor2);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

and this is the p5.js code:

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

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

  if (!serialActive) {
    print("click to select Serial Port");
    fill(0);
    text("click to select Serial Port", 20, 30);
  } else {
    applyForce(wind);
    applyForce(gravity);
    velocity.add(acceleration);
    velocity.mult(drag);
    position.add(velocity);
    acceleration.mult(0);
    ledVal = 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;
      ledVal = 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 == " ") {
    mass = random(15, 80);
    position.y = -mass;
    velocity.mult(0);
  }
}


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

function readSerial(data) {


  if (data != null) {
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 2) {
      let val = int(fromArduino[1]);
      wind.x = map(val, 0, 1023, -1, 1);
      print("wind", wind.x);
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    // left = slider.value();
    // right = slider.value();
    // console.log(position.y);

    let sendToArduino = ledVal + "," + ledVal + "\n";
    writeSerial(sendToArduino);
  }
}

The modifications in the p5.js code make it so that the user clicks on the screen to set up the serial. Once the game is started, the reading from the potentiometer is used to adjust the wind, and everytime the ball hits the ground the LED lights up. One thing that I struggled with was how to stop the LED from being perpetually lit up while the ball was just on the ground.

 

 

Week 11 – Final project idea

I had two ideas for my final project but I’m still undecided on what I want to do

1. Pachinko machine 

Creating a pachinko machine that incorporates Arduino to add interaction, perhaps using servo motors to control some obstacles, or adding sound/lights whenever the ball hits a nail, or using Arduino to detect which hole the ball fell into. However, I can’t think of a good way of integrating P5.JS with this project without it being gimmicky like showing the score on P5.js, or shooting the balls from P5.js. I feel those interactions belong in the physical world and implementing them digitally takes away from it. Any interaction I can think of is better served physically, so I am not sure if I will proceed with this idea even though I personally like this idea more as it’s more fun.
Christmas Gift [Handmade DIY] Pinball Game Board Game Wooden Toy Handmade DIY - Shop jwoodgarden Wood, Bamboo & Paper - Pinkoi

2. Hello Kitty photobooth

A photobooth-type project, where the p5.js sketch is responsible for displaying the camera and taking the photos. The ‘twist’ is the usage of Arduino and the presence of a physical Hello Kitty that is sensed by the Arduino. By moving around the physical Hello Kitty it adjusts her location on the screen, so you can move her around and adjust her size, make her big so the viewer can stand next to her in the photo, or make her small and the viewer can hold her in the palm of their hands.

Week 11 – In class exercises

  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 p5For this exercise, I modified the p5js code using a potentiometer on the arduino. Different values of the potentiometer are mapped to the x coordinates of the ellipse. This makes it move across the horizontal axis in the middle of the screen. The arduino code remains the same as the example code.
let y=height/2;
let x = 0;
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() {
  background(255);
  // one value from Arduino controls the background's red color
  fill(255, 0, 255, map(x, 0, 1023, 0, 255));
  ellipse(map(x, 0, 1023, 0, width), 30, 30);

  // the other value controls the text's transparency value

  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 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
      y = int(fromArduino[0]);
      x = int(fromArduino[1]);
    }

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

2. make something that controls the LED brightness from p5

again tweaking the previous p5js and arduino codes, for this one, Pressing the up or down arrow key on the keyboard, run through p5js, increases or decreases the brightness of the leds on the arduino respectively. this was done using the concept of pulse width modulation.

p5js code:

let rVal = 0;
let alpha = 255;
let brightness = 0;

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

function draw() {
  background(map(rVal, 0, 1023, 0, 255), 255, 255);
  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);
    text('rVal = ' + str(rVal), 20, 50);
    text('alpha = ' + str(alpha), 20, 70);
  }
}

function keyPressed() {
  if (key == " ") {
    setUpSerial();
  } else if (keyCode === UP_ARROW) {
    brightness = constrain(brightness + 20, 0, 255);
    sendToArduino();
  } else if (keyCode === DOWN_ARROW) {
    brightness = constrain(brightness - 20, 0, 255);
    sendToArduino();
  }
}

function sendToArduino() {
  let sendToArduino = brightness + "\n";
  writeSerial(sendToArduino);
}

function readSerial(data) {
  if (data != null) {
    let fromArduino = split(trim(data), ",");
    if (fromArduino.length == 2) {
      rVal = int(fromArduino[0]);
      alpha = int(fromArduino[1]);
    }
    let sendToArduino = brightness + "," + brightness + "\n";
    writeSerial(sendToArduino);
  }
}



arduino code:

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') {
      Serial.print("Left: ");
      Serial.print(left);
      Serial.print(", Right: ");
      Serial.println(right);

      analogWrite(leftLedPin, left);
      analogWrite(rightLedPin, right);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}



3. take the gravity wind example (https://editor.p5js.org/aaronsherwood/sketches/I7iQrNCul) 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

I found this one to be a little challenging but eventually made it work. the ball bounces with the same logic and physics from the example. Each time it touches the ground, using a boolean variable ballOnGround, it is equated to 1 or 0. this is then sent to the arduino where the LED turns on if it is 1. For the sensor contrilling wind, Im using a photoresitor whose values are mapped to the x coordinate of the wind vector. The ball moves faster when the value is larger. MouseClicking restarts the movement of the ellipse. The issue I face is slight delay in the led lighting up.

video:

p5.js Code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 20;
let ballOnGround=1;
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);
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    applyForce(wind);
    applyForce(gravity);
    velocity.add(acceleration);
    velocity.mult(drag);
    position.add(velocity);
    acceleration.mult(0);

    fill(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;
      ballOnGround = 1;
      let sendToArduino = ballOnGround + "\n";
    writeSerial(sendToArduino);
    ballOnGround = 0;
    sendToArduino = ballOnGround + "\n";
    writeSerial(sendToArduino);
    } else {
      ballOnGround = 0;
    }
  }
  
  
  if (mouseIsPressed) {
      restartSketch();
    }
}

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

function readSerial(data) {
  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
      let photoresistor = int(fromArduino[0]);
      
      //change the wind based on the photoresistor readings
      wind.x = map(photoresistor, 0, 1000, -5, 5);
      
    }

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


function restartSketch() {
  // Reset relevant variables to their initial values
  position = createVector(width / 2, 0);
  velocity = createVector(0, 0);
  acceleration = createVector(0, 0);
  wind = createVector(0, 0);
  mass = 50;
  ballOnGround = 0;
}

arduino code:

int ledPin = 2;
const int photoresistorPin = A0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(photoresistorPin, 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); // led on while receiving data
    int ballOnGround = Serial.parseInt();
    if (Serial.read() == '\n') {
      int photoresistorValue = analogRead(photoresistorPin);

      // Send photoresistor value to p5.js
      Serial.println(photoresistorValue);
      digitalWrite(ledPin, HIGH);
      digitalWrite(ledPin, LOW);
      // Control the LED based on the bouncing state.
      if (ballOnGround == 1) {
        digitalWrite(ledPin, HIGH);
      } else {
        digitalWrite(ledPin, LOW);
      }
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}