ink heater the beginnings of a blog

Media Controller

I worked with Nikolas Psaroudakis and Matt Swenson for our Physical Computing media controller assignment. From the outset, we knew wanted to create a physical device that controlled sound, allowed the user to change his/her actions and see in real time how these changes affected the sound.

We all had different ideas about what we wanted to build, some of them being easier and others more difficult. After toying around with numerous concepts, we whittled our ideas down to a MIDI controller that enabled the user to create fairly complex sounds by controlling simultaneous musical loops.

Some rambling sketches from our first brainstorm

Our device would enable the user to compose and perform unique compositions by moving their hands at varying distances above the sensors to control and modify prerecorded sounds, or music. Each sensor on the device would correspond to a different prerecorded sound sample, and the user could control the pitch, tone or tempo of the music.

We used Ableton Live for the music part of our project. We selected a set of sample loops that together nicely when played together and a set of audio filters that would be applied and controlled through MIDI.

Programming the sensors
We chose to use sonar sensors due to their ease of operation. The first step was to connect one sensor for testing. The MaxSonar EZ-1 and the Parallax PING were almost equally priced, so we decided to test both. The Parallax sensor gave more accurate results - but because it was less compact than the MaxSonar sensor, we decided to go with the MaxSonar.

Upon testing the three MaxSonar sensors simultaneously, we discovered some odd errors in the readings that hadn’t occurred when operated individually. After a bit of research, we realized the problem: the sensors were cross-talking, i.e. the pulse of one sensor was detected by another one, making the results very unstable (see below). To eliminate this interference, we could either position them farther apart, or point them in different directions, e.g. on a curved surface.

When we tested all three sonar sensors together, we found that the readings interfered with each other.

The first time the circuit was soldered together, only the sensor on pin 2 was working. Upon double-checking the code for accuracy, we determined that the error must be in the connections - so we unsoldered the circuit board and rewired the components to a breadboard for troubleshooting.

While positioning the sensors at different angles helped reduce interference between them, we found that it was not enough on its own. Readings continued to be unstable, and jumps were experienced at random moments. We decided to employ averaging on the readings and see if that helped, but unfortunately, it didn’t make much of a difference.

Our biggest problem was cross-talking between sensors as well as random jumps in our readings that were causing MIDI send events to take place.

Physical Design & Interface
We loaded prerecorded musical loops on the sensors and played around to determine what gestures made sense to control the levels, and decided that the vertical (up-down) motion of the user's hand above the sensors would provide the most intuitive method of controlling levels varying between high-low; enable the user to remain in place while operating the device; and lessen the chance of accidental interference from external sources.

The curved top surface allowed for fluid, natural hand movements. The positioning of the three sensors enables user can easily switch to right or left hand to control the center sensor.

At this point, the device was almost ready to go - we just had to attach the Plexi on top.

At this point, the device was almost ready to go - we just had to attach the Plexi on top.

We cut a rectangle of Plexiglas for the curved top of the device, and used the drill press in the shop to make holes for the screws to affix the Plexi to the base. The drill bits in the shop were too small to create holes for the sensors – so John Duane introduced me to the hole saw, a tiny saw in the shape of a circle that fits onto a drill (like a drill bit) and enables the user to cut large holes in fairly thin materials. Fun!

We used a hole saw fitted onto the drill press to make holes in the Plexi large enough to accommodate the sensors.

Matt created a Processing sketch to provide the user with a visual indication of the levels of the sensors.

The Presentation
We tested our MIDI controller in the student lounge on the ground floor of Tisch and were satisfied with the outcome. When the time came for us to present in class, however, the system proved unstable. After troubleshooting for some time, we realized that student lounge was ideal for our experiment due to the high ceiling – and additionally, we were the only people close to our device. In contrast, the classroom’s low ceiling, and perhaps also the presence of others in the vicinity, caused the sensor readings to become unstable.

If we were doing this project again, we’d probably try using IR sensors instead of sonar. We’d also use thinner Plexi, as the Plexi we used developed small cracks when we curved it.

The code we used is below.

int analogPin1 = 0;
int analogPin2 = 1;
int analogPin3 = 2;
int digPin12=12; //Set BW pin to HIGH
int digPin13=13; //Set pimn to HIGH after 250ms
int switchPin=2;
int sensorValue = 0;
int switchState=0;
int prevState=0;
int state=0;
int n=1;/// average over n times
int maxLevel=3000;
int cnt=0;
boolean started=true;
void setup()
{
  // start serial port at 9600 bps:
  pinMode(switchPin, INPUT);
  //pinMode(digPin12,OUTPUT);
  //pinMode(digPin13,OUTPUT);
  Serial.begin(9600);
  establishContact();
}
void loop() {
  //digitalWrite(digPin12,HIGH);
  initSensors();
}
void initSensors(){
  if (millis()>=250){
    if (started==false){
      //digitalWrite(digPin13,HIGH);
      delay(30);

      started=true;
    }
    else {
    //  digitalWrite(digPin13,LOW);
      readSensors();
    }
  }
}
void readSensors(){
  switchState = digitalRead(switchPin);
  if (switchState==1 && prevState==0){
    state=state%3;
    state++;
    prevState=1;
  }
  else if (switchState==0 && prevState==1){
    prevState=0;
  }
  if (Serial.available() > 0) {
    // read the incoming byte:
    int inByte = Serial.read();
    // read the sensor:
    sensorValue = avgReadings(analogPin1,n);//analogRead(analogPin1);
    // print the results:
    Serial.print(maxSense(sensorValue,maxLevel), DEC);
    Serial.print(",");

    // read the sensor:
    sensorValue = avgReadings(analogPin2,n);//analogRead(analogPin2);
    // print the results:
    Serial.print(maxSense(sensorValue,maxLevel), DEC);
    Serial.print(",");
    // read the sensor:
    sensorValue = avgReadings(analogPin3,n);//analogRead(analogPin3);
    // print the last sensor value with a println() so that
    // each set of four readings prints on a line by itself:
    Serial.print(maxSense(sensorValue,maxLevel), DEC);
    Serial.print(",");
    Serial.print(state,DEC);
    Serial.println("");
  }
}
void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("hello");   // send a starting message
    delay(300);
  }
}
int avgReadings(int pin,int n){
  int avg=0;
  for (int i=0;ilevel){
    return level;

  }
  else {

    return sensorValue;
  }
}

The processing code follows:
(File midiController.pde)

import promidi.*;
import processing.serial.*;
MidiIO midiIO;
MidiOut midiOut;
Controller controller,controller2;
//int inByte=20;
Serial myPort;
sonarSwitch switches;
int nSonars=3;
void setup () {
  size (1024,768);
  switches = new sonarSwitch(nSonars,0);
  background (0);
  smooth();
  initMidi();
  initSerial();
}
void draw(){

}
void myDraw() {
  //println("NO height is:"+height);
  switches.draw();
  fill(0,10);
  rect (0,0,width,height);
}
void serialEvent(Serial myPort) {
  switches.serialStuff(myPort);
  myDraw();
}
void initMidi(){
  //switches=new sonarSwitch(1,0);
  midiIO=midiIO.getInstance(this);
  midiIO.printDevices();
  midiOut=midiIO.getMidiOut(0,0);
}
void initSerial(){
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
}

(File dotColumn.pde)

class dotColumn {
  dotTrack[] dots;// = new dotTrack [1000];
  int r,g,b,x;
  int nLines=50;
  int nLinesCurrent=0;
  dotColumn(int _x, int _r,int _g, int _b){
    r=_r;
    g=_g;
    b=_b;
    x=_x;
    dots =new dotTrack[nLines];
    for (int i = 0; i < nLines; i++) {
      dots[i] = new dotTrack(x, height-i * 10, 6, 0, r,g,b, 23);
      //println("Height is:"+height);
    }
  }
  void  draw(){
    for (int i = 0; i < nLinesCurrent; i++){
      dots[i].dotDraw();
    }
  }
}

(File dotTrack.pde)

class dotTrack {
  float x;
  float y;
  int w;
  float ySpeed;
  float xSpeed;
  int r,g,b;
  int inByte;
  int h;
  dotTrack (int x_, int y_, int ySpeed_, int xSpeed_, int r_, int g_, int b_, int inByte_) {
    xSpeed = xSpeed_;
    ySpeed = ySpeed_;
    x = x_;
    y = y_;
    r=r_;
    g=g_;
    b=b_;
    inByte = inByte_;
  }
  void dotDraw() {
    noStroke();
    fill (r,g,b);
    float x2 = random (x,x+40);
    ellipse (x2,y,5,5);
  }
}

(File sonarSwitch.pde)

class sonarSwitch {
  int nSonars;
  boolean firstContact = false;
  dotColumn[] columns;
  int[] sonarON_OFF;//=new int[0];
  int [] sonarON_OFFprev;  //previous state
  int[] sonarLevel;//=0;
  int button=1;
  int thres;
  boolean state=false;
  String mySt;
  int check;
  int upperLevel=100;
  int lowerLevel=60;
  int sonarLevelMax=50;
  public int[] sensors;
  boolean[] states;
  sonarSwitch(int _nSonars, int _thres){
    nSonars=_nSonars;
    // sensors
    columns=new dotColumn[nSonars];
    //println("The number is: "+columns.length);
    //println("Switches are: "+nSonars);
    thres =_thres;
    states=new boolean[nSonars];
    sonarON_OFF= new int[nSonars];
    sonarON_OFFprev= new int[nSonars];
    sonarLevel=new int[nSonars];
    for (int i=0; i< sensors.length-1; sensorNum++) {
          if (sensors[sensorNum]>upperLevel){
            sensors[sensorNum]=upperLevel;
          }
          //print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
        }
        // add a linefeed after all the sensor values are printed:
        println();
        if  (sensors.length==nSonars+1){
          // println(sensors[nSonars]);
          for (int i=0;i 1) {
            switches.checkSwitches(sensors[nSonars]);
            switches.checkSliders(sensors[nSonars]);
            // println(sensors[nSonars]);
          }
        }
        myPort.write("A");
      }
    }
  }
  void checkSwitches(int button){
    // println("Switch "+button);
    for (int i=0;ithres&&columns[i].nLinesCurrent
Filed under: PComp No Comments

Beverage cabinet update!

Our interactive beverage cabinet is coming along... slowly! Alex and I have been working on the Arduino code for the past ten days or so, but we've hit a number of obstacles along the way and are still working through the kinks.

The cabinet has five switches, one in each compartment. When a bottle is removed, a switch is flipped in that compartment, triggering a music track and light sequence corresponding to that bottle.

Initially, we figured that the code would be relatively straightforward - it's just five switches, a few lights and some tunes, right? Well, yes, but using multiple switches to control multiple light sequences through the MIDI dimmer was a little trickier than anticipated.

Our first step was getting the MIDI dimmer to communicate with the Arduino. We tested this using Rory Nugent's test code.

Next, we programmed the dimmer to begin the light sequence when a switch is turned on, and stop the sequence then the switch is turned off, without delays (which cause problems as the Arduino stops).

When we tested the code using the lightGo() and lightHalt() functions, the light turned on as hoped when the switch is pressed, but didn't begin the incremental dimming up & down.

So, we sought advice and learned that the parts of code involving (switchState ! == lastSwitchState) and if (millis() - previousMillis > interval) were the source of our issues. So, we added arrays for brightness values, switchState, lastSwitchState, previousMillis and interval variables for each switch, ending up with the following code:

MIDI Dimmer code

int midiPin = 1;   //  digital output pin for the midi dimmer
int lastSwitchState[5]; // previous state of the switch
int lightToggle[5]; //DOES THIS NEED TO BE AN ARRAY? Variable for toggling the light at max and min values
int switchState[5];         // current state of each switch
int lastswitchState[5];     // previous state of each switch
int previousMillis[5];      //DOES THIS NEED TO BE LONG?
int brightness[5];          // array of brightnesses for each light
int switchPins[] = {
2,3,4,5,6};  // digital input array to hold the switch pin numbers

// brightness goes from 1-127...not sure what goes in the curly brackets below
//int brightness[] = { ? }

void setup() {
for (int thisChannel = 0; thisChannel < 5; thisChannel++) {
//initialize switch pins as inputs
pinMode(switchPins[thisChannel], INPUT);
pinMode(midiPin, OUTPUT); //initialize midi dimmer as output
Serial.begin(31250); // set MIDI baud rate
}
}

void loop() {
for (int thisChannel = 0; thisChannel < 5; thisChannel++){
// read the switch:
switchState[thisChannel] = digitalRead(switchPins[thisChannel]);
//if the switch has changed,
// compare the switchState to its previous state
if (switchState[thisChannel] != lastswitchState[thisChannel]) {
// if the switch has changed from off to on:
if (switchState[thisChannel] == HIGH) {
// if the current state is HIGH then the switch
// went from off to on:
lightGo(thisChannel, 10); //REPLACE 10 with "interval"
}
else {  // else the switch changed, going from on to off:
lightGo(thisChannel, 3); //REPLACE 10 with "interval"
}
// save the current state as the last state,
//for next time through the loop
lastswitchState[thisChannel] = switchState[thisChannel];
}
else {  // else the switch didn't change.
// dim all the light channels:
brightness[thisChannel]--;
lightGo(brightness[thisChannel], 30);

}
}

//if the switch is off:
if (switchState == LOW) {
//call the lightHalt function
lightHalt (0);
//lightHalt (1);
//lightHalt (2);
}
*/
}

// data1 should be from 0-5, and tells the dimmer which light group
// data2 should be from 0-127 and represents the brightness
void noteOn(char cmd, char data1, char data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}

void lightGo (int thisChannel, long interval) { //
if ((millis() - previousMillis[thisChannel]) > interval) {
//if the light is on at all
if (brightness[thisChannel] == 127) {
lightToggle[thisChannel] = 0;
// Serial.println("here");
}
//if light is off
else if (brightness[thisChannel] == 0) {
lightToggle[thisChannel] = 1;
}

if (lightToggle[thisChannel]==1) {
brightness[thisChannel]++;
}
else {
brightness[thisChannel]--;
}
//turn on the light
noteOn(0x90, thisChannel, brightness[thisChannel]);
// save the last time you blinked the light
previousMillis[thisChannel] = millis();
}
}

void lightHalt(int thisChannel) {
//if the switch is off, turn off the light:
noteOn(0x90, thisChannel, 0);
//save the last time the light blinked:
previousMillis[thisChannel] = millis();
}

We're still working on figuring out and finishing this code and making it work. In the meantime, we've hard-coded everything in the hope of making it work.

MP3 Trigger
The MP3 Trigger allowed two ways for us to play MP3 files through Arduino: we could either use the 7 trigger pins on the board to directly trigger 7 pre-selected tracks, or use serial communication through Arduino to enable remote triggering of all tracks on the board, with the added advantage of volume control. We opted for the latter - however, the MIDI dimmer was already using the serial port, so we got the MP3 Trigger functioning through software serial.

We loaded our tracks onto the MP3 Trigger, and used the XX library to link the songs to specific switches.

Switches = Wicked Witches!
We tried out one switch to see if the music and lights would work together and after a bit of troubleshooting, it worked! However, when we tried the cabinet with more than one switch, everything went a bit crazy.

And that's where we are right now. We've worked our posteriors off, we've learned a TON, and we're pretty certain that we're almost there.

Images/video of our progress shall be forthcoming. But first, sleep. And breakfast.

Pcomp final: Interactive Liquor Cabinet

Over the past few weeks, Alex Vessels and I have brainstormed on the floor at ITP, in the East Village, Chinatown and everywhere in between to settle upon the perfect form factor for our party device. Somewhere along the way, we settled upon the perfect form factor for our party device: an interactive liquor cabinet that will create a different type of party mood, depending on which liquor is selected.

We're using an existing antique cabinet with five compartments, which will light up when the cabinet is opened. There will be one object placed in each compartment. When an item is removed from the cabinet, a song corresponding to that object will play, and a light sequence will kick in. For example, take out the bottle of Jameson, and you'll hear the Pogues and be dazzled by a green light display. Or select the Jim Beam, and you'll hear Guns 'n' Roses and be dazzled by red and blue flashing lights.

We're experimenting with building various types of switches to place on the shelves of the cabinet, and we're currently learning to use the MIDI dimmer from the ER to control AC lights. For now, we'll use the Processing Minim library and a laptop to control the music - eventually, we'll probably switch to aWave Shield, which can be hidden inside the cabinet (and eliminating the laptop from the equation).

Below is a photo of the cabinet as is. We're hoping to keep the exterior appearance intact and preserve the old-time aesthetic.

 

Cabinet with the door open

 

 

 

PComp Lab: HBridge

In this lab, we learned to control the direction of a DC motor, i.e. reverse the direction of the current in the motor, using a H-Bridge circuit. I'd previously learned while doing the transistor lab that the motor I was using operated on between 3.3-5V, so I connected the motor to 5V in this lab instead of 12V - and as expected, the motor worked perfectly.

When the circuit is powered, the motor spins in one direction - and when the switch is pressed, it spins in the reverse direction.

H-Bridge lab from katherine keane on Vimeo.

Code

  const int switchPin = 2;    // switch input
  const int motor1Pin = 3;    // H-bridge leg 1 (pin 2, 1A)
  const int motor2Pin = 4;    // H-bridge leg 2 (pin 7, 2A)
  const int enablePin = 9;    // H-bridge enable pin
  const int ledPin = 13;      // LED 

  void setup() {
    // set the switch as an input:
    pinMode(switchPin, INPUT); 

    // set all the other pins you're using as outputs:
    pinMode(motor1Pin, OUTPUT);
    pinMode(motor2Pin, OUTPUT);
    pinMode(enablePin, OUTPUT);
    pinMode(ledPin, OUTPUT);

    // set enablePin high so that motor can turn on:
    digitalWrite(enablePin, HIGH); 

    // blink the LED 3 times. This should happen only once.
    // if you see the LED blink three times, it means that the module
    // reset itself,. probably because the motor caused a brownout
    // or a short.
    blink(ledPin, 3, 100);
  }

  void loop() {
    // if the switch is high, motor will turn on one direction:
    if (digitalRead(switchPin) == HIGH) {
      digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
      digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
    }
    // if the switch is low, motor will turn in the other direction:
    else {
      digitalWrite(motor1Pin, HIGH);  // set leg 1 of the H-bridge high
      digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
    }
  }

  /*
    blinks an LED
   */
  void blink(int whatPin, int howManyTimes, int milliSecs) {
    int i = 0;
    for ( i = 0; i < howManyTimes; i++) {
      digitalWrite(whatPin, HIGH);
      delay(milliSecs/2);
      digitalWrite(whatPin, LOW);
      delay(milliSecs/2);
    }
  }
Filed under: PComp No Comments

EL DJ: The best jukebox on the planet?

This morning while doing a bit of blog housekeeping, I realized that I'd accidentally left the PComp observation assignment in unpublished draft form on Wordpress. However, instead of immediately hitting the Publish button to avoid further delay, I decided to do a bit of additional digging regarding the origins of the interactive technology that I chose to observe.

With camera and notebook in hand, I stationed myself on a barstool at Hi Fi in the East Village - a good ol' divey kind of place, within walking distance from my apartment, with a decent selection of beers on draught - and what's more, Hi-Fi  happens to be the home of EL DJ (Extra Large Digital Jukebox), the best jukebox in the city, as far as I'm aware (full tracklist can be viewed here). What better place to watch people interact with technology while investigating from a user interface perspective the accuracy of Hi Fi's claim that theirs is "the best jukebox on the planet"?

EL DJ was custom-built "from a refurbished PC and some off-the-shelf additions," and houses tens of thousands of songs in MP3 format - many of which were manually uploaded from the owner's CD collection back in 2002.

Users spend the longest amount of time perusing all the choices that the jukebox presents to them. From personal experience, I doubt that this perusal time poses a problem to the majority of jukebox users, as many people seem to enjoy scanning the music at their leisure. On several occasions, users were approached by other people they didn't seem to know, who were curious/interested to see what music they were considering playing on the jukebox - so it could be said that the jukebox is a good way to meet new people through common interests - or at least spark conversation.

The EL DJ user interface consists of a trackball/mouse to scroll through the music on the display, and a keypad on which the user must key in the number of the song as displayed on the screen. Patrons seemed to experience the following problems with the user interface:

  1. Scrolling through albums using the trackball-mouse is rather unwieldy, as the movement doesn't always seem to be accurate. Also, the user must remove their hand from the trackball in order to key in the number of the song they want to hear.
  2. Many users seemed to have a bit of trouble entering their song choices into the jukebox - not only because they had to remove their hand from the trackball, but due to the length of the numbers that correspond to each song. As the night went on, some patrons seemed to have a bit of trouble remembering these five-digit numbers - and more than once, I heard users telling the person next to them to remember the song number as they keyed it in.
  3. Upon entering her song choices into EL DJ, one woman realized a moment too late that she'd misread a song number - perhaps an indication that the screen is too far away from the physical interface, or perhaps suggesting that the mapping isn't quite right. Upon observing this, the following quote came to mind from Norman's The Design of Everyday Things: "If  an error is possible. someone will make it. The designer must assume that all possible errors will occur and design so as to minimize the chance of the error in the first place, or its effects once it gets made. Errors should be easy to detect, they should have minimal consequences, and, if possible. their effects should be reversible."

Hi Fi's jukebox houses a staggering selection of sweet tunes, but the interface leaves room for improvement. Devices located in bars should be so easy, even a cavemen could do it.

CIMG0002

Bar patron experiences confusion with EL DJ's user interface

Using the trackball/mouse to browse the jukebox selection

Using the trackball/mouse to browse the jukebox selection

The bartender successfully completed her song choices on EL DJ. Familiarity helps.

The bartender successfully completed her song choices on EL DJ. Familiarity helps.

Instant party

Finals are upon us, and it's the most wonderful time of the year (almost). What better time to encourage stress-busting through partying? For the Pcomp final, I'm hoping to create a device that enables the user to get the party started, or at least host a 5-minute stress-busting mini party. The device should be portable, and possibly wearable, thus enabling the user to take, and start, the party anywhere.

Matt Ganucheau made the excellent suggestion of using this guy dancing on a hillside at the Sasquatch Festival as inspiration for the project. He dances around by himself for quite a while, another guy joins him after about 20 seconds, then another at 0:53, and around 1:10, a steady stream of others joins in. By the end of the three-minute clip, the lone dancer guy has created quite the dance party.

Watching the Sasquatch guy, we realized that a good way to tackle the potential annoying-ness of the device - for example, if used by the wrong hands, in the wrong social situation, or amidst an unwilling crowd - would be to adjust the party intensity depending on the amount of interaction/interest that the user receives upon activating the device. For instance, the music could become incrementally louder as others join in.

What are the essential ingredients to get everyone in the mood to party? Music, lights, disco ball, confetti and physical movement are some of the factors we'll explore in the next week or so...

Tagged as: No Comments

PComp Lab: Using a transistor to control high current loads

The purpose of this lab was to learn to control a high-current DC load - in this case, a DC motor - from a microcontroller. I used the DC motor and 12V DC adapter that came in our PComp kit.

Once I'd put together the circuit, it made clicking sounds but didn't move... and so the troubleshooting began: I triple-checked the wiring, used a multimeter to record the voltage between various points, changed out all the components one by one, and switched out the 10K ohm resistor for the 1K ohm.

The video clip embedded below depicts three different attempts to make this circuit work as the lab intended.

  • Take 1: The motor moves somewhat erratically, and the Arduino seems to be resetting itself.
  • Take 2: The motor moves at a SLOW constant, and emits a high-pitched buzz that sounds like bagpipes (easily my least favorite musical instrument in the world).
  • Take 3: Finally, we unplugged the 14V DC adapter and used 3.3V from the Arduino to power the DC motor, adjusting the speed with the pot. This worked perfectly - but defeated the purpose of the lab, which was to use a high current load.
Filed under: PComp No Comments

Phantom limbs, cognitive/sensory function and virtual tactility (and Kat’s nightmares)

Amputation is one of my greatest fears. I can't count the number of times I've awoken with a jerk and immediately checked to see that my limbs are still there. The existence of phantom limbs is new to me - after the initial traumatic experience of amputation, I can't fathom what it must be like to sense things as if the missing limb remained in place. Cognitive function is a crazy thing.

In chapter seven of "We Create What We See," Donald Hoffman argues that we construct everything that we sense and perceive, including all that we taste, hear, smell and feel. We also construct the location and point in time in which we sense and perceive things. Of all the senses, touch poses "the biggest impediment."

If we construct all that we feel, we "should be able to construct feeling in any body part, even if that part is amputated." Conversely, if an individual's constructive processes or cognitive functions are impaired, that individual will have difficulty with touch, even if the body part remains. Therefore, it's possible to create virtual realities -  or, more accurately, "virtual tactilities" - based on touch sensation.

I'm relieved that Donald Hoffman concludes this chapter with a discussion of the medical possibilities afforded by these findings, because I kind of expected him to go down the gaming/virtual worlds route. Once upon a time, when Second Life was the Next Big Thing, I played around with it for a while. Cool concept and all, but I felt it was a waste of real-life time to hang out in a virtual world that felt so, um, virtual. I'm all for using my imagination and whatnot, but I have enough to do in this joint without pottering around another world learning to fly, walk and talk.

Returning to Hoffman, this was a pretty intriguing read. I'd be interested in checking out any PComp projects (or those from more advanced classes) that explore or employ virtual tactility.

Filed under: PComp No Comments

Pcomp Lab: Servo Motor Control with an Arduino

This lab introduced us to the Servo, a small motor with an output shaft that can be easily used to create and control motion with a microcontroller.  Most servos allow for up to 180 degrees of movement, and can be used in applications involving levers, periodic or reciprocating motions. Servos are commonly used in projects including radio-control airplanes, radio-control cars and robotics, among others.

The goal of the lab was to control the position of the servo using analog sensor values. To set up the breadboard, I connected power and ground on the breadboard to 5V power and ground on the Arduino. I connected an FSR sensor to Analog pin 0 on the Arduino, connected the yellow wire of the servomotor to digital pin 2, the red wire to power, and the black wire to ground.

Part I: Pulsing the servo with a digital pin to set the position of the servo. The first part of the lab involved figuring out the pulse length and position (the easier route would be the Servo library, which we'll see in Part II). I controlled the Servo using an FSR sensor. To ensure that the servo moved through its full range of motion with the FSR, I first determined the range of values of the FSR and used the map(); function to adjust the servo code to fit.

Servo Lab Part I from katherine keane on Vimeo.

Part II: Controlling the servo using the Servo library. Part I was the hard part - because in Part II, we used the Arduino Servo library to take care of all the calculations.

Servo Lab Part II from katherine keane on Vimeo.

Tagged as: , , No Comments

The sweet music of continuity

Soldering, I've discovered, is nothing like riding a bicycle. My initial attempts at soldering a DC power connector to a set of wires for a breadboard were alarmingly, embarrassingly awful. Entirely unreflective of previous hours spent in secondary school with soldering iron in hand (for constructive purposes, promise).

I attribute my initial failures to the "helping" hands, which wouldn't seem to stay put, no matter how much I coaxed them to cooperate. After an hour or so, about six inches of solder, mass header pin destruction and multiple clippings of the red and black wires, I congratulated myself on my decision to use eight inches of red and black wire at the beginning of this project, rather than the suggested 4 inches.

Upon successful attachment of the wires to the header pins, everything appeared to be okay - but still, it was with trepidation that I dragged out the multimeter to test for continuity.

Center pin to red wire: BZZZZ!
Outside rim to black wire: BZZZZZ!

Understanding electricity is pretty, erm, fundamental for physical computing. I'll admit that I don't quite "get" it all yet. Therefore, it's time for me to spend some serious hours in the shop playing around in an attempt to really figure it out. Circuits can't be that hard, right?

This is but one of the things I'm planning to master...

Arduino is but one of the things I'm hoping to master...

Filed under: PComp No Comments

my posts

Categories

tag cloud??

android arduino art assistive technology breathing bronx zoo cabinet comics commlab communication computer vision eye tracking forster freshkills FSR games giraffes graphic arts graphics Hospitable Room images interactivity LEDs light midi Mobile Me(dia) museum Nature of Code park PComp physical computing public Rest of You sensor sensors servo spontaneous storytelling stupid sustainability swig & jig tree visitors