Final Project: RekasBot

Concept:

The idea was to create a bot that can be controlled with hand movement using machine learning with the P5.ml library. The P5 sketch has an in-car design with the steering wheel and the Arduino comprises 4dc motors, two ultrasonic sensors, and some LEDs.

Interactive Design:

For user interactivity, I decided to use the P5.js. The computer video webcam helps the machine learning library to detect the movement of the user’s hand and map these movements to the size of the canvas. This information is used to control the steering wheel, which controls the Arduino.

Arduino Code:

For the Arduino aspect, the motors are controlled using switch cases. The Arduino receives cases from the P5 sketch and based on those cases, the Arduino knows how to control the 4 DC motors. The Arduino uses the ultrasonic sensors to detect obstacles and sends this information to the P5 sketch to be viewed by the user.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <Servo.h>//include the Servo library/
#include <time.h>//include the time library for seeding random number
Servo myservo;//creating servo object
const int ain1Pin = 3;//setting pins for motor for left side which is connected in parallel
const int ain2Pin = 4;
const int pwmAPin = 5;
const int bin1Pin = 8;//setting pinf for motor for right side
const int bin2Pin = 7;
const int pwmBPin = 6;
const int trigPin1 = 11;//setting pins for front ultrasonic sensor
const int echoPin1= A0;//I used A0 pin cause I didnt have space...Please pardon me
const int trigPin2 = 10;//setting pins for back ultrasonic sensor
const int echoPin2 = A1;//here too
const int warningbuzzer=12;//setting the buzzer to 12
//servo motor
const int headmovePin=9;//setting the servo motor pin to 9
int wallstop=0;//initializing the obstacle detection
unsigned long previousMillis = 0;//setting millis to 0
const long interval = 5000;//setting interval for the millis
void setup() {
myservo.attach(headmovePin);//pass the servo pin to the servo library
randomSeed(time(NULL));//seed random number using the current time
pinMode(ain1Pin, OUTPUT);//setting the pins as output and input
pinMode(2, OUTPUT);//light checker
pinMode(ain2Pin, OUTPUT);//motor pin
pinMode(pwmAPin, OUTPUT); // not needed really
pinMode(bin1Pin, OUTPUT);
pinMode(bin2Pin, OUTPUT);
pinMode(pwmBPin, OUTPUT); // not needed really
// Start serial communication so we can send data
// over the USB connection to our p5js sketch
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(warningbuzzer, OUTPUT);
Serial.begin(9600);//setting the serial band
while (!Serial.available()) {
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(1000);//delay for a second
}
}
void loop() {
wallstop=crushstop();
//When the serial is detected do this
while (Serial.available()) {//while the serial connection exists
digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
wallstop=crushstop();//update the wallstop from the crush function
unsigned long currentMillis = millis();//set current millis
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
movehead();//if the interval is reached, move the head
}
int movement = Serial.parseInt();//get the movement case from p5
if (Serial.read() == '\n') {//when we read a new line,
switch(movement){//execute the following commmands based on the case
case 0://no movement
analogWrite(pwmAPin, 0);
digitalWrite(ain1Pin, HIGH);
digitalWrite(ain2Pin, LOW);
analogWrite(pwmBPin, 0);
digitalWrite(bin1Pin, LOW);
digitalWrite(bin2Pin, HIGH);
break;
case 1://forward
analogWrite(pwmAPin, 255);
digitalWrite(ain1Pin, LOW);
digitalWrite(ain2Pin, HIGH);
analogWrite(pwmBPin, 255);
digitalWrite(bin1Pin, HIGH);
digitalWrite(bin2Pin, LOW);
break;
case 2://reverse
analogWrite(pwmAPin, 255);
digitalWrite(ain1Pin, HIGH);
digitalWrite(ain2Pin, LOW);
analogWrite(pwmBPin, 255);
digitalWrite(bin1Pin, LOW);
digitalWrite(bin2Pin, HIGH);
break;
case 3://right front
analogWrite(pwmBPin, 255);
digitalWrite(bin1Pin, HIGH);
digitalWrite(bin2Pin, LOW);
break;
case 4://left front
analogWrite(pwmAPin, 255);
digitalWrite(ain1Pin, LOW);
digitalWrite(ain2Pin, HIGH);
break;
case 5://right back
analogWrite(pwmBPin, 255);
digitalWrite(bin1Pin, LOW);
digitalWrite(bin2Pin, HIGH);
break;
case 6://left back
analogWrite(pwmAPin, 255);
digitalWrite(ain1Pin, HIGH);
digitalWrite(ain2Pin, LOW);
break;
default://if not case is gotten within our expected range, stop
analogWrite(pwmAPin, 0);
digitalWrite(ain1Pin, HIGH);
digitalWrite(ain2Pin, LOW);
analogWrite(pwmBPin, 0);
digitalWrite(bin1Pin, LOW);
digitalWrite(bin2Pin, HIGH);
break;
}
delay(5);
Serial.println(wallstop);//send the detection to p5
}
}
}
int crushstop(){//this function returns 1 when an obstacle is ahead and 2 when an obstacle is behind
int wallstop=0;//initialize wallstop
digitalWrite(trigPin1, LOW);
delayMicroseconds(2); //basically shooting beems and using the time it takes to bounce back to calculate distance
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin1, LOW);
// Time it takes for the pulse to travel back from the object long
int duration1 = pulseIn(echoPin1, HIGH);
// Universal conversion of time into distance in cm
int distance1 = duration1 * 0.034 / 2;//divided by two beause its a two way thing
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);
digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2, LOW);
// Time it takes for the pulse to travel back from the object long
int duration2 = pulseIn(echoPin2, HIGH);
// Universal conversion of time into distance in cm
int distance2 = duration2 * 0.034 / 2;
if(distance1<5){//if collision is detected behind, send 2
wallstop=2;
tone(warningbuzzer,2000);//play the tone
delay(5);
}
else if(distance2<5){
wallstop=1;//if collision is detected infront, send 1
tone(warningbuzzer,2000);//play the tone
delay(5);
}
else{
wallstop=0;
noTone(warningbuzzer);//if nothing is detected dont play a tone
}
return wallstop;//return this info
}
void movehead(){
myservo.write(random(0, 180));//move the head to a random number between 0 and 180
delay(15);
}
#include <Servo.h>//include the Servo library/ #include <time.h>//include the time library for seeding random number Servo myservo;//creating servo object const int ain1Pin = 3;//setting pins for motor for left side which is connected in parallel const int ain2Pin = 4; const int pwmAPin = 5; const int bin1Pin = 8;//setting pinf for motor for right side const int bin2Pin = 7; const int pwmBPin = 6; const int trigPin1 = 11;//setting pins for front ultrasonic sensor const int echoPin1= A0;//I used A0 pin cause I didnt have space...Please pardon me const int trigPin2 = 10;//setting pins for back ultrasonic sensor const int echoPin2 = A1;//here too const int warningbuzzer=12;//setting the buzzer to 12 //servo motor const int headmovePin=9;//setting the servo motor pin to 9 int wallstop=0;//initializing the obstacle detection unsigned long previousMillis = 0;//setting millis to 0 const long interval = 5000;//setting interval for the millis void setup() { myservo.attach(headmovePin);//pass the servo pin to the servo library randomSeed(time(NULL));//seed random number using the current time pinMode(ain1Pin, OUTPUT);//setting the pins as output and input pinMode(2, OUTPUT);//light checker pinMode(ain2Pin, OUTPUT);//motor pin pinMode(pwmAPin, OUTPUT); // not needed really pinMode(bin1Pin, OUTPUT); pinMode(bin2Pin, OUTPUT); pinMode(pwmBPin, OUTPUT); // not needed really // Start serial communication so we can send data // over the USB connection to our p5js sketch pinMode(trigPin1, OUTPUT); pinMode(echoPin1, INPUT); pinMode(trigPin2, OUTPUT); pinMode(echoPin2, INPUT); pinMode(warningbuzzer, OUTPUT); Serial.begin(9600);//setting the serial band while (!Serial.available()) { 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(1000);//delay for a second } } void loop() { wallstop=crushstop(); //When the serial is detected do this while (Serial.available()) {//while the serial connection exists digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data wallstop=crushstop();//update the wallstop from the crush function unsigned long currentMillis = millis();//set current millis if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; movehead();//if the interval is reached, move the head } int movement = Serial.parseInt();//get the movement case from p5 if (Serial.read() == '\n') {//when we read a new line, switch(movement){//execute the following commmands based on the case case 0://no movement analogWrite(pwmAPin, 0); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); analogWrite(pwmBPin, 0); digitalWrite(bin1Pin, LOW); digitalWrite(bin2Pin, HIGH); break; case 1://forward analogWrite(pwmAPin, 255); digitalWrite(ain1Pin, LOW); digitalWrite(ain2Pin, HIGH); analogWrite(pwmBPin, 255); digitalWrite(bin1Pin, HIGH); digitalWrite(bin2Pin, LOW); break; case 2://reverse analogWrite(pwmAPin, 255); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); analogWrite(pwmBPin, 255); digitalWrite(bin1Pin, LOW); digitalWrite(bin2Pin, HIGH); break; case 3://right front analogWrite(pwmBPin, 255); digitalWrite(bin1Pin, HIGH); digitalWrite(bin2Pin, LOW); break; case 4://left front analogWrite(pwmAPin, 255); digitalWrite(ain1Pin, LOW); digitalWrite(ain2Pin, HIGH); break; case 5://right back analogWrite(pwmBPin, 255); digitalWrite(bin1Pin, LOW); digitalWrite(bin2Pin, HIGH); break; case 6://left back analogWrite(pwmAPin, 255); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); break; default://if not case is gotten within our expected range, stop analogWrite(pwmAPin, 0); digitalWrite(ain1Pin, HIGH); digitalWrite(ain2Pin, LOW); analogWrite(pwmBPin, 0); digitalWrite(bin1Pin, LOW); digitalWrite(bin2Pin, HIGH); break; } delay(5); Serial.println(wallstop);//send the detection to p5 } } } int crushstop(){//this function returns 1 when an obstacle is ahead and 2 when an obstacle is behind int wallstop=0;//initialize wallstop digitalWrite(trigPin1, LOW); delayMicroseconds(2); //basically shooting beems and using the time it takes to bounce back to calculate distance digitalWrite(trigPin1, HIGH); delayMicroseconds(10); digitalWrite(trigPin1, LOW); // Time it takes for the pulse to travel back from the object long int duration1 = pulseIn(echoPin1, HIGH); // Universal conversion of time into distance in cm int distance1 = duration1 * 0.034 / 2;//divided by two beause its a two way thing digitalWrite(trigPin2, LOW); delayMicroseconds(2); digitalWrite(trigPin2, HIGH); delayMicroseconds(10); digitalWrite(trigPin2, LOW); // Time it takes for the pulse to travel back from the object long int duration2 = pulseIn(echoPin2, HIGH); // Universal conversion of time into distance in cm int distance2 = duration2 * 0.034 / 2; if(distance1<5){//if collision is detected behind, send 2 wallstop=2; tone(warningbuzzer,2000);//play the tone delay(5); } else if(distance2<5){ wallstop=1;//if collision is detected infront, send 1 tone(warningbuzzer,2000);//play the tone delay(5); } else{ wallstop=0; noTone(warningbuzzer);//if nothing is detected dont play a tone } return wallstop;//return this info } void movehead(){ myservo.write(random(0, 180));//move the head to a random number between 0 and 180 delay(15); }
#include <Servo.h>//include the Servo library/
#include <time.h>//include the time library for seeding random number

Servo myservo;//creating servo object

const int ain1Pin = 3;//setting pins for motor for left side which is connected in parallel
const int ain2Pin = 4;
const int pwmAPin = 5;

const int bin1Pin = 8;//setting pinf for motor for right side 
const int bin2Pin = 7;
const int pwmBPin = 6;

const int trigPin1 = 11;//setting pins for front ultrasonic sensor
const int echoPin1= A0;//I used A0 pin cause I didnt have space...Please pardon me
const int trigPin2 = 10;//setting pins for back ultrasonic sensor
const int echoPin2 = A1;//here too

const int warningbuzzer=12;//setting the buzzer to 12
//servo motor
const int headmovePin=9;//setting the servo motor pin to 9

int wallstop=0;//initializing the obstacle detection

unsigned long previousMillis = 0;//setting millis to 0
const long interval = 5000;//setting interval for the millis


void setup() {
  myservo.attach(headmovePin);//pass the servo pin to the servo library
  
  randomSeed(time(NULL));//seed random number using the current time 

  pinMode(ain1Pin, OUTPUT);//setting the pins as output and input
  pinMode(2, OUTPUT);//light checker
  pinMode(ain2Pin, OUTPUT);//motor pin
  pinMode(pwmAPin, OUTPUT); // not needed really
  pinMode(bin1Pin, OUTPUT);
  pinMode(bin2Pin, OUTPUT);
  pinMode(pwmBPin, OUTPUT); // not needed really
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(warningbuzzer, OUTPUT);

  Serial.begin(9600);//setting the serial band

  while (!Serial.available()) {
    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(1000);//delay for a second
  }
}

void loop() {
  wallstop=crushstop();
  //When the serial is detected do this
  while (Serial.available()) {//while the serial connection exists
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
    wallstop=crushstop();//update the wallstop from the crush function
    unsigned long currentMillis = millis();//set current millis

    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
      movehead();//if the interval is reached, move the head
    }
    int movement = Serial.parseInt();//get the movement case from p5
   if (Serial.read() == '\n') {//when we read a new line,
     switch(movement){//execute the following commmands based on the case
      case 0://no movement
        analogWrite(pwmAPin, 0);
        digitalWrite(ain1Pin, HIGH);
        digitalWrite(ain2Pin, LOW);
        analogWrite(pwmBPin, 0);
        digitalWrite(bin1Pin, LOW);
        digitalWrite(bin2Pin, HIGH);
      break;
      case 1://forward
        analogWrite(pwmAPin, 255);
        digitalWrite(ain1Pin, LOW);
        digitalWrite(ain2Pin, HIGH);
        analogWrite(pwmBPin, 255);
        digitalWrite(bin1Pin, HIGH);
        digitalWrite(bin2Pin, LOW);
      break;
      case 2://reverse
        analogWrite(pwmAPin, 255);
        digitalWrite(ain1Pin, HIGH);
        digitalWrite(ain2Pin, LOW);
        analogWrite(pwmBPin, 255);
        digitalWrite(bin1Pin, LOW);
        digitalWrite(bin2Pin, HIGH);
      break;
      case 3://right front
        analogWrite(pwmBPin, 255);
        digitalWrite(bin1Pin, HIGH);
        digitalWrite(bin2Pin, LOW);
      break;
      case 4://left front
        analogWrite(pwmAPin, 255);
        digitalWrite(ain1Pin, LOW);
        digitalWrite(ain2Pin, HIGH);
      break;
      case 5://right back
       analogWrite(pwmBPin, 255);
        digitalWrite(bin1Pin, LOW);
        digitalWrite(bin2Pin, HIGH);
      break;
      case 6://left back
        analogWrite(pwmAPin, 255);
        digitalWrite(ain1Pin, HIGH);
        digitalWrite(ain2Pin, LOW);
      break;
      default://if not case is gotten within our expected range, stop
        analogWrite(pwmAPin, 0);
        digitalWrite(ain1Pin, HIGH);
        digitalWrite(ain2Pin, LOW);
        analogWrite(pwmBPin, 0);
        digitalWrite(bin1Pin, LOW);
        digitalWrite(bin2Pin, HIGH);
      break;
     }
      delay(5);
      Serial.println(wallstop);//send the detection to p5
      
    }
  }
  
}

int crushstop(){//this function returns 1 when an obstacle is ahead and 2 when an obstacle is behind
  int wallstop=0;//initialize wallstop
  digitalWrite(trigPin1, LOW); 
  delayMicroseconds(2); //basically shooting beems and using the time it takes to bounce back to calculate distance
  digitalWrite(trigPin1, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trigPin1, LOW); 
  // Time it takes for the pulse to travel back from the object long 
  int duration1 = pulseIn(echoPin1, HIGH); 
  // Universal conversion of time into distance in cm 
  int distance1 = duration1 * 0.034 / 2;//divided by two beause its a two way thing

  digitalWrite(trigPin2, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigPin2, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trigPin2, LOW); 
  // Time it takes for the pulse to travel back from the object long 
  int duration2 = pulseIn(echoPin2, HIGH); 
  // Universal conversion of time into distance in cm 
  int distance2 = duration2 * 0.034 / 2;
  if(distance1<5){//if collision is detected behind, send 2
    wallstop=2;
    tone(warningbuzzer,2000);//play the tone
    delay(5);
  }
  else if(distance2<5){
    wallstop=1;//if collision is detected infront, send 1
    tone(warningbuzzer,2000);//play the tone
    delay(5);
  }
  else{
    wallstop=0;
    noTone(warningbuzzer);//if nothing is detected dont play a tone
  }
  return wallstop;//return this info
}

void movehead(){
  myservo.write(random(0, 180));//move the head to a random number between 0 and 180
  delay(15);
}

 

P5.js:

For this part, the P5.js sketch receives the user hand positions info from the P5.ml library and maps it to get its corresponding points on the canvas. After, these values are averaged and the average-X value is used to control the steer’s left or right turn. The average-Y value is used to control the forward and backward movement. Based on this cases are developed and sent to the Arduino for execution of tasks.

The P5 sketch is divided into five parts

Serial connection:

This part is responsible for connecting the Arduino to the P5 sketch and since its not my code I will not post it

Intro Page:

The next part is the intro page. Is welcomes the user into the project and also gives some info to the user about how to use the vehicle. I made the background picture myself using photoshop and then I added some buttons and sounds

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class ipage{
constructor(IB,S1,S2,F1,F2){//receive all needed variables as in images and sound
this.BG=IB;//the background
this.S1=S1;//sound
this.playbool=false;//boolean to start game
this.helpbool=false;//boolean to open help page
this.F2=F2//font
}
show(){//this shows the designs in the page
this.BG.resize(windowWidth,windowHeight);//resize the introimage
image(this.BG,0,0);//displaying background
textAlign(CENTER);
this.createhelp();//calling the help function for the help page
this.playbox();//calling the playbox button function
if(this.helpbool){//if the helpbool is true display the help page
this.helppage();
}
return this.playbool;//this returns true if the play button is pressed
}
playbox(){//this function displays the start button
rectMode(CORNER);
fill(150,180,40);
if(mouseX>windowWidth*0.1&&mouseX<(windowWidth*0.1)+350&&mouseY>windowHeight*0.8&&mouseY<(windowHeight*0.8)+150){
fill(150,0,0);//creating the hover effect
}
if(mouseX>windowWidth*0.1&&mouseX<(windowWidth*0.1)+350&&mouseY>windowHeight*0.8&&mouseY<(windowHeight*0.8)+150&&mouseIsPressed&&!this.helpbool){
S2.pause();// the play is pressed, play pause the background music
this.S1.play();//playing the start button pressed sound
this.playbool=true;//sets the playboolean to true
}
rect(windowWidth*0.1,windowHeight*0.8,350,150,60);//drawing the start button
fill(0);
textFont(F1);
textSize(90);
textAlign(CENTER);
text("Start",windowWidth*0.1+180,windowHeight*0.8+110);
}
createhelp(){
fill(100);
if(dist(mouseX,mouseY,windowWidth*0.9,windowHeight*0.1)<=30){
fill(60);//create hover effect
}
if(dist(mouseX,mouseY,windowWidth*0.9,windowHeight*0.1)<=30&&mouseIsPressed){
this.helpbool=true;//set boolean to open help page
}
circle(windowWidth*0.9,windowHeight*0.1,60);//these following code just creates the help button
fill(255,255,0);
textSize(30);
textFont(NORMAL);
text("?",windowWidth*0.9,windowHeight*0.1+10);
}
helppage(){
fill(100);
rect(50,50,windowWidth*0.95,windowHeight*0.9,50);
textFont(this.F2);
fill(255);
textSize(80);
text('WELCOME',windowWidth*0.5,windowHeight*0.25);
textSize(30);
text('Move your Hand Up and Down while pressing the mouse to control the gear',windowWidth*0.5,windowHeight*0.4);
text('Move your Hand left and right to control the steer',windowWidth*0.5,windowHeight*0.5);
text('Click on the Q key to go to the Homepage',windowWidth*0.5,windowHeight*0.6);
text('Press the space bar to connect to Arduino',windowWidth*0.5,windowHeight*0.7);
text('GOOD LUCK!',windowWidth*0.5,windowHeight*0.8);
fill(100);
if(dist(mouseX,mouseY,windowWidth*0.5,windowHeight*0.9)<=30){
fill(60);//create hover effect
}
if(dist(mouseX,mouseY,windowWidth*0.5,windowHeight*0.9)<=30&&mouseIsPressed){
this.helpbool=false;//set boolean to close help page
}
circle(windowWidth*0.5,windowHeight*0.9,60);//these following code just creates the ok button
fill(255,255,0);
textSize(30);
textFont(NORMAL);
text("OK",windowWidth*0.5,windowHeight*0.9+10);
}
}
class ipage{ constructor(IB,S1,S2,F1,F2){//receive all needed variables as in images and sound this.BG=IB;//the background this.S1=S1;//sound this.playbool=false;//boolean to start game this.helpbool=false;//boolean to open help page this.F2=F2//font } show(){//this shows the designs in the page this.BG.resize(windowWidth,windowHeight);//resize the introimage image(this.BG,0,0);//displaying background textAlign(CENTER); this.createhelp();//calling the help function for the help page this.playbox();//calling the playbox button function if(this.helpbool){//if the helpbool is true display the help page this.helppage(); } return this.playbool;//this returns true if the play button is pressed } playbox(){//this function displays the start button rectMode(CORNER); fill(150,180,40); if(mouseX>windowWidth*0.1&&mouseX<(windowWidth*0.1)+350&&mouseY>windowHeight*0.8&&mouseY<(windowHeight*0.8)+150){ fill(150,0,0);//creating the hover effect } if(mouseX>windowWidth*0.1&&mouseX<(windowWidth*0.1)+350&&mouseY>windowHeight*0.8&&mouseY<(windowHeight*0.8)+150&&mouseIsPressed&&!this.helpbool){ S2.pause();// the play is pressed, play pause the background music this.S1.play();//playing the start button pressed sound this.playbool=true;//sets the playboolean to true } rect(windowWidth*0.1,windowHeight*0.8,350,150,60);//drawing the start button fill(0); textFont(F1); textSize(90); textAlign(CENTER); text("Start",windowWidth*0.1+180,windowHeight*0.8+110); } createhelp(){ fill(100); if(dist(mouseX,mouseY,windowWidth*0.9,windowHeight*0.1)<=30){ fill(60);//create hover effect } if(dist(mouseX,mouseY,windowWidth*0.9,windowHeight*0.1)<=30&&mouseIsPressed){ this.helpbool=true;//set boolean to open help page } circle(windowWidth*0.9,windowHeight*0.1,60);//these following code just creates the help button fill(255,255,0); textSize(30); textFont(NORMAL); text("?",windowWidth*0.9,windowHeight*0.1+10); } helppage(){ fill(100); rect(50,50,windowWidth*0.95,windowHeight*0.9,50); textFont(this.F2); fill(255); textSize(80); text('WELCOME',windowWidth*0.5,windowHeight*0.25); textSize(30); text('Move your Hand Up and Down while pressing the mouse to control the gear',windowWidth*0.5,windowHeight*0.4); text('Move your Hand left and right to control the steer',windowWidth*0.5,windowHeight*0.5); text('Click on the Q key to go to the Homepage',windowWidth*0.5,windowHeight*0.6); text('Press the space bar to connect to Arduino',windowWidth*0.5,windowHeight*0.7); text('GOOD LUCK!',windowWidth*0.5,windowHeight*0.8); fill(100); if(dist(mouseX,mouseY,windowWidth*0.5,windowHeight*0.9)<=30){ fill(60);//create hover effect } if(dist(mouseX,mouseY,windowWidth*0.5,windowHeight*0.9)<=30&&mouseIsPressed){ this.helpbool=false;//set boolean to close help page } circle(windowWidth*0.5,windowHeight*0.9,60);//these following code just creates the ok button fill(255,255,0); textSize(30); textFont(NORMAL); text("OK",windowWidth*0.5,windowHeight*0.9+10); } }
class ipage{
  constructor(IB,S1,S2,F1,F2){//receive all needed variables as in images and sound
    this.BG=IB;//the background
    this.S1=S1;//sound
    this.playbool=false;//boolean to start game
    this.helpbool=false;//boolean to open help page
    this.F2=F2//font
  }
  show(){//this shows the designs in the page
    this.BG.resize(windowWidth,windowHeight);//resize the introimage
    image(this.BG,0,0);//displaying background
    textAlign(CENTER);
    this.createhelp();//calling the help function for the help page
    this.playbox();//calling the playbox button function
    if(this.helpbool){//if the helpbool is true display the help page
      this.helppage();
    }
    return this.playbool;//this returns true if the play button is pressed
  }
  
  playbox(){//this function displays the start button
    rectMode(CORNER);
    fill(150,180,40);
      if(mouseX>windowWidth*0.1&&mouseX<(windowWidth*0.1)+350&&mouseY>windowHeight*0.8&&mouseY<(windowHeight*0.8)+150){
      fill(150,0,0);//creating the hover effect
    }
    if(mouseX>windowWidth*0.1&&mouseX<(windowWidth*0.1)+350&&mouseY>windowHeight*0.8&&mouseY<(windowHeight*0.8)+150&&mouseIsPressed&&!this.helpbool){
      S2.pause();// the play is pressed, play pause the background music
      this.S1.play();//playing the start button pressed sound
      this.playbool=true;//sets the playboolean to true 
    }
    rect(windowWidth*0.1,windowHeight*0.8,350,150,60);//drawing the start button
    fill(0);
    textFont(F1);
    textSize(90);
    textAlign(CENTER);
    text("Start",windowWidth*0.1+180,windowHeight*0.8+110);
  }
  createhelp(){
    fill(100);
    if(dist(mouseX,mouseY,windowWidth*0.9,windowHeight*0.1)<=30){
      fill(60);//create hover effect
    }
    if(dist(mouseX,mouseY,windowWidth*0.9,windowHeight*0.1)<=30&&mouseIsPressed){
      this.helpbool=true;//set boolean to open help page
    }
    circle(windowWidth*0.9,windowHeight*0.1,60);//these following code just creates the help button
    fill(255,255,0);
    textSize(30);
    textFont(NORMAL);
    text("?",windowWidth*0.9,windowHeight*0.1+10);
  }
  helppage(){
    fill(100);
    rect(50,50,windowWidth*0.95,windowHeight*0.9,50);
    textFont(this.F2);
    fill(255);
    textSize(80);
    text('WELCOME',windowWidth*0.5,windowHeight*0.25);
    textSize(30);
    text('Move your Hand Up and Down while pressing the mouse to control the gear',windowWidth*0.5,windowHeight*0.4);
    text('Move your Hand left and right to control the steer',windowWidth*0.5,windowHeight*0.5);
    text('Click on the Q key to go to the Homepage',windowWidth*0.5,windowHeight*0.6);
    text('Press the space bar to connect to Arduino',windowWidth*0.5,windowHeight*0.7);
    text('GOOD LUCK!',windowWidth*0.5,windowHeight*0.8);
    fill(100);
    if(dist(mouseX,mouseY,windowWidth*0.5,windowHeight*0.9)<=30){
      fill(60);//create hover effect
    }
    if(dist(mouseX,mouseY,windowWidth*0.5,windowHeight*0.9)<=30&&mouseIsPressed){
      this.helpbool=false;//set boolean to close help page
    }
    circle(windowWidth*0.5,windowHeight*0.9,60);//these following code just creates the ok button
    fill(255,255,0);
    textSize(30);
    textFont(NORMAL);
    text("OK",windowWidth*0.5,windowHeight*0.9+10);
    
  }
}

Help Page:

This page is just to give the user info about the game and wish them luck as they embark on the Journey.

the code is found in the intro class and the page is controlled with the use of Boolean variables.

Dashboard:

Coming into the main page, the Dashboard shows the gearbox and the collision screen that alerts the user when the user is close to an obstacle.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class dash{//this class prints the dashboard, the gear and the detection screen
constructor(dashY){
this.Y=dashY;//the Y coordinate to which the dashboard is drawn
this.movementFB=0;//the front and back movement counter
this.gearY=0;//this controls the gearmovement
}
showdash(){
push();//creating the dashboard
strokeWeight(5)//set stroke weight to 5
fill(193, 154, 107);//fill with brown
beginShape();//we draw the dashboard
curveVertex(0,this.Y);
curveVertex(0,this.Y);
curveVertex(windowWidth/2,this.Y-50);//creating the curve look
curveVertex(windowWidth,this.Y);
curveVertex(windowWidth,windowHeight);
curveVertex(0,windowHeight);
curveVertex(0,this.Y);
curveVertex(0,this.Y);
endShape();
pop();
}
showgear(gearY){//this function shows the gear
this.gearY=gearY;//capies value of the gearY from handpose
rectMode(CENTER);//set rectange mode
textSize(50);
fill(0);//fill with black
rect(windowWidth*0.5,this.Y+110,150,300,50);
if(mouseIsPressed){//if the mouse is pressed means gear is being controlled
if(this.gearY<windowHeight*0.35){
this.movementFB=1;//set gear to drive
}
else if(this.gearY>windowHeight*0.5){
this.movementFB=2;//set gear to reverse
}
else{
this.movementFB=0;//set gear to P
}
}
textAlign(CENTER);//align text to center
textSize(50);
fill(0,128,0);//fill with green
switch(this.movementFB){
case 0:
text('P',windowWidth*0.5,this.Y+110);//p for parking
break;
case 1:
text('D',windowWidth*0.5,this.Y+110);//D for drive
break;
case 2:
text('R',windowWidth*0.5,this.Y+110);//R for reverse
break;
}
textAlign(LEFT);
textSize(12);
return this.movementFB;//return the gear movement info
}
showScreen(wallstop){//this shows the detection
rectMode(CENTER);
textSize(50);
textAlign(CENTER);
fill(0);
rect(windowWidth*0.75,this.Y+110,500,300,50);//create screen
fill(128,0,0);//fill the text with red
if(wallstop==1){//if the front ultrasonic sensor is the one sensing
text('OBJECT',windowWidth*0.75,this.Y+50);
text('DETECTED',windowWidth*0.75,this.Y+130);
text('AHEAD',windowWidth*0.75,this.Y+210);
}
else if(wallstop==2){//if the back ultrasonic is the one sensing
text('OBJECT',windowWidth*0.75,this.Y+50);
text('DETECTED',windowWidth*0.75,this.Y+130);
text('BEHIND',windowWidth*0.75,this.Y+210);
}
else{
fill(0,128,0);//fill the text with green
text('No',windowWidth*0.75,this.Y+50);
text('OBJECT',windowWidth*0.75,this.Y+130);
text('DETECTED',windowWidth*0.75,this.Y+210);
}
textAlign(LEFT);
textSize(12);
}
}
class dash{//this class prints the dashboard, the gear and the detection screen constructor(dashY){ this.Y=dashY;//the Y coordinate to which the dashboard is drawn this.movementFB=0;//the front and back movement counter this.gearY=0;//this controls the gearmovement } showdash(){ push();//creating the dashboard strokeWeight(5)//set stroke weight to 5 fill(193, 154, 107);//fill with brown beginShape();//we draw the dashboard curveVertex(0,this.Y); curveVertex(0,this.Y); curveVertex(windowWidth/2,this.Y-50);//creating the curve look curveVertex(windowWidth,this.Y); curveVertex(windowWidth,windowHeight); curveVertex(0,windowHeight); curveVertex(0,this.Y); curveVertex(0,this.Y); endShape(); pop(); } showgear(gearY){//this function shows the gear this.gearY=gearY;//capies value of the gearY from handpose rectMode(CENTER);//set rectange mode textSize(50); fill(0);//fill with black rect(windowWidth*0.5,this.Y+110,150,300,50); if(mouseIsPressed){//if the mouse is pressed means gear is being controlled if(this.gearY<windowHeight*0.35){ this.movementFB=1;//set gear to drive } else if(this.gearY>windowHeight*0.5){ this.movementFB=2;//set gear to reverse } else{ this.movementFB=0;//set gear to P } } textAlign(CENTER);//align text to center textSize(50); fill(0,128,0);//fill with green switch(this.movementFB){ case 0: text('P',windowWidth*0.5,this.Y+110);//p for parking break; case 1: text('D',windowWidth*0.5,this.Y+110);//D for drive break; case 2: text('R',windowWidth*0.5,this.Y+110);//R for reverse break; } textAlign(LEFT); textSize(12); return this.movementFB;//return the gear movement info } showScreen(wallstop){//this shows the detection rectMode(CENTER); textSize(50); textAlign(CENTER); fill(0); rect(windowWidth*0.75,this.Y+110,500,300,50);//create screen fill(128,0,0);//fill the text with red if(wallstop==1){//if the front ultrasonic sensor is the one sensing text('OBJECT',windowWidth*0.75,this.Y+50); text('DETECTED',windowWidth*0.75,this.Y+130); text('AHEAD',windowWidth*0.75,this.Y+210); } else if(wallstop==2){//if the back ultrasonic is the one sensing text('OBJECT',windowWidth*0.75,this.Y+50); text('DETECTED',windowWidth*0.75,this.Y+130); text('BEHIND',windowWidth*0.75,this.Y+210); } else{ fill(0,128,0);//fill the text with green text('No',windowWidth*0.75,this.Y+50); text('OBJECT',windowWidth*0.75,this.Y+130); text('DETECTED',windowWidth*0.75,this.Y+210); } textAlign(LEFT); textSize(12); } }
class dash{//this class prints the dashboard, the gear and the detection screen
  constructor(dashY){
    this.Y=dashY;//the Y coordinate to which the dashboard is drawn
    this.movementFB=0;//the front and back movement counter
    this.gearY=0;//this controls the gearmovement
  }
  showdash(){
    push();//creating the dashboard
    strokeWeight(5)//set stroke weight to 5
    fill(193, 154, 107);//fill with brown
    beginShape();//we draw the dashboard
    curveVertex(0,this.Y);
    curveVertex(0,this.Y);
    curveVertex(windowWidth/2,this.Y-50);//creating the curve look
    curveVertex(windowWidth,this.Y);
    curveVertex(windowWidth,windowHeight);
    curveVertex(0,windowHeight);
    curveVertex(0,this.Y);
    curveVertex(0,this.Y);
    endShape();
    pop();
  }
  showgear(gearY){//this function shows the gear
    this.gearY=gearY;//capies value of the gearY from handpose
    rectMode(CENTER);//set rectange mode
    textSize(50);
    fill(0);//fill with black
    rect(windowWidth*0.5,this.Y+110,150,300,50);
    if(mouseIsPressed){//if the mouse is pressed means gear is being controlled
      if(this.gearY<windowHeight*0.35){
        this.movementFB=1;//set gear to drive
      }
      else if(this.gearY>windowHeight*0.5){
        this.movementFB=2;//set gear to reverse
      }
      else{
        this.movementFB=0;//set gear to P
      }
    }
    textAlign(CENTER);//align text to center
    textSize(50);
    fill(0,128,0);//fill with green
    switch(this.movementFB){
      case 0:
        text('P',windowWidth*0.5,this.Y+110);//p for parking
        break;
      case 1:
        text('D',windowWidth*0.5,this.Y+110);//D for drive
        break;
      case 2:
        text('R',windowWidth*0.5,this.Y+110);//R for reverse
        break;
    }
    textAlign(LEFT);
    textSize(12);
    return this.movementFB;//return the gear movement info 
  }
  showScreen(wallstop){//this shows the detection
    rectMode(CENTER);
    textSize(50);
    textAlign(CENTER);
    fill(0);
    rect(windowWidth*0.75,this.Y+110,500,300,50);//create screen
    fill(128,0,0);//fill the text with red
    if(wallstop==1){//if the front ultrasonic sensor is the one sensing
      text('OBJECT',windowWidth*0.75,this.Y+50);
      text('DETECTED',windowWidth*0.75,this.Y+130);
      text('AHEAD',windowWidth*0.75,this.Y+210);
    }
    else if(wallstop==2){//if the back ultrasonic is the one sensing
      text('OBJECT',windowWidth*0.75,this.Y+50);
      text('DETECTED',windowWidth*0.75,this.Y+130);
      text('BEHIND',windowWidth*0.75,this.Y+210);
    }
    else{
      fill(0,128,0);//fill the text with green
      text('No',windowWidth*0.75,this.Y+50);
      text('OBJECT',windowWidth*0.75,this.Y+130);
      text('DETECTED',windowWidth*0.75,this.Y+210);
    }
    textAlign(LEFT);
    textSize(12);
  }
}

In order to show the gear box info it gets info from the poseNet calculations done in the sketch and for the collision screen it uses info from the ultrasonic sensors.

The Steering wheel:

Though also part of the Dashboard, this is a separate class because it  controls the left and right movement using info from the other parts. That is, is uses info from the gear box and collision screen. It is not a picture downloaded from somewhere but a hand coded diagram.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class Steer{//this class creates the steer and controls the car movement front and back
constructor(ctr,F2,X=windowWidth/3,Y=windowHeight/2){//takes the steerX,the font and the position for the steer to be placed
this.angle=0;//equate the angle to 0
this.X=X;//set the X and Y for the placement of the steering wheel
this.Y=Y;
this.ctr=ctr;
this.movementLR=0;//create this Left right variable to store the movement
this.F2=F2;
}
show(ctr){//takes steer x
this.ctr=ctr;//update the ctr with steerX
push();//designing the steering using stack so that it can be rotated entirely at once
translate(this.X,this.Y);//making the orijin these
rotate(this.angle);//causes the rotation
noFill(0);
strokeWeight(80);
rectMode(CENTER);
circle(0,0,500);
fill(0);
stroke(0);
strokeWeight(12);
beginShape();
curveVertex(-230,-80);
curveVertex(-230,-80);
curveVertex(0,-120);
curveVertex(230,-80);
curveVertex(230,0);
curveVertex(80,70);
curveVertex(40,230);
curveVertex(-40,230);
curveVertex(-80,70);
curveVertex(-230,0);
curveVertex(-230,-80);
curveVertex(-230,-80);
fill(0);
endShape();
fill(100);
noStroke()
textSize(50)
textAlign(CENTER);
textFont(this.F2);
text('REKAS',0,0);//steering wheel/car brand
pop();
if(this.ctr>0&&this.ctr<windowWidth){//while the value is within our range
this.angle=map(this.ctr,0,windowWidth,-PI/2,PI/2);//update angle based on this
}
}
steerTurn(movementFB,wallstop){//this function controls the turning of the steer
if(this.angle<-PI/7.5&&movementFB==1&&wallstop!=1){
this.movementLR=4;//front left
}
else if(this.angle<-PI/7.5&&movementFB==2&&wallstop!=2){
this.movementLR=6;//back left
}
else if(this.angle>=-PI/7.5&&this.angle<-PI/8){
this.movementLR=0;//to prevent bugs
}
else if(this.angle>=-PI/7&&this.angle<PI/8&&movementFB==1&&wallstop!=1){
this.movementLR=1;//move straight ahead
}
else if(this.angle>=-PI/7&&this.angle<PI/7&&movementFB==2&&wallstop!=2){
this.movementLR=2;//reverse
}
else if(this.angle>=PI/7&&this.angle<PI/5){
this.movementLR=0;//yeah
}
else if(this.angle>=PI/5&&movementFB==1&&wallstop!=1){
this.movementLR=3;//front right
}
else if(this.angle>=PI/5&&movementFB==2&&wallstop!=2){
this.movementLR=5;//back right
}
else{
this.movementLR=0;//dont move
}
return this.movementLR;
}
}
class Steer{//this class creates the steer and controls the car movement front and back constructor(ctr,F2,X=windowWidth/3,Y=windowHeight/2){//takes the steerX,the font and the position for the steer to be placed this.angle=0;//equate the angle to 0 this.X=X;//set the X and Y for the placement of the steering wheel this.Y=Y; this.ctr=ctr; this.movementLR=0;//create this Left right variable to store the movement this.F2=F2; } show(ctr){//takes steer x this.ctr=ctr;//update the ctr with steerX push();//designing the steering using stack so that it can be rotated entirely at once translate(this.X,this.Y);//making the orijin these rotate(this.angle);//causes the rotation noFill(0); strokeWeight(80); rectMode(CENTER); circle(0,0,500); fill(0); stroke(0); strokeWeight(12); beginShape(); curveVertex(-230,-80); curveVertex(-230,-80); curveVertex(0,-120); curveVertex(230,-80); curveVertex(230,0); curveVertex(80,70); curveVertex(40,230); curveVertex(-40,230); curveVertex(-80,70); curveVertex(-230,0); curveVertex(-230,-80); curveVertex(-230,-80); fill(0); endShape(); fill(100); noStroke() textSize(50) textAlign(CENTER); textFont(this.F2); text('REKAS',0,0);//steering wheel/car brand pop(); if(this.ctr>0&&this.ctr<windowWidth){//while the value is within our range this.angle=map(this.ctr,0,windowWidth,-PI/2,PI/2);//update angle based on this } } steerTurn(movementFB,wallstop){//this function controls the turning of the steer if(this.angle<-PI/7.5&&movementFB==1&&wallstop!=1){ this.movementLR=4;//front left } else if(this.angle<-PI/7.5&&movementFB==2&&wallstop!=2){ this.movementLR=6;//back left } else if(this.angle>=-PI/7.5&&this.angle<-PI/8){ this.movementLR=0;//to prevent bugs } else if(this.angle>=-PI/7&&this.angle<PI/8&&movementFB==1&&wallstop!=1){ this.movementLR=1;//move straight ahead } else if(this.angle>=-PI/7&&this.angle<PI/7&&movementFB==2&&wallstop!=2){ this.movementLR=2;//reverse } else if(this.angle>=PI/7&&this.angle<PI/5){ this.movementLR=0;//yeah } else if(this.angle>=PI/5&&movementFB==1&&wallstop!=1){ this.movementLR=3;//front right } else if(this.angle>=PI/5&&movementFB==2&&wallstop!=2){ this.movementLR=5;//back right } else{ this.movementLR=0;//dont move } return this.movementLR; } }
class Steer{//this class creates the steer and controls the car movement front and back
  constructor(ctr,F2,X=windowWidth/3,Y=windowHeight/2){//takes the steerX,the font and the position for the steer to be placed
    this.angle=0;//equate the angle to 0
    this.X=X;//set the X and Y for the placement of the steering wheel
    this.Y=Y;
    this.ctr=ctr;
    this.movementLR=0;//create this Left right variable to store the movement
    this.F2=F2;
  }
  show(ctr){//takes steer x
    this.ctr=ctr;//update the ctr with steerX
  push();//designing the steering using stack so that it can be rotated entirely at once
  translate(this.X,this.Y);//making the orijin these
  rotate(this.angle);//causes the rotation
  noFill(0);
  strokeWeight(80);
  rectMode(CENTER);
  circle(0,0,500);
  fill(0);
  stroke(0);
  strokeWeight(12);
  beginShape();
  curveVertex(-230,-80);
  curveVertex(-230,-80);
  curveVertex(0,-120);
  curveVertex(230,-80);
  curveVertex(230,0);
  curveVertex(80,70);
  curveVertex(40,230);
  curveVertex(-40,230);
  curveVertex(-80,70);
  curveVertex(-230,0);
  curveVertex(-230,-80);
  curveVertex(-230,-80);
  fill(0);
  endShape();
  fill(100);
    noStroke()
  textSize(50)
    textAlign(CENTER);
  textFont(this.F2);
  text('REKAS',0,0);//steering wheel/car brand
  pop();
    if(this.ctr>0&&this.ctr<windowWidth){//while the value is within our range
  this.angle=map(this.ctr,0,windowWidth,-PI/2,PI/2);//update angle based on this
  }
  }
  steerTurn(movementFB,wallstop){//this function controls the turning of the steer
    if(this.angle<-PI/7.5&&movementFB==1&&wallstop!=1){
        this.movementLR=4;//front left
      }
      else if(this.angle<-PI/7.5&&movementFB==2&&wallstop!=2){
        this.movementLR=6;//back left
      }
      else if(this.angle>=-PI/7.5&&this.angle<-PI/8){
        this.movementLR=0;//to prevent bugs 
      }
      else if(this.angle>=-PI/7&&this.angle<PI/8&&movementFB==1&&wallstop!=1){
        this.movementLR=1;//move straight ahead
      }
      else if(this.angle>=-PI/7&&this.angle<PI/7&&movementFB==2&&wallstop!=2){
        this.movementLR=2;//reverse
      }
      else if(this.angle>=PI/7&&this.angle<PI/5){
        this.movementLR=0;//yeah
      }
      else if(this.angle>=PI/5&&movementFB==1&&wallstop!=1){
        this.movementLR=3;//front right
      }
      else if(this.angle>=PI/5&&movementFB==2&&wallstop!=2){
        this.movementLR=5;//back right
      }
      else{
        this.movementLR=0;//dont move
      }
    return this.movementLR;
  }
}

Sketch:

This is the last part that kind of sums everything up. This is where all the other components come together to produce this artwork. This is also where the poseNet functions and full screen Functions are declared.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let mySteer;//variable going to store steer object
let myDash;//gonna store the dashboard object
let handpose;//gonna store posenet object
let video;//gonna store video object
let predictions = [];//gonna store set of predictions from posenet
let steerX=300;//gonna store the average x coordinate of the hand
let gearY=250;//gonna store the average y coordinate of the hand
let movementLR=0;//gonnna store the left and right movement
let movementFB=0;//gonna store the front and back movement
let wallstop=0;//gonna store the obstacle detection
let steercontrol=0;//gonna control steer to make it feel smooth
let IntroBackground;//intropage background
let S1;//sound 1(button)
let S2;//sound 2
let F1;
let F2;
let introp;//gonna store intropage object
let introbool=true;//going to control the intropage display
let gamebool=false;//going to control the mainpage display
function preload(){
//in this preload function we will load all the uploads we need before we even start the game.
IntroBackground=loadImage("intro1.jpg");//this is for the background
S1=loadSound("button.mp3");//these sets are for the sounds
S2=loadSound("msound.mp3");
F1=loadFont("font1.ttf");//these sets are for the fonts
F2=loadFont("font2.ttf");
}
function setup() {
createCanvas(windowWidth, windowHeight);
video = createCapture(VIDEO);//capture video using camera
video.size(width, height);//set the size of the video to that of the screen
steercontrol=windowWidth/2//set the steercontrol for smoothness
handpose = ml5.handpose(video);//get posenet from the video feed using the ml library
// 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();
introp=new ipage(IntroBackground,S1,S2,F1,F2);//create intropage object
mySteer=new Steer(steerX,F2,windowWidth*0.5,windowHeight*0.85);//create steer object
myDash=new dash(windowHeight*0.85);//create dashboard object
S2.loop();//start playing the sound but with loop property
}
function draw() {
if(introbool){//if the introbool is true show intropage
gamebool=introp.show();//update gamebool from intro.show function
if(gamebool){introbool=false;}//if the gamebool is true,set intro to false
}
else{
background(50,150,255);
myDash.showdash()//show the dash
drawKeypoints();//call this function for geting info from the video hand detection
movementFB=myDash.showgear(gearY);//update the front back movement from the showgear function
movementLR=mySteer.steerTurn(movementFB,wallstop);//update the leftright movement from the steerturn function
if(steerX>0&&steerX<windowWidth){//if the steerX is within the range we want
mySteer.show(steerX);//show the steer with this value
steercontrol=steerX;//update the steercontrol incase we stop getting data
}
else{//if the steerX is not in our range,
if(steercontrol<windowWidth/2-5){steercontrol+=10;}//using our steercontrol,slowly move the steer to the center
else if(steercontrol>windowWidth/2+5){steercontrol-=10;}
mySteer.show(steercontrol);
}
myDash.showScreen(wallstop);//show the screen with the wallstop getten form the Arduino
}
}
function keyPressed() {//if spaebar is pressed connect to arduino
if (key == " ") {
// important to have in order to start the serial connection!!
setUpSerial();//connect to arduino
}
}
function readSerial(data) {
if (data!=null){//if the data is not null
//////////////////////////////////
//READ FROM ARDUINO HERE (handshake)
//////////////////////////////////
wallstop= int(trim(data));
//////////////////////////////////
//SEND TO ARDUINO HERE (handshake)
//////////////////////////////////
let sendToArduino = movementLR + "\n";
writeSerial(sendToArduino);
}
}
function drawKeypoints() {
let totalX=0;//set variable to store the sum of the x coordinates of all the predictions
let totalY=0;//same for y
let avgctr=0;//set a counter to count the predictions
let len=0;//I dont use len here but i was experimenting somthing
for (let i = 0; i < predictions.length; i += 1) {
const prediction = predictions[i];
len=predictions.lenght*prediction.landmarks.length;
for (let j = 0; j < prediction.landmarks.length; j += 1) {
const keypoint = prediction.landmarks[j];
totalX+=windowWidth-map(keypoint[0],0,video.width,0,windowWidth);//map the points to our window size and sum it
totalY+=map(keypoint[1],0,video.height,0,windowHeight);
avgctr++;//increase this too
}
}
steerX=totalX/avgctr;//update steerX with the average of X
gearY=totalY/avgctr;//same for Y but with average of Y
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);//resize the canvas to go to fullpage
}
function keyTyped() {
// $$$ For some reason on Chrome/Mac you may have to press f twice to toggle. Works correctly on Firefox/Mac
if (key === 'f') {
toggleFullscreen();//if f is pressed, show fullpage
}
if(key==='q'){//if q is pressed go to h=intro page
if(introbool==false){
introbool=true;
introp.playbool=false;
S2.play();
}
}
// uncomment to prevent any default behavior
// return false;
}
// Toggle fullscreen state. Must be called in response
// to a user event (i.e. keyboard, mouse click)
function toggleFullscreen() {
let fs = fullscreen(); // Get the current state
fullscreen(!fs); // Flip it!
}
let mySteer;//variable going to store steer object let myDash;//gonna store the dashboard object let handpose;//gonna store posenet object let video;//gonna store video object let predictions = [];//gonna store set of predictions from posenet let steerX=300;//gonna store the average x coordinate of the hand let gearY=250;//gonna store the average y coordinate of the hand let movementLR=0;//gonnna store the left and right movement let movementFB=0;//gonna store the front and back movement let wallstop=0;//gonna store the obstacle detection let steercontrol=0;//gonna control steer to make it feel smooth let IntroBackground;//intropage background let S1;//sound 1(button) let S2;//sound 2 let F1; let F2; let introp;//gonna store intropage object let introbool=true;//going to control the intropage display let gamebool=false;//going to control the mainpage display function preload(){ //in this preload function we will load all the uploads we need before we even start the game. IntroBackground=loadImage("intro1.jpg");//this is for the background S1=loadSound("button.mp3");//these sets are for the sounds S2=loadSound("msound.mp3"); F1=loadFont("font1.ttf");//these sets are for the fonts F2=loadFont("font2.ttf"); } function setup() { createCanvas(windowWidth, windowHeight); video = createCapture(VIDEO);//capture video using camera video.size(width, height);//set the size of the video to that of the screen steercontrol=windowWidth/2//set the steercontrol for smoothness handpose = ml5.handpose(video);//get posenet from the video feed using the ml library // 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(); introp=new ipage(IntroBackground,S1,S2,F1,F2);//create intropage object mySteer=new Steer(steerX,F2,windowWidth*0.5,windowHeight*0.85);//create steer object myDash=new dash(windowHeight*0.85);//create dashboard object S2.loop();//start playing the sound but with loop property } function draw() { if(introbool){//if the introbool is true show intropage gamebool=introp.show();//update gamebool from intro.show function if(gamebool){introbool=false;}//if the gamebool is true,set intro to false } else{ background(50,150,255); myDash.showdash()//show the dash drawKeypoints();//call this function for geting info from the video hand detection movementFB=myDash.showgear(gearY);//update the front back movement from the showgear function movementLR=mySteer.steerTurn(movementFB,wallstop);//update the leftright movement from the steerturn function if(steerX>0&&steerX<windowWidth){//if the steerX is within the range we want mySteer.show(steerX);//show the steer with this value steercontrol=steerX;//update the steercontrol incase we stop getting data } else{//if the steerX is not in our range, if(steercontrol<windowWidth/2-5){steercontrol+=10;}//using our steercontrol,slowly move the steer to the center else if(steercontrol>windowWidth/2+5){steercontrol-=10;} mySteer.show(steercontrol); } myDash.showScreen(wallstop);//show the screen with the wallstop getten form the Arduino } } function keyPressed() {//if spaebar is pressed connect to arduino if (key == " ") { // important to have in order to start the serial connection!! setUpSerial();//connect to arduino } } function readSerial(data) { if (data!=null){//if the data is not null ////////////////////////////////// //READ FROM ARDUINO HERE (handshake) ////////////////////////////////// wallstop= int(trim(data)); ////////////////////////////////// //SEND TO ARDUINO HERE (handshake) ////////////////////////////////// let sendToArduino = movementLR + "\n"; writeSerial(sendToArduino); } } function drawKeypoints() { let totalX=0;//set variable to store the sum of the x coordinates of all the predictions let totalY=0;//same for y let avgctr=0;//set a counter to count the predictions let len=0;//I dont use len here but i was experimenting somthing for (let i = 0; i < predictions.length; i += 1) { const prediction = predictions[i]; len=predictions.lenght*prediction.landmarks.length; for (let j = 0; j < prediction.landmarks.length; j += 1) { const keypoint = prediction.landmarks[j]; totalX+=windowWidth-map(keypoint[0],0,video.width,0,windowWidth);//map the points to our window size and sum it totalY+=map(keypoint[1],0,video.height,0,windowHeight); avgctr++;//increase this too } } steerX=totalX/avgctr;//update steerX with the average of X gearY=totalY/avgctr;//same for Y but with average of Y } function windowResized() { resizeCanvas(windowWidth, windowHeight);//resize the canvas to go to fullpage } function keyTyped() { // $$$ For some reason on Chrome/Mac you may have to press f twice to toggle. Works correctly on Firefox/Mac if (key === 'f') { toggleFullscreen();//if f is pressed, show fullpage } if(key==='q'){//if q is pressed go to h=intro page if(introbool==false){ introbool=true; introp.playbool=false; S2.play(); } } // uncomment to prevent any default behavior // return false; } // Toggle fullscreen state. Must be called in response // to a user event (i.e. keyboard, mouse click) function toggleFullscreen() { let fs = fullscreen(); // Get the current state fullscreen(!fs); // Flip it! }
let mySteer;//variable going to store steer object
let myDash;//gonna store the dashboard object
let handpose;//gonna store posenet object
let video;//gonna store video object
let predictions = [];//gonna store set of predictions from posenet
let steerX=300;//gonna store the average x coordinate of the hand
let gearY=250;//gonna store the average y coordinate of the hand
let movementLR=0;//gonnna store the left and right movement
let movementFB=0;//gonna store the front and back movement

let wallstop=0;//gonna store the obstacle detection
let steercontrol=0;//gonna control steer to make it feel smooth

let IntroBackground;//intropage background
let S1;//sound 1(button)
let S2;//sound 2
let F1;
let F2;
let introp;//gonna store intropage object
let introbool=true;//going to control the intropage display
let gamebool=false;//going to control the mainpage display

function preload(){
  //in this preload function we will load all the uploads we need before we even start the game.
  IntroBackground=loadImage("intro1.jpg");//this is for the background
  S1=loadSound("button.mp3");//these sets are for the sounds
  S2=loadSound("msound.mp3");
  F1=loadFont("font1.ttf");//these sets are for the fonts 
  F2=loadFont("font2.ttf");
  
}

function setup() {
  createCanvas(windowWidth, windowHeight);
  video = createCapture(VIDEO);//capture video using camera
  video.size(width, height);//set the size of the video to that of the screen
   steercontrol=windowWidth/2//set the steercontrol for smoothness
  handpose = ml5.handpose(video);//get posenet from the video feed using the ml library

  // 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();
  introp=new ipage(IntroBackground,S1,S2,F1,F2);//create intropage object
  mySteer=new Steer(steerX,F2,windowWidth*0.5,windowHeight*0.85);//create steer object
  myDash=new dash(windowHeight*0.85);//create dashboard object
  S2.loop();//start playing the sound but with loop property
}

function draw() {
  if(introbool){//if the introbool is true show intropage
    gamebool=introp.show();//update gamebool from intro.show function
    if(gamebool){introbool=false;}//if the gamebool is true,set intro to false
  }
  else{
    background(50,150,255);
  myDash.showdash()//show the dash
  drawKeypoints();//call this function for geting info from the video hand detection
  movementFB=myDash.showgear(gearY);//update the front back movement from the showgear function
  movementLR=mySteer.steerTurn(movementFB,wallstop);//update the leftright movement from the steerturn function
  if(steerX>0&&steerX<windowWidth){//if the steerX is within the range we want
    mySteer.show(steerX);//show the steer with this value
    steercontrol=steerX;//update the steercontrol incase we stop getting data
  }
  else{//if the steerX is not in our range,
    if(steercontrol<windowWidth/2-5){steercontrol+=10;}//using our steercontrol,slowly move the steer to the center
    else if(steercontrol>windowWidth/2+5){steercontrol-=10;}
    mySteer.show(steercontrol);
  }
  myDash.showScreen(wallstop);//show the screen with the wallstop getten form the Arduino
  }
}
function keyPressed() {//if spaebar is pressed connect to arduino
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();//connect to arduino
  }
}
function readSerial(data) {
  

  if (data!=null){//if the data is not null
    //////////////////////////////////
    //READ FROM ARDUINO HERE (handshake)
    //////////////////////////////////
    wallstop= int(trim(data));
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = movementLR + "\n";
    writeSerial(sendToArduino);
  }
    
}
function drawKeypoints() {
  let totalX=0;//set variable to store the sum of the x coordinates of all the predictions
  let totalY=0;//same for y
  let avgctr=0;//set a counter to count the predictions
  let len=0;//I dont use len here but i was experimenting somthing
  for (let i = 0; i < predictions.length; i += 1) {
    const prediction = predictions[i];
    len=predictions.lenght*prediction.landmarks.length;
    for (let j = 0; j < prediction.landmarks.length; j += 1) {
      const keypoint = prediction.landmarks[j];
       totalX+=windowWidth-map(keypoint[0],0,video.width,0,windowWidth);//map the points to our window size and sum it
      totalY+=map(keypoint[1],0,video.height,0,windowHeight);
      avgctr++;//increase this too
    }
  }
  steerX=totalX/avgctr;//update steerX with the average of X
  gearY=totalY/avgctr;//same for Y but with average of Y
}
function windowResized() {
  resizeCanvas(windowWidth, windowHeight);//resize the canvas to go to fullpage
}

function keyTyped() {
  // $$$ For some reason on Chrome/Mac you may have to press f twice to toggle. Works correctly on Firefox/Mac
  if (key === 'f') {
    toggleFullscreen();//if f is pressed, show fullpage
  }
  if(key==='q'){//if q is pressed go to h=intro page
    if(introbool==false){
      introbool=true;
      introp.playbool=false;
      S2.play();
    }
  }
  // uncomment to prevent any default behavior
  // return false;
}

// Toggle fullscreen state. Must be called in response
// to a user event (i.e. keyboard, mouse click)
function toggleFullscreen() {
  let fs = fullscreen(); // Get the current state
  fullscreen(!fs); // Flip it!
}

Rekas Bot:

My inspiration for this project comes from my zeal to use the ml library in p5 and I had fun developing this.

Model:

Test Video:

Arduino Circuit Diagram:

Schematic Diagram:

Clarification on the Schematic motor drawing:

By Aya Riad

Future Improvements:

I Tried to implement Bluetooth but I was not able to because it kept on failing even though I had connected and set up everything right so I wish to be able to find a way to make this connection more reliable and also I plan to make the machine learning more reliable in future.

 

IM Showcase:

So just before the showcase started, I added one line of code which made the bot move randomly as though it had life.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if(introbool){//if the introbool is true show intropage
gamebool=introp.show();//update gamebool from intro.show function
movementLR=int(random(0,6));//do random stuff
if(gamebool){introbool=false;}//if the gamebool is true,set intro to false
}
if(introbool){//if the introbool is true show intropage gamebool=introp.show();//update gamebool from intro.show function movementLR=int(random(0,6));//do random stuff if(gamebool){introbool=false;}//if the gamebool is true,set intro to false }
if(introbool){//if the introbool is true show intropage
    gamebool=introp.show();//update gamebool from intro.show function
    movementLR=int(random(0,6));//do random stuff
    if(gamebool){introbool=false;}//if the gamebool is true,set intro to false
  }

I am really proud of this last decision.

and when you  want to drive it, it stops the random movements.

For more videos

Thank you.

Final Project so far:

I have been looking into the machine learning library, and so far, I have achieved the poseNet creation for the palms but I am now looking into how this can be used to control my steering wheel. What steering wheel you might be wondering. So I have created a steering wheel that I plan to use to control the wheels of the car I would create. That is if I should choose to create a car. The p5 sketch for the steering wheel so far is below

So I continue to look into how to do the integration but for the ML so far this is what I have below:

Its not much but its cooking. Inshallah!

Week 11 Group assignment:

Exercise 1:

make something that uses only one sensor on Arduino and makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on Arduino is controlled by p5

For Arduino, I used a potentiometer to change the position of the ellipse in the p5js sketch. The ellipse starts from the left of the canvas, and it moves horizontally as the values from the potentiometer increase. The values from the potentiometer are mapped to the x coordinates of the ellipse, moving it across the horizontal axis in the middle of the screen.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//// Arduino Code
//void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//}
//void loop() {
// put your main code here, to run repeatedly:
int sensor = analogRead(A0);
delay(5);
Serial.println(sensor);
//}
let left = 0;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220,110,250);
fill("green");
ellipse(left, 50, 50, 50);
}
function keyPressed() {
if (key == " ") {
// important to have in order to start the serial connection!!
setUpSerial();
}
}
function readSerial(data) {
left = map(data, 0, 1023, 0, 400);
}
//// Arduino Code //void setup() { // put your setup code here, to run once: Serial.begin(9600); //} //void loop() { // put your main code here, to run repeatedly: int sensor = analogRead(A0); delay(5); Serial.println(sensor); //} let left = 0; function setup() { createCanvas(400, 400); } function draw() { background(220,110,250); fill("green"); ellipse(left, 50, 50, 50); } function keyPressed() { if (key == " ") { // important to have in order to start the serial connection!! setUpSerial(); } } function readSerial(data) { left = map(data, 0, 1023, 0, 400); }
//// Arduino Code


//void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

//}

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

//}


let left = 0;

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

function draw() {
  background(220,110,250);
  fill("green");
  ellipse(left, 50, 50, 50);
}

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

function readSerial(data) {
  left = map(data, 0, 1023, 0, 400);
}

 

 

Exercise 2:

make something that controls the LED brightness from p5

In this p5.js sketch, moving the mouse horizontally controls the brightness of an LED, represented by the variable `mybrightness`. The canvas background changes in shades of blue with the mouse’s x-position. Pressing the space bar initiates a serial connection to the Arduino, enabling real-time communication. The `readSerial` function reads data from the Arduino, and the current brightness value is sent back by appending a new line character. This simple interaction allows the LED brightness to respond in real time to the horizontal mouse movement on the canvas.

Arduino:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// - 5 - LED
int ledpin=5;//pin for led to be used
void setup() {
// Start serial communication so we can send data
// over the USB connection to our p5js sketch
Serial.begin(9600);
pinMode(5,OUTPUT);//setting mode as output
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// wait for data from p5 before doing something
while (Serial.available()) {//while we read from serial
digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
int brightness=Serial.parseInt();//the brightness is gotten from data from p5
if (Serial.read() == '\n') {//if we read \n,
analogWrite(ledpin, brightness);//turn on the led based on the intensity gotten from p5
Serial.println();//send \n
}
}
digitalWrite(LED_BUILTIN, LOW);//if it is not reading, turn of checker light
}
// - 5 - LED int ledpin=5;//pin for led to be used void setup() { // Start serial communication so we can send data // over the USB connection to our p5js sketch Serial.begin(9600); pinMode(5,OUTPUT);//setting mode as output pinMode(LED_BUILTIN, OUTPUT); } void loop() { // wait for data from p5 before doing something while (Serial.available()) {//while we read from serial digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data int brightness=Serial.parseInt();//the brightness is gotten from data from p5 if (Serial.read() == '\n') {//if we read \n, analogWrite(ledpin, brightness);//turn on the led based on the intensity gotten from p5 Serial.println();//send \n } } digitalWrite(LED_BUILTIN, LOW);//if it is not reading, turn of checker light }
// - 5 - LED
int ledpin=5;//pin for led to be used

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

  pinMode(5,OUTPUT);//setting mode as output
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {//while we read from serial
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data
    int brightness=Serial.parseInt();//the brightness is gotten from data from p5
    if (Serial.read() == '\n') {//if we read \n,
      analogWrite(ledpin, brightness);//turn on the led based on the intensity gotten from p5
      Serial.println();//send \n
    }
  }
  digitalWrite(LED_BUILTIN, LOW);//if it is not reading, turn of checker light
}

P5 code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let mybrightness=0;
function setup() {
createCanvas(255,255);//make the canvas size 255 by 255
textSize(18);//set text size to 18
}
function draw() {
background(0,0,mouseX);//background be shades of blue
fill(255);//text be white
if (!serialActive) {
text("Press Space Bar to select Serial Port", 20, 30);
} else {
text("Connected", 20, 30);
}
mybrightness=mouseX;//equate the mouseX to mybrightness
}
function keyPressed() {
if (key == " ") {
// important to have in order to start the serial connection!!
setUpSerial();//when space is pressed connect to arduino
}
}
// 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) {
let sendToArduino = mybrightness+'\n';
writeSerial(sendToArduino);//send mybrightness to arduino
}
let mybrightness=0; function setup() { createCanvas(255,255);//make the canvas size 255 by 255 textSize(18);//set text size to 18 } function draw() { background(0,0,mouseX);//background be shades of blue fill(255);//text be white if (!serialActive) { text("Press Space Bar to select Serial Port", 20, 30); } else { text("Connected", 20, 30); } mybrightness=mouseX;//equate the mouseX to mybrightness } function keyPressed() { if (key == " ") { // important to have in order to start the serial connection!! setUpSerial();//when space is pressed connect to arduino } } // 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) { let sendToArduino = mybrightness+'\n'; writeSerial(sendToArduino);//send mybrightness to arduino }
let mybrightness=0;
function setup() {
  createCanvas(255,255);//make the canvas size 255 by 255
  textSize(18);//set text size to 18
}

function draw() {

  background(0,0,mouseX);//background be shades of blue
  fill(255);//text be white

  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
    
  }
  mybrightness=mouseX;//equate the mouseX to mybrightness
}

function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();//when space is pressed connect to arduino
  }
}

// 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) {
    let sendToArduino = mybrightness+'\n';
    writeSerial(sendToArduino);//send mybrightness to arduino
}

Exercise 3: 

take the gravity wind example and make it so every time the ball bounces one led lights up and then turns off, and you can control the wind from one analog sensor

The p5.js sketch features a blue ball that bounces on the canvas, and a corresponding LED turns on whenever the ball hits the floor. The wind effect on the ball’s movement is controlled by an analog sensor connected to the Arduino. When a ‘d’ key is pressed, a serial connection is established between p5.js and the Arduino. Pressing the space bar creates a new bouncing ball with a random mass and resets its position. The Arduino reads the wind intensity from an analog light sensor, and the LED is turned on or off based on the received brightness value from p5.js. The wind strength is then sent back to p5.js, completing the real-time interaction between the bouncing ball simulation and the Arduino-controlled LED.

Video :

Arduino Code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int LedPin = 5;//pin to display light
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(LedPin, OUTPUT);//set pin as output
}
void loop() {
// wait for data from p5 before doing something
while (Serial.available()) {//while we read from serial
digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data for checker
int bright = Serial.parseInt();//read data from p5 and store in bright
if (Serial.read() == '\n') {//if the serial read is \n,
digitalWrite(LedPin, bright);//turn on or off led depending on the value of bright
int windsens=analogRead(A0);//read the windspeed from lightsensor
delay(5);//wait small to get reading
Serial.println(windsens);//send windspeed to p5
}
}
digitalWrite(LED_BUILTIN, LOW);//if not active turn checker led off
}
int LedPin = 5;//pin to display light 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(LedPin, OUTPUT);//set pin as output } void loop() { // wait for data from p5 before doing something while (Serial.available()) {//while we read from serial digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data for checker int bright = Serial.parseInt();//read data from p5 and store in bright if (Serial.read() == '\n') {//if the serial read is \n, digitalWrite(LedPin, bright);//turn on or off led depending on the value of bright int windsens=analogRead(A0);//read the windspeed from lightsensor delay(5);//wait small to get reading Serial.println(windsens);//send windspeed to p5 } } digitalWrite(LED_BUILTIN, LOW);//if not active turn checker led off }
int LedPin = 5;//pin to display light

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(LedPin, OUTPUT);//set pin as output

}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {//while we read from serial
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data for checker
    int bright = Serial.parseInt();//read data from p5 and store in bright
    if (Serial.read() == '\n') {//if the serial read is \n,
      digitalWrite(LedPin, bright);//turn on or off led depending on the value of bright
      int windsens=analogRead(A0);//read the windspeed from lightsensor
      delay(5);//wait small to get reading
      Serial.println(windsens);//send windspeed to p5
    }
  }
  digitalWrite(LED_BUILTIN, LOW);//if not active turn checker led off
}

P5 code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let led=0;//variable controlling the led
function setup() {
createCanvas(640, 360);
fill(0,0,255);//ball to be blue
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(0,50);//background black with transperacy 50
applyForce(wind);
applyForce(gravity);
velocity.add(acceleration);
velocity.mult(drag);
position.add(velocity);
acceleration.mult(0);
ellipse(position.x,position.y,mass,mass);
if (position.y > height-mass/2) {
velocity.y *= -0.9; // A little dampening when hitting the bottom
position.y = height-mass/2;
}
if(position.y==height-mass/2){led=1;}//if the ball touches the floor, turn on led
else{led=0;}//otherwise turn led off
}
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 == "d") {//when d is pressed create connection
// important to have in order to start the serial connection!!
setUpSerial();
}
if (key==' '){//when space is pressed create new ball and call bounce effect
mass=random(15,80);
position.y=-mass;
velocity.mult(0);
}
}
function readSerial(data) {
wind.x=map(int(data),0,1023,-2,2);//map the value gotten from the arduino to wind.x
let sendToArduino = led+'\n';
writeSerial(sendToArduino);//send the value of led to the srduino
}
let velocity; let gravity; let position; let acceleration; let wind; let drag = 0.99; let mass = 50; let led=0;//variable controlling the led function setup() { createCanvas(640, 360); fill(0,0,255);//ball to be blue 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(0,50);//background black with transperacy 50 applyForce(wind); applyForce(gravity); velocity.add(acceleration); velocity.mult(drag); position.add(velocity); acceleration.mult(0); ellipse(position.x,position.y,mass,mass); if (position.y > height-mass/2) { velocity.y *= -0.9; // A little dampening when hitting the bottom position.y = height-mass/2; } if(position.y==height-mass/2){led=1;}//if the ball touches the floor, turn on led else{led=0;}//otherwise turn led off } 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 == "d") {//when d is pressed create connection // important to have in order to start the serial connection!! setUpSerial(); } if (key==' '){//when space is pressed create new ball and call bounce effect mass=random(15,80); position.y=-mass; velocity.mult(0); } } function readSerial(data) { wind.x=map(int(data),0,1023,-2,2);//map the value gotten from the arduino to wind.x let sendToArduino = led+'\n'; writeSerial(sendToArduino);//send the value of led to the srduino }
let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let led=0;//variable controlling the led

function setup() {
  createCanvas(640, 360);
  fill(0,0,255);//ball to be blue
  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(0,50);//background black with transperacy 50
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  if (position.y > height-mass/2) {
      velocity.y *= -0.9;  // A little dampening when hitting the bottom
      position.y = height-mass/2;
    }
  if(position.y==height-mass/2){led=1;}//if the ball touches the floor, turn on led
  else{led=0;}//otherwise turn led off
}

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 == "d") {//when d is pressed create connection
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  if (key==' '){//when space is pressed create new ball and call bounce effect
    mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
}
function readSerial(data) {
    wind.x=map(int(data),0,1023,-2,2);//map the value gotten from the arduino to wind.x
    let sendToArduino = led+'\n';
    writeSerial(sendToArduino);//send the value of led to the srduino
}

Thank you

Week 10 Response:

Last week I thought we were in the 11th week so I wrote the response for this week. To make up for that, I am writing the response for last week now.

Do you seriously think the Future Of Interaction should be a single finger? Throughout the article, I was mostly not in agreement with Bret. Why? Because, well I feel like he was writing as though he didn’t want a change in reality but we all know that development comes with change. The only part I kind of agreed with him was when he said that this form of interaction is a transition to the future but even with that, we must keep in mind that the future keeps changing. Today, the “then” future(using screens) is the current present, and saying that this form of interaction is a transition into the future is like saying the keypad is the transition to using smartphones. True but are smartphones still the future? What I am trying to say is, that development comes with change and one can not say he has developed without changing. As we grow, we tend to stop doing/using some things for example, even in biology, humans have evolved to a point where we do not have a use for the appendix or the spleen, some organs that were once vital. I feel like saying we should not develop into an age of pictures behind screens hinders our “capabilities” to grow. Through this, we got to create new word to which we now explore. A new future. For me I would say the future is not something that should be controlled cause then we can not explore our capabilities to the fullest.

Week 11 Response:

Diversity and Equality is something that currently is being pushed forward to reduce discrimination against particular groups and I like the fact that Graham makes us acknowledge that fact that in designing we should try to incorporate these values into our design.  For the past weeks we have been talking about integrating the emotions of the user and making the design have an aesthetic feel or look to it, I am not surprised to see this concept once more.

Rekas & Boamah-Powers: Ab3n

Concept:

Back home, we usually play the trumpet, but when we came to the UAE, we couldn’t find any trumpets. So, we decided to create our own – an electronic trumpet. It works by using a light sensor for the blowing effect and regular buttons for playing the notes. The sound comes out from a speaker. Simple as that!

The circuit diagram looks a bit messy but it works 🙂

Circuit Diagram:

Code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include "pitches.h"
//set the pins for the button, buzzer, and photoresistor
int firstKeyPin = 13;
int secondKeyPin = 12;
int thirdKeyPin = 11;
int buzzerPin = 9;
int blow = A2;
// variables regulate when value is read
const long interval = 200;
unsigned long previousMillis = 0;
int blowVal;
void setup() {
Serial.begin(9600);
//set the button pins as inputs
pinMode(firstKeyPin, INPUT_PULLUP);
pinMode(secondKeyPin, INPUT_PULLUP);
pinMode(thirdKeyPin, INPUT_PULLUP);
//set the buzzer pin as an output
pinMode(buzzerPin, OUTPUT);
// reads value on setup to avoid later error
blowVal = analogRead(blow);
}
void loop() {
// reads current time
unsigned long currentMillis = millis();
// checks if specified duration has passed
if (currentMillis - previousMillis >= interval) {
// updates time since value was read from sensor
previousMillis = currentMillis;
// reads value from sensor
blowVal = analogRead(blow);
}
Serial.println(blowVal);
// conditions to play specific notes
if (blowVal <= 350) {
if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_F3);
}
if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == LOW)) {
tone(buzzerPin, NOTE_G3);
}
if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_A3);
}
if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_AS3);
}
}
if (blowVal > 350) {
if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_C4);
}
if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_D4);
}
if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_E4);
}
if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
tone(buzzerPin, NOTE_AS3);
}
if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == LOW)) {
tone(buzzerPin, NOTE_F4);
}
}
}
#include "pitches.h" //set the pins for the button, buzzer, and photoresistor int firstKeyPin = 13; int secondKeyPin = 12; int thirdKeyPin = 11; int buzzerPin = 9; int blow = A2; // variables regulate when value is read const long interval = 200; unsigned long previousMillis = 0; int blowVal; void setup() { Serial.begin(9600); //set the button pins as inputs pinMode(firstKeyPin, INPUT_PULLUP); pinMode(secondKeyPin, INPUT_PULLUP); pinMode(thirdKeyPin, INPUT_PULLUP); //set the buzzer pin as an output pinMode(buzzerPin, OUTPUT); // reads value on setup to avoid later error blowVal = analogRead(blow); } void loop() { // reads current time unsigned long currentMillis = millis(); // checks if specified duration has passed if (currentMillis - previousMillis >= interval) { // updates time since value was read from sensor previousMillis = currentMillis; // reads value from sensor blowVal = analogRead(blow); } Serial.println(blowVal); // conditions to play specific notes if (blowVal <= 350) { if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_F3); } if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == LOW)) { tone(buzzerPin, NOTE_G3); } if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_A3); } if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_AS3); } } if (blowVal > 350) { if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_C4); } if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_D4); } if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_E4); } if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) { tone(buzzerPin, NOTE_AS3); } if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == LOW)) { tone(buzzerPin, NOTE_F4); } } }
#include "pitches.h"

//set the pins for the button, buzzer, and photoresistor
int firstKeyPin = 13;
int secondKeyPin = 12;
int thirdKeyPin = 11;
int buzzerPin = 9;
int blow = A2;

// variables regulate when value is read
const long interval = 200;  
unsigned long previousMillis = 0;
int blowVal;


void setup() {

  Serial.begin(9600);
  //set the button pins as inputs
  pinMode(firstKeyPin, INPUT_PULLUP);
  pinMode(secondKeyPin, INPUT_PULLUP);
  pinMode(thirdKeyPin, INPUT_PULLUP);

  //set the buzzer pin as an output
  pinMode(buzzerPin, OUTPUT);

  // reads value on setup to avoid later error
  blowVal = analogRead(blow);
}

void loop() {

  // reads current time
  unsigned long currentMillis = millis();

  // checks if specified duration has passed
  if (currentMillis - previousMillis >= interval) {
    // updates time since value was read from sensor
    previousMillis = currentMillis;

    // reads value from sensor
    blowVal = analogRead(blow);
  }

  Serial.println(blowVal);

  // conditions to play specific notes
  if (blowVal <= 350) {
    if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_F3); 
    }

    if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == LOW)) {
      tone(buzzerPin, NOTE_G3); 
    }

    if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_A3); 
    }

    if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_AS3); 
    }

  }
  
  if (blowVal > 350) {
    if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_C4); 
    }

    if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_D4); 
    }

    if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == LOW) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_E4); 
    }

    if ((digitalRead(firstKeyPin) == LOW) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == HIGH)) {
      tone(buzzerPin, NOTE_AS3); 
    }

    if ((digitalRead(firstKeyPin) == HIGH) && (digitalRead(secondKeyPin) == HIGH) && (digitalRead(thirdKeyPin) == LOW)) {
      tone(buzzerPin, NOTE_F4); 
    }

  }
}

Highlights:

The light sensor passes value to the blowVal variable which uses either a high blow effect or a low blow effect. The part of the code that was a bit difficult for us was preventing unstable behavior we get in between the low blow and the high blow.  To solve this we used millis() to cause a frameRate reduction effect as used in p5 when reading the blow value.

Video:

Thank you!

Reflection:

Blending the two ideas, Tigoe is like, “Why stick to the same old system when we can spice it up?” Even if it’s another dance floor pad or a gesture-controlled gadget, there’s a whole treasure trove of learning. It’s about giving users the stage to express themselves through art. Creators should give room to users to play and explore, setting up a playground for artistic talents. It’s like peeking into people’s thoughts, adding value to your creation by tuning in to their reactions. All in all, artwork should allow us the viewers or listeners to know the inner thoughts of the viewer to which their reaction was used to create the artwork as well as the designer that made the platform. This is one main thing I resonated with. After all isn’t that what interactive media is?

Week 9: Eye Protection

Concept:

I often use my phone late in the night with my light out and this has been messing up my eyesight for this Project I decided to create a form of eye protection warning system that alerts the user with the use of an LED when the light from their phone screen or laptop is too bright.

So when the screen brightness is low the LED remains off and as the user increases the brightness the LED gets brighter. When the screen brightness reaches a level where the user’s eye is at harm the LED starts to blink and when the brightness gets too high the LED blinks faster.

Code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int warning=0;//variable to store the warning value used to control blinking and led brightness
void setup() {
// put your setup code here, to run once:
pinMode(13,OUTPUT);//set the 13 pin to output type
pinMode(8,INPUT);//set pin 8 to input type
pinMode(6,OUTPUT);//set pin 6 to output type
Serial.begin(9600);//set serial screen for viewing values
}
void loop() {
// put your main code here, to run repeatedly:
int anasens=analogRead(A2);//read info from light sensor and store in anasens
int digsens=digitalRead(8);//read info from switch sensor and store digsens
Serial.println(anasens);//print anasens on serial board
anasens=constrain(anasens,100,680);//keep the values between 100 and 680 at all times
warning=map(anasens,100,680,0,255);//rescale the values from 100 and 680 to 0 and 255
if(digsens==1){//if the switch is pressed
digitalWrite(13,1);//turn on yellow LED
}
else{//if the switch is not pressed
digitalWrite(13,0);//turn off LED
}
if(warning>200){//if the warning is greater than 200
analogWrite(6,warning);//turn on red LED based on warning value
delay(100);//wait for 100 milliseconds
analogWrite(6,0);//turn off red LED
delay(100);//wait for 100 milliseconds
}
if(warning>100&&warning<200){//the value is between 100 and 200
analogWrite(6,warning);//turn on red LED based on warning value
delay(500);//wait for 500 milliseconds
analogWrite(6,0);//turn off red LED
delay(500);//wait for 500 milliseconds
}
analogWrite(6,warning);//turn on red LED based on warning value
}
int warning=0;//variable to store the warning value used to control blinking and led brightness void setup() { // put your setup code here, to run once: pinMode(13,OUTPUT);//set the 13 pin to output type pinMode(8,INPUT);//set pin 8 to input type pinMode(6,OUTPUT);//set pin 6 to output type Serial.begin(9600);//set serial screen for viewing values } void loop() { // put your main code here, to run repeatedly: int anasens=analogRead(A2);//read info from light sensor and store in anasens int digsens=digitalRead(8);//read info from switch sensor and store digsens Serial.println(anasens);//print anasens on serial board anasens=constrain(anasens,100,680);//keep the values between 100 and 680 at all times warning=map(anasens,100,680,0,255);//rescale the values from 100 and 680 to 0 and 255 if(digsens==1){//if the switch is pressed digitalWrite(13,1);//turn on yellow LED } else{//if the switch is not pressed digitalWrite(13,0);//turn off LED } if(warning>200){//if the warning is greater than 200 analogWrite(6,warning);//turn on red LED based on warning value delay(100);//wait for 100 milliseconds analogWrite(6,0);//turn off red LED delay(100);//wait for 100 milliseconds } if(warning>100&&warning<200){//the value is between 100 and 200 analogWrite(6,warning);//turn on red LED based on warning value delay(500);//wait for 500 milliseconds analogWrite(6,0);//turn off red LED delay(500);//wait for 500 milliseconds } analogWrite(6,warning);//turn on red LED based on warning value }
int warning=0;//variable to store the warning value used to control blinking and led brightness

void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT);//set the 13 pin to output type
  pinMode(8,INPUT);//set pin 8 to input type
  pinMode(6,OUTPUT);//set pin 6 to output type
  Serial.begin(9600);//set serial screen for viewing values
}

void loop() {
  // put your main code here, to run repeatedly:
  int anasens=analogRead(A2);//read info from light sensor and store in anasens
  
  int digsens=digitalRead(8);//read info from switch sensor and store digsens
  Serial.println(anasens);//print anasens on serial board
  anasens=constrain(anasens,100,680);//keep the values between 100 and 680 at all times
  warning=map(anasens,100,680,0,255);//rescale the values from 100 and 680 to 0 and 255
  
  if(digsens==1){//if the switch is pressed 
    digitalWrite(13,1);//turn on yellow LED
  }
  else{//if the switch is not pressed
    digitalWrite(13,0);//turn off LED
  }
  if(warning>200){//if the warning is greater than 200
    analogWrite(6,warning);//turn on red LED based on warning value
    delay(100);//wait for 100 milliseconds
    analogWrite(6,0);//turn off red LED
    delay(100);//wait for 100 milliseconds
  }
  if(warning>100&&warning<200){//the value is between 100 and 200
    analogWrite(6,warning);//turn on red LED based on warning value
    delay(500);//wait for 500 milliseconds
    analogWrite(6,0);//turn off red LED
    delay(500);//wait for 500 milliseconds
  }
  analogWrite(6,warning);//turn on red LED based on warning value
}

Highlight:

This was an interesting assignment. I am happy I was able to do it. What i look forward to is making this a wireless connection as connecting the wires was stressful

Circuit Diagram:

Set-Up Picture:

Video:

https://drive.google.com/drive/folders/17efBVjbUX72MkYQmuw92EqgqJVYxm1Oi?usp=sharing

 

Thank You!.

Autonomous Switch

Concept:

So, for my microwave, when I close the door, sometimes it doesn’t close and it is kind of hard to know whether it is closed or not so, for this assignment, I decided to create a switch that turns on when the microwave is closed to let me know that the thing is closed.

Circuit Diagram:

Video Description:

IMGhttps://drive.google.com/drive/folders/1a_zcv3GP1p9fMuXYDW-MN694Dwo3lf2_?usp=sharing

if that link doesn’t work, try this IMG_6562

Thank you.