Week 11 – In Class Exercises (Serial Communication)

Exercise 1: The value obtained from the potentiometer makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on arduino is controlled by p5.

p5.js

let rVal = 0;
let xPos = 0;
let rad = 50;


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

function draw() {
  background(255);

  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
    
    xPos = map(rVal, 0, 900, 0, 400);
    // Print the current values
    text('rVal = ' + str(rVal), 20, 50);
    ellipse(xPos, 200, rad, rad);
    text('xPos = ' + str(xPos), 20, 70);

  }
  
}

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) {
    
    let fromArduino = split(trim(data), ",");

    if (fromArduino.length == 1) {
      rVal = fromArduino[0];
    }

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

Arduino

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

 

Exercise 2: Change the LED brightness by moving the ellipse on p5.js left or right.

let left = 0;
let right = 0;
let brightness = 0;
let rad = 50;

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

function draw() {
  background(255);

  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);

    //the x position of the cirlce will control the brightness of the LED
    xPos = mouseX;
    ellipse(xPos, 200, rad, rad);
    brightness = map(xPos, 0, 400, 0, 255);
    brightness = int(brightness);
    
    // Print the current values
    text('Brightness = ' + str(brightness), 20, 60);
    text('xPos = ' + str(xPos), 20, 90);

  }
  
}

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) {
    
    let fromArduino = split(trim(data), ",");
    if (fromArduino.length == 1) {
      // we're not getting input from arduino
    }
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = brightness + "\n";
    writeSerial(sendToArduino);
  }
}

Arduino

int ledPin = 5;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ledPin, OUTPUT);
  // 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 brightness = Serial.parseInt();
    if (Serial.read() == '\n') {
      delay(5);
      Serial.println("1");
    }
    analogWrite(ledPin, brightness);
  }
  digitalWrite(LED_BUILTIN, LOW);
}

 

Exercise 3: Alter the gravity wind example to make the LED light up and turn off every time the ball bounces , and control the wind using potentiometer.

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() {
  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;
      isBouncing = 1;
    } else {
      isBouncing = 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 == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  } else if (key == "ENTER") {
    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
    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 potValue = int(fromArduino[0]);
      
      //change the wind based on the potentiometer value
      wind.x = map(potValue, 0, 900, -5, 5);
    }

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

Arduino

int ledPin = 5;
const int potPin = A0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(potPin, 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
    digitalWrite(ledPin, LOW);
    int isBouncing = Serial.parseInt();
    if (Serial.read() == '\n') {
      int potValue = analogRead(potPin);
      delay(5);
      Serial.println(potValue);
    }
    // Set LED brightness based on whether bouncing.
    if (isBouncing == 1) {
      digitalWrite(ledPin, HIGH);
    } else {
      digitalWrite(ledPin, LOW);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

Demo

 

In Class Exercises (Arduino + p5)

Team: Swostik, Naz, Aibar

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”

The code provided in the lecture notes for both Arduino and P5.js was used as-is, except for the draw function in P5.js. We modified the code to make the ellipse’s horizontal location change when the potentiometer was turned, and the vertical location change when the LDR input was changed. To prevent multiple visual responses from P5.js when the potentiometer and LDR were manipulated, we removed the background and fill functions.

Arduino Code

p5 Sketch

Demo Video

 

Exercise 2

“Make something that controls the LED brightness from p5”

We made some changes to both the Arduino and P5.js code for this task. To adjust the brightness of the LED, we utilized the keyboard’s Up and Down arrows as the input for the P5.js code. This changing value was then sent to the LED connected to PWM pin 5. We used analog write to this pin, which increased or decreased the LED value. If the value exceeded 255, it reset to 0 and vice versa.

Arduino Code

p5 Sketch

Demo Video

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”

To complete the exercise, we made changes only to the P5.js code by incorporating the gravity wind example. The original Arduino code from the lecture notes remained unchanged. We divided the range of the potentiometer into three intervals, which set the wind vector to -1, 0, and 1 depending on its direction. These values are acceptable for the wind. We also implemented a collision detection flag. When a collision occurs, the LED on pin 2 is turned on. Whenever there is no collision, the LED is turned off.

Arduino Code

p5 Sketch

Demo Video

Week11 Assignment

A)

Video:

scheme:

p5js:

let ardVarMove = 200;

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

function draw() {
  background(220);
  
  ellipse(ardVarMove, 200, 50, 25);
}

function keyPressed() {
  if (key == " ") {
    setUpSerial();
  }
}

function readSerial(data) {
  if (data != null) {
    let fromArduino = split(trim(data), ",");
    if (fromArduino.length == 1) {
      ardVarMove = int(fromArduino[0]);
    }
  }
}

 

arduino:

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

  while (Serial.available() <= 0) {
    int sensor = analogRead(A0);
    Serial.println(sensor);
  }
}

 

B)

Video:

Scheme:

P5js:

let redButton;
let yellowButton;
let blueButton;

function setup() {
  createCanvas(400, 400);
  redButton = new button(100, "red");
  yellowButton = new button(300, "yellow");
  blueButton = new button(200, "blue");
}

function draw() {
  background(220);
  redButton.display();
  yellowButton.display();
  blueButton.display();
}

function keyPressed() {
  if (key == " ") {
    setUpSerial();
  }
}

class button {
  constructor(x, col) {
    this.x = x;
    this.y = 200;
    this.size = 80;
    this.light = 0;
    this.col = col;
  }

  display() {
    fill(this.col);
    ellipse(this.x, this.y, this.size);
  }

  clicked() {
    
    if (dist(mouseX, mouseY, this.x, this.y) < this.size) {
      if(this.light == 0){
        this.light = 1;
      }
      else{
        this.light = 0;
      }
    }
  }
}



function readSerial(data) {
  let sendToArduino = redButton.light + "," + blueButton.light + "," + yellowButton.light + "\n";
  //let sendToArduino = left + "," + right + "\n";
  writeSerial(sendToArduino);
}

function mousePressed(){
  redButton.clicked();
  yellowButton.clicked();
  blueButton.clicked();
}

 

arduino:

int RedLedPin = 2;
int BlueLedPin = 12;
int YellowLedPin = 11;

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

  pinMode(LED_BUILTIN, OUTPUT);

  pinMode(RedLedPin, OUTPUT);
  pinMode(BlueLedPin, OUTPUT);
  pinMode(YellowLedPin, OUTPUT);

  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); 
    Serial.println("0,0"); 
    delay(300);           
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH);

    int lightR = Serial.parseInt();
    int lightY = Serial.parseInt();
    int lightB = Serial.parseInt();

    if (Serial.read() == '\n') {
      digitalWrite(RedLedPin, lightR);
      digitalWrite(BlueLedPin, lightY);
      digitalWrite(YellowLedPin, lightB);
      Serial.println();
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

 

C)

Video:

scheme:

p5js:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let light = 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;
  }
  turnLight(velocity.y);
}

function turnLight(vel){
  if(vel < 0){
    light = 1;
  }
  else{
    light = 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==' '){
    mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
  if (keyCode == 90) {
    setUpSerial();
  }
}

function readSerial(data) {
  if (data != null) {
    let fromArduino = split(trim(data), ",");
    if (fromArduino.length == 1) {
      wind.x = (fromArduino[0] - 512) / 1000;
    }
    let sendToArduino = light + "\n";
    writeSerial(sendToArduino);
  }
}

 

arduino:

int LedPin = 2;

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

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LedPin, OUTPUT);

  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); 
    Serial.println("0,0"); 
    delay(300);           
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); 

    int light = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(LedPin, light);
      int sensor = analogRead(A0);
      delay(5);
      Serial.println(sensor);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

 

Final Project Proposal

WHAC-A-MOLE

Concept:

For my final project I’m thinking of making a whac a mole video game stand where users can hit a mole that is showed in the screen but connected to the arduino board so that users can hit the physical mole that pops up on the screen. For the moment, I’m still thinking of my own creative twist for this project, but I really like the idea of physically hitting something that will connect a circuit through the board to make the system complete and score a point on p5js.

Implementation:

The user will see a couple of holes in the screen where a mole will pop up every now and then, and the user will have to hit the correlating sensor with a special hammer I will design that will finish the circuit, which will send a signal to the arduino board and will interpret as a “hit” of the mole and score a point. So basically the hammer is a big switch that the user must turn on precisely when the mole peaks its head out.

Final Project – Preliminary Concept

For the purposes of the Final Project, in order to satisfy the requirements of an interactive system which requires systems of listening, thinking, and speaking from at least 2 parties, and should make use of Arduino and P5Js, we have preliminarily thought of developing an ‘Arcade Game’ console.

While the intricacies are not fine tuned yet, the initial idea is to develop an Extensive Game in p5Js, not a simple one, but an elaborate game with multiple levels which is very challenging. For this, we have though of a childhood favorite called ‘PacXon’ which is similar to PacMan but involves a relatively free space with area to capture. To have a sense of a similar game, we can look here (https://www.gamesbutler.com/game/29933/pacxon-deluxe/)

We believe creating this would require some algorithms, and extremely complex state machines with the utility of power-ups, and would develop our Object Oriented Programming skills in P5Js to an advanced level.

Moving forward, we would then develop a ‘JoyStick’ for this game, that would be designed for the purposes of this game. As an idea, the JoyStick would be a breadboard with multiple buttons for left, right, up, and down movements as well as a Potentiometer to control speeds, and a Piezo Buzzer to produce vibration like sounds on collisions for ‘Haptic Feedback’. We would also incorporate multiple LEDs and different notes of sounds with the state machines, realizing the mechanism to play the required tone at the appropriate time.

The idea is still in works and we are open to feedback!

The project is intended to be completed by Ishmal Khalid, Zunair Viqar, and Abraiz Azhar.

Final Project Concept – Mini Basketball Arcade Game

Concept

The goal of this Final Project is to create a physically interactive system that relies on a multimedia computer for some sort of processing or data analysis. My Final Project uses BOTH P5 AND Arduino to create a Mini Basketball Arcade Machine. The mini Basketball Arcade Machine will be a tabletop-sized arcade game that will allow users to play basketball by shooting miniature basketballs into a hoop. The game will have a digital scoreboard that will display the player’s score and time remaining. The machine will use Arduino to sense when the user shoots the basketball and p5.js to display the score and time on the scoreboard.

Implementation

The user will start the game by pressing a pushbutton, which will light up an LED on the scoreboard and start the timer. The user will then have a set amount of time to shoot as many mini basketballs into the hoop as possible. Arduino will detect when the user shoots the basketball by using a sensor attached to the hoop. Each time the user makes a shot, the scoreboard will update the score and display it on the LED screen. When the time is up, the game will end, and the final score will be displayed on the scoreboard.

The mini Basketball Arcade Machine will provide an interactive and engaging experience for users. It will rely on careful and timely sensing of the user’s actions and provide clear, prompt, and effective responses through the use of Arduino and p5.js.

Final Project Proposal

For the purposes of the Final Project, in order to satisfy the requirements of an interactive system which requires systems of listening, thinking, and speaking from at least 2 parties, and should make use of Arduino and P5Js, we have preliminarily thought of developing an ‘Arcade Game’ console.

While the intricacies are not fine tuned yet, the initial idea is to develop an Extensive Game in p5Js, not a simple one, but an elaborate game with multiple levels which is very challenging. For this, we have though of a childhood favorite called ‘PacXon’ which is similar to PacMan but involves a relatively free space with area to capture. To have a sense of a similar game, we can look here (https://www.gamesbutler.com/game/29933/pacxon-deluxe/)

We believe creating this would require some algorithms, and extremely complex state machines with the utility of power-ups, and would develop our Object Oriented Programming skills in P5Js to an advanced level.

Moving forward, we would then develop a ‘JoyStick’ for this game, that would be designed for the purposes of this game. As an idea, the JoyStick would be a breadboard with multiple buttons for left, right, up, and down movements as well as a Potentiometer to control speeds, and a Piezo Buzzer to produce vibration like sounds on collisions for ‘Haptic Feedback’. We would also incorporate multiple LEDs and different notes of sounds with the state machines, realizing the mechanism to play the required tone at the appropriate time.

The idea is still in works and we are open to feedback!

The project is intended to be completed by Ishmal Khalid, Zunair Viqar, and Abraiz Azhar.

Assignment 8: In-class exercises

For the 11th Week assignment, we were tasked to pair up in groups of 2-3, and complete the following 3 exercises to fully understand the connection and communication methodologies between Arduino and p5Js. The 3 exercises were:

      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
      2. make something that controls the LED brightness from p5
      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

The requirements were to post the code for each exercise, and the video of the LED lighting up with the ball bouncing.

We paired up in a group of 3, consisting of Abraiz Azhar, Ishmal Khalid, and Zunair Viqar. In the next few sections, we have described the solutions to each of the above exercises.

Prompt 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

Implementation

For this part, I made use of a potentiometer and connected it to the Arduino’s A0 port. The variable rVal changes according to the position of the potentiometer and this variable is in turn mapped to the ellipse’s x-position. I made the ellipse’s grey-scale value change according to the potentiometer’s reading.

Code
let rVal = 0;

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

  }
  
  // making an ellipse that moves according to the potentiometer's rVal 
  noStroke()
  fill(map(rVal, 0, 1023, 0, 255));
  ellipse(map(rVal, 0, 1023, 20, width - 20), height/2, 20);
}
Circuit

 

 

 

 

 

 

Prompt 2

Implementation & Challenges

The prompt for the second task seemed straightforward initially: create a system to control LED brightness using p5. However, it turned out to be more challenging than expected. Our initial approach was to map the mouseX position relative to the screen width to adjust the brightness of the lamp accordingly. We removed the code for reading from p5 and writing to Arduino, as we thought only sending data from p5 was needed. However, we later realized that both read and write operations are necessary for establishing a connection.

Despite this realization, we still encountered issues as we didn’t initially understand that data must be continuously read and written from both Arduino and p5 for the circuit to function properly. It wasn’t just limited to the handshake phase, but required continuous data exchange. Despite the challenges, this exercise provided us with a deeper understanding of the serial connection between p5 and Arduino.

We also faced challenges with data formatting during the data exchange. It was important to ensure that the data sent from p5 was properly formatted with the addition of ‘\n’, and that Arduino used println instead of print to receive the data. This was crucial for establishing reliable communication between p5 and Arduino, and it required careful attention to detail to get the formatting right.

Code
p5Js
let rVal = 0;
let alpha = 255;
let left = 0;
let right = 0;
let brightness = 0;

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

  // the other value controls the text's transparency value
  brightness = map(mouseX, 0, 640, 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);

  }

}

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

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = brightness + "\n";
    writeSerial(sendToArduino);
  }
}
Arduino .ino
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"); // 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 right = Serial.parseInt();
    if (Serial.read() == '\n') {
      analogWrite(rightLedPin, right);
      int sensor = analogRead(A0);
      Serial.println(sensor);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

Prompt 3

Implementation & Challenges

For the very last prompt, we were required to take an input from Arduino in the form of an Analog Sensor and also send data to Arduino to blink an LED.

Using an existing p5Js Sketch (https://editor.p5js.org/aaronsherwood/sketches/I7iQrNCul), the requirement was to blink the LED when the ball bounces, and use an Analog Sensor to control the wind.

Therefore, making use of the circuit we designed in class by taking help from the basics of these 3 sources, we began to adapt the Gravity Wind Example from p5Js:

The first task was to detect a bounce, and once a bounce was detected, we just simply sent a signal of ‘1’ to the Arduino – which only meant switching on the light, which would then switch off with ‘0’ being sent when the ball was in motion.

Similarly, the Potentiometer value was read from the Arduino, and its value was sent to the P5Js sketch. This value was checked to be either greater then 512, or less than that, which then meant left or right movement of the wind.

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

let rVal = 0;
let alpha = 255;
let left = 0;
let right = 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() {
  left = 0;
  background(255);
  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;
    }
  
  
  if(abs(velocity.y)>1){
    if(position.y+(mass/2)>=(height)){
      left = 1;
    }
  }
  
  // print(alpha);
  
  if(alpha>512){
    // print("right");
    wind.x=1;
  }
  else{
    // print("left");
    wind.x=-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();
  }
  
  if (keyCode==UP_ARROW){
    // wind.x=-1;
    position.y = 200;
  }
  
  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
    alpha = data;

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = left + "\n";
    writeSerial(sendToArduino);
  }
}
Arduino .ino
// 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;

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();
    // int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(leftLedPin, left); // Write value to the bulb, to blink it
      int sensor2 = analogRead(A1); // Read input from the Potentiometer
      delay(5);
      Serial.println(sensor2); // Send message to p5js
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}
Circuit

 

Week 11 – In-class Exercises (moving ellipse, LED brightness, Gravity wind example)

Group mates: Swostik Pati and Irem Naz Celen

Task 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

The code provided in the lecture notes for both Arduino and P5.js was used as-is, except for the draw function in P5.js. We modified the code to make the ellipse’s horizontal location change when the potentiometer was turned, and the vertical location change when the LDR input was changed. To prevent multiple visual responses from P5.js when the potentiometer and LDR were manipulated, we removed the background and fill functions.

Code:

Arduino Code

p5.js code

Video:

 

Task 2:

make something that controls the LED brightness from p5

We made some changes to both the Arduino and P5.js code for this task. To adjust the brightness of the LED, we utilized the keyboard’s Up and Down arrows as the input for the P5.js code. This changing value was then sent to the LED connected to PWM pin 5. We used analog write to this pin, which increased or decreased the LED value. If the value exceeded 255, it reset to 0 and vice versa.

Code:

Arduino Code

p5.js code

Video:

Task 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

To complete the exercise, we made changes only to the P5.js code by incorporating the gravity wind example. The original Arduino code from the lecture notes remained unchanged. We divided the range of the potentiometer into three intervals, which set the wind vector to -1, 0, and 1 depending on its direction. These values are acceptable for the wind. We also implemented a collision detection flag. When a collision occurs, the LED on pin 2 is turned on. Whenever there is no collision, the LED is turned off.

Code:

Arduino Code

p5.js code

Video:

Final Project: Report #1 – Proposal

Arduino Radar:

My idea for my final project I thought of creating some sort of Arduino Radar, something like shown below:

So essentially, I plan to have maybe the ultrasonic-distance sensor maybe on a servo motor which keeps track of how far people are and based on that, it would map out onto a sensor which would look something like shown above.

I was thinking of several applications of using this for my project. For example: Perhaps, there could be treasure somewhere, and the user had to get that treasure without alerting this radar. If the radar detects the user, it would activate a solenoid to open a door and shoot the user with maybe a nerf bullet or something.

A really AWESOME idea could be if I could hide the treasure maybe somewhere around the IM showcase, and the user must use my radar device to track this treasure before some time limit. Hence, they would have to go around the showcase and find this treasure.

If they don’t find it by the given time, then the solenoids can be activated and they get shot. It could also be some sort of game where people can try and compete to find the treasure for the fastest time or something.

Arduino and p5js division:

  • The hardware as in the sensor, the shooting mechanism can all be through Arduino
  • The radar visualization can be drawn onto p5js. Maybe even the treasure icon or something can be mapped out onto p5js as well.

Initial Challenges: 

I’m thinking that this project is doable but if I were to maybe do the finding treasure around the showcase idea, I’m not entirely sure how I would track the treasure’s location at all times. I’m not even sure how the sensor would be able to track it. Maybe through OSC so the computer (p5js) knows where the ball is at all times (like its coordinates) and that way it can map out on the radar and as you walk around, the sensor can start to pick it up and when it does, it can map out on the radar or something.

I’m not sure but i’ll have to do a little more thinking and investigating.

HW 8: 3 in-class exercises

Group mates: Swostik Pati and Aibar Talip
The Arduino circuit is kept the same as it was directed in the Lecture Notes.

Exercise 1 – Code & Video

The Arduino Code and the P5.Js code were directly used as given in the lecture notes, except for the draw function of p5.js. We amended the code so that turning the potentiometer would change the horizontal location of the ellipse. On the other hand, the LDR input would amend the vertical location of the ellipse. We also omitted the background and fill functions in order to not have multiple responses from the p5js visually for the actions observed on the potentiometer and the LDR.

The new draw function used in the p5.js code is shown below:

function draw() {
  background(0);
  fill(255);
  
  ellipse(map(alpha, 0, 1023, 0, width),map(rVal, 0, 1023, 0, height),40,60);
 
  // 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);
  }
}

Exercise 2 – Code & Video

For this exercise we amended the Arduino code a little as well as the p5.js code. In order to control the LED brightness, we used the keyboard, Up and Down arrows, as the input for the p5.js code that was running and then send this changing value to the LED that was connected in PMW pin 5. We analog wrote to this pin, by the incrementing/decrementing value of the LED, which resets 0 if it passes 255, and vice versa.

The new draw function and the keyPressed() function is as follows:

function draw() {
  background(255, 255, upVal,upVal);

  if(upVal==255) upVal =0;
  if(upVal==0) upVal=255;

  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
  }
}


function keyPressed() {
  if (keyCode == UP_ARROW) {
    upVal += 10;
  }
  if (keyCode == DOWN_ARROW) {
    upVal -= 10;
  }
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

 

The following change is made to the p5.js code in the definition of the values that are sent to the Arduino, as the information for the LED at pin 5 is not digital but analog now, while the pin 2 LED is set to 0 indefinitely.

//////////////////////////////////
      //SEND TO ARDUINO HERE (handshake)
      //////////////////////////////////
      let sendToArduino = upVal + "," + 0 + "\n";
      writeSerial(sendToArduino);

Amendments to the Arduino code are as follows, in the section where the LED values are set:

// inside loop function of arduino
void loop{
.....
    int right = Serial.parseInt();
    int left = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(leftLedPin, left);
      analogWrite(rightLedPin, right);
...}

 

Exercise 3 – Code & Video

Only the p5.js code from the lecture notes is amended for the exercise after being combined with the gravity wind example given while the original Arduino code from the lecture notes is used. The range of the potentiometer is divided into 3 intervals, which accordingly sets the wind vector as -1, 0, and 1, as these are the acceptable values for the wind according to its direction. A flag for checking a collision has happened is put in place, in which ever case it is true the LED on pin 2 is turned on, and everytime it is “not collided” the LED is turned down.

The final version of the p5.js code used is as follows:

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

let rVal = 0;
let upVal = 0;
let alpha = 255;
let left = 0;
let right = 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(bFlag){
      print("collided");
      bFlag=false;
      left = 1;
    }
    else
      left=0;
  }
  else{
    bFlag=true;
    left=0;
  }

  // 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);
  }
//wind.x = map(alpha, 0, 1023, 0, 255);
  if(alpha>670)
    wind.x=1;
  else if(alpha>320)
    wind.x=0;
  else
    wind.x=-1;
  print(wind.x);
 
  // click on one side of the screen, one LED will light up
  // click on the other side, the other LED will light up
}
function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  if(keyCode==UP_ARROW){
    position = createVector(width / 2, 0);
  }
  if (key == " ") {
    mass = random(15, 80);
    position.y = -mass;
    velocity.mult(0);
  }
}

// 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
      rVal = fromArduino[0];
      alpha = fromArduino[1];
    }

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

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

Reflections

These exercises were very enjoyable and definitely interesting to try as they allowed us to grasp the communication between the p5.js and Arduino way better. We were able to get exercises in for this complex relationship before devising our plan for the final project.