Final Project- User Testing

I conducted the user testing without giving them any prior notice and only reading from the interface, and they had some questions like when the game ends? So I added more text after that to make things more clear for the users. Other than that, once they got the hang of it, they were able to play the game easily and they figured out everything on how it works and how to stop. From the third iteration onwards, they become a master and play even better than I do(at least most of them). One area that could be improved is the addition of a text on the prototype saying Hover here or Put your hand here since they didn’t know where the sensor was in the beginning. That part of explaining where to hover the hand was the issue, which I will address by adding text on the prototype as mentioned.

 

Video:

week 12 : Final project update

 

“frenzy jump”

so previously i thought about making an instrument using the serial communication between arduino and p5, that turned out to be very difficult , i could have done it, but unfortunately with the time on hand i could not get it finished on time. therefore, i decided to create a very simple game on p5js that consists of a ball jumping over obstacles, and for the arduino part, i have created a remote switch/button panel that contains the arduino, and 4 different components, but i will use only two. The 4 components are 3 paddle switches, and one button, i will use one paddle switch, and one button to control the ball in the game.

My switch panel controller :

components:

Arduino protoshield

arduino board

3 paddle switches

one button

Initial code :

const player = {
  posX: 0,
  posY:  0,
  size: 50,
  forceY: 0,
  isJumping: false
}

const obstacles = [{
  posX: 600,
  height: 50,
  width: 70
},{
  posX: 1800,
  height: 50,
  width: 70
},{
  posX: 2500,
  height: 50,
  width: 70
}];

const gravity = 0.3;
const mapSpeed = 5;

const floorPosition = 100;

let gameover = false;

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);
  
  player.posX = width / 3;
  player.posY = height - floorPosition - 100;
  
}

function draw() {
  background(0);
  
  if(!gameover) {
    
    // Check for serial connection
    if(!serialActive) {
      fill(255);
      text("Press space to select serial port.", 20, 30);  
    }
    else {
      fill(255);
      text("Connected", 20, 30);  

    }

    // Draw game
    drawFloor();
    drawObstacles();
    drawPlayer();


    // Move game
    movePlayer();
    moveObstacles();
  }
}

function drawFloor() {
  fill(255);
  
  rect(0, height - floorPosition, width, floorPosition);
}

function drawPlayer() {
  fill(255, 150, 0);
  
  ellipse(player.posX, player.posY, player.size, player.size);
}

function drawObstacles() {
  fill(255);
  for(o of obstacles) {
    rect(o.posX, height - floorPosition, o.width, -o.height);    
  }
}

function testCollisions(x, y) {
  // Test collide with floor
  if(player.forceY > 0 && y > height - floorPosition - player.size/2) {
    return true;
  }
  
  for(o of obstacles) {
    if(x + player.size / 2 > o.posX && x - player.size / 2 < o.posX + o.width && y > height - floorPosition - o.height - player.size / 2) {
      return true;  
    }
  }
  
  return false;
}

function movePlayer() {
  
  if(testCollisions(player.posX, player.posY)) {
    player.posX -= mapSpeed;
    player.isJumping = false;
    
    if(player.posX < 0 - player.size) {
      // gameover
      gameover = true;
    }

  }
  else if(player.posX < width / 3) {
    player.posX += 0.5;
  }
  
  const nextPos = player.posY + player.forceY;
  
  if(testCollisions(player.posX, nextPos)) {
    player.forceY = 0;
    player.isJumping = false;
  }
  else {
    player.posY += player.forceY;
    player.forceY += gravity;
  }
  
  
}

function moveObstacles() {
  for(o of obstacles) {
    o.posX -= mapSpeed;
    
    if(o.posX < -o.width) {
      o.posX = random(width, width*1.5);
      o.width = random(50, 200);
      o.height = random(20, 200);
    }
  }  
  
  
}

function readSerial(data) {
  const pin = data.split(':')[0]; 
  const action = data.split(':')[1];
  
  console.log(action);
  
  if(action == "pressed") {
    pressed = true;
  }
  else {
    pressed = false;
  }

}

function keyPressed() {
  if(key == " ") {
    setUpSerial();
  }
  
  if(key == 'z' && !player.isJumping) {
    player.isJumping = true;
    player.forceY = -8;
  }
}

 

 

idea of possibly how the game will look like:

Final Project Draft

Currently I have figured out the connection between arduino and p5 so that based on poseNet I can move the servo as if it is following me. I have done this on the basis of getting the position of nose pose and sending it to arduino mapped to the servo range. Currently it works as intended however I think it might be a bit off when I am at extreme edges of the canvas video. I am thinking of rectifying by getting a distance variable for my next draft where i will use the distance between eyes to maybe get a more accurate angle.

I will follow a cardboard tutorial to make the CCTV:

let video;
let poseNet;
let pose;
let skeleton;
let loco= 0;

function setup() {
  createCanvas(640, 480);
  video = createCapture(VIDEO);
  video.hide();
  poseNet = ml5.poseNet(video, modelLoaded);
  poseNet.on('pose', gotPoses);
}

function gotPoses(poses) {
  //console.log(poses); 
  if (poses.length > 0) {
    pose = poses[0].pose;
    skeleton = poses[0].skeleton;
  }
}


function modelLoaded() {
  console.log('poseNet ready');
}

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

  if (pose) {
    
    fill(255, 0, 0);
    ellipse(pose.nose.x, pose.nose.y, 20);
   
    loco = int(pose.nose.x);
    val = int(map(loco, 0, 640, 0, 180));

    print(val)
    
  
  }
}

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) {
    // 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
      print("nice");
      // We take the string we get from Arduino and explicitly
      // convert it to a number by using int()
      // e.g. "103" becomes 103
    
    }

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

P5 👆

#include <Servo.h>

Servo myservo;  // create servo object to control a servo


void setup() {

  Serial.begin(9600);

  myservo.attach(9);

  // 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);
           myservo.write(90);                  // sets the servo position according to the scaled value

  }
}

void loop() {
  // wait for data from p5 before doing something
  
  while (Serial.available()) {
    Serial.println("0,0");
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
    int value = Serial.parseInt();
    if (Serial.read() == '\n') {
       myservo.write(value);                  // sets the servo position according to the scaled value
    }
  }
}

arduino 👆

trial video: https://youtube.com/shorts/h1etPCv24vA

 

Final Project Draft 1

My aim in this project was to try and make a game that allows the player to help sell pie.

Using the serial connectios the player should be able to use the potentiometer in order to get the wanted order. When one is chosen they press a button to confirm the choice.

The game goes for 2.5 minuts and the player must complete as many orders as possible.

 

So far I have this

P5.js sketch:

let x = 0;

let backgroundImage;
let rawImage, undercookedImage, perfectImage, overcookedImage, burntImage;

function preload() {
  // Load background image only for now
  backgroundImage = loadImage('Background.jpg');
}

function loadFoodImages() {
  // Load images after the serial connection starts
  rawImage = loadImage('raw.jpg');
  undercookedImage = loadImage('undercooked.jpg');
  perfectImage = loadImage('perfect.jpg');
  overcookedImage = loadImage('overcooked.jpg');
  burntImage = loadImage('burnt.jpg');
}

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

function draw() {
  // Display background image
  image(backgroundImage, 0, 0, width, height);

  // Display image based on the value of x
  displayFoodImage();
  
  // Display serial connection status
  fill(0);
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
  }
}

function displayFoodImage() {
  // Define the ranges for each image
  const rawRange = [0, 200];
  const undercookedRange = [201, 400];
  const perfectRange = [401, 600];
  const overcookedRange = [601, 800];
  const burntRange = [801, 1023];

  // Map x to the corresponding image based on the ranges
  let currentImage;
  if (x >= rawRange[0] && x <= rawRange[1]) {
    currentImage = rawImage;
  } else if (x >= undercookedRange[0] && x <= undercookedRange[1]) {
    currentImage = undercookedImage;
  } else if (x >= perfectRange[0] && x <= perfectRange[1]) {
    currentImage = perfectImage;
  } else if (x >= overcookedRange[0] && x <= overcookedRange[1]) {
    currentImage = overcookedImage;
  } else if (x >= burntRange[0] && x <= burntRange[1]) {
    currentImage = burntImage;
  }

  // Display the current image
  if (currentImage) {  // Check if the image is defined
    image(currentImage, width / 2 - 50, height / 2 - 50, 100, 100);
  }
}

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) {
    x = int(trim(data));
    
    // Load images only when the serial connection starts
    if (serialActive) {
      loadFoodImages();
    }
  }
}

 

Arduino sketch:

int sensorPin = A0;  
int sensorValue;

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

void loop() {
  // Read the sensor value
  sensorValue = analogRead(sensorPin);

  // Print the sensor value to the serial port
  Serial.println(sensorValue);

  delay(100);  
}

 

Circuit:

My potineometer works just fine. I still need to

-Display the required image according the the divided readings of the potineometer

-work on the button as a submitted answer

-figure out how to add timer and end results (maybe a leadboard)

-add sounds

-Finalize Instructions

Final Project – Draft 2 – Walking Buddy

Building on my initial idea to create an assistive device, I have decided to create a robot that serves as a walking assistant by warning the user of possible obstructions along the way. The robot would be voice controlled to give commands such as the direction of the robot. Based on the reading of an ultrasonic sensor the walking buddy would send out signals through the speaker to alert the user. Additionally, the user would be informed of the distance between the next obstruction to have a better sense while walking. If time permits, I plan to include the option of controlling the robot through hand movements as well to make the model more inclusive.

Arduino:

  • Uses the ultrasonic sensor to provide input on possible obstructions and sends it to p5.
  • Based on the ultrasonic reading the speaker plays a tune to warn the user.
  • The movement of the robot is controlled using the DC motors.

P5.js program:

  • Begins with informing the user of the different tunes and voice commands.
  • The user gives a voice command to change the direction of the robot.
  • The direction is communicated to the Arduino and the robot starts moving accordingly
  • P5 stores the distance from the next obstruction received from the Arduino and increases the frequency of the tune as the user gets closer to it.

Final Project: Something ml5.js

Progress:

As previously mentioned in my final project concept, I intend to create an “electronic buddy” or an “art robot” (which sounds better than my previous term). Thus far, I have successfully established communication between p5 and Arduino. Specifically, I utilized the handpose model from the ml5 library to detect if the hand is within specific areas on the screen and transmit a corresponding index to the Arduino.

As this is only a preliminary test, I have two motors connected to the Arduino, rotating in one direction if the hand is in the upper third of the screen, halting if the hand is in the middle portion, and rotating in the opposite direction if the hand is in the lower third. Currently, there is only unidirectional communication from p5 to Arduino, with p5 sending data to the latter. I hope to achieve meaningful communication from the Arduino to p5 as I progress. I have included the p5 sketch, Arduino sketch, and a video of the test run for reference.

p5 sketch:

let handpose;
let value = -1;
let video;
let predictions = [];

function setup() {
  createCanvas(640, 480);
  video = createCapture(VIDEO);
  video.size(width, height);

  handpose = ml5.handpose(video, modelReady);

  // This sets up an event that fills the global variable "predictions"
  // with an array every time new hand poses are detected
  handpose.on("predict", results => {
    predictions = results;
  });

  // Hide the video element, and just show the canvas
  video.hide();
}

function modelReady() {
  console.log("Model ready!");
}

function draw() {
  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    image(video, 0, 0, width, height);

    // We can call both functions to draw all keypoints and the skeletons
    drawKeypoints();

    // draws sections on the screen
    for (let i = 0; i <= width / 2; i += (width / 2) / 3) {
      stroke(255, 0, 0);
      line(i , 0, i, height);
    }

    for (let i = 0; i <= height; i += height / 3) {
      stroke(255, 0, 0);
      line(0, i, width / 2, i);
    }

  }
  
}


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

function readSerial(data) {

  if (data != null) {

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

// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
  for (let i = 0; i < predictions.length; i += 1) {
    const prediction = predictions[i];
    let area = [0, 0, 0, 0, 0, 0, 0, 0, 0];
    for (let j = 0; j < prediction.landmarks.length; j += 1) {
      const keypoint = prediction.landmarks[j];
      fill(0, 255, 0);
      noStroke();
      ellipse(keypoint[0], keypoint[1], 10, 10);
      
      // count number of trues
      // -- helps to detect the area the detected hand is in
      if (withinTopLeft(keypoint[0], keypoint[1])) {
        area[0] += 1;
      }
      if (withinTopCenter(keypoint[0], keypoint[1])) {
        area[1] += 1;
      }
      if (withinTopRight(keypoint[0], keypoint[1])) {
        area[2] += 1;
      }
      if (withinMiddleLeft(keypoint[0], keypoint[1])) {
        area[3] += 1;
      }
      if (withinMiddleCenter(keypoint[0], keypoint[1])) {
        area[4] += 1;
      }
      if (withinMiddleRight(keypoint[0], keypoint[1])) {
        area[5] += 1;
      }
      if (withinBottomLeft(keypoint[0], keypoint[1])) {
        area[6] += 1;
      }
      if (withinBottomCenter(keypoint[0], keypoint[1])) {
        area[7] += 1;
      }
      if (withinBottomRight(keypoint[0], keypoint[1])) {
        area[8] += 1;
      }
      // end of count
    }
    
    // print index
    for (let i = 0; i < area.length; i += 1) {
      if (area[i] == 21) {
        value = i;
      }
    }
  }
}

// returns true if a point is in a specific region
function withinTopLeft(x, y) {
  if (x >= 0 && x < (width / 2) / 3 && y >=0 && y < height / 3) {
    return true;
  }
  return false;
}

function withinTopCenter(x, y) {
  if (x > (width / 2) / 3  && x < 2 * (width / 2) / 3 && 
      y >=0 && y < height / 3) {
    return true;
  }
  return false;
}

function withinTopRight(x, y) {
  if (x > 2 * (width / 2) / 3 && x < (width / 2) && 
      y >=0 && y < height / 3) {
    return true;
  }
  return false;
}

function withinMiddleLeft(x, y) {
  if (x >= 0 && x < (width / 2) / 3 && y > height / 3 && y < 2 * height / 3) {
    return true;
  }
  return false;
}

function withinMiddleCenter(x, y) {
  if (x > (width / 2) / 3  && x < 2 * (width / 2) / 3 && 
      y > height / 3 && y < 2 * height / 3) {
    return true;
  }
  return false;
}

function withinMiddleRight(x, y) {
  if (x > 2 * (width / 2) / 3 && x < (width / 2) && 
      y > height / 3 && y < 2 * height / 3) {
    return true;
  }
  return false;
}

function withinBottomLeft(x, y) {
  if (x >= 0 && x < (width / 2) / 3 && y > 2 * height / 3 && y < height) {
    return true;
  }
  return false;
}

function withinBottomCenter(x, y) {
  if (x > (width / 2) / 3  && x < 2 * (width / 2) / 3 &&
      y > 2 * height / 3 && y < height) {
    return true;
  }
  return false;
}

function withinBottomRight(x, y) {
  if (x > 2 * (width / 2) / 3 && x < (width / 2) &&
      y > 2 * height / 3 && y < height) {
    return true;
  }
  return false;
}

Arduino sketch:

const int ain1Pin = 3;
const int ain2Pin = 4;
const int pwmAPin = 5;

const int bin1Pin = 8;
const int bin2Pin = 7;
const int pwmBPin = 6;


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

  pinMode(LED_BUILTIN, OUTPUT);

  pinMode(ain1Pin, OUTPUT);
  pinMode(ain2Pin, OUTPUT);
  pinMode(pwmAPin, OUTPUT); // not needed really

  pinMode(bin1Pin, OUTPUT);
  pinMode(bin2Pin, OUTPUT);
  pinMode(pwmBPin, OUTPUT); // not needed really

  // TEST BEGIN
  // turn in one direction, full speed
  analogWrite(pwmAPin, 255);
  analogWrite(pwmBPin, 255);
  digitalWrite(ain1Pin, HIGH);
  digitalWrite(ain2Pin, LOW);
  digitalWrite(bin1Pin, HIGH);
  digitalWrite(bin2Pin, LOW);

  // stay here for a second
  delay(1000);

  // slow down
  int speed = 255;
  while (speed--) {
    analogWrite(pwmAPin, speed);
    analogWrite(pwmBPin, speed);
    delay(20);
  }

  // TEST END

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

  while (Serial.available()) {
    // sends dummy data to p5
    Serial.println("0,0");

    // led on while receiving data
    digitalWrite(LED_BUILTIN, HIGH); 

    // gets value from p5
    int value = Serial.parseInt();

    // changes brightness of the led
    if (Serial.read() == '\n') {
      
      if (value >= 0 && value <= 2) {
        digitalWrite(ain1Pin, HIGH);
        digitalWrite(ain2Pin, LOW);
        digitalWrite(bin1Pin, HIGH);
        digitalWrite(bin2Pin, LOW);

        analogWrite(pwmAPin, 255);
        analogWrite(pwmBPin, 255);

      }

      else if (value >= 3 && value <= 5) {
        analogWrite(pwmAPin, 0);
        analogWrite(pwmBPin, 0);
      }

      else {
        digitalWrite(ain1Pin, LOW);
        digitalWrite(ain2Pin, HIGH);
        digitalWrite(bin1Pin, LOW);
        digitalWrite(bin2Pin, HIGH);

        analogWrite(pwmAPin, 255);
        analogWrite(pwmBPin, 255);
      }
    }
  }
  // led off at end of reading
  digitalWrite(LED_BUILTIN, LOW);
}

Video:

Final Draft 1

Concept:

I’ve tentatively decided on a concept for my final project, though I’m not completely set on it yet. I’m considering creating a reaction time game centered around colors, featuring various levels of difficulty. The project involves a platform housing colored buttons capable of lighting up, with two buttons assigned to each of the four colors.

In the first level, a color will display on the screen, prompting the corresponding button to light up. Clicking that button reveals another color, illuminating the alternative button. The subsequent level increases the challenge by lighting up only one of the two buttons of the same color. For the third level, the screen will exhibit the name of the color in a different hue, requiring the player to press the button matching the displayed color rather than its name. This challenge can be reversed, prompting the player to press based on the text rather than the color, adding complexity to the game. a game will be around 10 lights color combination.

p5 interface

Regarding the interface, there will be a welcome screen on the p5 platform featuring a play button as well as an info button. After the player has read the instructions they click the play button. Clicking this will lead to a page displaying multiple levels for the user to select and start the game.

Components:

    • Arduino uno
    • 8 buttons
    • rigid body for the buttons
    • lots of jumper wirds

Arduino (Outgoing Data):

the ardunio would send feedback to p5 about the status of the buttons if pressed or not.

p5.js (Outgoing Commands):

during specific levels, the p5 will signal the Arduino to activate the light for the targeted button.

sketch:

 

Pet the Plant

Concept:
“Pet the Plant” is an interactive project that merges the physical and digital realms to provide users with the satisfaction of nurturing a virtual plant without the responsibilities and risks associated with real plants. Inspired by the creator’s struggles in maintaining live plants, the project employs Arduino and various sensors to simulate the physical actions of caring for a plant, while the digital aspect, coded in p5.js, reflects the plant’s growth.

Components:
1. Arduino Sensors:
– Potentiometer: Used to select from five different virtual plants.
– Force Resistor Sensor: Mimics soil patting motions by squeezing between fingers.
– Water Level Sensor: Allows users to virtually water the plant by pouring water into a cup.
– Photocell: Reads ambient “sunlight” affecting the virtual plant’s size and cloud visibility.

2. Digital Interface:
– Coded in C++ for Arduino and p5.js for the virtual experience.
– Utilizes p5.serialcontrol for communication between Arduino and p5.js.
– Screenshots in a GIF format showcase various scenes of the digital experience.

“Plant the Pet” Set-Up:
The physical interface is designed to align with the plant theme:
– Arduino and wires hidden inside a shoebox with a connecting hole to the laptop.
– Four holes on top for the sensors, placed inside small plant pots.
– Brown air-dry clay serves as simulated dirt, covered with fake grass to enhance the plant-like appearance.

Smart Plant Growth Monitor:
This project introduces a hands-on experience for users to monitor virtual plant growth on a computer screen. Key components include:
– Physical Soil Sensor: Arduino-powered soil moisture sensor.
– Digital Plant Simulation: Developed using P5.js for visual appeal.
– Real-time Data Exchange: Arduino collects and sends soil moisture data to the P5.js environment.
– User Interaction: Users physically water the virtual plant by adding water to the soil sensor.
– Feedback System: Visual feedback in the P5.js simulation reflects plant growth based on soil moisture levels.

Arduino & P5.js Outgoing Ongoing Data:
The Arduino collects real-time soil moisture data and transmits it to the P5.js environment. This ongoing data exchange facilitates a dynamic and responsive virtual plant simulation, allowing users to observe the impact of their actions on the plant’s growth in real-time. The interaction is designed to be user-friendly, creating an engaging and educational experience in the realm of virtual gardening.

 

Arduino Code

int pot; //potentiometer
int fsr; // force sensitive resistor
int humid; // humidity & temperature level sensor
int light; // photocell

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

void loop() {
  pot = analogRead(A0);
  fsr = analogRead(A1);
  humid = analogRead(A2);
  light = analogRead(A3);
  Serial.print(pot);
  Serial.print(',');
  Serial.print(fsr);
  Serial.print(',');
  Serial.print(humid);
  Serial.print(',');
  Serial.print(light);

}

 

Final Project Idea 2

Concept:

Create an automatic trash can that uses sensors to detect and sort different types of waste (plastic, paper, etc.) into separate compartments within the can. The system will utilize Arduino for hardware control and p5.js for a user interface to monitor and interact with the trash can.

Components:

  1. Arduino Uno
  2. Ultrasonic sensors or weight sensors to detect the type of waste being disposed of.
  3. Servo motors or stepper motors to control the compartments for different types of waste.
  4. P5.js for the user interface to monitor the trash can’s status and possibly interact with it.

Arduino (Outgoing Data):

Detecting and Sorting: Arduino reads sensor data to detect the type of material placed in the trash can. Based on this detection, it activates servo motors to sort the materials into their respective compartments.
Serial Communication: Once the material is detected and sorted, Arduino sends updates about the detected material type and sorting process status via the Serial connection.

p5.js (Outgoing Commands):

p5.js sends commands/instructions to the Arduino via the Serial connection, requesting the disposal of a particular type of waste.

Arduino (Incoming Commands):

Receiving Instructions: Arduino listens for incoming commands from p5.js through the Serial connection. It interprets these commands to initiate the disposal process.
Status Queries: Arduino responds to queries from p5.js by sending updates on the system status, like whether it’s ready to receive new commands or the current state of the sorting mechanism.

p5.js (Incoming Data):

Display and Feedback: p5.js receives data from Arduino about detected materials and system status.

Final Project Draft 2: HFR

Concept
In my previous blog post, I introduced the idea of creating a Human Following Robot inspired by sci-fi movies like Wall-E. The concept revolves around developing a robot companion that autonomously follows a person, adjusting its position based on their movements. This project aims to bring a touch of cinematic magic into real life by utilizing sensors as the robot’s eyes and ears, allowing it to perceive the presence and actions of the person it follows.

Key Components
1. Ultrasonic Sensor:
Role: Measures the distance between the robot and a person.
Functionality: Enables the robot to make decisions about its movement based on the person’s proximity.
2. DC Motors and Motor Driver:
Role: Facilitates the robot’s movement.
Functionality: Allows the robot to move forward, backward, and turn, responding to the person’s position.
3. Servo Motor:
Role: Controls the direction in which the robot is facing.
Functionality: Adjusts its angle based on the horizontal position of the person, ensuring the robot follows the person accurately.
4. P5.js Integration:
Role: Provides visualization and user interface interaction.
Functionality: Creates a graphical representation of the robot’s perspective and the person’s position. Visualizes the direction of the servo motor, offering a clear indicator of the robot’s orientation.

Finalized Concept
Building upon the initial concept, the finalized idea is to implement a real-time human following mechanism. The robot will utilize the input from the ultrasonic sensor to determine the person’s distance, adjusting its movement accordingly. The servo motor will play a crucial role in ensuring the robot faces the person, enhancing the user experience.

Arduino Program
Inputs: Ultrasonic sensor readings for distance measurement.
Outputs: Control signals for DC motors based on a person’s proximity.

Video 1

P5 Program
The P5 program will focus on creating a visual representation of the robot’s perspective and the person’s position. It will receive data from the Arduino regarding the robot’s orientation and the person’s horizontal position, updating the graphical interface accordingly. (I’m thinking of representing an ellipse where the closer you are to the sensor the smaller the ellipse and the further you are the larger it gets). Furthermore, I have tried to implement a clickable control in p5 where it can move the robot frontwards and backwards by clicking on the right and left side of the p5 sketch.

Video 2