« August 2006 | Main | October 2006 »

September 27, 2006

Basic Water Droplets

I have a really hard time thinking up little programming sketches that don't turn into really involved projects. I almost prefer helping others write their code so I can learn from the ideas they are trying to implement.

This week, I created some water droplets. In the process, I found a really obscure compiler error. Word to the wise: don't use "#define" in Processing. It doesn't work and the message the compiler returns (something dealing with "webcolor" and "preproc" is not at all helpful in narrowing things down. James Kolstad and I stared at this for a while before I commented out just about every line of my program.

Observation Assignment - Part 2

The Interaction:
The driver for Community Lines operates the controls in the cockpit of the Gate 51 minibus.

Setting:
The Gate 51 Bus which I ride to the Port Authority Bus Terminal

Physical Orientation:
The driver is seated

Background:
Each minibus has a personality of its own. The whole fleet of them is a motley crew -- inside and out. I do not know who decorates these vehicles (whether the driver or a separate interior designer). They are not as colorful as I have heard their counterparts in India are, but nevertheless each seems optimized for the comfort and personality of the driver.

My Assumptions:
I assumed (and hoped) that the bus driver would pay attention to the road and traffic rather adjusting the many controls within his reach.

Quick Sketch of the Interaction Area:
minibus observation

- The areas of greatest activity were the steering wheel and the passenger door handle.

- While driving in New Jersey prior to entering the Lincoln Tunnel, the driver rested his right hand on the passenger door handle. He frequently opened and closed the door to allow passengers to enter and exit the bus. His right hand remained on the steering wheel except when he was counting money.

- A metal plate above the passenger door handle prevented it from opening unexpectedly. This locking mechanism required the driver to bend his hand forward so he could release the catch with his thumb before opening the door by swinging his arm out away from his body and towards the passenger door. This motion was very fluid.

- As riders exited the bus, the driver collected their money and inserted it into the slot between the air conditioning vent and the vent's trim ring. To secure the dollar bills there, he pushed in the right side of the vent so it squashed the money against the trim ring. This is an innovation I had not seen on other bus trips.

- I could not perceive that the driver payed any attention to the engine monitor. He neither looked at it nor pressed any of the buttons on it. I had wondered on an earlier trip what the device was and spent most of the ride trying to figure out the pattern of the numbers on its display. Neither the engine monitor nor the lighting control panel appeared to be part of the original equipment of the minibus. Both appeared to have been bolted onto the dashboard after the vehicle had been purchased.

- Unlike other buses I have ridden, this one did not contain a radio. The trip was quite quiet except for the occassional bleep from the driver's cell phone. I believe he stored his cell phone somewhere along the door to his right. After we exited the Lincoln Tunnel in Manhattan, he picked up the phone after it bleeped at him.

- Having read CH 1 of the Design of Everyday Things (Norman), I was mindful of the design of the climate controls in the minibus. Even from a distance, it was clear where the controls were set: the knob was molded in the shape of a pointer which indicated the current setting.


September 25, 2006

Towards Tuesday

I just received email from Michael Dory regarding his group's presentation in Applications of Interactive Technology. Just in case the comment I made at the Help Tank site doesn't make it up there... Kelly and I visited the Museum of Arts and Design in Manhattan several months ago to see an exhibit entitled "Beyond Green: Toward a Sustainable Art". One of the exhibits there was by Michael Rakowitz. You can read about his paraSite project for some ideas of what has already been done in the area of ad-hoc homeless shelters.

Lab 2 - Analog Inputs (part 2)

When considering what to do for the creative part of my Physical Computing lab, I initially thought of some sort of mood-proclaiming piece of clothing.

Instead of using a flex or pressure sensor to light up the LEDs on a "luv-o-meter," I wanted to prototype a display for a t-shirt that could display a short and partially encrypted message about the wearer's stress level. I remember seeing a persistence of vision project on one of my first trips to ITP (perhaps it was the winter show?) and thought I might be able to make a single column of LEDs light up and scroll the message past.

Using only a slightly modified version of the circuit from my game of catch, I set about drafting some code to drive a vertical array of 5 LEDs.

(written during experimentation)
- First attempt unsuccessful... I tried moving my head back and forth to see the image, but didn't get to a point where I could see the image persisting. In the interest of time, though, I'm going to try a couple more speeds before I set about rewiring

- I added potentiometers to the circuit in order to vary the delay between the columns of the character as well as between each letter. When I move the board back and forth I can make out the characters, but it seems like they might be going backwards.

- Seems like the rocking back and forth I'm doing may be causing the character to be rendered backwards. On the bicycle example, the direction is constant. I wonder how the clock I've seen that uses this trick works... it swings back and forth... perhaps it has to write the characters in reverse order...

I could eventually try mounting this contraption on a motor

/* ----------------------------------------
    Persistence
   ---------------------------------------- 
    Michael Chladil
    
    Physical Computing
    2006-09-23
    
    written for Arduino v1.18
    
   ---------------------------------------- 
*/

#include 

#define DEBUG_LVL 1

// Going to try first with 5-line characters
#define CharacterPin1 3
#define CharacterPin2 4
#define CharacterPin3 5
#define CharacterPin4 6
#define CharacterPin5 7
#define CHAR_WIDTH    5
#define CHAR_HEIGHT   5

byte Letter_M[CHAR_WIDTH][CHAR_HEIGHT] = { {1, 0, 0, 0, 1},
                                           {1, 0, 0, 0, 1},
                                           {1, 1, 0, 1, 1},
                                           {1, 0, 1, 0, 1},
                                           {1, 0, 0, 0, 1} };

byte Letter_C[CHAR_WIDTH][CHAR_HEIGHT] = { {0, 1, 1, 1, 1},
                                           {1, 0, 0, 0, 0},
                                           {1, 0, 0, 0, 0},
                                           {1, 0, 0, 0, 0},
                                           {0, 1, 1, 1, 1} };                                                                                      

#define CharacterPin6 8
#define CharacterPin7 9
#define Switch1  10
#define Switch2  11 

int delayTime      = 0;
int charRow        = 0;
int interCharDelay = 0;

void setup ()
{
  pinMode (CharacterPin1, OUTPUT);
  pinMode (CharacterPin2, OUTPUT);
  pinMode (CharacterPin3, OUTPUT);
  pinMode (CharacterPin4, OUTPUT);
  pinMode (CharacterPin5, OUTPUT);

  pinMode (Switch1, INPUT);
  pinMode (Switch2, INPUT);  
  
  if (DEBUG_LVL > 0)
  {
    Serial.begin (9600);
  }
}


void writeChar (char charToWrite)
{
  byte Letter[5][5];
  int charCol = 0;
  int charRow = 0;
  int i;
  
  // Needed a way to copy the constants I defined above without going 
  // pixel by pixel.  memcpy seems to do the trick.  I initially wanted
  // to copy the entire 2-D array at once, but it didn't seem to work
  // and I wanted to move on to verifying other things
  switch (charToWrite)
  {
    case 'M' : 
    {
      for (int i = 0; i < CHAR_HEIGHT; i++)
        memcpy (Letter[i], Letter_M[i], CHAR_WIDTH);

      break; 
    } 
    case 'C' : 
    {
      for (int i = 0; i < CHAR_HEIGHT; i++)
        memcpy (Letter[i], Letter_C[i], CHAR_WIDTH);
        
      break;
    }
  }
  
  for (charCol = 0; charCol < CHAR_WIDTH; charCol++)
  {  
    for (charRow = 0; charRow < CHAR_HEIGHT; charRow++)
    {
      digitalWrite(CharacterPin1 + charRow, Letter[charRow][charCol]);
    }
    
    delay (delayTime);
    
    for (charRow = 0; charRow < CHAR_HEIGHT; charRow++)
    {
      digitalWrite(CharacterPin1 + charRow, LOW);
    }
    delay (10);  
  }
}

void loop()
{
  delayTime      = analogRead(5);
  interCharDelay = analogRead(4);
  
  writeChar('M');
  delay(interCharDelay);
  writeChar('C');
  delay(interCharDelay);
}

Lab 2 - Analog Inputs (part 1)

LAB 3 - Pulse Width Modulation

In addition to the adjustable LED level suggested in the lab notes, I decided to program the Arduino board to gradually fade the LED level down from the level set by the potentiometer. Last week when I was working on my game of catch I wanted to have the first LED gently fade in and out during the "wind-up" phase of the throw. This week, I figured out how to do it.
/* PWM Lab
   I've added my own twist to the code to make the the LED fade
    
   Michael Chladil
*/

#define ANALOG_INPUT  0
#define PWM_OUTPUT    9
#define DELAY_TIME    10

int  potValue        = 0;
long lastMillis      = 0;
int  currentLEDLevel = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  potValue = analogRead (ANALOG_INPUT);
  
  Serial.println (potValue); 
  /* Use the value read from the potentiometer to determine 
     a starting level for the LED.                          */
  
  for (currentLEDLevel = potValue; currentLEDLevel >= 0; currentLEDLevel--)
  {
    analogWrite(PWM_OUTPUT, currentLEDLevel);
    delay (DELAY_TIME);
  }
  
  delay (DELAY_TIME);  
}

September 21, 2006

Observation Assignment 1

I tried my first series of observations during my morning commute to ITP on September 14. After our discussion of the observation assignment in class on 9/20, I discovered I had been going about the observations incorrectly. The focus was supposed to be observation -- not interpretations.

Here is what I saw during my observations

- 2 iPods
- 1 mobile device user browsing emails
- one tablet PC user (me) observing others
- EZ pass readers wirelessly collecting tolls from cars, trucks, buses going into the Lincoln tunnel -- this is transparent technology
- GPS system in a Lexus SUV
- cell phones on the bus (making calls, playing games)
- many cell phone users in cars holding their phones and talking
- Toll-taker at the Lincoln Tunnel toll plaza grooving to his iPod

Once in Manhattan and on the A train, I encountered many more iPods and other personal audio devices: almost half of the riders were wearing earbuds of some sort.

It seemed that everyone was isolated from everyone else.

One lady who boarded the train after me thumbed her Blackberry nervously for about 3 minutes.

September 20, 2006

More on Spatial Design Assignment 2

Lisa Lurie commented that the shape of the photo collage I assembled was an interesting piece by itself. She also suggested that a black background might increase the sense of being in the room.

Somewhere in the back of my mind were memories of books from my childhood -- the kind of books you cut shapes out of that become 3-dimensional objects. The form of the Living Room Composites I was created must have reminded me of the flattened out spheres from those books.

Living Room Composite - Final

Originally, I was trying to assemble and distort the photos to represent the 3-dimensional space on the flat surface of the computer screen. With the second composite, I worried less about distoring the perspective of the photos and more about matching up each of the rows of shots I had taken. Taking the X-Acto in hand, I was able to transform the flat images back into 3-dimensional space by way of the curved lens through which the light in the room had reflected into the camera. After cutting between the "arms" of the image, I pulled them together into a hemisphere to match up the duplicated parts of the images.

The unknown is whether this satisfies the requirements of the assignment. I worked with thumbnails of the original 3 megapixel images in order to keep the "technology frustration" to a minimum -- not having to worry so much about the time I had invested in the slow process of manipulating large images if the concept didn't work out. As it stands, my "model" is about 4" across and I'm not sure if it will be possible for people who are unfamiliar with my room to discern the objects in it.

September 18, 2006

Catch is Done for Now

I finished the first version of my catch game. The schematic is pretty basic... catch schematic.jpg ... and in fact it should be noted that I found a soldering problem on the little board I salvaged. Apparently when I rewired it, I knocked one of the circuit traces loose, which prevented the upper right switch from working. This caused me much consternation while trying to develop the catching algorithm. Thankfully Serial.println helped me figure things out. I modified my program to use the upper left switch for both throwing and catching. Maybe it's not so interactive anymore, but it's done and I have other things like Spatial Design homework to do. If you like to read source code, you can do so in the full entry.
/* ----------------------------------------
    A Small Game of Catch
   ---------------------------------------- 
    Michael Chladil
    
    Physical Computing
    2006-09-18
    
    written for Arduino v1.18
*/

#define DEBUG_LVL 2

#define BallPin1 3
#define BallPin2 4
#define BallPin3 5
#define BallPin4 6
#define BallPin5 7
#define BallPin6 8
#define BallPin7 9
#define Switch1  10
#define Switch2  11 

void setup ()
{
  pinMode (BallPin1, OUTPUT);
  pinMode (BallPin2, OUTPUT);
  pinMode (BallPin3, OUTPUT);
  pinMode (BallPin4, OUTPUT);
  pinMode (BallPin5, OUTPUT);
  pinMode (BallPin6, OUTPUT);
  pinMode (BallPin7, OUTPUT);
  pinMode (Switch1, INPUT);
  pinMode (Switch2, INPUT);  
  
  if (DEBUG_LVL > 0)
  {
    Serial.begin (9600);
  }
}

boolean Throw (int delay_time)
{
  long    Last_Millis;
  long    SW2_pressed = 0;
  int     PinNumber   = BallPin1;
  boolean Caught      = false;
  
  Last_Millis = millis ();
  digitalWrite (PinNumber, HIGH);
  
  while ((PinNumber <= BallPin7) && 
         (Caught == false) &&
         (SW2_pressed == 0))    // Once the switch has been pressed, the attempted "catch" is over
  {
    if ((millis() - Last_Millis) > delay_time)
    {
      digitalWrite (PinNumber, LOW);
      PinNumber++;
      if (PinNumber <= BallPin7)
        digitalWrite (PinNumber, HIGH);
      Last_Millis = millis ();
    }
   
    if (digitalRead (Switch1) == HIGH)
    {
      /* Because of a poor soldering job, I have to use switch one twice */
      if (DEBUG_LVL == 2)
      {
        Serial.println ("SW2 Pressed when pin=");
        Serial.println (PinNumber);
      }
      
      SW2_pressed = millis ();
      
      if ((PinNumber >= BallPin7) && 
          ((SW2_pressed - Last_Millis) < delay_time))
        Caught = true; 
      else
        Caught = false;
    }
  }
  
  // Turn all LEDs off
  int i;
  for (i = BallPin1; i <= BallPin7; i++)
  {
    digitalWrite (i, LOW);
  } 
  
  return (Caught);

  /* I initially wrote the throw routine using delays, but realized the
     delays would prevent Arduino from detecting the second switch.
  
     From here down is old code.
  */
    
  /*
  for (PinNumber = BallPin1; PinNumber <= BallPin7; PinNumber++)
  {
    digitalWrite(PinNumber, HIGH);
    
    if (PinNumber > BallPin1)
    {
      digitalWrite(PinNumber - 1, LOW);
    }
    else
    {
      digitalWrite(BallPin7, LOW);
    }
    delay (delay_time);
  }
  */
}

void loop ()
{
  int     delay_time;
  long    Last_Millis;
  long    SW1_pressed;
  long    SW1_released;
  boolean Blink_State = LOW;
 
  if (digitalRead (Switch1) == HIGH) 
  {
    SW1_pressed = millis();
    Last_Millis = SW1_pressed;
    
    while (digitalRead (Switch1) == HIGH)
    {
      if ((millis() - Last_Millis) > 150)  
      {
        /* Initially I tried to do the blink using the time difference % 150, but this produced
           erratic blinking because sometimes the milliseconds wouldn't be evenly divisible by 
           150 at exactly the time when the condition was tested.  This meant the loop had to 
           go back around again.  By changing the test to a subtraction (and allowing for a 
           margin of error by using ">", I have made the blink more regular
        */
        Last_Millis = millis();
        Blink_State = !Blink_State;
        digitalWrite (BallPin1, Blink_State);
      }
    }
    Blink_State = LOW;
    digitalWrite (BallPin1, Blink_State);
    
    SW1_released = millis();
    
    if (DEBUG_LVL >= 3) 
    {
      Serial.print ("t=");
      Serial.println (SW1_released - SW1_pressed);
    }
    
    if (Throw ((SW1_released - SW1_pressed) / 7) == true)  
    {
      /* The project uses 7 LEDs, so divide the press and release time by 7.
         
         TODO: For future development, I would like the minimum throw speed when the
         game starts to be fairly high... This way the thrower can't immediately 
         overwhelm the catcher.
         
         TODO: Is there some way to write a chunk of data to pins using a char or a string? 
         This way I would be able to shift bits to cause the effect I wanted.
      */
      
      // Ball caught - alternately blink all lights
      if (DEBUG_LVL > 0)
        Serial.println ("Caught!");
      
      // TODO: The following is an ideal candidate for refactoring...
      int i;
      for (i = 1; i <= 3; i++)
      {
        digitalWrite (BallPin1, HIGH);
        digitalWrite (BallPin2, LOW);
        digitalWrite (BallPin3, HIGH);
        digitalWrite (BallPin4, LOW);
        digitalWrite (BallPin5, HIGH);
        digitalWrite (BallPin6, LOW);
        digitalWrite (BallPin7, HIGH);
        delay (150);  
        digitalWrite (BallPin1, LOW);
        digitalWrite (BallPin2, HIGH);
        digitalWrite (BallPin3, LOW);
        digitalWrite (BallPin4, HIGH);
        digitalWrite (BallPin5, LOW);
        digitalWrite (BallPin6, HIGH);
        digitalWrite (BallPin7, LOW);
        delay (150);
      }

      // Clear all LEDs
      for (i = BallPin1; i <= BallPin7; i++)
        digitalWrite (i, LOW);
        
      while (digitalRead (Switch1) == HIGH)
      {
        // Busy wait for switch 1 to go low before proceeding  
      }
     
    }
    else
    {
      if (DEBUG_LVL > 0)
        Serial.println ("Missed!");
     
      // Ball missed - do one long blink of the entire row and then reset.
      int i;
      for (i = BallPin1; i <= BallPin7; i++)
        digitalWrite (i, HIGH);
        
      delay (300);
      
      for (i = BallPin1; i <= BallPin7; i++)
        digitalWrite (i, LOW);
        
      while (digitalRead (Switch1) == HIGH)
      {
        // Busy wait for switch 1 to go low before proceeding  
      }  
    }      
  }
}

September 17, 2006

Working on Assignment 2

Living Room Composite - 1

I spent a bit of the afternoon photographing my living room. I spent even more time manipulating the images to try to reconstruct the perspective of the room. Am I spending too much time on this? I'm not sure that sketching would be quicker -- but it would look more accurate.

Working on Catch

the whole layout

I'm working on a game of catch as my first self-chosen project in Physical Computing.

The idea is simple: two players throw a ball (represented by moving LED) back and forth. The thrower controls the speed by the amount of time he takes to release SW 1 after pressing it. To catch the ball, the second player, must press his button exactly when the ball reaches him.

The implementation is not as simple: it appears that I may need to draw a state diagram. The schematic isn't complex, but I have a feeling that the code will be.

For now, I will keep my goals simple.

1. Test out a throwing algorithm (done). I've already made the "ball" move and at varying speeds
2. Make SW1 trigger the throwing algorithm
3. Work out a catching algorithm

In order to get my salvaged switches working, I visually inspected the circuit traces and then poked around measuring continuity until I found the pairs that matched.

t-salvaged switch

September 16, 2006

M5 Bus Trip

bus banner
I took a trip down memory lane for my Applications of Interactive Technology class. One of the two assignments is to ride the Manhattan M5 bus from it's origin at La Guardia Place and Houston all the way to its final stop at the George Washington Bridge bus terminal (179th and Ft. Washington).

My original goal for the trip was to collect sound samples for use in my assignment. I wanted to make a sound collage of my journey to fulfill the requirements of the assignment, but I quickly discovered that the only sounds I could capture from inside the bus were the conversations of the passengers and the rumbling of the engine. If I'm going to make this happen, I will have to ride my bicycle along the route another day.

This is only the second time I've ridden a bus in Manhattan. My first ride was in a torrential downpour years ago when I was visiting colleges. Although I've cycled some of the route the M5 took, I haven't had the opportunity until now to travel most of the length of the island above ground. Cycling in Manhattan doesn't allow for leisurely observations or photography.

September 14, 2006

Meditation: Light and Space

Summary:
This two minute video explores the interaction between light and space.

Idea:
A melancholy sleepless night is transformed by a thunderstorm.

Details:
- 1' x 1' x 1' (appx) set made out of foamcore
- Sound design created from Creative Commons-licensed elements from FreeSound
- Piano music recorded in my home studio


September 09, 2006

Roosevelt Island

Note:
This entry is a duplicate of the entry that I tried to post to the Spatial Design blog. Hopefully I will figure out a better way to do this instead of creating entries in both places. Suggestions?

Rode out to Roosevelt Island (history) with folks from class. The view from the tram was quite spectacular. We were in the middle of the air in a space defined by the walls and floor of the tram car -- held in place by the cable above us.

Roosevelt Island Tram (reduced).jpg

I attracted the attention of the Grog Shop's owner by stopping to shoot a photo.

the grog shop.jpg

I was more interested in documenting the duplicated shops signs and the glass-enclosed walkway rather than taking a picture of his shop. He sent someone out to ask me what I was doing. I fumbled a bit for words because he gave me the impression I was doing something wrong. When I explained that I was on Roosevelt Island as part of a class assignment, he asked if I could send him the photo. The Grog Shop doesn't seem to have a website, though... so I guess he'll have to wait until the next time I'm on the island -- and remember to print the photo.

I found the island to be very angular: many of the buildings had strong prependicular lines jutting out of their facades. It seemed very ordered, controlled, and planned -- a stark contrast to Manhattan's jumble of towers. In some ways it made me forget about the presence of Manhattan. The tall apartment towers on the west side of Main street effectively block off any view or sound of Manhattan.

We spent some time at the northern tip of the island watching passing tug boats. I wondered who Vicki Holland was, but couldn't find out much about her.

Vicki Holland Lighthouse.jpg

One of the things that intrigued me in our first class with Jean-Marc was his sense of the history of places. I would have to admit that I rarely have had an interest about this -- until now. From the small bit I've read about the island it has changed drastically over the past forty years from "Welfare Island" into a self-governed (?), intentional community (again? -- perhaps this is not the correct term).

Noguchi

I'm in a world of stone -- meticulously processed stone. Stone that is drilled and cracked and chipped and polished. Before this trip to the Noguchi museum (and our first class on light I had very little appreciation for the variety of values that texture can produce. The same material, seemingly on the same plane in space can exhibit difference in value just by subtley texturing it.

This is a peaceful space -- but an overwhelming one. I have come in contact with the work of one man's lifetime. There is so much to take in, to try to understand, to appreciate.

The pieces I enjoyed the most were:

Well

The Roar

IMG_0288

I found the texture of one of the pieces really fascinating:
grooves

As I learned in class today, the stone is generally drilled in the quarry, but Noguchi used this technique in "miniature" to work details into his work. Note the areas that were left rough and those that were polished

September 04, 2006

The Summer Project

I spent a bunch of my summer building this bookshelf.

Bookshelf - Front View - Angled.jpg

Ikea sells them, but I guess I was looking for a character-building project. Perhaps the "patience" that came from constructing router jigs, the "peace" that comes from embracing imperfection, and the "wisdom" of knowing the correct tool to use for a job will show up at a later date. I must have started this project back in May or June...

The most difficult part of the project was cutting the box joints on the shelf support. There were thirty-two of them.

Bookshelf - Joint Detail.jpg