All posts by Jeremiah Jarrett

ASL Learning Game (attempt)

So I decided to build upon my ASL project that I did earlier this semester. Originally I was going to do a search engine using the ASL alphabet. But during the user testing session Anna had an idea to make it into an ASL learning game. What would happen is at the top of the screen images of the handshapes of letters would appear. The object is that you would copy the handshapes which would input a query (which you wouldn’t see) and then it would pull up the first google image of what you signed. Then you would type into an answer box what you think the word you signed meant. If you got it correct you’d move onto the next level, if not you’d have to guess again. When I started putting all of these ideas together I ran into many road blocks though. When I first started I was trying to use a LeapMotion but it wasn’t working with Processing at all. Then when I started with the flex sensors I couldn’t get the Arduino to work (turns out I had the wrong numbers put into the program, but whatever). Then I got the Arduino to work but I had to find all the various numbers for the letters again, and it wasn’t working as nicely as the last time I ran the ASL program. Next I just tried to get Processing to print the letter on the screen, but I couldn’t figure out how to get readings from the Arduino to be slower and I couldn’t figure out how to make the letters into one string. Because I couldn’t figure out this I wasn’t able to think of a way to get the letters into a query. So I don’t have the entire project all together… But I do have all the pieces of the code (except for the ASL Handshape pictures).

Here is the Processing code for getting the letters to show up on the screen.

import processing.serial.*;

Serial myPort;
int flexFore;
int flexNumbers;

void setup() {
  size(640, 480);
  // List all the available serial ports:
  printArray(Serial.list());
  // Print out the list and look for port your Microcontroller is on
  // Finding the Arduino is not easy because they have weird names on the mac and on the pc they look like COM1.
  // Ardnino is almost always the first one so you can usually use Serial.list()[0].
  String portName = Serial.list()[5];
  myPort = new Serial(this, portName, 9600);
  myPort.readStringUntil('\n');  //clean out anything already in the buffer
  size(640, 480);
}

void draw() {
  background(255);
  textSize(40);
  fill(0);
  if (flexNumbers >= 90 && flexNumbers <=100) {
    if (flexFore >= 25 && flexFore < 40) {
      text("A",width/2,height/2);
      delay(1000);
    }
  }

  if (flexNumbers >= 90&& flexNumbers <110) {
    if (flexFore >=100 && flexFore <115) {
      text("H",width/2,height/2);
      delay(1000);
    }
  }
  if (flexNumbers >=80 && flexNumbers <90) {
    if (flexFore >= 100 && flexFore <115) {
      text("G",width/2,height/2);
      delay(1000);
    }
  }
   if (flexNumbers >=60 && flexNumbers <70) {
    if (flexFore >=50 && flexFore <65) {
text("C",width/2,height/2);
      delay(1000);
    }
  }
  if (flexNumbers >=50 && flexNumbers <60) {
    if (flexFore >=40 && flexFore <55) {
text("F",width/2,height/2);
      delay(1000);
    }
  }
  if (flexNumbers >=70&& flexNumbers <78) {
    if (flexFore >= 90 && flexFore <=115) {
text("D",width/2,height/2);
      delay(1000);
    }
  }
  else if (flexNumbers >=30 && flexNumbers <65) {
    if (flexFore >=90 && flexFore <=115) {
text("B",width/2,height/2);
      delay(1000);
    }
  }
  if (flexNumbers <50) {
    if (flexFore >= 0 && flexFore < 50) {
text("E",width/2,height/2);
      delay(1000);
    }
  }
  else if (flexNumbers > 110) {
    if (flexFore >115 ) {
text(" ",width/2,height/2);
      delay(1000);
    }
  }
}

void serialEvent(Serial _port) { //this is a callback function
  if (myPort == null) return;
  String input = myPort.readStringUntil('\n');
  if (input != null) {  //if a '\n' character has in fact now arrived
    String[] parts = split(input, ",");  //split the message into parts based on the comma
    //the parts got put into a special kind of variable called an array that has slots
    String var1 = parts[0]; //they came in the order they were sent 
    String var2 = parts[1]; //so the force will be in the first slot of the array fire in second
    flexFore = int(var1);  //Turn it into a number for eelipse in draw
    flexNumbers = int(var2);  //Turn it into a number for fill in draw
    println(flexFore, flexNumbers);
  }
}

And here is the query code:

import java.io.*;
String query = "";

void setup() {
  size(640, 480);
  background(0);
  fill(255, 255, 255);
}

void draw() {
}

void queryGoogleImages(String _q) {
  String url = "https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" + _q;
  //this is a special url for getting google image results as json
  println(url);
  JSONObject result =  loadJSONObject(url);
  //make a network call and get the results back into a json object
  println(result);
  //make sure the results are not an error
  int status = result.getInt("responseStatus");
  if (status != 200) {
    String reason = result.getString("responseDetails");
    //this sucks that google does not allow you to do very many of these in a row
    println("You are too fast, take a break." + reason);
    return;
  }
  //go one level down in to the results to just get the data not the info about the package
  JSONObject response = result.getJSONObject("responseData");
  println(response);
  //get the arrary of stuff you got back
  JSONArray values = response.getJSONArray("results");
  int vOffset = 20;
  for (int i = 0; i < min(values.size(),3); i++) {
    //pick out the picture information for each picture
    JSONObject thisGuy = values.getJSONObject(i); 
    String r = thisGuy.getString("url");
    int w = thisGuy.getInt("tbWidth");
    int h = thisGuy.getInt("tbHeight");
    println(r + " "+ w + " " + h );
    PImage thisImage = loadImage(r);
    if (thisImage != null) {
      image(thisImage, 0, 0, 640, 460);
    }
    else {
      text((i + 1) + " key", 10, vOffset+13);
      rect(10, vOffset, w, h);
    }
    //make vOffset bigger so we will draw the next picture below this one.
    vOffset  += h;

  }//end for
}

void keyPressed() {
  if (keyCode == RETURN || keyCode == ENTER) {
    background(0);
    queryGoogleImages(query); //execute the query
    query = "";  //clear the query
  } 
  else if (key > 48 && key < 123) {  //letters and numbers only
    query = query + key;
    text(query, 320, 470);  //draw the query so far on the scrren
  }
}

 

Art Accessability and Computational Media

When we started this class we were discussing what computational media is. At that point if had I been asked to define it I wouldn’t be able to and I probably would have babbled something out about computers and art and “stuff”. Even now I don’t think I can articulate it very well and I would say that it’s not entirely a short coming on my part, but that it’s also hard to define succinctly. So to quote the late Justice Stewart, “I know it when I see it.” Beyond that I know that computational media and physical computing are revolutionizing art everyday and that blows my mind and has shaped my concentration at the same time.

Computational media has allowed for a whole new level of interaction in performance/installation art that wasn’t there before. It allows for a higher level of multi-media interaction between performer and audience or the audience performer and art. It also helps make it more accessible to audiences in ways that may not have been often thought about before. For example, using physical computing components like the gloves developed by Imogene Heap, a project that is only in the idea stages in my head would allow Deaf individuals interact with music in a way that would bring enjoy meant to hearing and non-hearing people. This project would allow individuals to paint on a projection (using LED tracking), and would allow them to change color and line quality through manipulation of the gloves. This aspect is the visual and tactilely appealing part for those involved (but especially Deaf individuals). A program similar to this one: http://games.fugly.com/Game/repeating-sound-grid.swf would then take the color and location of the drawing and create a looping sound that would always sound good together (go ahead try the program, it is tuned so that any combination of notes sounds good together unless you just click too many than it just get’s jumbled but whatever) which would be the appealing part for hearing individuals. In other words this allows Deaf people and hearing people to interact in a way previously barred to them, it would create a bridge between the two in art. Without computational media I personally don’t see a way that this project could come into being.

This is just one of the ways that I feel computational media has had a positive impact on the world and why I feel like it should be pursued. It allows for further accessibility for those with different abilities, sometimes in ways which one wouldn’t expect. So though some may fear what the future holds in this field, I for one am looking forward to the future.

It’s Raining, It’s Pouring (Brain Tracking)

So I was busy and just kept my program simple. I just took the color tracking program, made the ellipse into a bucket, and added falling raindrops. If you catch 20 raindrops “Winner!” shows up on the screen. I tried to add sound but I kept getting a NullPointerException so I just am using external sound. I also tried to have an image appear that said “Winner!” instead of just text but it gave the same error. As for the brain, well I just had it laying around and needed something colorful.

Here is the program in action.
Here is the program in action.

And here’s the code, I didn’t clean it up because I was busy, but it works!

//tracking the average pixel makes it shake less
//Sound and winning sign I wanted not working.
import processing.video.Capture;
Capture cam;// regular processing libary
int threshold = 20; //255 is white, 0 is black
int aveX, aveY; //this is what we are trying to find
float objectR =255;
float objectG = 0;
float objectB = 0;
boolean debug = true;
int lastTime, ellapsedTime; //for checking performance
//import ddf.minim.*;
//Minim m;
//AudioPlayer raindropFalling;
//PImage winning;

Raindrop[] rain = new Raindrop[20];
int howManyCaught = 0;
void setup() {
  size(640, 480);
  println(Capture.list());
  cam = new Capture(this, width, height);
  cam.start();

  //m = new Minim(this);
  //raindropFalling = m.loadFile("raindrops-processing.wav",1024);

  for (int i = 0; i<20; i++) {
    rain[i] = new Raindrop();
  }
  //winning = loadImage("http://bbsimg.ngfiles.com/1/24409000/ngbbs50e4c4e6e051d.jpg");
}
void draw() {
  //raindropFalling.play();
  //raindropFalling.rewind();
  if (cam.available()) {
    ellapsedTime = millis() - lastTime;  //find time since last time, only print it out if you press "t"
    lastTime = millis();  //reset timer for checking time next fram
    cam.read();
    int totalFoundPixels= 0;  //we are going to find the average location of change pixes so
    int sumX = 0;  //we will need the sum of all the x find, the sum of all the y find and the total finds
    int sumY = 0;
    //enter into the classic nested for statements of computer vision
    for (int row = 0; row < cam.height; row++) {
      for (int col = 0; col < cam.width; col++) {
        //the pixels file into the room long line you use this simple formula to find what row and column the sit in 

        int offset = row * cam.width + col;
        //pull out the same pixel from the current frame 
        int thisColor = cam.pixels[offset];

        //pull out the individual colors for both pixels
        float r = red(thisColor);
        float g = green(thisColor);
        float b = blue(thisColor);

        //in a color "space" you find the distance between color the same whay you would in a cartesian space, phythag or dist in processing
        float diff = dist(r, g, b, objectR, objectG, objectB);

        if (diff < threshold) {  //if it is close enough in size, add it to the average
          sumX = sumX + col;
          sumY= sumY + row;
          totalFoundPixels++;
          if (debug) cam.pixels[offset] = 0xff000000;//debugging
        }
      }
    }
    image(cam, 0, 0);
    if (totalFoundPixels > 0) {
      aveX = sumX/totalFoundPixels;
      aveY = sumY/totalFoundPixels;
      stroke(255);
      fill(100);
      quad(aveX, aveY, aveX+20, aveY+100, aveX+80, aveY+100, aveX+100, aveY);
    }
  }
  for (int i = 0; i<20; i++) {
    rain[i].drop();
    catchdrop(i);
  }
  if (howManyCaught >= 20) {
    textSize(160);
    fill(0,255,0);
    text("Winner!", 50, 200);
    //image(winning, 640, 480);
  }
}

void catchdrop(int tempNum) {
  if ( dist(aveX+55, aveY, rain[tempNum].x, rain[tempNum].y) <= 50) {
    rain[tempNum].y = -20;
    howManyCaught++;
  }
}

/*void stop() {
  raindropFalling.close();
  m.stop();
  super.stop();
}*/

void mousePressed() {
  //if they click, use that picture for the new thing to follow
  int offset = mouseY * cam.width + mouseX;
  //pull out the same pixel from the current frame 
  int thisColor = cam.pixels[offset];

  //pull out the individual colors for both pixels
  objectR = red(thisColor);
  objectG = green(thisColor);
  objectB = blue(thisColor);
  println("Chasing new color  " + objectR + " " + objectG + " " + objectB);
}
void keyPressed() {
  //for adjusting things on the fly
  if (key == '-') {
    threshold--;
    println("Threshold " + threshold);
  } 
  else if (key == '=') {
    threshold++;
    println("Threshold " + threshold);
  }
  else if (key == 'd') {
    background(255);
    debug = !debug;
    println("Debug " + debug);
  }
  else if (key == 't') {
    println("Time Between Frames " + ellapsedTime);
  }
  else if (key == 'r') {
    howManyCaught = 0;
  }
}

 

 

Piggy Bubbles (Popped by hand, wow, so cool, I’m amazing!)

So I had a busy week so I just tried to incorporate telecommunications into last weeks project. So I just used a pressure sensor and when you press the sensor it’s supposed to pop one bubble. However, I cannot get it to pop only one bubble and I keep trying to fix it but it doesn’t end up working. So in reality it’s supposed to only pop one bubble and only play that bubbles sound. I also feel that my code could be made simpler and had I had the time I’m sure I would have figured it out but like I said I was busy but whatever.

Here's a screen cap of the program running.
Here’s a screen cap of the program running.
import processing.serial.*;
Serial myPort;
int shouldPop;
float tempNumNo;
int tempNum;
boolean letItPop = false;
import ddf.minim.*;
Minim m;
//AudioPlayer s0,s1,s2,s3,s4,s5,s6,s7,s8,s9;
AudioPlayer[] sounds;

//background photo
PImage photo;

//creates bubble array
Bubble[] bubbles = new Bubble[10]; 

void setup() {

  printArray(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, "COM3", 9600);
  myPort.readStringUntil('\n');  

  size(510, 418);
  for (int i=0; i < bubbles.length; i++) {
    bubbles[i] = new Bubble();
  }

  m = new Minim(this);
  sounds = new AudioPlayer[10];
  sounds[0] = m.loadFile("pop1.wav");
  sounds[1] = m.loadFile("moo.wav");
  sounds[2] = m.loadFile("meow.wav");
  sounds[3] = m.loadFile("fart.wav");
  sounds[4] = m.loadFile("elephant.wav");
  sounds[5] = m.loadFile("pop2.mp3");
  sounds[6] = m.loadFile("splash.wav");
  sounds[7] = m.loadFile("pig.wav");
  sounds[8] = m.loadFile("rubberduck.wav");
  sounds[9] = m.loadFile("belch.wav");

  photo = loadImage("http://www.kimballstock.com/pix/PIG/01/PIG-01-RK0133-01P.JPG");
}

void draw() {
  smooth();
  background(photo);
  for (int i=0; i < bubbles.length; i++) {
    bubbles[i].everything();
  }

  tempNumNo = random(0, 10);
  int tempNumAlmost = int (tempNumNo);
  popPop(tempNumAlmost);
}  

void serialEvent(Serial _port) { 
  if (myPort == null) return;
  String input = myPort.readStringUntil('\n');
  if (input != null) {  
    input = input.trim();  
    shouldPop = int(input);   
    println(shouldPop);
  }
}

void popPop(int tempNum) {
  if (shouldPop > 0 && letItPop == false) {
    letItPop = true;

    if (letItPop == true) {
      float soundTemp = random(0, 9);
      int soundNum = int(soundTemp);
      sounds[tempNum].play();
      sounds[tempNum].rewind();
      bubbles[tempNum].bubbleChange();
      letItPop = false;
    }
  }
}

 

Piggy Bubbles

So I wanted to make something with bubbles just to figure out object oriented programming. But I wanted to take it a step further by adding something with popping. Then I thought… WAIT…. I NEED SOUND! So I decided to add a wide variety of sounds with each bubble corresponding to a different sound.

Here's a screen cap of the program running.
Here’s a screen cap of the program running.

And here is my code, the sound files were taken from freesound.org and I’ll put them on my flashdrive so we can hear them.

 

//imports sounds library and sets up sound
import ddf.minim.*;
Minim m;
AudioPlayer s0,s1,s2,s3,s4,s5,s6,s7,s8,s9;
AudioPlayer[] sounds;

//background photo
PImage photo;

//creates bubble array
Bubble[] bubbles = new Bubble[10];

void setup() {
size(510, 418);
bubbles[0] = new Bubble();
bubbles[1] = new Bubble();
bubbles[2] = new Bubble();
bubbles[3] = new Bubble();
bubbles[4] = new Bubble();
bubbles[5] = new Bubble();
bubbles[6] = new Bubble();
bubbles[7] = new Bubble();
bubbles[8] = new Bubble();
bubbles[9] = new Bubble();

m = new Minim(this);
sounds = new AudioPlayer[10];
sounds[0] = m.loadFile("pop1.wav");
sounds[1] = m.loadFile("moo.wav");
sounds[2] = m.loadFile("meow.wav");
sounds[3] = m.loadFile("fart.wav");
sounds[4] = m.loadFile("elephant.wav");
sounds[5] = m.loadFile("pop2.mp3");
sounds[6] = m.loadFile("splash.wav");
sounds[7] = m.loadFile("pig.wav");
sounds[8] = m.loadFile("rubberduck.wav");
sounds[9] = m.loadFile("belch.wav");

photo = loadImage("http://www.kimballstock.com/pix/PIG/01/PIG-01-RK0133-01P.JPG");
}

void draw() {
smooth();
background(photo);
bubbles[0].everything();
bubbles[1].everything();
bubbles[2].everything();
bubbles[3].everything();
bubbles[4].everything();
bubbles[5].everything();
bubbles[6].everything();
bubbles[7].everything();
bubbles[8].everything();
bubbles[9].everything();

}

void stop() {
s1.close();
m.stop();
super.stop();
}

void mouseClicked() {
popDist(0);
popDist(1);
popDist(2);
popDist(3);
popDist(4);
popDist(5);
popDist(6);
popDist(7);
popDist(8);
popDist(9);
}

void popDist(int tempNum) {
if ( dist(mouseX, mouseY, bubbles[tempNum].x, bubbles[tempNum].y) <= bubbles[tempNum].Size) {
float soundNot = random(0,9);
int soundNum = int(soundNot);
sounds[soundNum].play();
sounds[soundNum].rewind();
bubbles[tempNum].bubbleChange();
}
}

and here is the bubble class with the functions:

class Bubble {
  float x;
  float y;
  float Red=random(1, 255);
  float Green=random(1, 255);
  float Blue=random(1, 255);
  float Opaque=random(75, 200);
  float Size=random(50, 90);

  //creates the bubble location
  Bubble() {
    x = random(width);
    y = height;
  }

  void everything() {
    display();
    ascend();
    top();
  }

  //creates the bubble
  void display() {
    noStroke();
    fill(Red, Green, Blue, Opaque);
    ellipse(x, y, Size, Size);
  }

  //makes the bubble rise
  void ascend() {
    y--;
    x = x +random(-2, 2);
  }

  //checks if the bubble reaches the top
  void top() {
    if (y < 0-Size) {
      bubbleChange();
    }
  }

  //changes bubble properties
  void bubbleChange() {
    y = height+Size;
    x = random(width);
    Red = random(1, 255);
    Green = random(1, 255);
    Blue = random(1, 255);
    Opaque = random(75, 200);
    Size = random(50, 90);
  }

}

 

Interactive Screen Saver: NOW WITH 20% MORE INTERACTIVITY

So I just continued to work on my bouncing ball screen saver thingy but I tried to add a new feature. A “stop sign” where if the mouse is in the stop sign the ball would stop bouncing until you move the mouse off of the sign. I got this to work… kinda… but there is one problem. If the ball is moving in a negative direction when it is stopped, then when it begins moving again it moves in the positive direction. I know why this is; however, I have not been able to figure out how to fix it.

Here is the code:

//going to need another variable to take care of the stop problem I think... maybe a for loop? Always goes positive when stopped
float circlex = 0;
float xSpeed = 2;
float xVelocity = 2;
float circley =0;
float ySpeed = 2;
float yVelocity = 2;
float i = 0;
float red = random(255);
float green = random(255);
float blue = random(255);
void setup() {
  size(1360, 700);
  background (75, 100, 200);
}
void mouseClicked() {

  red = random(255);
  green = random(255);
  blue = random(255);
  background (green, blue, red);
  circley = mouseY;
  circlex = mouseX;
  xreversal();
  yreversal();
}

void draw() {

  StopSign();
  shoulditstop();
  stroke(0);
  fill(red, green, blue);
  ellipse(circlex, circley, 20, 20);
  ballspeed();
  if (circlex > width || circlex <= 0) {
    xreversal();
  }
  if (circley > height || circley <= 0) {
    yreversal();
  }
  i = i+1;
  if (i > 2500) {  
    background (blue, red, green);
    i = i - 2500;
  }
  if (circlex <= 0 || circlex >= width+1 || circley <= 0 || circley >= height+1) {
    red = random(255);
    green = random(255);
    blue = random(255);
  }
}

void xreversal() {
  xSpeed = xSpeed * -1;
}
void yreversal() {
  ySpeed = ySpeed * -1;
}

//stop toggle
// giving me problems, debug it!!!!!!!!
void shoulditstop() {
  if (dist(mouseX, mouseY, 680, 350) < 50) {
    speedstop();
  }
  else if (dist(mouseX,mouseY,680,350) >=50 && xSpeed == 0 && ySpeed == 0 ){

    xSpeed = xVelocity;
    ySpeed = yVelocity;
    ballspeed();
  }
}

//stops the ball
void speedstop() {
  xSpeed = xSpeed * 0;
  ySpeed = ySpeed * 0;
}

//Creates stop button
void StopSign() {
  noStroke();
  fill(0);
  ellipse(680, 350, 50, 50);
}

//starts ball again
void ballspeed(){
  circlex = circlex + xSpeed;
  circley = circley + ySpeed;
}

The problem is that to stop the ball xSpeed and ySpeed go to zero. I tried to work around that with the x and y Velocity variables but that didn’t work because they both are positive… So currently I’m lost. Also I think there may be more instances where I could have used functions but I wasn’t sure how to go about that.

Interactive Screen Saver… what?

So I wanted to make something that would allow the bouncing ball to vary speed, direction, and size. However, once I started I tried messing with speed when I would click, but I could not get the effect I wanted and though I knew why I didn’t know how to fix it. But I was able to change direction and location of the ball. So I made a screensaver that is the stereo typical bouncing ball, but if you were to click on the screen the ball would move to where you clicked and would move in the opposite direction of that which it was bouncing in before. I also wanted it to erase after a while after you let it sit for a while or if you click so that it doesn’t get too crazy.

Here is the code:

float circlex = 0;
float xSpeed = 2;
float circley =0;
float ySpeed = 2;
float i = 0;
void setup() {
  size(600, 370);
  background (75, 100, 200);
}
void mouseClicked() {
  background (75, 100, 200);
  circley = mouseY;
  circlex = mouseX;
  xSpeed = xSpeed *-1;
  ySpeed = ySpeed *-1;

}

void draw() {

  stroke(0);
  fill(200, 40, 10);
  ellipse(circlex, circley, 20, 20);
  circlex = circlex + xSpeed;
  circley = circley + ySpeed;
  if (circlex > width || circlex <= 0) {
    xSpeed = xSpeed * -1;
  }
  if (circley > height || circley <= 0) {
    ySpeed = ySpeed * -1;
  }
  i = i+1;
  if (i > 2500){  
    background (75, 100, 200);
    i = i - 2500;
   }

}

And I made it color-changing too!

float circlex = 0;
float xSpeed = 2;
float circley =0;
float ySpeed = 2;
float i = 0;
float red = random(255);
float green = random(255);
float blue = random(255);
void setup() {
  size(600, 370);
  background (75, 100, 200);
}
void mouseClicked() {

  red = random(255);
  green = random(255);
  blue = random(255);
  background (75, 100, 200);
  circley = mouseY;
  circlex = mouseX;
  xSpeed = xSpeed *-1;
  ySpeed = ySpeed *-1;
}

void draw() {

  stroke(0);
  fill(red, green, blue);
  ellipse(circlex, circley, 20, 20);
  circlex = circlex + xSpeed;
  circley = circley + ySpeed;
  if (circlex > width || circlex <= 0) {
    xSpeed = xSpeed * -1;
  }
  if (circley > height || circley <= 0) {
    ySpeed = ySpeed * -1;
  }
  i = i+1;
  if (i > 2500) {  
    background (75, 100, 200);
    i = i - 2500;
  }
  if (circlex <= 0 || circlex >= width || circley <= 0 || circley >= height) {
    red = random(255);
    green = random(255);
    blue = random(255);
  }
}

 

I Can Draw Flowers (And Other Daily News) (AKA Flower Power)

I decided just to get used to drawing with the simplest idea I could think of. A flower on some grass with some clouds. And that is what I did. As you can see in the picture:

This is a flower.
This is a flower.

I wanted to try working with arcs and that’s what I did. I was going to add more but then I decided why mess with a perfectly beautiful drawing. As far as the other daily news, well I lied about that, you can always ask me about that later if you so choose.

Now for the fun part! Here’s my code:

size(600,600);
background(0,150,255);

stroke(255);
fill(255);
ellipse(50,50,200,200);
ellipse(200,30,200,150);
ellipse(350,50,200,250);
ellipse(500,20,200,75);
ellipse(575,45,200,160);

stroke(0);
fill(255);
arc(50,50,100,100,0,PI+QUARTER_PI,OPEN);
arc(250,30,75,75,0-QUARTER_PI,PI-QUARTER_PI,OPEN);
arc(400,10,50,50,PI-QUARTER_PI,PI+QUARTER_PI,OPEN);
arc(575,30,60,60,0-QUARTER_PI,PI-QUARTER_PI,OPEN);

stroke(0,50);
fill(0,255,0);
ellipse(450,425,100,30);

stroke(0,90);
line(415,425,490,425);
line(415,425,420,430);
line(415,425,420,420);
line(425,425,435,435);
line(425,425,435,415);
line(435,425,445,435);
line(435,425,445,415);
line(445,425,455,435);
line(445,425,455,415);
line(455,425,465,435);
line(455,425,465,415);
line(465,425,475,435);
line(465,425,475,415);
line(475,425,480,430);
line(475,425,480,420);
line(485,425,487,427);
line(485,425,487,423);

stroke(0,255,0);
fill(0,255,0);
rect(380,300,25,400);

stroke(200,40,255);
fill(200,40,255);
ellipse(395,320,150,150);

stroke(100,0,255,50);
fill(100,0,255,75);
ellipse(395,320,100,20);

stroke(255,0,0,50);
fill(255,0,0,75);
ellipse(395,320,20,100);

stroke(0,50);
fill(0,50);
ellipse(395,320,25,25);

stroke(50,255,50);
fill(50,255,50);
rect(0,500,600,100);

 

And there you have it folks!

ASL to LED (AKA American Sign LED-uage)

For my project I wanted to combine American Sign Language and what we’ve been working on in class. So I decided to translate the sign language alphabet into Morse code (done through flashes on an LED). I used two flex sensors, one on my thumb and one on my forefinger to do so. For this project I only did the letters A through H because to go past that I would need another flex sensor as well as an accelerometer to accurately transmit the letters. However, for A through H only the thumb sensor would technically be needed, but for accuracy (and I bought the thing so I figured why not) I used the one on the forefinger as well. It took me a while to figure out exactly how to code it and I feel like there would be a way to shorten down the code, but I did not know how at this point. But the biggest time consumer was figuring out the sensor ranges needed to code. And here is the video explaining some of this and a demonstration.

//all the alphabet used to monitor my accuracy of handshapes
// to make sure it was picking up the right letter.
int A = 1;
int B = 2;
int C = 3;
int D = 4;
int E = 5;
int F = 6;
int G = 7;
int H = 8;
int dot = 500;
int dash = 1000;
int pause = 200;
void setup(){
  pinMode (8, OUTPUT);
  Serial.begin(9600);

}

void loop(){
  int input = analogRead(A1);
  int inputF = analogRead (A2);
  int flexFore = map (inputF, 320, 557, 0, 100);
  int flexNumbers = map(input, 360, 540, 0, 100);

  if (flexNumbers >= 90 && flexNumbers <=100){
    if (flexFore >= 25 && flexFore < 35){
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
      Serial.println(A);
    delay(3000);
    }
  }

   else if (flexNumbers >= 80 && flexNumbers <90){
     if (flexFore >=80 && flexFore <95) {
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
       Serial.println(H);
    delay(3000);
     }
  }
  else if (flexNumbers >=70 && flexNumbers <80) {
    if (flexFore >= 80 && flexFore <95){
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);  
    Serial.println(G);
    delay(3000);
    }
  }
  else if (flexNumbers >=60 && flexNumbers <70){
    if (flexFore >=50 && flexFore <60){
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);  
    Serial.println(C);
    delay(3000);
    }
  }
  else if (flexNumbers >=50 && flexNumbers <60) {
    if (flexFore >=30 && flexFore <40){
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
      Serial.println(F);
    delay(3000);
    }
  }
  else if (flexNumbers >=40 && flexNumbers <50) {
    if (flexFore >= 90 && flexFore <=100){
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
      Serial.println(D);
    delay(3000);
    }
  }
  else if (flexNumbers >=30 && flexNumbers <40){
    if (flexFore >=90 && flexFore <=100){
    digitalWrite (8, HIGH);
    delay (dash);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
    delay (pause);
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
      Serial.println(B);
    delay(3000);
    }
  }
  else if (flexNumbers <30){
    if (flexFore >= 0 && flexFore < 20){
    digitalWrite (8, HIGH);
    delay (dot);
    digitalWrite (8, LOW);
      Serial.println(E);
    delay(3000);
    }
  }

}

 

Don’t Forget Your Keys (Part 2)

The switch is activated.
The switch is activated.

So to be 100% honest I forgot to take a picture of my circuit before I disassembled it and I just didn’t feel making it again just to take a picture. However, because my project this week tied in to last weeks switch I just reused that picture. So I’ll just describe everything and I swear it works. The idea was that if the keys were on the hook and the door was closed one LED would flash on and off. If the key was on the hook but the door was opened the LED would stay on constantly and a buzzer would go off. If the key wasn’t on the hook though nothing would happen. To keep things simple though I just used two panic button switches instead of using the key and door switches. Below is the code for this. Also I couldn’t get the buzzer to work so I just used two LED lights instead.

void setup(){
pinMode(8,INPUT);
pinMode(7,OUTPUT);
pinMode(13,INPUT);
pinMode(12,OUTPUT);
}
void loop(){
if (digitalRead(8) == HIGH){
if (digitalRead(13)==HIGH){
digitalWrite(7,HIGH);
digitalWrite(12,LOW);
delay(1000);
digitalWrite(7,LOW);
digitalWrite(12,LOW);
delay(1000);
}
else {digitalWrite(7,HIGH);
digitalWrite(12,HIGH);}
}
else {digitalWrite(7,LOW);
digitalWrite(12,LOW);
}
}

Water Weight (or Don’t Forget Your Keys!)

This is a close up of the set up.
This is a close up of the set up.

Full setup with the switch
Full setup with the switch
The switch is activated.
The switch is activated.

From the beginning I wanted to do something with water for my switch. However, I wasn’t sure how to make it a true switch at first. While chatting with friends about this project one of them gave me the idea to displace the water somehow. This idea led me to this setup. The circuit itself has two wires going into a cup of salt water. One under the water level and another just above. The switch is a lever (in this case a hanger) with equal weights placed on either side. When weight, such  as keys, are added to the side above the water, the weight dips into the water, raising the water level enough to complete the circuit. By giving a visual signal you’re more likely to remember to put your keys on the hook and take them with you making it less likely that you’ll lose your keys.