The concept is as follows. A person would walk into a small dark booth and be prompted to relinquish fears by exploring and opening the drawers and the door of a cabinet that is symbolic of our psyche. I intended to make it an emotional experience, thus I constructed a small booth,which would create darkness and allow for a personal experience. Large images would be projected right in front of the person and they would be extending all the way to the ceiling. I wanted the images to be large on the screen because that is the way most things look like to us when we are children – the time when we acquire our most significant fears. In order to become our best true selves we need to release those fears or as they say “master” them, which is something I like doing very much.
The first fear is represented by the hands and grains of rice. It’s the fear of not being able to sustain our physical body.
The second fear is symbolized in the photo of an abandoned teddy bear. It’s a fear of being unsafe – physically, economically or being abandoned.
The third fear is the fear of not belonging or not being loved and the image I chose is pretty straight – forward: a child being yelled at or whose presence is being disregarded .
The forth fear is of not being good enough and has to do with our self-esteem. It is represented by a towering over the viewer nun, just like any figure of authority in our childhood that suggested we might be not good enough for this or that or just to be.
The fifth fear is let out when the viewer opens the door of the cabinet. It’s the fear of getting old and ultimately dying. The viewer looks into the mirror inside of the cabinet when the door is open and hidden in the jewelry camera identifies the viewer’s eyes. Processing sketch runs and puts a semi-transparent image of a senior woman on top of the viewer’s video and outputs it as a projection onto the screen in front of the viewer. The sketch runs only when the viewer is looking at themselves in the mirror. Due to transmission delay he/she can see on the big screen how their image changes from their current age to very old one.
Physical Computing and ICM
Arduino Sketch
const int ledPin0 = 9;
const int ledPin1 = 10;
const int ledPin2 = 8;
const int ledPin3 = 7;
void setup() {
Serial.begin(9600);
// LED will be the output
pinMode(ledPin0,OUTPUT);
pinMode(ledPin1,OUTPUT);
pinMode(ledPin2,OUTPUT);
pinMode(ledPin3,OUTPUT);
}
void loop() {
// byte brightness;
// if(Serial.available()){
// // read the most recent byte
// brightness=Serial.read();
// // set the brightness of the LED
// analogWrite(ledPin0,brightness);
// analogWrite(ledPin1,brightness);
// }
int sensorValue = analogRead(A0)/4;
analogWrite(ledPin0,sensorValue);
Serial.print(sensorValue);
Serial.print(",");
sensorValue = analogRead(A1)/4;
analogWrite(ledPin1,sensorValue);
Serial.print(sensorValue);
Serial.print(",");
sensorValue = analogRead(A2)/4;
analogWrite(ledPin2,sensorValue);
Serial.print(sensorValue);
Serial.print(",");
sensorValue = analogRead(A3)/4;
analogWrite(ledPin3,sensorValue);
Serial.println(sensorValue);
}
Processing Sketch
1) Sketch for Drawers that changes pictures on the screen
// my sliding Pot's range is 0 to 1023
void setup() {
Serial.begin(9600); // initialize serial communications
}
void loop()
{
int analogValue = analogRead(A0); // read the analog input
Serial.println(analogValue); // print it
}
2) Controlled LED with 1 Slide Pot
const int ledPin = 9; // pin that the LED is attached to
int analogValue = 0; // value read from the pot
int brightness = 0; // PWM pin that the LED is on.
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
// declare the led pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop() {
analogValue = analogRead(A0); // read the pot value
brightness = analogValue /4; //divide by 4 to fit in a byte
analogWrite(ledPin, brightness); // PWM the LED with the brightness value
Serial.println(brightness); // print the brightness value back to the serial monitor
}
November 29, 2011
Refreshed Serial Communication in memory
1. The sensor is set. Open serial communication port and pulse electric signal to it. You’ll see gibberish characters in Serial Monitor and that’s ok for now.
void setup() {
Serial.begin(9600);
}
void loop() {
int analogValue = analogRead(A0) /4; // read the pot value
Serial.write(analogValue); // print the value in the serial monitor as a binary value
}
2. Processing Sketch that draws a line in correspondence with the Potentiometer’s changing resistance
// lets see how the sensor translates physical changes into digital changes
// global xPos
float xPos = 0;
float yPos;
import processing.serial.*;
//create an instance of the library in a global variable
Serial myPort;
//In the setup(), set the window size, and use the serial library to get a list of the serial ports:
void setup () {
size(800, 600); // window size
// List all the available serial ports
println(Serial.list());
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
//background(0);
}
void draw () {
// nothing happens in draw. It all happens in SerialEvent()
}
void serialEvent (Serial myPort) {
// make a variable and put an incoming bite into it
int inByte = myPort.read();
float yPos=height-inByte;
// print it:
println(inByte);
stroke(255,random(0,255),0);
line(xPos,height,xPos,yPos);
// at the edge of the screen, go back to the beginning:
if (xPos >= width) {
xPos = 0;
background(0);
// clear the screen by resetting the background:
}
else {
// increment the horizontal position for the next reading:
xPos++;
}
}
Lets Move a Ball using Slide Pot – lovely, it works!
Here is the code for the ball move
// lets see how the sensor translates physical changes into digital changes
// global xPos
float xPos = 250;
float yPos;
import processing.serial.*;
//create an instance of the library in a global variable
Serial myPort;
//In the setup(), set the window size, and use the serial library to get a list of the serial ports:
void setup () {
smooth();
size(800, 500); // window size
// List all the available serial ports
println(Serial.list());
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw () {
background(#081640);
stroke(255,0,0);
fill(255,0,0);
ellipse(xPos,yPos*2,50,50);
// nothing happens in draw. It all happens in SerialEvent()
}
void serialEvent (Serial myPort) {
// make a variable and put an incoming bite into it
int inByte = myPort.read();
yPos=inByte;
// print it:
println(inByte);
// float yPos=height-inByte;
// at the edge of the screen, go back to the beginning:
}
November 30, 2011
1) Worked out Processing Sketch that detects face in the camera and starts drawing animation. Animation changes in accordance with the distance between the face and the camera. When the user looks away the animation disappears.
import hypermedia.video.*;
import java.awt.Rectangle;
OpenCV opencv;
// contrast/brightness values
int contrast_value = 0;
int brightness_value = 0;
int framesSinceFace = 0;
float deg = 0;
void setup() {
size( 320, 240 );
opencv = new OpenCV( this );
opencv.capture( width, height ); // open video stream
opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT ); // load detection description, here-> front face detection : "haarcascade_frontalface_alt.xml"
// print usage
println( "Drag mouse on X-axis inside this sketch window to change contrast" );
println( "Drag mouse on Y-axis inside this sketch window to change brightness" );
}
public void stop() {
opencv.stop();
super.stop();
}
void draw() {
// grab a new frame
// and convert to gray
opencv.read();
//opencv.convert( GRAY );
opencv.contrast( contrast_value );
opencv.brightness( brightness_value );
// proceed detection
Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );
// display the image
image( opencv.image(), 0, 0 );
// draw face area(s)
noFill();
stroke(255,0,0);
if(faces.length ==0){
ellipse(50, 50, 10, 10);
framesSinceFace++; //if there is no face add 1 to the timer.
}else{
framesSinceFace = 0; // we saw a face, reset the timer.
}
println(framesSinceFace);
for( int i=0; i<faces.length; i++ ) {
// rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height );
pushMatrix();
translate(faces[i].x+(faces[i].width/2), faces[i].y+(faces[i].height/2));
rotate(radians(deg));
rectMode(CENTER);
rect(0, 0, 100, 100);
deg += faces[i].width*faces[i].height/300;
popMatrix();
rectMode(CORNER);
}
}
/**
* Changes contrast/brigthness values
*/
void mouseDragged() {
contrast_value = (int) map( mouseX, 0, width, -128, 128 );
brightness_value = (int) map( mouseY, 0, width, -128, 128 );
}
2) Soldered wires to Pot's outputs, got cabinet and cut out an opening to fit a slide pot into it.
Questions: how best to make LED flashlight and where to get semi-transparent mirror fast
Ingredients:
- screen for back projecting (Canal Plastics)
- flashlight for drawers
- smoke?
- filters for drawers
- semi-transparent mirror
- motor for rotating necklaces and pulling them up
- fishing line to go through necklaces
- photocell (already have) for the door that starts the motor to spin the necklaces
- watch Never Ending Story
1) Order Parts: 4 linear potentiometers and 2 rotary ones – check
2) Make Drawers
2.1. Insert Sensors – when they arrive
3) Program Arduino to read sensors and talk to Processing
4) Write a program for Processing that moves a circle on the screen in accord with the movement of the drawers
5) Insert light projection into the drawer and set up 2 projectors to create the aforementioned illusion
6) Create animations for Processing
7) Add another set of sensors that will change the images on the screen depending on where the person stands on the stage
Calendar:
Project due: December 7, that’s 2 weeks from now
Wednesday, Nov. 23:
1) Go over Image chapters in Processing book
2) Meet with Processing Residents:
- finalize how images will be changed on the screen through interaction with humans: whether to use a proximity sensor (if a person stands in front of the sensor, “studying at the screen”, the image starts to change), or simply pressure sensors in different parts of the stage
- ask questions about 3D effects
3) Present final project in ICM and P.Comp
Progress:
1. Drawers will be triggering swapping .png image files with transparency .
2. Mirror will be placed inside of the drawer and projection will be shone on it. See if that reflects images together with the light that comes out of the drawer.
3. Checked out Pico projector for 2 days, will play at home over the holidays.
4. Installed CV Processing library and Downloaded example for face detection.
Image on the screen will dissolve into another when the face of an onlooker is detected by inserting an if statement:
if (faces.length > 0) {
image (image1,width/2,height/2)
} else {
image (image2, width/2,height/2) ;
Here is the simple face detection code:
OpenCV opencv;
// contrast/brightness values
int contrast_value = 0;
int brightness_value = 0;
void setup() {
size( 320, 240 );
opencv = new OpenCV( this );
opencv.capture( width, height ); // open video stream
opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT ); // load detection description, here-> front face detection : "haarcascade_frontalface_alt.xml"
// print usage
println( "Drag mouse on X-axis inside this sketch window to change contrast" );
println( "Drag mouse on Y-axis inside this sketch window to change brightness" );
}
public void stop() {
opencv.stop();
super.stop();
}
void draw() {
// grab a new frame
// and convert to gray
opencv.read();
opencv.convert( GRAY );
opencv.contrast( contrast_value );
opencv.brightness( brightness_value );
// proceed detection
Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );
// display the image
image( opencv.image(), 0, 0 );
// draw face area(s)
noFill();
stroke(255,0,0);
for( int i=0; i<faces.length; i++ ) {
rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height );
}
}
/**
* Changes contrast/brigthness values
*/
void mouseDragged() {
contrast_value = (int) map( mouseX, 0, width, -128, 128 );
brightness_value = (int) map( mouseY, 0, width, -128, 128 );
}
Thursday – Saturday, 11/24-11/25
1) Read up on serial communication
2) Build model with any sensors that are available
3) Write Arduino code
4) Move a circle on the screen with a drawer
5) Build drawers
6) Create PNG sequences
7) Create Camera tracking – image dissolve program
The main challenge in serial communication using several sensors is for the devices to understand which value belongs to which sensor as data is being constantly transmitted through serial port . So in addition to us telling the devices when to start reading data and in which order, we also need to find a way to tell our Processing program how to parse the long strings of data it is getting from the serial buffer.
There are 2 methods that we will go over in this lab: punctuation and “handshake” (call and response).
2. Lab – Media Controller
2.1. Prepare parts
Arduino, Breadboard, Wires, 2 analog sensors: photocell and pressure sensor, 1 button switch
2. 2. Set up the breadboard and Arduino Micro Controller (MC)
2.3. Read and send data from one sensor using Arduino
void setup(0) {
Serial.begin(9600);
}
void loop() {
int analogValue = analogRead(A0)/4;
Serial.println(analogValue);
}
Once I upload this program to MC, I see in serial monitor numbers running from 0 to 255. The numbers come up in this format because Serial.println() is a special function that formats values from sensors as ASCII – encoded DECimals with a linefeed at a carriage return at the end. Serial Monitor, in turn, assumes it should show us ASCII – encoded values.
When I changed Serial.println to Serial.write, I saw a bunch of jibberish running in the Serial Monitor instead of numbers 0-255. That’s happening because Serial.write () command doesn’t format bytes with ASCII-encoding. What we see is raw binary values of the bytes. Serial Monitor receives bytes and still assumes it should show us ASCII-encoded values though.
Note: if analog value from sensor is 32, how many bytes of information gets sent? Correct answer is 4. 1st byte for “3″, 2nd byte for “2″, 3rd byte for cursor to move onto another line, 4th – to tell the cursor to move all the way to the left.
2. 4. Send Data In Many Formats ( just so we can see all available formats)
We upload Arduino Code to the Arduino MC
void setup() {
// open serial communications at 9600 bps
Serial.begin(9600);
}
void loop() {
// read the analog input, divide by 4:
int analogValue = analogRead(A0) /4;
// print in many formats:
Serial.write(analogValue); // Print the raw binary value analogValue
Serial.print('\t'); // print a tab
Serial.print(analogValue, BIN); // print the ASCII encoded binary analogValue
Serial.print('\t'); // print a tab
Serial.print(analogValue, DEC); // print the ASCII encoded decimal analogValue
Serial.print('\t'); // print a tab
Serial.print(analogValue, HEX); // print the ASCII encoded hexadecimal analogValue
Serial.print('\t'); // print a tab
Serial.print(analogValue, OCT); // print the ASCII encoded octal analogValue
Serial.println(); // print a linefeed and carriage return
}
and we get the following reading in the serial monitor ( 4 types of data representation: raw binary value, then the ASCII-encoded binary value, then the ASCII-encoded decimal, hexadecimal, and octal values.):
Close Up of Serial Monitor:
â 11100010 226 E2 342
á 11100001 225 E1 341
á 11100001 225 E1 341
á 11100001 225 E1 341
à 11100000 224 E0 340
à 11100000 224 E0 340
ß 11011111 223 DF 337
ß 11011111 223 DF 337
ß 11011111 223 DF 337
2.5.2. We see that we are getting some values but all in one row, separated by comma. Which value belongs to which sensor? If we are going to affect media using Processing, Prosessing needs to know which sensor is giving what values. In order to parse this data, 2 methods can be employed: punctuation and “Handshake”.
a) Punctuation: we modify our Arduino sketch like so:
const int switchPin = 2; // digital input
void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital input:
pinMode(switchPin, INPUT);
}
void loop() {
// read the sensor:
int sensorValue = analogRead(A0);
// print the results:
Serial.print(sensorValue);
Serial.print(",");
// read the sensor:
sensorValue = analogRead(A1);
// print the results:
Serial.print(sensorValue);
Serial.print(",");
// read the sensor:
sensorValue = digitalRead(switchPin);
// print the last reading with a println() so that
// each set of three readings prints on a line by itself:
Serial.println(sensorValue);
}
Once we upload this program to MC, we will see data at the bottom of Arduino sketch window coming formatted in 3 columns:
453, 675, 0
567,876, 0
or
analog1, analog2, switch
analog1, analog2, switch
Now we have data coming in and we can read values of each sensor in a different program such as Processing.
2.5.2. 1. We need to write program for Processing now to be getting sensors’ values that we saw at the bottom of Ardwino’s sketch screen from serial buffer and we need to tell Processing what we want it to do with those values. we are going to attempt to control a circle on the Processing sketch screen with our sensors.
import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial port
float bgcolor=0;
float fgcolor;
float xpos, ypos;
boolean firstContact = false;// whether we've heard from MC
void setup() {
size(500,500);
// 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 module, so I open Serial.list()[0].
// Change the 0 to the appropriate number of the serial port
// that your microcontroller is attached to.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil('\n');
}
void draw() {
background(bgcolor);
fill(fgcolor);
// Draw the shape
ellipse(xpos, ypos, 40, 40);
}
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
if (myString != null) {
println(myString);
}
myString = trim(myString);
// split the string at the commas
// and convert the sections into integers:
int sensors[] = int(split(myString, ','));
// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
// make sure there are 3 values before you use them:
if ( sensors.length > 1) {
xpos = map(sensors [0], 0, 500, 0, width);
ypos = map(sensors [1], 25, 5, 0, height);
// the switch values are 0 and 1. This makes them 0 and 255:
fgcolor = sensors[2] * 255;
}
}
b) “Handshake”
With this method we send one set of values at a time, instead of sending data repeatedly. We modify Arduino and Processing codes: for Arduino to listen when Processing is ready for more data and give new string of date only then.
Arduino program:
const int switchPin = 2;// declare switchPin variable's value
void setup() {
Serial.begin(9600);
pinMode(switchPin, INPUT);
establishContact();
}
void loop () {
if (Serial.available() > 0) {
int inByte = Serial.read();
}
// read sensor and print results
int sensorValue = analogRead(A0);
Serial.print(sensorValue);
Serial.print(",");
sensorValue = analogRead(A1);
Serial.print(sensorValue);
Serial.print(",");
sensorValue = digitalRead(switchPin);
Serial.println(sensorValue);
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.println("hello");
delay(300);
}
}
Processing Program:
import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial port
float bgcolor=150;
float fgcolor;
float xpos, ypos;
boolean firstContact = false;// whether we've heard from MC
void setup() {
background(bgcolor);
size(500,500);
// 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 module, so I open Serial.list()[0].
// Change the 0 to the appropriate number of the serial port
// that your microcontroller is attached to.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil('\n');
}
void draw() {
fill(fgcolor);
// Draw the shape
ellipse(xpos, ypos, 40, 40);
}
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you get any bytes other than the linefeed:
if (myString != null) {
//println(myString);
myString = trim(myString);
// if you haven't heard from the microcontroller yet, listen
if (firstContact == false) {
if(myString.equals("hello")) {
myPort.clear(); // clear the serial buffer
firstContact = true; // you've heard first contact from MC
myPort.write ('A'); // ask for data
}
}
// if you have heard from MC, proceed:
else {
// split the string at the commas
// convert the sections into integers:
int sensors[] = int(split(myString, ','));
// print out values you've got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor" + sensorNum + ":" + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensors.length >1) {
xpos = map(sensors[0], 0, 580,0,width);
ypos = map(sensors[1], 100,23,0, height);
fgcolor = sensors[2] * 255;
}
}
// after you parse the data, ask for more:
myPort.write('A');
}
}
2.6. After we upload Arduino program to MC and run Processing program we are able to control the ball on the sketch’s screen with our sensors: photocell, FSR and a digital switch (button):
3. Reading: Visual Intelligence
Phantom limb – a sensation of an absent limb that feels as real as if the limb were there. It is widespread among amputees.When touched in the area, person experiences 2 sensations: one from skin contact and another is a referred sensation, the feeling of the phantom hand being touched as well.
Psychologist Vilyanur S. Ramachandran studied it. He mapped the phantom limb on the body of the amputee. It turned out that the person had 3 maps of the absent limb on his body: one 6 centimeters above the stump, one 13 centimeters above the stump and one on his face. If the amputee was touched in the area of his face where hand was mapped, he felt sensation of the skin on the face and also the feeling of being touched on his thumb, for example. Specific places are different for all amputees.
Fingers were mapped on the areas where they were sensed by the amputee, and when researcher asked the amputee to supernate or pronate his hand, the maps on his body were re-measured and it was shown that maps shifted in the same direction as the rotation was prescribed.
How does this relate to “Visual Intelligence”?
Everything that you see, smell, feel and taste you construct. You are the constructing genius.
I used to think, like many others, as the author notes, that I might be constructing what I smell, feel or see, but touch would be the surest thing of being the result of none-construction. I see a table, I smell the wood, I may be imagining it but once I touch it, I can be sure that table in front of me does exist. Well, no. The author argues that touch is a sensation that is also constructed by me. I create the entire “feel”. The evidence of this is the phantom limb: one continues constructing the feel even when there is no physical limb present. Amputees, having had water trickle down their face where the area of the hand was mapped were pointing into the empty space where their hand was supposed to be.
When you construct 2 equally good interpretations, you alternate between 2 of them. That is what’s happening in somatosensory cortex of our brain. If you stimulate it in the brain, patients feel being touched in specific part of their body. Some part of the body have more, others – less of the area corresponding to them in the brain. The hand has a lot bigger area than torso. The area devoted to the hand is between the areas of face and arm. If the hand is amputated then it can’t send signals to its bits of cortex. In other words, the sensor is absent that needs to be sending data to “hand” are of the cortex. Does data stop being transmitted?
It turns out that data doesn’t stop being transmitted. Amputee receives data that was supposed to be sensed by hand through arm and face. Face and arm regions in the cortex “invade” the hand’s region. Very interesting. That makes me think: is our body just sort of a magnetic field, drawn to some core of gravity, a “body” of information in the shape of our body?
This process works backwards. When someone gets a stroke, a part of their brain is damaged. They feel that their limb does not sense anything. What turns out to be true is that the limb still has sensory functions, it doesn’t “break”, what “breaks” is the function that is responsible for making connections of the sensory data and constructing it into a recognizable object.
Because we construct what we feel, there is endless application to this discovery in interactive telecommunications. The research is underway at the UCL (which makes me immensely happy and I’d love to contribute to it somehow) that will allow surgeons to train not on animals (one of my biggest issues in this life) but using virtual human bodies in 3D environment while wearing special tactile gloves that will allow them to get appropriate feelings of pressure, resistance, cutting. For the same reason, I want to learn more about Magnetic Source Imaging which measures brain activity without opening skull. I have a big issue with inserting electrodes into monkeys and other living beings who should be free to live their lives outside of labs.
Observation. Pick a piece of interactive technology in public, used by multiple people. Write down your assumptions as to how it’s used, and describe the context in which it’s being used. Watch people use it, preferably without them knowing they’re being observed. Take notes on how they use it, what they do differently, what appear to be the difficulties, what appear to be the easiest parts. Record what takes the longest, what takes the least amount of time, and how long the whole transaction takes. Consider how the readings from Norman and Crawford reflect on what you see.
October 19, 2011
Homework
1. Concept
Serial Communication is the most common form of communication between electronic devices. In the following lab I am going to set up serial communication between my Arduino micro-controller and my laptop. I will write a program in Arduino that will start listening to the electric pulses coming through the serial pipe (USB wire connecting Arduino and laptop) and getting each of their values. Then I am going to write a program in Processing that will access that information on the laptop’s Serial buffer where serial data coming out of the serial pipe is stored and will interpret it into visual form – a graph.
2. Lab
a) Setup:
b) Write program for Arduino to establish serial connection between micro-controller and laptop and start reading analog input
- This is accomplished in 2 steps: first we need to find out the range of values our photocell is capable of outputting in current conditions. I uploaded following program to Arduino and read in serial monitor that the range is between 230 and 630.
c) Then I wrote the following code for Processing to start accessing Serial Buffer of my laptop and interpreting data into visual form
float xPos = 0;
// import serial library
import processing.serial.*;
// create an instance of the Serial class to use the library
Serial myPort;
void setup() {
// set window size,
size(600,600);
// get the list of all available serial ports,
//we will need to find ours to tell processing to listen to it later
println(Serial.list());
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
background(#081640);
}
void draw() {
//nothing happens here, everything happens in serial event
}
void serialEvent (Serial myPort) {
//get the byte
int inByte = myPort.read();
//print it
println(inByte);
float yPos = height - inByte;
//draw the line in a pretty color
stroke(#A8D9A7);
line(xPos, height, xPos, height - inByte);
//at the edge of the screen go back to beginning
if (xPos >=width) {
xPos = 0;
//clear screen
}
else {
//increment horizontal positionfor next reading
xPos++;
}
}
d) The resulting graph can be viewed here
3. Observation
I observed how people were interacting with the “Welcome” kiosk at AT&T store. Even though it’s right at the entrance, has a bit unusual and attractive UFO shape, noticeable upon closer observation, and orange “Welcome” signs on 3 sides of it, it was ignored by almost everyone who walked in. People would go and stand in the line first, then try to get attention of personnel to be finally diercted to the Welcome kiosk to sign in for an electronic line to be later called by available personnel. That seemed like a bit of waste of time for shoppers and visitors. If the kiosk was more attention-grabbing for people who just walked in and may be if it had a sign that simply stated “Please Sign In to Speak to Personnel” or something of that sort, it would make operations more efficient. The problem is that the kiosk is mainly white and blends too well with the rest of the interior. It is also not tall enough but is the height of a regular table just like all other ones displaying cellphones for sale. It is not distinct enough. It would help to give it an elevated flag of some sort or blinking lights that would be at an average person’s eye level.
I also noticed that it was taking a while for people to go through the process of signing in, so I used the kiosk twice myself and every time stumbled on the screen where my first name and first letter of last name had to be inputted. The main reason this was happening was that there is no “tab” button on the screen to jump onto the “last name” line easily and one had to press inside the input area several times before the cursor would switch into it.
I also found that signing-in process took at least 5 “NEXT” screens. That’s a bit too much to be allowed to stand in the line finally.
//Stupid Pet Trick Code
//GIVE VARIABLES NAMES
const int sensorPin = A0; // minimum reading of the sensors that generates a note
const int speakerPin = 8; // pin number for the speaker
const int noteDuration = 20; // play notes for 20 ms
int sensorValue = 0;
int pitch = 100;
//SETUP
void setup() {
//Initiate Serial communication
Serial.begin(9600);
pinMode(A0, INPUT);
pinMode(8, OUTPUT);
}
void loop() {
sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);
if (sensorValue < 9 ) {
//map the sensor value to a new pitch range
pitch = map(sensorValue,110,0,1200,500);
tone(8, pitch, noteDuration);
}
}