Project Attributes physical computing

The Book Project

Posted by | | No Comments

An interpretive look at how books can be used to tell a story.

Made together with Jayoung Chung, “Neo” Sangzoon Park, and Ozge Kirimlioglu.

As a rule, when you have read a book and closed the cover, you can expect to find that the story is the same every subsequent time you open it. The words will not have changed. There is order and structure inherent in the experience of reading a book.
In this project, however, we have changed the rules a bit. We have attempted to stretch
the boundaries of the classic reading experience by creating a stage upon which the words can change on each viewing.
There is a technique employed by many writers called free-writing. It is very useful for generating ideas, getting rid of blocks and freeing your creative mind.

Using a hollowed out book and 20 dice with words/short phrases pasted on them, our system is a nod to the that technique. And of course you can add and remove words/phrases/die as you see fit.

Full documentation/analysis can be found here.

Train Stop Watch

Posted by | | No Comments

A device that alerts you when your train stop is coming up.

Made together with Tim Haynes.


    It all started with the thought that when you’re coming home late, and you’re tired or drunk or both, you can sometimes miss your trainstop. Or if you’re reading a good book or watching a movie or even just having a nap. So, what if you had a device that could A) alert you that your stop was coming up and B) let you know that your stop was here.

It’s a simple box with very basic inputs and outputs.

  • – You turn on the Device. By default, its set to two train stops, because why would you need something like this for only one stop?
  • You increment the number of stops by pushing a red on the side. This is also useful in the case of false stop detection.
  • When you reach the stop before your stop, a yellow light goes on and stays on until…
  • You near your stop where a red light comes on and a buzzer/vibrator goes off.

Do It Yourself

So the setup is pretty simple and the materials are cheap/easy to come by.

  • Arduino (or some other microcontroller thingy)
  • 2 LEDs
  • 1 (or more) (we used a piezo) Buzzer/vibrating motor/loud-annoying-wake-me-up-thing
  • 1 accelerometer
  • 1 pushbutton switch
  • 1 on/off type switch
  • power supply for arduino (we used a 9v battery)
  • breadboard, wires, wirecutter
  • 2x 220 ohm resistors, 1x 10k ohm resistor
  • A casing to hold the Device

Circuit Diagram

Code

int analogPin0 = 0;
int analogPin1 = 1;
int analogPin2 = 2;

int analogValue0 = 0;
int analogValue1 = 0;
int analogValue2 = 0;            // outgoing ADC value

int wasOn=-1;

int y = 0;

float distance, distanceo, totaldist, totaldisto;
float velocity, speedo, accel, accelo; 

int d1, d2, d3, d1o, d2o, d3o;
int count = 1;

float lowend, highend, lowendo, stayold, stayold2;
int highcount, lowcount, staycount, mystopcount, countdown;
int iteration, iterationo;

int switchPin = 7;      //  digital input pin for a switch
int yellowLedPin = 3;   //  digital output pin for an LED
int redLedPin = 6;      //  digital output pin for an LED
int buzzerPin = 8;      //  digital output pin for a buzzer
int switchState = 0;    //  the state of the switch
int stops = 2;          //  number of stops
int buzzerState = 0;    //  if buzzer is on

void setup()
{
  pinMode(switchPin, INPUT);       // set the switch pin to be an input
  pinMode(yellowLedPin, OUTPUT);   // set the yellow LED pin to be an output
  pinMode(redLedPin, OUTPUT);      // set the red LED pin to be an output
  pinMode(buzzerPin, OUTPUT);      // set the buzzer pin to be an output

  // start serial port at 9600 bps:
  Serial.begin(9600);
  lowend=highend=accel=velocity=distance=d1=d2=d3=staycount=mystopcount=0;
  iteration=0;
  lowendo=totaldisto=accelo=speedo=totaldist=distanceo=d1o=d2o=d3o=iterationo=0;
  highcount=lowcount=3;
  stayold=0; stayold2=1;
  countdown=3;
}

void loop()
{
  switchState = digitalRead(switchPin);

  analogValue0 = analogRead(analogPin0); 

  analogValue1 = analogRead(analogPin1); 

  analogValue2 = analogRead(analogPin2); 

 if (switchState == 1) {
    wasOn=1;
  }
  if(switchState == 0 && wasOn == 1)
  {
    stops = stops + 1;
    //Serial.println("HAI! I'm on!");
    wasOn=0;
  }

  /*
 Serial.print(analogValue0);
 Serial.print("*");
  Serial.print(analogValue1);
   Serial.print("*");
   Serial.println(analogValue2);
   */
  // pause for 10 milliseconds:
  delay(10);

	/*
	the data is collected every 10 ms, so a count of 100 is 1 second
	*/
        if(count==100)
        {
          iteration++;

          /*
            if 3 data points are high and close enough to each other then a 
	    high-end point is recorded
          */
          if(totaldist-300 > lowend) // looking for a number above the lowest 
                                     //data point (lowend) 
          {
            if(highcount >=2) // on the 3rd occurence of a high point within
                              // 100 points of itself, see if its ok to say 
 			      // its a high point 
            {

              if(totaldisto+100 >= totaldist && totaldisto-100 <= totaldist)
              {  highend=totaldist; } else{ highcount=0;}
            } else { //else the count is restarted and the search for 
                     // consecutive high data points continues
              if(totaldisto+100>=totaldist && totaldisto-100<=totaldist)
              {  highcount++; } else { highcount=0; }
            }
          }

          /* A cheap hack. Just puts the first data point lower than the first 
	     high data point into the low end point. */
          if(highend>0 && lowend==0) {
            if(totaldist 0)
          {
            if(totaldist>lowend){highend=totaldist;}
          }

          /*
            if 3 data points in succession are low, then a  new low end point is
	    recorded
          */
          if(totaldist+300 < highend)// looking for a number below the high 
				     //data point
          {
            if(lowcount >=2){ // on the 3rd occurence of a low data point w/in 
                              // 100 points of itself, check to see if its ok 
			      // to record
              if(totaldisto+100>=totaldist && totaldisto-100<=totaldist)
              { lowendo=lowend; lowend=totaldist; } else {lowcount=0;}
            } else {//else the count is restarted and the search for consecutive
                    // low points resumes
              if(totaldisto+100>=totaldist && totaldisto-100<=totaldist)
              {  lowcount++; } else { lowcount=0; }
            }
          }

          /*
          Serial.print("!");
          Serial.print("*");
          Serial.print(highend,DEC);
          Serial.print("*");
          Serial.print(lowend,DEC);
          Serial.print("*");
          Serial.println(totaldist,DEC);
          */

         /*if the last low end point is close enough to the current low end
        point, then start saying that maybe we're stopping or have stopped */
          if(lowendo+100>=lowend && lowendo-100<=lowend)
          {staycount++; stayold2=lowendo;}else{staycount=0;}
          /* if we've been at a low end for quite a while and its not the 
          beginning of the program then check to see if we've been staying 
             at the same place as well and if so then say that we think that 
             we've stopped */
          if(staycount>=3 && highend!=0 && lowend!= 0 && stayold!=stayold2)
          {
            //Serial.println("@");
            stayold=lowendo;
            stayold2=stayold;
            staycount=0;
            if(mystopcount==-1)
            {
              //Serial.println("#");
              countdown--;
              stops--;
            }

	    /*
            stops--;
            Serial.print(iteration);
            Serial.print(" ");
            Serial.println(stops);
	    */
            if (stops == 1) {
              digitalWrite(yellowLedPin, HIGH);   // turn on the yellow LED
            }
            if (stops == 0) {
              digitalWrite(yellowLedPin, LOW);   // turn off the yellow LED
              digitalWrite(redLedPin, HIGH);     // turn on the red LED
              digitalWrite(buzzerPin, HIGH);     // turn on the buzzer
              buzzerState = 1;
              stops=0;
            }

            mystopcount++;
            iterationo=iteration;

          }

          //this is the number we need to play with to finesse things
          if(iterationo+8 < iteration){mystopcount=-1;}
          if(iterationo+3 < iteration){
          digitalWrite(buzzerPin, LOW); digitalWrite(redLedPin,LOW);
        }

          /* reset distances and times */
          totaldisto=totaldist;
          totaldist=0;
          count=1;

          speedo=velocity;
          accelo=accel;

        }

        /*below this line is all graph data */

        //X
        y = analogValue0;
        d1 =  y- d1o;
        d1o = y;

        //Y
        y = analogValue1;
        d2 = y - d2o;
        d2o = y;

        //Z
        y = analogValue2;
        d3 = y - d3o;
        d3o = y;

        //Distance
        if(d1o != 0 && d2o != 0 && d3o != 0)
        {
          distance = sqrt(sq(d1)+sq(d2)+sq(d3));
          distanceo= distance;
        }

        //Speed (averaged over time (every reading is 1 second)), reset @ STOPs
        totaldist+=distance;  //DONT'T DELETE THIS LINE OR EVERYTHING WILL DIE
        velocity = totaldist/count;

        //Accel
        accel = velocity/count;

        count++;  //OR THIS
}

Q-ECG

Posted by | | 16 Comments

Electrocardiograph Reader for Linux.

    Most electrocardiogram programs require the use of a special Data Aquisition card. QEcg is a program to interpret an electrocardiogram through the sound card on a Linux computer. The program displays the ECG and calculates the heart rate. This program can be used with an ECG simulator or even a real ECG ( although the ECG will need to be amplified using a circuit such as that described here or here [local copy] ). Just connect the ECG output to the sound card and run the program. It only works under Linux.

This software was ported from the original Windows version described here or here [local copy].


Program requirements:

  • Qt version 3.x or most recent version.
  • A recent version of the gcc compiler.
  • 8 bit minimum soundcard
  • – Linux


Download

QEcg. ( Uncompress by: zcat qecg.tgz | tar xfv – )


Credits

This project was supported by the Research Experience for Undergraduates program of the National Science Foundation, under grant DBI-0096596 (PI: David Christini, Ph.D.)
I would like to thank the following people for their help with this project:

  • Jason Nguyen
  • David Christini, Ph.D.
  • Calin Culianu
  • Anil Maybhate, Ph.D.
  • Yunfan Gong, Ph.D.