Week 11 – In class exercises

  1. make something that uses only one sensor  on Arduino and makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on arduino is controlled by p5For this exercise, I modified the p5js code using a potentiometer on the arduino. Different values of the potentiometer are mapped to the x coordinates of the ellipse. This makes it move across the horizontal axis in the middle of the screen. The arduino code remains the same as the example code.
let y=height/2;
let x = 0;
let left = 0; // True (1) if mouse is being clicked on left side of screen
let right = 0; // True (1) if mouse is being clicked on right side of screen

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

function draw() {
  background(255);
  // one value from Arduino controls the background's red color
  fill(255, 0, 255, map(x, 0, 1023, 0, 255));
  ellipse(map(x, 0, 1023, 0, width), 30, 30);

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

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


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

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

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

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

2. make something that controls the LED brightness from p5

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

p5js code:

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

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

function draw() {
  background(map(rVal, 0, 1023, 0, 255), 255, 255);
  fill(255, 0, 255, map(alpha, 0, 1023, 0, 255));

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

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

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

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



arduino code:

int leftLedPin = 2;
int rightLedPin = 5;

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

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

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

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

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

    int left = Serial.parseInt();
    int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      Serial.print("Left: ");
      Serial.print(left);
      Serial.print(", Right: ");
      Serial.println(right);

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



3. take the gravity wind example (https://editor.p5js.org/aaronsherwood/sketches/I7iQrNCul) and make it so every time the ball bounces one led lights up and then turns off, and you can control the wind from one analog sensor

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

video:

p5.js Code:

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

function draw() {
  background(255);
  
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    applyForce(wind);
    applyForce(gravity);
    velocity.add(acceleration);
    velocity.mult(drag);
    position.add(velocity);
    acceleration.mult(0);

    fill(0);
    ellipse(position.x, position.y, mass, mass);
    if (position.y > height - mass / 2) {
      velocity.y *= -0.9; // A little dampening when hitting the bottom
      position.y = height - mass / 2;
      ballOnGround = 1;
      let sendToArduino = ballOnGround + "\n";
    writeSerial(sendToArduino);
    ballOnGround = 0;
    sendToArduino = ballOnGround + "\n";
    writeSerial(sendToArduino);
    } else {
      ballOnGround = 0;
    }
  }
  
  
  if (mouseIsPressed) {
      restartSketch();
    }
}

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


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

function readSerial(data) {
  if (data != null) {
    // make sure there is actually a message
    // split the message
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 1) {
      // only store values here
      // do everything with those values in the main draw loop
      let photoresistor = int(fromArduino[0]);
      
      //change the wind based on the photoresistor readings
      wind.x = map(photoresistor, 0, 1000, -5, 5);
      
    }

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


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

arduino code:

int ledPin = 2;
const int photoresistorPin = A0;

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

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

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
    int ballOnGround = Serial.parseInt();
    if (Serial.read() == '\n') {
      int photoresistorValue = analogRead(photoresistorPin);

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

 

Leave a Reply