Description
In this lab we explored the functionality of two new analog sensors: the photocell (phot) and force sensistive resistor (FSR). A photocell works by converting varying intensity of light into variable resistance. A force sensitive resistor works by converting varying forces applied to sensor into corresponding variable resistance. These sensors reinforce the concept of transduction, in which one form of energy (i.e. light or physical force) is converted into another form of energy (i.e. electricity). This lab also introduced a new tool enabling the creation of much more interesting graphical interfaces that can be utilized in conjunction with the senors and the Arduino.
This lab expanded on the circuit we constructed during the last lab period. To learn about how the phot and FSR work, I used an Arduino Uno to read the analog input from different types of sensors. The output was evidenced through the 3 parallel LED circuit previously described. I used photocells and the FSR in place of the Pots from the last lab to induce different outputs. Following this, I explored some of the capabilities of Processing by loading two different example sketches.
For the coding portion of the homework, I took a creative spin on generating an intersting visual output that is influenced by an analog sensor input. I created a game where the controller is an analog sensor. In this game, the objective is to navigate a ball across the entire screen while avoiding the obstacles. If the user is successful, they will get a point. When an obstacle is hit, however, the ball will reset to the beginning of that "level" and the user will lose a point. Upon successful completion of each level, the obstacles will randomly reset and the ball will respawn at the beginning of the new frame. Furthermore, the ball and the obstacles will change color and brightness, adding an engaging aesthtic element to the game. The colors are also randomly selected, and are designed so that the ball will be the negative color of the obstacles (or contrast sharply). The Processing and Arduino code can be found below.
For the mechanical portion of the homework, I contructed a force-sensing coaster. I sandwiched the FSR between two cardboard coasters in an attemt to distribute the physical force experienced by the FSR when the force is exerted on the sensor. The set-up does an adequate job of distributing the forces applied to the top coaster, however it is not as well distributed as I would have hoped. I think that with stiffer material, forces would have been more well distributed.
Components
1- Arduino Uno Microcontroller
1- Breadboard
3- 220Ω Resistors
2- 10KΩ Resistors
3- Light Emitting Diodes (LEDs) (Red, Green, Blue)
1- USB Cable
1- Apple Laptop Computer (Mac OSX)
1- Potentiometer
1- Force Sensitive Resistor (FSR)
2- Photocells (Phot)
Code
Aruduino Sketch:
/* Stuart Altman
Lab 4 Analog input to control processing GUI)
(Adapted Open Source "Graph" processing example found online originally by David A. Mellis)
*/
void setup() {
// initialize the serial communication:
Serial.begin(9600);
}
void loop() {
// send the value of analog input 0:
Serial.println(analogRead(A0));
// wait a bit for the analog-to-digital converter
// to stabilize after the last reading:
delay(2);
}
Processing Code:
/* Stuart Altman
Lab 4 Homework (Adapted Open Source "Graph" processing example found online originally by David A. Mellis)
Created a game where you navigate a ball across a screen while avoiding the obstacles.
Control the ball using a variable input resistor (FSR, Pot, or Phot).
Connect this to an analog input and read the serial values (reference arduino sketch example submitted with lab).
When an obstacle is hit, the game resets and the counter will update by subtracting a point.
Each frame change is accompanied by color changes with respect to the ball and the obstacles.
Obstacles reset in random locations.
*/
import processing.serial.*;
Serial myPort; // The serial port
int xPos = 1; // horizontal position
int n = 170;
int n1 = 56;
int n2 = 80;
int n3 = 178;
int n4 = 278;
int n5 = 300;
int n1a = 60;
int n2a = 132;
int n3a = 198;
int n4a = 244;
int c1 = 255; //color variables to be randomized later
int c2 = 255;
int c3 = 255;
int count = 0; //counter varible for level
void setup () {
// set the window size:
size(1000, 400);
// List all the available serial ports
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my Arduino, so I open Serial.list()[0].
myPort = new Serial(this, Serial.list()[0], 9600);
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
// set inital background:
background(0);
}
void draw () {
// everything happens in the serialEvent()
fill(255, 255, 255); //make text color white
text(count, 25, 385); //counter appears on display
textSize(32); // increase font text size
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil('\n');
if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
// convert to an int and map to the screen height:
float inByte = float(inString);
inByte = map(inByte, 0, 1023, 0, height);
// draw the ellipsoid:
fill(c2,c3,c1);
ellipse(xPos, height - inByte, 22, 25);
// draw the obstacles
fill(c1,c2,c3);
rect(130,n,30,30);
rect(200,n1,30,30);
rect(300,n2,30,30);
rect(400,n3,30,30);
rect(500,n4,30,30);
rect(600,n5,30,30);
rect(700,n1a,30,30);
rect(800,n2a,30,30);
rect(900,n3a,30,30);
rect(970,n4a,30,30);
//reset the ball if you hit an obstacle
if (height-inByte <= n+35 && height-inByte >= n-15 && xPos <= 130+15 && xPos >= 130-30) {
xPos=0;
background(0);
count = count - 1; //reset counter for hitting obstacle
}
if (height-inByte <= n1+35 && height-inByte >= n1-15 && xPos <= 200+15 && xPos >= 200-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n2+35 && height-inByte >= n2-15 && xPos <= 300+15 && xPos >= 300-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n3+35 && height-inByte >= n3-15 && xPos <= 400+15 && xPos >= 400-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n4+35 && height-inByte >= n4-15 && xPos <= 500+15 && xPos >= 500-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n5+35 && height-inByte >= n5-15 && xPos <= 600+15 && xPos >= 600-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n1a+35 && height-inByte >= n1a-15 && xPos <= 700+15 && xPos >= 700-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n2a+35 && height-inByte >= n2a-15 && xPos <= 800+15 && xPos >= 800-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n3a+35 && height-inByte >= n3a-15 && xPos <= 900+15 && xPos >= 900-30) {
xPos=0;
background(0);
count = count - 1;
}
if (height-inByte <= n4a+35 && height-inByte >= n4a-15 && xPos <= 1000 && xPos >= 1000-30) {
xPos=0;
background(0);
count = count - 1;
}
// at the edge of the screen, go back to the beginning, randomize obstacle locations, increment counter:
if (xPos >= width) {
xPos = 0;
n = (int)random(401);
n1 = (int)random(401);
n2 = (int)random(401);
n3 = (int)random(401);
n4 = (int)random(401);
n5 = (int)random(401);
n1a = (int)random(401);
n2a = (int)random(401);
n3a = (int)random(401);
n4a = (int)random(401);
c1 = (int)random(256);
c2 = (int)random(256);
c3 = (int)random(256);
background(0);
count= count+1; //increment the counter after making it through a wave
}
else {
// increment the horizontal position:
xPos++;
}
}
}
Images
- Login to post comments