Handshake

Description

We must have heard people defining various intensities of handshakes. Some say that a handshake was “mellow” and some say it was “warm”. Well, these terms sound pretty vague as they are subjective. It’s time to bring in a device that actually measures how strong was your handshake. I used a Force Sensitive Resistor on a glove to measure how hard the handshake was. The way people would be able to measure this “hardness” is by seeing the color change of the LED on the glove and the sound of the speaker. The harder the handshake, the higher the frequency. It was a difficult task to find out the exact spot on the hand that would measure the intensity appropriately. Light handshakes might not involve the touch of palms, so the FSR had to be placed somewhere, where there is a definite contact. I figured it out to be the tip of the index finger.

Components

  • 1 Arduino Uno R3
  • 1 Piezo Speaker
  • 1 Force Sensitive Resistor
  • 3 LEDs
  • 1 Glove (woolen)

Code

 

// The three primary colour LEDs, driven as analogue outputs (actually PWM, but
// close enough for our analogue eyes).

const int ledPinRed = 11; // Red LED connected to analogue out pin
const int ledPinGrn = 10; // Green LED connected to analogue out pin
const int ledPinBlu = 9; // Blue LED connected to analogue out pin
const int piezoPin = 7;

// The Brightness potentiometer goes on an analogue pin, taking the pin from
// 0V to 5V.

const int fsr = 1;

// Constants to define the ranges.

const int hueRedLow = 0;
const int hueRedHigh = 255;
const int hueBlue = 170;

// The size of the angle of one sector (1/6 of a colour wheel), and of a complete
// cycle of the colour wheel.

const int angleMin = 0;
const int angleSector = 60;
const int angleMax = 360;

const int brightMin = 0;
const int brightMax = 255;

//constants to define the range of beats
const int beatsMin = 40;
const int beatsMax = 220;

// Work variables.

// The hue potentiometer value is mapped to the range 0 to 360 (degrees).
int fsrValueHue;

//The brightness potentiometer value is mapped from 0 to 255 (full brightness)
int fsrValueSound;

int hue, brightness;

const int saturation = 255;

// The brightess of each LED (0 to 255).

unsigned int r, g, b;

void setup() {
// Still need to set a baud rate, even for USB.
Serial.begin(9600);

// Set LED pins to output.
pinMode(ledPinRed, OUTPUT);
pinMode(ledPinGrn, OUTPUT);
pinMode(ledPinBlu, OUTPUT);
pinMode(piezoPin , OUTPUT);

// Poteniometer analogue pin is an input.
pinMode(fsr, INPUT);
}

void loop() {

// fsr values are mapped to create a color based on the intensity of the handshake
fsrValueHue = map(analogRead(fsr), 0, 1023, angleMin, angleMax);
// fsr values are mapped to create sound of a particular frequency based on the intensity of the handshake. Lower the intensity, lower the frequency
fsrValueSound = map(analogRead(fsr), 0, 1023, 75, 10000);

// Colour wheel mode (red to red, wrapped around in a cycle).
hue = map(fsrValueHue, angleMin, angleMax, hueRedLow, hueRedHigh);

// Do the conversion.
HSBToRGB(hue, saturation, brightness, &r, &g, &b);

analogWrite(ledPinRed, r);
analogWrite(ledPinGrn, g);
analogWrite(ledPinBlu, b);
digitalWrite(piezoPin , fsrValueSound);
}

// This function taken from here:
// http://eduardofv.com/read_post/179-Arduino-RGB-LED-HSV-Color-Wheel-

void HSBToRGB(
unsigned int inHue, unsigned int inSaturation, unsigned int inBrightness,
unsigned int *oR, unsigned int *oG, unsigned int *oB )
{
if (inSaturation == 0)
{
// achromatic (grey)
*oR = *oG = *oB = inBrightness;
}
else
{
unsigned int scaledHue = (inHue * 6);
unsigned int sector = scaledHue >> 8; // sector 0 to 5 around the color wheel
unsigned int offsetInSector = scaledHue - (sector << 8); // position within the sector unsigned int p = (inBrightness * ( 255 - inSaturation )) >> 8;
unsigned int q = (inBrightness * ( 255 - ((inSaturation * offsetInSector) >> 8) )) >> 8;
unsigned int t = (inBrightness * ( 255 - ((inSaturation * ( 255 - offsetInSector )) >> 8) )) >> 8;

switch( sector ) {
case 0:
*oR = inBrightness;
*oG = t;
*oB = p;
break;
case 1:
*oR = q;
*oG = inBrightness;
*oB = p;
break;
case 2:
*oR = p;
*oG = inBrightness;
*oB = t;
break;
case 3:
*oR = p;
*oG = q;
*oB = inBrightness;
break;
case 4:
*oR = t;
*oG = p;
*oB = inBrightness;
break;
default: // case 5:
*oR = inBrightness;
*oG = p;
*oB = q;
break;
}
}
}
 

gloves

Pocket Tanks !

Description

 

We all (most of us) have played the popular game of Pocket Tanks. For those who dont know about it, it’s a two player turn based game where one player controls the velocity and the angle at which his/her tank will shoot so as to land a hit on the opponent’s tank. I thought of an interesting way in which pocket tanks can be played. I used a potentiometer to control the angle of the nozzle and the force sensor to decide the velocity with which one is supposed to hit the other tank. The harder you press on the force sensor , the further the shot goes. I mapped the values of the potentiometer from 0 to 180 and the values of the FSR from 0 to 100.

Materials

  • Arduino
  • 1 Force Sensitive Resistor (FSR)
  • 1 Potentiometer
  • 1 10 KΩ resistor

Code

Arduino


const int fsrPin = 0;
const int potPin = 1;

void setup()  {
    // Still need to set a baud rate, even for USB.
    Serial.begin(9600);
    // Poteniometer analogue pin is an input.
    pinMode(potPin, INPUT);
    pinMode(fsrPin, INPUT);
}

void loop()  {

    int velocity = map(analogRead(fsrPin),0,1023,0,100);
    int angle = map(analogRead(potPin),0,1023,0,180);
    Serial.print(String(velocity) +'a'+ String(angle)+' ');
    delay(50);
    
    
}

Processing


//importing processing libraries
import processing.serial.*;
// Change this to the portname your Arduino board
String portname = "COM5"; // or "COM5"
//defining custom font
PFont mono;
//defingin position values for the two tanks
int xpos1, ypos1, xpos2, ypos2, xpos, ypos, distance = 0, angleX, angleY;
int velocity = 50, velocity1 = 50, velocity2 = 50;      //saves velocity and angles for each person
int angle = 90, angle1 = 90, angle2 = 90;
int fuel1 = 50, fuel2 = 50, fuel = 50;
int tS = 15;                //tank size
float bS = .1;            //ball size
boolean player1Turn = true, shoot = false, gameEnd = false, loopOne = true, moveTank = false;
float ballX, ballY;
float vx, vy, grav = 9.8, t = 0;
int win1 = 0, win2 = 0;        //counts the wins for each person
int btnMoveRed = 255, btnMoveGreen = 255,btnMoveBlue = 255;      //change the color of the move button when clicked
int btnSSR = 255, btnSSG = 255,btnSSB = 255, btnSmallR = 37, btnSmallG = 116,btnSmallB = 169,btnMedB = 255, btnMedR = 255, btnMedG = 255,btnBigB = 255, btnBigR = 255, btnBigG = 255;    //change color of gamemode buttons
Serial myPort;
//Built on the base program provided by
/* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/374777*@* */
//Jarod Searle
void setup() {
  size(1000, 800);
  smooth();
  do {
    xpos1 = int(random(1000));
    ypos1 = 600;
    xpos2 = int(random(1000));
    ypos2 = 600;
    distance = abs(xpos2 - xpos1);
  } while(distance < 75);
  textSize(13);
  stroke(0);
  mono = createFont("segoeui.ttf",32);
  textFont(mono);
  // List all the available serial ports:
  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 9600);
  //buffering each input till the delimiter for easy read
  myPort.bufferUntil(' ');
}

void draw() {
  
  //drawing the various elements in the game
  textSize(13);
  background(236,236,236);
  fill(0);
  line(0, 600, 1000, 600);
  fill(22, 160, 133);
  ellipse(xpos1, ypos1, tS, tS);    //player 1 = red
  text("Player 1 Color", 50, 650);
  text("Fuel: " + fuel1, 50, 670);
  text("Player 1 Wins: " + win1, 700, 125);
  fill(214,69,65);
  ellipse(xpos2, ypos2, tS, tS);    //player 2 = blue
  text("Player 2 Color", 825, 650);
  text("Fuel: " + fuel2, 825, 670);
  text("Player 2 Wins: " + win2, 700, 145);
  fill(0);
  text("Velocity: " + velocity + " m/s", 440, 690);
  text("Angle: " + angle + " degrees", 440, 710);
  text("Controls: Use the potentiometer to adjust the angle, and the FSR to adject the velocity, Spacebar to shoot", 280, 730);
  text("NOTE - to hit the other player, the shot must land within their circle.", 300, 60);
  text("This means that the shot can technically go through the upper half of the other player.", 250, 80);
  fill(btnMoveRed, btnMoveGreen, btnMoveBlue);
  rect(50, 690, 150, 75);
  fill(0);
  textSize(30);
  text("MOVE", 80, 740);
  fill(btnSSR, btnSSG, btnSSB);
  rect(20, 100, 100, 50);
  fill(btnSmallR, btnSmallG, btnSmallB);
  rect(140, 100, 100, 50);
  fill(btnMedR, btnMedG, btnMedB);
  rect(260, 100, 100, 50);
  fill(btnBigR, btnBigG, btnBigB);
  rect(380, 100, 100, 50);
  fill(0);
  textSize(13);
  text("Super Small", 30, 130);
  text("Small", 170, 130);
  text("Medium", 285, 130);
  text("Big", 420, 130);
  
  
  if (player1Turn == true) {      //Player 1's turn
    if (loopOne == true) {
      velocity = velocity1;    //saves the previous turn's velocity and angle
      angle = angle1;
      xpos = xpos1;
      ypos = ypos1;
      fuel = fuel1;
    }
    loopOne = false;
    velocity1 = velocity;
    angle1 = angle;
    xpos1 = xpos;
    ypos1 = ypos;
    fuel1 = fuel;
    
    //defining the trajectory
    angleX = int(xpos - velocity * cos(angle * (3.14/180)));      //velocity * the rest will make the line longer for more power
    angleY = int(ypos - velocity * sin(angle * (3.14/180)));
    line(xpos, ypos, angleX, angleY);
    
    if (shoot == true) {
      loopOne = true;
      shot();
       
       
       textSize(30);
       //code to check if the trajectory of the tank shot hits the other tank
       if ((ballX >= xpos2 - tS / 2 && ballX <= xpos2 + tS / 2) && (ballY >= ypos2 - tS)) {
         text("PLAYER 1 WINS", 350, 300);
         gameEnd = true;
         fill(255);
         rect(420, 350, 100, 50);
         fill(0);
         text("RESET", 430, 380);
         win1 += 1;
       }
       else {
         text("CLICK TO CONTINUE", 350, 300); 
         player1Turn = false;
         noLoop();
       }
    }
  }
  
  
  else if (player1Turn == false) {        //Player 2's turn
    if (loopOne == true) {
      velocity = velocity2;
      angle = angle2;
      xpos = xpos2;
      ypos = ypos2;
      fuel = fuel2;
    }
    loopOne = false;
    velocity2 = velocity;
    angle2 = angle;
    xpos2 = xpos;
    ypos2 = ypos;
    fuel2 = fuel;
    
    angleX = int(xpos - velocity * cos(angle * (3.14/180)));
    angleY = int(ypos - velocity * sin(angle * (3.14/180)));
    line(xpos, ypos, angleX, angleY);
    if (shoot == true) {
      loopOne = true;
      shot();
       
      textSize(30);
      
      //code to check if the trajectory of the tank shot hits the other tank
      if ((ballX >= xpos1 - tS / 2 && ballX <= xpos1 + tS / 2) && (ballY >= ypos1 - tS)) {
        text("PLAYER 2 WINS", 350, 300);
        gameEnd = true;
        fill(255);
        rect(420, 350, 100, 50);
        fill(0);
        text("RESET", 430, 380);
        win2 += 1;
      }
      else {
        text("CLICK TO CONTINUE", 350, 300);
        player1Turn = true;
        noLoop();
      } 
    }
  }
  
  if (gameEnd == true) {
    noLoop();
  }
}

void shot() {                //will shoot the ball, gets rid of code up above
  do {
        vx = velocity * cos(angle * (3.14/180));
        vy = velocity * sin(angle * (3.14/180));
        t += .02;
        ballX = xpos -(vx * t);
        ballY = ypos -(vy * t - (grav/2)*t*t);
        fill(0);
        ellipse(ballX, ballY, bS, bS);
      } while (!(ballY > 600));
}

void resetButtons() {
  btnSSR = 255;
  btnSSG = 255;
  btnSSB = 255;
  btnSmallR = 255;
  btnSmallG = 255;
  btnSmallB = 255;
  btnMedR = 255;
  btnMedG = 255;
  btnMedB = 255;
  btnBigR = 255;
  btnBigG = 255;
  btnBigB = 255;
}

// called whenever serial data arrives
void serialEvent(Serial p) {
  
  while (myPort.available() > 0) {
    
    //reading the buffer until ' ' which is the delimiter
    String inString = myPort.readStringUntil(' '); 
    //the two values of the sensors are separated by 'a'
    String nums[] = inString.split("a");
    velocity = int(nums[0]);
    nums[1] = trim(nums[1]);
    angle = int(nums[1]);
    printArray(nums);
  }
 
}

void keyPressed() {
  if (key == CODED) {    
    if (keyCode == RIGHT) {
      if (moveTank == true && fuel > 0) {
        xpos += 1;
        fuel -= 1;
      }
    }
    else if (keyCode == LEFT) {      
      if (moveTank == true && fuel > 0) {
        xpos -= 1;
        fuel -= 1;
      }
    }
  }
  else if (keyCode == ' ')
    shoot = true;  
}

void mousePressed() {
  if (shoot == true && gameEnd == false) {
    shoot = false;
    t = 0;
    moveTank = false;
    loop();
    btnMoveGreen = 255;
    btnMoveRed = 255;
    btnMoveBlue = 255;
  }
  else if (gameEnd == true) {
    if (mouseX >= 420 && mouseX <= 520 && mouseY >= 350 && mouseY <= 400) {
      do {
        xpos1 = int(random(1000));
        xpos2 = int(random(1000));
        distance = abs(xpos2 - xpos1);
      } while(distance < 75);
      angle1 = 90;
      angle2 = 90;
      velocity1 = 50;
      velocity2 = 50;
      fuel1 = 50;
      fuel2 = 50;
      textSize(13);
      shoot = false;
      gameEnd = false;
      loopOne = true;
      t = 0;
      
      if (win1 > win2) 
        player1Turn = false;
      else if (win2 > win1)
        player1Turn = true;
      else {
        int x = int(random(2));
        if (x == 1) 
          player1Turn = true;
        else
          player1Turn = false;
      }
      loop();
    }
  }
  else if (mouseX >= 50 && mouseX <= 200 && mouseY >= 690 && mouseY <= 765) {    //move button
    if (moveTank == false) {
      moveTank = true;
      btnMoveGreen = 116;
    btnMoveRed = 37;
    btnMoveBlue = 169;
    }
    else {
      moveTank = false;
      btnMoveGreen = 255;
    btnMoveRed = 255;
    btnMoveBlue = 255;
    }
  }
  else if (mouseX >= 20 && mouseX <= 120 && mouseY >= 100 && mouseY <= 150) {      //super small
    resetButtons();
    btnSSR = 37;
    btnSSG = 116;
    btnSSB = 169;
    tS = 5;
  } 
  else if (mouseX >= 140 && mouseX <= 240 && mouseY >= 100 && mouseY <= 150) {
    resetButtons();
    btnSmallR = 37;
    btnSmallG = 116;
    btnSmallB = 169;
    tS = 15;
  }
  else if (mouseX >= 260 && mouseX <= 360 && mouseY >= 100 && mouseY <= 150) {
    resetButtons();
    btnMedR = 37;
    btnMedG = 116;
    btnMedB = 169;
    tS = 100;
  }
  else if (mouseX >= 380 && mouseX <= 480 && mouseY >= 100 && mouseY <= 150) {
    resetButtons();
    btnBigR = 37;
    btnBigG = 116;
    btnBigB = 169;
    tS = 200;
  }
}
fsr

game