Week 11 – Arduino and P5 + Final Project Concept

Exercises

Exercise 1

For exercise 1, we used a light sensor. As brightness of light in the surrounding was changed, the ball moved along the horizontal axis in p5. Higher the brightness, the farther right the ball moved.

The values from the light sensor roughly ranged between 0 and 500,000 so we mapped them between 0 and width of the screen and used the mapped value as x-coordinate of the ellipse

//Exercise 1 P5js Code

let ellipseX; // Variable to store ellipse's x-coordinate

function setup() {
  createCanvas(400, 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(255, 0, 0); // 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
    console.log(data);
    console.log("fromArduino");
   
    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
      console.log("working");
//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);
  }
}
//Exercise 1 Arduino Code 

void setup() {
  Serial.begin(9600); // Start serial communication at 9600 bps

  pinMode(LED_BUILTIN, 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

  // Read sensor value
  int sensorValue = analogRead(A0);
   Serial.print(sensorValue);
  // Map sensor value to screen width (e.g. 0 to 800 pixels)
  int screenValue = map(sensorValue, 0, 1023, 0, 800);

  // Send mapped value to p5.js
  Serial.println(screenValue);

  delay(50); //    for stability
}
digitalWrite(LED_BUILTIN, LOW);
}

Exercise 2

For this exercise, we used a slider in p5 to control brightness of the LED. Value of slider ranged between 0 and 255 and these values were sent to Arduino and used as brightness for the LED.

//Exercise 2 P5js Code
let slider;
function setup() {
   createCanvas(400, 400); // Create a canvas of 800x400 pixels
  slider = createSlider(0, 255, 0);
  slider.position(160,height/2); // Set the position of the slider
  slider.style('width', '80px'); // Set the width of the slider
 
  
  noStroke(); // No stroke for the ellipse
}
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 == " ") {
    // important to have in order to start 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);
  
}
//Exercise 2 Arduino Code

const int ledPin =3;
int brightness = 0;
void setup() {
  Serial.begin(9600); // 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 while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
  }
}
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); //set brightness of LED
     
      }else
      {
        digitalWrite(LED_BUILTIN, HIGH);
      }
    }
}

Exercise 3

For this exercise, we used a potentiometer to control the wind. The potentiometer’s values ranged between 0 and 1023. So, for any value less than 500, wind moved the ball forward/wind blew to right. We added this layer that if value was between 500 and 600, wind stopped so the ball stopped. Finally, if value was above 600, wind blew in opposite direction moving the ball in the opposite direction.

For LED part, we used a flag called heightOfBall. Whenever ball touched the ground, this flag was set to zero. Otherwise, it was set to one. This was sent to Arduino to check whenever ball bounced. When this happened, LED would be turned on. Otherwise it would be turned off.

//Exercise 3 P5js Code

let velocity;
let gravity;
let position;
let acceleration;
let wind;
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);
  wind = createVector(0,0); 
}

function draw() {
  background(215);
  fill(0);
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else 
  {
    text("Connected. Press s to jump.", 20, 30);
  
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  //heightOfBall set to zero whenever ball is touching the ground. Otherwise it is set to 1.
  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=='s'){
    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]);
      console.log("Sensor value: ")
      console.log(sensorVal);

//sensor values range between 0 and 1023
//for any sensor value less than 500, make wind move ball forward/wind blows to right
      if (sensorVal <500){
        wind.x=1
      }
//if sensorVal between 500 and 600, wind stops so ball stops
      else if(sensorVal >=500 && sensorVal < 600){
        wind.x = 0
      }
//if sensorVal over 600, wind blows in opposite direction moving ball to left
      else {
        wind.x =-1
      }
          //////////////////////////////////
          //SEND TO ARDUINO HERE (handshake)
          //////////////////////////////////
    }

//send heightOfBall to arduino to indicate if ball is on the floor or not
    let sendToArduino = heightOfBall  + "\n";
    writeSerial(sendToArduino);
  }
}
//Exercise 3 Arduino code

const int poten_pin = A0;
const int ledPin =3;

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

Video for Exercise 3:

Teammate: Ramsha Bilal

Final Project Proposal

I have decided to take inspiration from one of the classic mobile  games of the past generations: Flappy Bird!

Flappy Bird became popular due to how made it made people when they could just never get the mechanics down for the game.

This of course led many people to break their phones and scream loudly. Well with my idea, you get to let out your energy while playing my game. I will be connecting a microphone up to my own version of this game where, in order to make the character fly, you have to scream into the mic!

SO best prepare your vocal cords and have a drink to soothe them afterwards for when my game eventually comes to fruitition!

Final Project Proposal

Concept

I am considering expanding my sound project for the final project by creating a table piano with enhanced features. The piano will be based on either an ultrasonic sensor or a pressure sensor. The concept is to integrate P5.js code as a game. The start screen will allow users to choose between three modes: free mode, game mode, and record mode.

In free mode, users can play the piano for as long as they want and try to figure out a tune on their own. Record mode will be an extension of free mode, where each key played by the user will be stored within P5.js and can be played back by pressing a button.

In game mode, users will be presented with a pre-set tune, including its sound, the keys to be played, and the order in which they should be played. The goal will be for the user to memorize the tune/keys and then play it on the piano. Correctly played tunes will earn points, while pressing the wrong key will result in a buzzer sound and the need to start over. Users will have the option to replay the tune or skip to a new one.

To add more challenge, game mode may have different difficulty levels such as easy, medium, and hard, with tunes of varying lengths and number of keys. The fastest player in each category will have their name displayed on the screen throughout the exhibition, motivating others to beat the record.

Week 11 – Serial Communication (In-Class Exercises)

Exercise 1:

During the exercise, we had to use an Arduino with an analog sensor to manipulate a feature in P5js based on the readings. We opted for an ultrasonic sensor to achieve this, where the data obtained was utilized to shift an ellipse along its horizontal axis in P5js.

CODE FOR P5JS

//declare variables for the dimensions and coordiantes of ellipse
let ellipseXcord;
let ellipseYcord;
let ellipseRadius;

function setup() 
{
  createCanvas(500, 500); //create canvas
  background(100);
  textDisplay();
  //set the initial ellipse to be in the centre
  ellipseXcord = width/2;
  ellipseYcord = height/2;
  ellipseRadius = height/10;
}

//displays this text in the starting
function textDisplay()
{
  text("PRESS ANY KEY TO START SERIAL PORT", width/2 - 109, height/2 - 5);
}

function draw() 
{
  background(220);
  if (serialActive) //if the serial is active
  {
    ellipse(ellipseXcord, ellipseYcord, ellipseRadius, ellipseRadius); //then keep changing the coordinates of ellipse bases on ellipseXcord
  }
  else //if the serial is not active
  {
    textDisplay(); //then display the text with instructions
  }
}

function readSerial(data) //call back function
{
  if (data != null) //if the data received is not null
    {
      ellipseXcord = map(data, 300, 1500, ellipseRadius, width - ellipseRadius); //map the value of the data and then update the variable
      //do it with ellipse radius because dont want half the circle off the screen
    }
}

function keyPressed() //if any key is pressed, then set up serial
{
  setUpSerial();
}

CODE FOR ARDUINO

const int pingPin = 2; //Trigger Pin of Ultrasonic Sensor
const int echoPin = 3; //Echo Pin of Ultrasonic Sensor
long distance = 0; //will contain the distance of the object

void setup() {
  //Start serial communication at 9600 baud
  Serial.begin(9600);

  //Set the ultrasonic sensor pins as output and input respectively
  pinMode(pingPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  //Send a short low pulse
  digitalWrite(pingPin, LOW);
  delay(2); //delay to avoid complications
  digitalWrite(pingPin, HIGH); //sends a high pulse for 10 microseconds
  delay(10);
  digitalWrite(pingPin, LOW); //turn off the ping pin
  distance = pulseIn(echoPin, HIGH); //Measure the duration of the ultrasonic pulse and calculate the distance
  Serial.println(distance); //print it in the serial (P5js)
}

EXERCISE 2

In this particular exercise, the primary objective was to control the LEDs on an Arduino board through P5js code. We utilized the left and right arrow keys, which functioned as input devices to alter the dimness of the bulb. The code starts off with the LED at its maximum brightness but as the right arrow key is pressed, the brightness keeps decreasing. When the left arrow key is pressed, the brightness starts increasing again.

CODE FOR P5JS

let dimnessCounter = 0; //this will control the brightness and dimness of the LED

function setup() 
{
  createCanvas(400, 400);  //create canvas
}


function textDisplay() //display text in the starting
{
  text("PRESS SPACE TO START SERIAL PORT", width/2 - 109, height/2 - 5);
}

function draw() 
{
  
  background(100);  //grey background
  
  if (serialActive) //if serial is active
  {
    text("CONNECTED!", width/2 - 27, height/2 - 5); //tell the user that it is connected
    text("PRESS RIGHT ARROW TO LOWER BRIGHTNESS!", width/2 - 130, height/2 + 15); //give instructions on how to control brightness
  }
  else
  {
    textDisplay(); //display instructions on how to start serial is not active
  }
}


function keyPressed() //built in function
{ 
  if (key == " ") //if space is pressed then
  {
    setUpSerial(); //setup the serial
  }
  else if (keyCode == LEFT_ARROW) //if left arrow pressed
  {
    if (dimnessCounter != 0) //check if brightness is not already at the lowest
    {
      dimnessCounter = dimnessCounter - 50; //if not then decrease by 50
    }
  }
  else if (keyCode == RIGHT_ARROW) //for the right key
  {
    if (dimnessCounter != 250) //check if dimness not at the maximum
    {
      dimnessCounter = dimnessCounter + 50; //increase dimness by 50
    }
  }
    
}

//callback function
function readSerial(data) 
{
    let sendToArduino = dimnessCounter + "\n"; //add the next line to dimness counter
    writeSerial(sendToArduino); //write serial and send to arduino
}

CODE FOR ARDUINO

//declare variables
const int LED_PIN = 5;
int dimness = 0; //contains the dimness fothe LED

void setup() 
{
  Serial.begin(9600); // Start serial communication at 9600 baud

  pinMode(LED_PIN, OUTPUT); //declare pin to be output

  while (Serial.available() <= 0) 
  {
    Serial.println("CONNECTION ESTABLISHED"); // send a starting message
  }
}
void loop() 
{
  //wait for p5 to do something
    while (Serial.available()) //when serial is available
    {
      dimness = Serial.parseInt(); //parse the dimness from the serial to the variable
      Serial.println(dimness); //checking purposes

      if (Serial.read() == '\n') //since the "\n" would be present in the serial, read that and
      {
        analogWrite(LED_PIN, dimness); //write it to the LED
      }
    }
}

EXERCISE 3

In this exercise, we were tasked with creating an interactive p5js program that simulates a bouncing ball, which changes direction based on a variable called ‘wind.’ The ball bounces on the floor and we needed to detect when it hit the floor, so we could turn an LED on. For the second part of this exercise, we used an analog sensor (ultrasonic sensor) to control the wind variable. We set a default value in which the ball would stay in the middle of the screen. When the object is moved to the right from the center, the ball would move to the right, and when moved to the left, the ball would move to the left.

CODE FOR P5JS

//declare variables
let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let LEDvalue = 1401;
let goRight = 0;
let goLeft = 0;
let first

function setup() {
  createCanvas(1000, 360); //create canvas
  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 textDisplay()
{
  text("PRESS SPACE TO START SERIAL PORT", width/2 - 109, height/2 - 5); //display the appropriate text in the start
}

function draw() {
  background(255);
  if (serialActive) //if the serial is active
  {
    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)  //if the ball touches the bottom
    {
      velocity.y *= -0.9;  // A little dampening when hitting the bottom
      position.y = height-mass/2;
      LEDvalue = 1401; //take LED value to be 1401 because we dont want the value (1) to be lurking in the serial and then affecting the wind values

    }
    else
    {
      LEDvalue = 1400; //when the LED is off
    }
    
  }
  else
  {
    fill(0);
    textDisplay();
  }
}

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==' '){ //if space is pressed, then serial is set up
    setUpSerial();
  }
  
  if (keyCode == DOWN_ARROW) //if down arrow is pressed
  {
    //mass etc is changed
    mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
}

function readSerial(data) //call back function
{
  let sendToArduino = LEDvalue + "\n"; //sends value of LED to arduino with \n added
  writeSerial(sendToArduino); //write to arduino
  
  
  if (data != null) //if the data is not null and something is received
  {
    console.log(data);
    if (data > 1450) //if the distance is greater than 1450, then
    {
      wind.x = 1; //the ball/wind goes right
    }
    else if (data < 1350) //if the distance is less than 1350
    {
      wind.x = -1; //the ball/wind goes left
    }
  } 
}

CODE FOR ARDUINO

//declare variables
const int LED_PIN = 4;
int LEDvalue = 0; //will contain whether or not the LED should be on or off
int distance = 0; //will contain the distance by ultrasonic sensor
const int pingPin = 2; //Trigger Pin of Ultrasonic Sensor
const int echoPin = 3; //Echo Pin of Ultrasonic Sensor

void setup() 
{
  Serial.begin(9600); // Start serial communication at 9600 baud

  pinMode(LED_PIN, OUTPUT); //pin mode is output

  //Set the ultrasonic sensor pins as output and input respectively
  pinMode(pingPin, OUTPUT);
  pinMode(echoPin, INPUT);

  while (Serial.available() <= 0) 
  {
    Serial.println(1400); //connection establishment. 1400 so that the wind values do not change
  }
}

void loop() 
{
  //wait for p5js
    while (Serial.available()) 
    {
      sensorReading(); //reads data from the sensor

      LEDvalue = Serial.parseInt(); //parsing from the serial written data from p5js

      if (LEDvalue == 1400) //if the LED value is 1400
      {
        digitalWrite(LED_PIN, LOW); //then turn off the LED
      }
      else if (LEDvalue == 1401) //if the LED value is 1401
      {
        digitalWrite(LED_PIN, HIGH); //then turn on the LED
      }
    }
}

//Function to read the ultrasonic sensor and measure distance
void sensorReading()
{
  //Send a short low pulse
  digitalWrite(pingPin, LOW);
  delay(2); //delay to avoid complications
  digitalWrite(pingPin, HIGH); //sends a high pulse for 10 microseconds
  delay(10);
  digitalWrite(pingPin, LOW); //turn off the ping pin
  distance = pulseIn(echoPin, HIGH); //Measure the duration of the ultrasonic pulse and calculate the distance
  Serial.println(distance); //print the serial from distance
}

VIDEO

Assignment 8: Serial Communication – In Class Exercises

Exercise 1

During the exercise, we utilized an Arduino with an analog sensor to manipulate a feature in p5js based on the readings. We opted for an ultrasonic sensor to achieve this, where the data obtained was utilized to shift an ellipse along its horizontal axis in p5js.

Code P5js:

//declare variables for the dimensions and coordinates of ellipse
let ellipseXcord;
let ellipseYcord;
let ellipseRadius;

function setup()
{
createCanvas(500, 500); //create canvas
background(100);
textDisplay();
//set the initial ellipse to be in the centre
ellipseXcord = width/2;
ellipseYcord = height/2;
ellipseRadius = height/10;
}

//displays this text in the starting
function textDisplay()
{
text("PRESS ANY KEY TO START SERIAL PORT", width/2 - 109, height/2 - 5);
}

function draw()
{
background(220);
if (serialActive) //if the serial is active
{
ellipse(ellipseXcord, ellipseYcord, ellipseRadius, ellipseRadius); //then keep changing the coordinates of ellipse bases on ellipseXcord
}
else //if the serial is not active
{
textDisplay(); //then display the text with instructions
}
}

function readSerial(data) //call back function
{
if (data != null) //if the data received is not null
{
ellipseXcord = map(data, 300, 1500, ellipseRadius, width - ellipseRadius); //map the value of the data and then update the variable
//do it with ellipse radius because dont want half the circle off the screen
}
}

function keyPressed() //if any key is pressed, then set up serial
{
setUpSerial();
}

Code Arduino:
const int pingPin = 2; //Trigger Pin of Ultrasonic Sensor
const int echoPin = 3; //Echo Pin of Ultrasonic Sensor
long distance = 0; //will contain the distance of the object

void setup() {
//Start serial communication at 9600 baud
Serial.begin(9600);

//Set the ultrasonic sensor pins as output and input respectively
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);
}

void loop() {
//Send a short low pulse
digitalWrite(pingPin, LOW);
delay(2); //delay to avoid complications
digitalWrite(pingPin, HIGH); //sends a high pulse for 10 microseconds
delay(10);
digitalWrite(pingPin, LOW); //turn off the ping pin
distance = pulseIn(echoPin, HIGH); //Measure the duration of the ultrasonic pulse and calculate the distance
Serial.println(distance); //print it in the serial (P5js)
}

Exercise 2

In this particular exercise, the primary objective was to control the LEDs on an Arduino board through p5js code. The process involved utilizing the left and right arrow keys, which functioned as input devices to alter the brightness of the bulb.

Code P5js:
let dimnessCounter = 0; //this will control the brightness and dimness of the LED

function setup()
{
createCanvas(400, 400); //create canvas
}

function textDisplay() //display text in the starting
{
text("PRESS SPACE TO START SERIAL PORT", width/2 - 109, height/2 - 5);
}

function draw()
{

background(100); //grey background

if (serialActive) //if serial is active
{
text("CONNECTED!", width/2 - 27, height/2 - 5); //tell the user that it is connected
text("PRESS RIGHT ARROW TO LOWER BRIGHTNESS!", width/2 - 130, height/2 + 15); //give instructions on how to control brightness
}
else
{
textDisplay(); //display instructions on how to start serial is not active
}
}

function keyPressed() //built in function
{
if (key == " ") //if space is pressed then
{
setUpSerial(); //setup the serial
}
else if (keyCode == LEFT_ARROW) //if left arrow pressed
{
if (dimnessCounter != 0) //check if brightness is not already at the lowest
{
dimnessCounter = dimnessCounter - 50; //if not then decrease by 50
}
}
else if (keyCode == RIGHT_ARROW) //for the right key
{
if (dimnessCounter != 250) //check if dimness not at the maximum
{
dimnessCounter = dimnessCounter + 50; //increase dimness by 50
}
}

}

//callback function
function readSerial(data)
{
let sendToArduino = dimnessCounter + "\n"; //add the next line to dimness counter
writeSerial(sendToArduino); //write serial and send to arduino
}

Code Arduino:
//declare variables
const int LED_PIN = 5;
int dimness = 0; //contains the dimness fothe LED

void setup()
{
Serial.begin(9600); // Start serial communication at 9600 baud

pinMode(LED_PIN, OUTPUT); //declare pin to be output

while (Serial.available() <= 0)
{
Serial.println("CONNECTION ESTABLISHED"); // send a starting message
}
}
void loop()
{
//wait for p5 to do something
while (Serial.available()) //when serial is available
{
dimness = Serial.parseInt(); //parse the dimness from the serial to the variable
Serial.println(dimness); //checking purposes

if (Serial.read() == '\n') //since the "\n" would be present in the serial, read that and
{
analogWrite(LED_PIN, dimness); //write it to the LED
}
}
}

Exercise 3

In this exercise, we were tasked with creating an interactive p5js program that simulates a bouncing ball, which changes direction based on a variable called ‘wind.’ The ball bounces on the floor and we needed to detect when it hit the floor, so we could turn an LED on. For the second part of this exercise, we used an analog sensor (ultrasonic sensor) to control the wind variable. We set a default value in which the ball would stay in the middle of the screen. When the sensor is moved to the right from the center, the ball would move to the right, and when moved to the left, the ball would move to the left.

Code P5js:
//declare variables
let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let LEDvalue = 1401;
let goRight = 0;
let goLeft = 0;
let first

function setup() {
createCanvas(1000, 360); //create canvas
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 textDisplay()
{
text("PRESS SPACE TO START SERIAL PORT", width/2 - 109, height/2 - 5); //display the appropriate text in the start
}

function draw() {
background(255);
if (serialActive) //if the serial is active
{
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) //if the ball touches the bottom
{
velocity.y *= -0.9; // A little dampening when hitting the bottom
position.y = height-mass/2;
LEDvalue = 1401; //take LED value to be 1401 because we dont want the value (1) to be lurking in the serial and then affecting the wind values

}
else
{
LEDvalue = 1400; //when the LED is off
}

}
else
{
fill(0);
textDisplay();
}
}

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==' '){ //if space is pressed, then serial is set up
setUpSerial();
}

if (keyCode == DOWN_ARROW) //if down arrow is pressed
{
//mass etc is changed
mass=random(15,80);
position.y=-mass;
velocity.mult(0);
}
}

function readSerial(data) //call back function
{
let sendToArduino = LEDvalue + "\n"; //sends value of LED to Arduino with \n added
writeSerial(sendToArduino); //write to Arduino

if (data != null) //if the data is not null and something is received
{
console.log(data);
if (data > 1450) //if the distance is greater than 1450, then
{
wind.x = 1; //the ball/wind goes right
}
else if (data < 1350) //if the distance is less than 1350
{
wind.x = -1; //the ball/wind goes left
}
}
}

Code Arduino:
//declare variables
const int LED_PIN = 4;
int LEDvalue = 0; //will contain whether or not the LED should be on or off
int distance = 0; //will contain the distance by ultrasonic sensor
const int pingPin = 2; //Trigger Pin of Ultrasonic Sensor
const int echoPin = 3; //Echo Pin of Ultrasonic Sensor

void setup()
{
Serial.begin(9600); // Start serial communication at 9600 baud

pinMode(LED_PIN, OUTPUT); //pin mode is output

//Set the ultrasonic sensor pins as output and input respectively
pinMode(pingPin, OUTPUT);
pinMode(echoPin, INPUT);

while (Serial.available() <= 0)
{
Serial.println(1400); //connection establishment. 1400 so that the wind values do not change
}
}

void loop()
{
//wait for p5js
while (Serial.available())
{
sensorReading(); //reads data from the sensor

LEDvalue = Serial.parseInt(); //parsing from the serial written data from p5js

if (LEDvalue == 1400) //if the LED value is 1400
{
digitalWrite(LED_PIN, LOW); //then turn off the LED
}
else if (LEDvalue == 1401) //if the LED value is 1401
{
digitalWrite(LED_PIN, HIGH); //then turn on the LED
}
}
}

//Function to read the ultrasonic sensor and measure distance
void sensorReading()
{
//Send a short low pulse
digitalWrite(pingPin, LOW);
delay(2); //delay to avoid complications
digitalWrite(pingPin, HIGH); //sends a high pulse for 10 microseconds
delay(10);
digitalWrite(pingPin, LOW); //turn off the ping pin
distance = pulseIn(echoPin, HIGH); //Measure the duration of the ultrasonic pulse and calculate the distance
Serial.println(distance); //print the serial from distance
}

Video:

Week 11 – Arduino and P5 + Final Project Concept

Exercises

Exercise 1

For exercise 1, we used a light sensor. As brightness of light in the surrounding was changed, the ball moved along the horizontal axis in p5. Higher the brightness, the farther right the ball moved.

The values from the light sensor roughly ranged between 0 and 500,000 so we mapped them between 0 and width of the screen and used the mapped value as x-coordinate of the ellipse

//Exercise 1 P5js Code

let ellipseX; // Variable to store ellipse's x-coordinate

function setup() {
  createCanvas(400, 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(255, 0, 0); // 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
    console.log(data);
    console.log("fromArduino");
   
    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
      console.log("working");
//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);
  }
}
//Exercise 1 Arduino Code 

void setup() {
  Serial.begin(9600); // Start serial communication at 9600 bps

  pinMode(LED_BUILTIN, 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

  // Read sensor value
  int sensorValue = analogRead(A0);
   Serial.print(sensorValue);
  // Map sensor value to screen width (e.g. 0 to 800 pixels)
  int screenValue = map(sensorValue, 0, 1023, 0, 800);

  // Send mapped value to p5.js
  Serial.println(screenValue);

  delay(50); //    for stability
}
digitalWrite(LED_BUILTIN, LOW);
}

Exercise 2

For this exercise, we used a slider in p5 to control brightness of the LED. Value of slider ranged between 0 and 255 and these values were sent to Arduino and used as brightness for the LED.

//Exercise 2 P5js Code

let slider;
function setup() {
   createCanvas(400, 400); // Create a canvas of 800x400 pixels
  slider = createSlider(0, 255, 0);
  slider.position(160,height/2); // Set the position of the slider
  slider.style('width', '80px'); // Set the width of the slider
 
  
  noStroke(); // No stroke for the ellipse
}

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 == " ") {
    // important to have in order to start 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);
  
}
//Exercise 2 Arduino Code

const int ledPin =3;
int brightness = 0;
void setup() {
  Serial.begin(9600); // 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 while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
  }
}
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); //set brightness of LED
     
      }else
      {
        digitalWrite(LED_BUILTIN, HIGH);
      }
    }
}

Exercise 3

For this exercise, we used a potentiometer to control the wind. The potentiometer’s values ranged between 0 and 1023. So, for any value less than 500, wind moved the ball forward/wind blew to right. We added this layer that if value was between 500 and 600, wind stopped so the ball stopped. Finally, if value was above 600, wind blew in opposite direction moving the ball in the opposite direction.

For LED part, we used a flag called heightOfBall. Whenever ball touched the ground, this flag was set to zero. Otherwise, it was set to one. This was sent to Arduino to check whenever ball bounced. When this happened, LED would be turned on. Otherwise it would be turned off.

//Exercise 3 P5js Code

let velocity;
let gravity;
let position;
let acceleration;
let wind;
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);
  wind = createVector(0,0); 
}

function draw() {
  background(215);
  fill(0);
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else 
  {
    text("Connected. Press s to jump.", 20, 30);
  
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  //heightOfBall set to zero whenever ball is touching the ground. Otherwise it is set to 1.
  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=='s'){
    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]);
      console.log("Sensor value: ")
      console.log(sensorVal);

//sensor values range between 0 and 1023
//for any sensor value less than 500, make wind move ball forward/wind blows to right
      if (sensorVal <500){
        wind.x=1
      }
//if sensorVal between 500 and 600, wind stops so ball stops
      else if(sensorVal >=500 && sensorVal < 600){
        wind.x = 0
      }
//if sensorVal over 600, wind blows in opposite direction moving ball to left
      else {
        wind.x =-1
      }
          //////////////////////////////////
          //SEND TO ARDUINO HERE (handshake)
          //////////////////////////////////
    }

//send heightOfBall to arduino to indicate if ball is on the floor or not
    let sendToArduino = heightOfBall  + "\n";
    writeSerial(sendToArduino);
  }
}

Arduino

//Exercise 3 Arduino code

const int poten_pin = A0;
const int ledPin =3;

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


Video for Exercise 3:

Teammate: Mohid Raza

Final Project Proposal

For the final project, I am planning to make a musical instrument. While I do not have the exact image in mind, I want to use input from different sensors, for example touch and distance sensors, to allow user to control the music.

Elements:

  1. Live sketching/sound visualization on P5 screen using sensor input
  2. Sound control using sensor input
  3. Motor-controlled moving music record controlled by sensor input

other possible:

  • drawing options on p5 screen
  • sound options
  • buttons/LEDs

P5

The P5 screen will first present instructions on how to use the instrument. Once the experience begins, the screen will show a visualization of the music created using input from the sensors. This way, every user will, in a way, create an art piece that is theirs. So, not only can the user change their motion/touch to change the output sound but to also add something to their sketch. Also, P5 will have some buttons that, when pressed, will send output to Arduino – for example LEDs light up when Start button is pressed or if sensor value exceeds a threshold or maybe different tone/sound/volume options available on screen that will be used to change the output melody.

Arduino

For the Arduino end, as mentioned, sensors and buttons will be arranged in a box. I might integrate a motor as well that moves something, for example a music record, according to the sensor values.

Inspiration

Inspiration for the visualization for sound came from this really creative website: https://patatap.com/.

One instrument that inspired me to want to use distance sensors is a Theremin that is a non-contact instrument. I find the instrument both fascinating and beautiful and I would love to create something close to it.

Ennio Morricone - The Ecstasy of Gold - Theremin & Voice - YouTube

Final Project Proposal

Concept

For the final project, me and Sanjana are thinking of creating a Virtual Fruit Ninja. We want to take the concept of this mobile game to the next level by creating an immersive and interactive game experience allowing players to slice fruits virtually with their hands! The following project and our love for the game fruit ninja is the inspiration for this project: (https://naziafakhruddin.medium.com/gesture-controlled-flower-art-with-ml5-js-posenet-and-p5-js-61b98fa3fc68)

For this project, we are thinking of using the ml5 library, built on top of Tensor.js, and the PoseNet function to accurately track the position of the player’s hand in real time through the camera video. The goal is to create a seamless integration between the player’s hand movements and a virtual sword or blade in the game, simulating the experience of slicing real fruits with a knife.

The game mechanics will be intuitive and engaging. Players can wave their hands across the screen to slice the fruits as they appear, and the PoseNet function will accurately track their hand movements in real time, providing precise and responsive slicing actions. We will also leverage p5.js to create visually appealing graphics and animations, creating an engaging game environment that enhances the overall gameplay experience.

Challenge

One of the main challenges of this project will be optimizing the game’s performance to ensure smooth gameplay and minimize latency. We will need to carefully understand the output of the PoseNet model and use the information to update the virtual sword’s position and orientation in real-time.

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

 

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

Assignment 8: Serial Communication – In Class Exercises

Exercise 1: Control p5js through Arduino

In this exercise, we had to have an analog sensor on our Arduino and let those values control something in p5js. Hence, I used a photo resistor and the values from that would make an ellipse in p5js move along its horizontal axis.

Schematic:

p5js Code:
//Class Exercise 1: Controlling P5JS objects from Arduino
let xValue = 0;  

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

function draw() {
  background(220);
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } 
  
  else {
    text("Connected", 20, 30);
    ellipse(xValue, height/2, 150, 150);
  }
}

//Sets up the serial connection
function keyPressed() {
  if (key == " ") {
    setUpSerial();
  }
}

//Function to read in serial data from the Serial Port. 
function readSerial(data) {
  if (data != null) {
    //Mapping the sensor values from 'data' - 0 to 500 - 0
    xValue = map(data, 0, 1023, 0, width);
  }
}

Arduino Code:
const int lightSensor = A0;

void setup() {
  Serial.begin(9600);
  pinMode(lightSensor, INPUT);
}

void loop() {
  //Reads value from the sensor and prints it to the Serial Port (p5js)
  int lightValue = analogRead(lightSensor);
  Serial.println(lightValue);
}
Video:

Exercise 2: Control Arduino LEDs through p5js

In this exercise, we had to simply control LEDs on our Arduino board via p5js code. Hence, I decided to do something where depending on where the user’s mouse is on the canvas on p5js, it will light up a specific LED. So, for instance, if it’s on the far left side, it will switch on the left most LED, and if it’s on the right side, it will switch on the right most LED and so on.

Schematic:

p5js Code:
let circle_size = 50;

//These are variables to determine whether the any of the coloured lights are ON or OFF
let g_ON = 0;
let b_ON = 0;
let r_ON = 0;
let y_ON = 0;

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

function draw() {
  background(0);
  fill(255);
  textAlign(CENTER);
  textSize(20);
  text("Move the cursor around to switch the LED's ON!", width/2, 40);
  
  if (!serialActive) {text("Press Space Bar to select Serial Port", width/2, 75); } 
  else {text("Connected", width/2, 75); }
  
  //Depending on which side of the canvas the mouse is on, that specific LED will switch on and the circle icon will also be switched to that color as well
  if(mouseX < width/4) {
    fill("red");
    r_ON = 1;
    y_ON = 0;
    b_ON = 0;
    g_ON = 0;
  }
  
  else if(mouseX >= width/4 && mouseX < width/2) {
    fill("yellow");
    r_ON = 0;
    y_ON = 1;
    b_ON = 0;
    g_ON = 0;
  }
  
  else if(mouseX >= width/2 && mouseX < 3*width/4) {
    fill("blue");
    r_ON = 0;
    y_ON = 0;
    b_ON = 1;
    g_ON = 0;
  }
  
  else {
    fill("green");
    r_ON = 0;
    y_ON = 0;
    b_ON = 0;
    g_ON = 1;
  }
  
  circle(mouseX, mouseY, circle_size);
}

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

function readSerial(data) {
  if(data != null) {
    //Sends the light ON/OFF messages for all the lights to the arduino
    let sendToArduino = r_ON + "," + y_ON + "," + b_ON + "," + g_ON + "\n";
    writeSerial(sendToArduino);
  }
}
Arduino:
const int red_pin = 13;
const int yellow_pin = 11;
const int blue_pin = 4;
const int green_pin = 2;

void setup() {
  Serial.begin(9600);
  pinMode(red_pin, OUTPUT);
  pinMode(yellow_pin, OUTPUT);
  pinMode(blue_pin, OUTPUT);
  pinMode(green_pin, OUTPUT);

  // Blink them so we can check the wiring
  digitalWrite(red_pin, HIGH);
  digitalWrite(yellow_pin, HIGH);
  digitalWrite(blue_pin, HIGH);
  digitalWrite(green_pin, HIGH);
  delay(200);
  digitalWrite(red_pin, LOW);
  digitalWrite(yellow_pin, LOW);
  digitalWrite(blue_pin, LOW);
  digitalWrite(green_pin, LOW);

  //Checks while the Serial Port is available then we send '0'
  while(Serial.available() <= 0) {
    Serial.println("0");
    delay(300);
  }
}

void loop() {
  while(Serial.available()) {
    //We parse the integer values (ON/OFF) to the respective leds
    int red = Serial.parseInt();
    int yellow = Serial.parseInt();
    int blue = Serial.parseInt();
    int green = Serial.parseInt();

    //Once it's read the \n character, then we switch the according LEDs on
    if (Serial.read() == '\n') {
      digitalWrite(red_pin, red);
      digitalWrite(yellow_pin, yellow);
      digitalWrite(blue_pin, blue);
      digitalWrite(green_pin, green);
    }
    Serial.println(); //Needs two way handshake commuincation between ports. 
  }
}
Video:

Exercise 3: Two-way communication between p5js and Arduino

In this exercise, we were given a p5js code which drew a bouncing ball and it could change directions depending on some ‘wind’ variable. We were supposed to relay the information of when the ball bounced (hit the floor), then the LED would switch on, otherwise it’s off. Similarly, we would also be able to control the wind value through an analog sensor, hence I chose the photo resistor.

Schematic:

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

//These are the variables which would be read and written from/to the Arduino
let sensor_wind = 0;
let led_ON = 0;

function setup() {
  createCanvas(640, 640);
  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 {text("Connected!", 20, 30); }
  
  fill(0);
  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;
      led_ON = 1;  //If the ball makes contact with the ground, the LED will be ON
  }
  else {led_ON = 0;}   //Else the LED will be OFF
  
  //If the sensor_wind value from the Arduino that was mapped is greater than 0, then it will move the ball to the right
  if(sensor_wind > 0) {
    wind.x = 1;
  }
  
  //Else if the sensor_wind value from the Arduino is less than 0, it will move the ball to the left
  else if(sensor_wind < 0) {
    wind.x = -1;
  }
  
  //If it's 0, aka no wind, then it will just keep the ball where it is, no wind. 
  else {
    wind.x = 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 == "m"){
    mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
  
  if(key == " ") {
    setUpSerial();
  }
}

function readSerial(data) {
  if(data != null) {
    //Sends the LED ON/OFF information to the Arduino
    let sendToArduino = led_ON + "\n";
    writeSerial(sendToArduino);
    //Reads the sensor_wind values from the Arduino and maps its value to either -1 or 1 to correspond to wind direction. 
    sensor_wind = map(data, 0, 1023, -1 , 1);
  }
}
Arduino Code:
const int led_pin = 13;
const int lightSensor = A0;

void setup() {
  Serial.begin(9600);
  pinMode(led_pin, OUTPUT);
  pinMode(lightSensor, INPUT);

  //Check wiring: 
  digitalWrite(led_pin, HIGH);
  delay(200);
  digitalWrite(led_pin, LOW);

  while(Serial.available() <= 0) {
    Serial.println("0");
  }

}

void loop() {
  while(Serial.available()) {
    //Gets the led ON/OFF information from p5js and switches the led on/off accordingly
    int led_ON = Serial.parseInt();
    digitalWrite(led_pin, led_ON);

    //Gets the light value from the sensor and sends it to p5js
    int lightValue = analogRead(lightSensor);
    Serial.println(lightValue);
  }
}
Video: