Week 11: Production

Group Member: Aditi

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.

We used a potentiometer as the analog sensor on Arduino to move the ellipse on the horizontal axis.

p5js code:

// Serial port object
let port;

// Latest sensor value
let sensorVal = 0;

function setup() {
  createCanvas(400, 300);
  background(220);

  // Create the serial connection object
  port = createSerial();

  // If a port was used before, auto-reconnect
  let used = usedSerialPorts();
  if (used.length > 0) {
    port.open(used[0], 9600);
  }
}

function draw() {
  background(220);

  // Read one line of text until newline "\n"
  let str = port.readUntil("\n");

  // Make sure we actually received something
  if (str.length > 0) {

    // Convert the string into an integer
    let val = int(str.trim());

    // Map sensor value (0–1023) to screen X position (0–400)
    let x = map(val, 0, 1023, 0, width);

    // Draw a circle at mapped position
    ellipse(x, height / 2, 40, 40);

  } else {

    // If empty data is received, print it for debugging
    console.log("Empty:", str);
  }
}

Arduino code:

const int sensor=A2;
int sensorValue;
void setup() {
  // put your setup code here, to run once:
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  Serial.println(0); // send a starting message
}

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

Task 2: make something that controls the LED brightness from p5.

We decided to control the LED’s brightness through four buttons on p5js.

p5js code:

let port;
let brightnessToSend = 0;
const baudrate = 9600;

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

  // Create the serial port
  port = createSerial();

  // connect automatically if used before
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], baudrate);
  } else {
    connectBtn = createButton("Connect to Serial");
    connectBtn.position(10, 10);
    connectBtn.mousePressed(() => port.open(baudrate));
  }
}

function draw() {
  background(30);

  drawStarButton(80, 150, 40, 20, 5, 64);
  drawStarButton(160, 150, 40, 20, 5, 128);
  drawStarButton(240, 150, 40, 20, 5, 192);
  drawStarButton(320, 150, 40, 20, 5, 255);

  fill(255);
  textAlign(CENTER);
  text("Current brightness: " + brightnessToSend, width / 2, 280);
}

function mousePressed() {
  if (!port.opened()) return; // p5.webserial function to check if open

  let stars = [
    { x: 80,  brightness: 64  },
    { x: 160, brightness: 128 },
    { x: 240, brightness: 192 },
    { x: 320, brightness: 255 }
  ];

  for (let s of stars) {
    if (dist(mouseX, mouseY, s.x, 150) < 30) {
      brightnessToSend = s.brightness;

      // Send brightness (0–255)
      port.write(brightnessToSend);
    }
  }
}

function drawStarButton(x, y, radius1, radius2, points, brightness) {
  let angle = TWO_PI / points;
  let halfAngle = angle / 2;

  if (brightnessToSend === brightness) fill(255, 200, 0);
  else fill(255);

  push();
  translate(x, y);
  beginShape();
  for (let a = 0; a < TWO_PI; a += angle) {
    vertex(cos(a) * radius1, sin(a) * radius1);
    vertex(cos(a + halfAngle) * radius2, sin(a + halfAngle) * radius2);
  }
  
  endShape(CLOSE);
  pop();
}

Arduino code:

int ledPin = 9;

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

void loop() {
  if (Serial.available() > 0) {
    int brightness = Serial.read();  // 0–255
    analogWrite(ledPin, brightness); // PWM LED brightness
  }
}

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.

p5js code:

let velocity;        // velocity vector of the ball
let gravity;         // gravity force vector
let position;        // position of the ball
let acceleration;    // accumulated acceleration each frame
let wind;            // wind force vector
let drag = 0.99;     // drag factor to slow down velocity a bit
let mass = 50;       // "mass" of the ball, also used as its size
let port;            // serial port object for Arduino ↔ p5 communication
let button;          // button to trigger serial connection popup
let open=false;      // flag to track if we've tried to open the port

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);   // start ball at top center
  velocity = createVector(0,0);          // start with no movement
  acceleration = createVector(0,0);      // acceleration accumulates forces
  gravity = createVector(0, 0.5*mass);   // gravity pulls ball downward
  wind = createVector(0,0);              // wind starts with no force
  port = createSerial(); //port is an object that will be used to send message and receeieve message from arudnio
 
  //createbutton creates button in p5js with quote
  button=createButton("Connect to Arduino");
  button.position(width/2,height/2); //where you want your button to be
  button.mousePressed(openArduino); 
}

function openArduino(){
  if(!port.opened()){ //to check if the port is opened or not we use function opened
    port.open(9600) // we open the port for communication with 9600 frequency
   
    button.remove() // once arudino is opended we removed the button to connect to ardunio
   
    open=true; //just a variable to check if we opended the port or not
  } 
}

function draw() {
  if(port.opened()){             // run main logic only if serial port is open
  background(255);               // clear canvas every frame
  applyForce(wind);              // apply wind force first
  applyForce(gravity);           // then apply gravity force
  velocity.add(acceleration);    // a → v
  velocity.mult(drag);           // apply drag to slowly reduce velocity
  position.add(velocity);        // v → position
  acceleration.mult(0);          // reset acceleration so next frame starts fresh
  ellipse(position.x,position.y,mass,mass);  // draw the ball
 
  }

  // collision + LED control are outside the port.opened() block,
  // so they always run based on current position
  if (position.y > height-mass/2) {     
      velocity.y *= -0.9;         // A little dampening when hitting the bottom (bounce)
      position.y = height-mass/2; // keep ball from sinking below the "floor"
      port.write("1\n")           // send "1" to Arduino → turn LED ON
    }
    else {
      port.write("0\n")    // otherwise send "0" → turn LED OFF
    }
    potvalue=port.readUntil("\n");  // read a line from Arduino (pot value as text)
    // console.log(potvalue);
 
    if(potvalue>514){      // simple threshold: above midpoint = wind to the right
      wind.x=1
    }
    else{                  // below midpoint = wind to the 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);  // scale force by mass → acceleration
  acceleration.add(f);                 // accumulate acceleration for this frame
}

function keyPressed(){
  if (keyCode==LEFT_ARROW){
    wind.x=-1;              // keyboard override: push ball left
  }
  if (keyCode==RIGHT_ARROW){
    wind.x=1;               // keyboard override: push ball right
  }
  if (key==' '){
    mass=random(15,80);     // randomize mass (and drawn size)
    position.y=-mass;       // reset ball above the top so it falls back down
    velocity.mult(0);       // clear velocity so it restarts clean
  }
}

Arduino code:

int greenLight=7;
int sensor=A0;
void setup() {
  // put your setup code here, to run once:
  pinMode(greenLight,OUTPUT);
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  digitalWrite(greenLight,0);
}

void loop() {
  // put our main code here, to run repeatedly:
  // Serial.print("0");
 
  int value= analogRead(sensor);
  Serial.print(value);
  Serial.print("\n");

  while(Serial.available()>0){ //avaiable checks if there is any message in inbox of ardino
    String a=Serial.readStringUntil('\n');
    a.trim();
    if(a=="1"){
       digitalWrite(greenLight,1);
    }
    else{
      digitalWrite(greenLight,0);
    }   
  }
}

Video:

Leave a Reply