Making Things Interactive

May 12, 2008

The Amazing Booth Device

Filed under: Final Project,Lea — tovelet @ 10:23 am



The details are rather long-winded for this blog, so I’ve put some explanations here and the full source code here.

May 1, 2008

Tell us what you really think.

Filed under: Final Writing Assignment,Lea — tovelet @ 11:34 am

The class this semester has certainly helped me with the “how” questions of actuators and microcontrollers. I had scraps of knowledge about the electronics and code involved, but was lacking a formal synthesis. The lectures and the Lady Ada tutorials were therefore very helpful, even if at times they verged on obviousness, because it was important that I actually had that baseline understanding. The assignment dates and overall temporal structure of the class were as helpful as they could be, given the hectic scheduling of most CMU students.

As for the “why” questions, the class has helped me answer some, but not all, of them. There were some projects that I believe gave solid responses to the open-ended project question, either in presenting a clever solution to a real-life problem (notably, Gee’s fireflies project and Gaku’s Bathroom Gauntlet) or in making steps toward rational visualisations of the future (Nadeem’s book project).

I still believe that my own projects will not focus on “technology” (in this case, embedded circuits) as an ends in itself, but just another means– albeit an increasingly prevalent one. The ability to write simple code is as useful as a basic knowledge of woodworking or perspective drawing; the concept of state machines is a fundamental mental model akin to the structure of an essay. These things should be taught at an even younger age (and it’s exciting that there are indeed people striving to make this happen); the truly revolutionary ideas will come from people that have processed and absorbed these techniques, and can draw on them as readily as writing a sentence in their native language.

Paul wrote below that he “can’t imagine a project being very interesting without incorporating what [he] learned in this class,” but that is not true for me. There is still plenty of merit in a project that gains dynamism through more traditional means, such as a cathedral with stained-glass windows designed to catch the light perfectly for a precise moment on a particular day, or a skirt made with sheer fabric that catches a subtle breeze and swirls when the wearer walks. The techniques presented in this class, along with the precedents we looked at in class and online, are an expansion of this repertoire.

March 27, 2008

State machine

Filed under: 8: State Machine,Lea — tovelet @ 1:42 pm

I am not very good at this game, actually.

A blinky light game. Once a player has decided to “participate,”
the LED’s blink in turn. If a player hits the button that corresponds
to the currently lit LED, they gain a point, and the lights cycle slightly
faster. They can exit the game at any time, and the score and speed
reset for the next player.

int ledOne = 4;
int ledTwo = 7;
int buttonOne = 2;
int buttonTwo = 8;
int participate = 9;
int delayTime = 200;
int answer = 0; //”right” or “wrong” for any given round
int score = 0; //score tally, reset at the beginning of the game
int playPrint = 1; //should it print “Will you play?”

const int sAttract = 0;
const int sQuestion = 1;
const int sIncorrect = 2;
const int sCorrect = 3;

int state = 0;

void setup ()
pinMode(ledOne, OUTPUT);
pinMode(ledTwo, OUTPUT);
pinMode(buttonOne, INPUT);
pinMode(buttonTwo, INPUT);
pinMode(participate, INPUT);

void loop ()
switch (state)
case sAttract: //state is attract
digitalWrite (ledOne, LOW); //reset LEDs to off
digitalWrite (ledTwo, LOW);
if (playPrint == 1)
{Serial.println(“Will you play?”);}
score = 0; //reset score
delayTime = 200; //reset delayTime
if (digitalRead(participate)==HIGH)
{state = sQuestion;}
playPrint = 0; //only print it once

case sQuestion: //state is question:
Serial.println(“Push the lit button.”);
if (digitalRead(participate)==LOW) //check if participate is off
state = sAttract;
playPrint = 1;
answer = cycleLed(); //run the cycling lights, return correct or incorrect
score = score + answer; //tally score
if (answer == 0)
{state = sIncorrect;}
if (answer == 1)
{state = sCorrect;}

case sIncorrect: //state is incorrect:
Serial.println(“Your score is:”);
Serial.println(score); //print score
delay (500);
if (digitalRead(participate)==LOW) //check if participate is off
{state = sAttract;
playPrint = 1;}
{state = sQuestion;} //return to question state

case sCorrect: //state is correct:
Serial.println(“Your score is:”);
delay (500);
delayTime = (delayTime – (delayTime/(100-score))); //cycle lights faster next time
if (delayTime <= 50) {delayTime = 50;} //do not make it too hard if (digitalRead(participate)==LOW) {state = sAttract; playPrint = 1;} else {state = sQuestion;} break; default: Serial.println ("error"); //this shouldn't happen state = sAttract; playPrint = 1; break; } } int cycleLed () { while (true) { for (int i=0; i<=delayTime; i++) { digitalWrite(ledOne, HIGH); //ledOne is on digitalWrite(ledTwo, LOW); if (digitalRead(participate)==LOW) //make sure participate is high {state = sAttract; playPrint = 1; return (0);} if (digitalRead(buttonOne)==HIGH) {return (1);} //so if buttonOne is pressed, correct if (digitalRead(buttonTwo)==HIGH) {return (0);} //and if button Two is pressed, incorrect delay(1); } for (int i=0; i<=delayTime; i++) { digitalWrite(ledOne, LOW); //inverse of the other one digitalWrite(ledTwo, HIGH); if (digitalRead(participate)==LOW) {state = sAttract; playPrint = 1; return (0);} if (digitalRead(buttonOne)==HIGH) {return (0);} if (digitalRead(buttonTwo)==HIGH) {return (1);} delay(1); } } } [/sourcecode]

March 25, 2008

Final proposal

Filed under: Final Project,Lea — tovelet @ 1:45 pm

My project will be a panel of buttons, knobs, and switches, for a booth for CMU’s Spring Carnival.
The panel is supposed to be “science-y,” like a prop from 2001 or Star Trek, and it should invite exploratory interactions.  The board will react deterministically, but its responses might not always be directly obvious to the viewer.

The proposal is here:

March 20, 2008


Filed under: 8: State Machine,Lea — tovelet @ 1:57 pm

A booth game, for Carnival:

March 6, 2008


Filed under: 7: Mid-Term Project,Lea — tovelet @ 1:32 pm

I made a “whisker” sensor out of a guitar string, a photoresistor, and some scrap copper. It has two ways of registering a “high” reading (which causes the sequenced motion to speed up), either by touching the spring wire to the edge of its hole, or by seeing light.

The solenoids turned out to be poor at producing motion; the force holding the center rod in position is fairly strong once tripped, but it has a hard time overcoming the force of the spring. Possibly it could be mounted to bias the forces toward tripping the solenoid. In the meantime, I set up a simple LED version of the circuit, to see if I could get the code working.

The LED charlieplexed circuit is the same as the one from the Instructables tutorial (here), and the sensors are in the simple circuit from the class notes (here).

 * CharlieBlink
 * Cycling through six LEDs set up according to the diagram
 * at

int pinA = 9;                // 
int pinB = 10;               //
int pinC = 11;               //
int buttonPin = 2;
int photoPin = 3;
int delayTime = 500;

void setup()                   // setup
   pinMode(buttonPin, INPUT);  // no need to set pinmode for light pins, since we do that later

void loop()                    // loop

     lightNode(pinA, pinB, pinC);      //LED1, from
     lightNode(pinB, pinA, pinC);      //LED2
     lightNode(pinB, pinC, pinA);      //LED3
     lightNode(pinC, pinB, pinA);      //LED4
     lightNode(pinA, pinC, pinB);       //LED5
     lightNode(pinC, pinA, pinB);      //LED6

void lightNode(int upPin, int downPin, int nullPin)
    pinMode(upPin, OUTPUT);
    pinMode(downPin, OUTPUT);
    pinMode(nullPin, INPUT);
    digitalWrite(upPin, HIGH);
    digitalWrite(downPin, LOW);
    if (digitalRead(buttonPin) == HIGH) {delayTime = 100;}
    if (digitalRead(buttonPin) == LOW) {delayTime = 500;}

I need a better way to switch sequence directions. I had thought that putting each LED’s settings for up pin, down pin, and null pin into an array would be helpful, since I could then find a way of incrementing or decrementing between arrays, instead of listing the sequence. However, it seems that reading out values from the array is more trouble than the current method if I don’t have the benefit of easily switching from array to array.

February 28, 2008

Midterm project proposal

Filed under: Lea — tovelet @ 1:54 am

There is a pdf here*, lacking a circuit diagram.

*It’s not as nice as Nadeem’s.

February 12, 2008

Fan, knife

Filed under: 5: Making Motion,Lea — tovelet @ 2:17 pm

For this exercise, I got to box of motors too late to borrow one, and decided that I would instead use whatever spare motors I could find in my house. I had a few stepper motors and a DC fan which drives air into four tubes. We worked with the steppers in a class I took last semester. One of them already had a convenient laser cut mount, and I still had the integrated circuit that we used, so I just wanted to make the same setup work again (and hopefully actually understand it this time).

Although I could not find any specifications online for the motors I had, Tom Igoe’s page about stepper motor control was very helpful, and I figured that I had a unipolar stepper, and that the two matching leads were probably the center connections to the coils. I adapted his code, which uses the Arduino Stepper library.

The DC fan was simply the circuit and code presented in class last Thursday (see page 2 of the notes). I found the diagrams here and here to be useful in translating the circuit diagram into a breadboard layout. I didn’t have any diodes of the non-light-emitting variety, so I just used what I had, and they served as nice indicators as well.

A 9V battery seems to be sufficient to power the stepper motor; the fan was more powerful with the 12V wall adapter.

The plan, once I had the stepper and fan working, was to create a device that inflated a plastic bag and, on button press, attacked it with a knife. After taping a blade to the swinging arm of the stepper, I found that the bag was fairly resilient to slicing attacks. Since the device was approximately as comically futile with and without the knife, I removed the blade to minimize robot-related injuries in the near future.

 Stress device

 This program swings a knife on a stepper motor to strike a bag being filled by a DC fan, 
 based on stepper motor code by Tom Igoe ( 
 and DC motor code and wiring diagram from ITP ( 
 It uses the built-in Stepper library.

#include <Stepper.h>

#define motorSteps 200     // I don't actually know how many steps my motor has,
                           // but this seems to give good results.
#define motorPin1 8
#define motorPin2 9
#define motorPin3 10
#define motorPin4 11
#define ledPin 13

int fanPin=4;
int switchPin=12;
int buttonPress=1;

// initialize the Stepper library:
Stepper myStepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4); 

void setup() {
  // set the motor speed at 60 RPMS:

  // set up the pins:
  pinMode(ledPin, OUTPUT);
  pinMode(fanPin, OUTPUT);
  pinMode(switchPin, INPUT);

void loop() {
  digitalWrite(fanPin, HIGH);
  if (digitalRead(switchPin) == HIGH)
    digitalWrite(fanPin, LOW);


February 5, 2008

Binary Counter

Filed under: 4: Counting Sensor Input,Lea — tovelet @ 12:32 am

I made a binary counter, that displays the number of button presses with four green LEDs, because I wanted to see if I could figure out a simple way of coding it. My answer uses the modulus function.

 * Binary Blink
 * Four LEDs as a counting display

int onesPlace = 12;                // 
int twosPlace = 11;                // 
int foursPlace = 10;               // 
int eightsPlace = 9;               // Pins for ones through eights places
int switchPin = 2;                 // Pin for switch
int n = 0;                         // Number of clicks
int buttonPress = 1;               // Will change when button is pressed

void setup()                       // run once, when the sketch starts
  pinMode(onesPlace, OUTPUT);
  pinMode(twosPlace, OUTPUT); 
  pinMode(foursPlace, OUTPUT);
  pinMode(eightsPlace, OUTPUT);     // sets the LED pins as output
  pinMode(switchPin, INPUT);
  Serial.begin(9600);               // for feedback that "n" is correct

void loop()                         // run over and over again
if (digitalRead(switchPin) == HIGH) {buttonPress = 0;}
if (digitalRead(switchPin) == LOW && buttonPress == 0) // only if the button has been pushed and released
      n++;                          // increment "n"
      digitalWrite(onesPlace, n % 2);
      digitalWrite(twosPlace, (n / 2) % 2);
      digitalWrite(foursPlace, (n / 4) % 2);
      digitalWrite(eightsPlace, (n / 8 ) % 2);
      Serial.println(n);            // tell me what "n" is
      buttonPress = 1;              // don't do anything until another button press

I did all of the coding without testing, unfortunately, because I’d left my Arduino elsewhere. I also drew a quick wiring diagram, so I’d be able to put my breadboard together relatively quickly once I had the components.

Once I figured out the right direction for the DPST switch, the counter worked, surprisingly smoothly. The only glitch is that the counter occasionally skips forward quickly during a button press, and I think that is the switch malfunctioning, or a loose contact.

January 29, 2008

Hello Ada

Filed under: 3: LadyAda Tutorials,Lea — tovelet @ 2:55 pm

Here is a photo of my little barebones board with the light on, mid-blink.

I don’t have three different colored LEDs of similar intensity, so I’ll point to a project from last semester of the same approximate coding difficulty, which involved timing on a simple loop: anemone sculpture. The step that I hadn’t done before with Arduino was Tutorial 4: using the serial monitor.

Next Page »

Blog at