MyBike Photo Booth: Fun with Arduino

July 13th, 2010 at 10:13am Josh

With an exhibition as widely accessible as Bespoke: The Handbuilt Bicycle, we knew that we wanted to do a web-based project that would engage as broad of an audience as possible. The idea of doing a photobooth-type installation had been in on my for quite a while (I had actually wanted to put out a video booth to capture visitor comments at our opening two years ago, but had too many other things going on to put it together), and Bespoke seemed like the perfect opportunity.

booth and feet

The concept: visitors pose in front of the Museum with their own bike, the photobooth snaps a photo, and the photobooth gets uploaded to an online gallery. While the initial designs had a few more features, by the time it came time to actually start putting everything together (the weekend before the opening), the idea really got pared down to it’s essence. Here’s the result: http://mybike.madmuseum.org. I have to say that I’m pretty proud of my first physical computing project, and it was a lot of fun to work on. In this post, I’ll go over the actual construction of the photobooth, and I’ll follow shortly with how we built the web gallery.

The Guts
I knew that I wanted to build my project around Arduino, the fantastic microcontroller that can be kitted out with all sorts of sensors, displays, buttons, motors, and a ton of other components. The photobooth would have to sit inside the museum, behind the glass windows of the lobby floor, so any interaction with visitors would have to be done with motion/light sensing. As far as actually taking and storing the pictures, I’ve used a piece of camera control software from granite bay software called GB Timelapse for a number of other projects. This software offers really fine-grained control over an attached camera (I used a cheapish Canon PowerShot), and it also lets you snap a photo by pressing the F5 key. This seemed like a perfect way to drive the photobooth – rather than trying to build something that would talk directly to the camera, I’d build something that would emulate a single keystroke, connect it to a laptop, and then let this software do the hard stuff.

With that conceptual stuff out of the way, I started buying. First, the Arduino: I used a Arduino Duemilanove, which goes for $30. I also needed a prototyping shield for the arduino (something to solder everything to), which was $12.50. Next, a photosensor. RadioShack offers a grab bag of 4 sensors for something like $2. (I can’t find the link, but it’s in the components cabinet in-store). I picked up a 7-segment LED to act as a countdown timer ($.95), and a plain green LED ($.50-ish at any number of places online) to let the photo-taker know when the shutter was being snapped. Add in some random resistors (pennies a piece – here’s a great kit that contains a few hundred) and some wire, and the arduino and shield were pretty much finished. Total cost: $50 or so.

The communicating with the computer part turned out to be a little trickier than I thought. First, I attempted to emulate a USB keyboard by following this project from the book Practical Arduino. No luck – I got the usb port hooked up to the arduino without a problem, but when I loaded the library and then plugged the thing in, all I got were device unrecognized errors. I spent a few hours messing with this problem (and two trips to 269 Electronics in Chinatown) before I decided to give up and call the experts. My friend Ian is in ITP at NYU, and he pointed me towards Mike Knuepfel. Mike totally came through (thanks Mike!) with a different approach, based loosely on this Instructable. In this approach, rather than trying to emulate a keyboard with software, you just pull the guts out of a usb keyboard an integrate them into the project. This way, you get all of the communication stuff with the computer for free.

keyboard guts

The way that a keyboard registers a particular keystroke is by making a connection between pins from two different registers. By process of elimination, Mike found the combination that makes the F5 key. By wiring these together, he created a keyboard only capable of pressing the F5 key over and over, which is exactly I was looking for.

So, here’s how it all came together:

the board

schematic

First, the particular 7-segment led I used was common anode, meaning that the entire packages shares a connection to a 330 ohm resistor then to +5, and then each individual PIN / LED is connected to ground. Everything on the left half of the prototype board in the photo is related to that 7-segment. Next, the photosensor. Super simple: just +5 connected to a 10K resistor connected to the sensor, connected to an analog pin on the arduino, then connected to ground. Likewise simple: the green led is just connected +5 to the led to a 330 ohm resistor to ground. The keyboard connection (not on my little schematic drawing) is perhaps simplest of all – just the voltage supply from the keyboard guts connected out to a resistor (can’t remember exactly what Mike used, but looks like 3800K) connected to one of the Arduino digital pins.

(Note: you’ll see in the photo that I put a piece of black electrical tape around the photo sensor. This little tunnel greatly reduces the incident light that falls on the sensor through the thickness of the glass window, which makes it much more directional and much more effective.)

The arduino sketch that makes it all work is posted below. The light sensor takes a reading every .25 seconds. If the value recorded falls above a threshold value (set initially at 140, then recalibrated every 2 minutes to account for changing lighting conditions), then the 7-segment led shows a countdown from 9. At 0, the green led fires, and +5 is sent out to the digital pin connected to the keyboard for .1 second. The attached computer running the photo control program reads the signal as F5 and fires the shutter, and then the system is primed to capture another event. Pretty cool!

The booth has been up for close to 8 weeks now, and, amazingly, there hasn’t been a single problem with the electronics (we had a network issue once, but that wasn’t my fault!). Next I’ll write up a post (hopefully shorter) on the code that makes the website run, which is a combination of python and php, plus html and css. In the meantime, if you have any questions, leave them in the comments.

int seg_a = 9;
int seg_b = 8;
int seg_c = 6;
int seg_d = 5;
int seg_e = 4;
int seg_f = 3;
int seg_g = 2;
int seg_dp = 7;
int photoPin=1;
int ledPin = 10;
int keyPin =  13;
int primed = 1;
int threshold = 140;
int interval = 480;
int count = 0;

void setup() {
  //light sensor
  Serial.begin(9600);  //Begin serial communcation

  //7-segment
  pinMode(seg_a, OUTPUT);
  pinMode(seg_b, OUTPUT);
  pinMode(seg_c, OUTPUT);
  pinMode(seg_d, OUTPUT);
  pinMode(seg_e, OUTPUT);
  pinMode(seg_f, OUTPUT);
  pinMode(seg_g, OUTPUT);
  pinMode(seg_dp, OUTPUT);
  off();

  //led
  pinMode(ledPin, OUTPUT);

  //usbKeyboard
  pinMode(keyPin, OUTPUT);
}

void loop(){

  Serial.println(analogRead(photoPin)); //Write the value of the photoresistor to the serial monitor.
  Serial.println(threshold);
  Serial.println(count);

  count++;

 //recalibrate light sensor
  if (count == interval)
  {
    threshold = analogRead(photoPin) + 70;
    count=0;
  }

  if (analogRead(photoPin) > threshold)
  {
     if (primed==1)
     {
     primed=0;
     countdown();
     }
  }
  delay(250);
}

void num1()
{
  digitalWrite(seg_a, HIGH);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, HIGH);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, HIGH);
  digitalWrite(seg_g, HIGH);
  digitalWrite(seg_dp, HIGH);
}
void num2()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, HIGH);
  digitalWrite(seg_d, LOW);
  digitalWrite(seg_e, LOW);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, HIGH);
  digitalWrite(seg_dp, HIGH);
}
void num3()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, LOW);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, HIGH);
  digitalWrite(seg_dp, HIGH);
}
void num4()
{
  digitalWrite(seg_a, HIGH);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, HIGH);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, LOW);
  digitalWrite(seg_dp, HIGH);
}
void num5()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, HIGH);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, LOW);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, LOW);
  digitalWrite(seg_dp, HIGH);
}
void num6()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, HIGH);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, LOW);
  digitalWrite(seg_e, LOW);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, LOW);
  digitalWrite(seg_dp, HIGH);
}
void num7()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, HIGH);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, HIGH);
  digitalWrite(seg_g, HIGH);
  digitalWrite(seg_dp, HIGH);
}
void num8()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, LOW);
  digitalWrite(seg_e, LOW);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, LOW);
  digitalWrite(seg_dp, HIGH);
}
void num9()
{
  digitalWrite(seg_a, LOW);
  digitalWrite(seg_b, LOW);
  digitalWrite(seg_c, LOW);
  digitalWrite(seg_d, HIGH);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, LOW);
  digitalWrite(seg_dp, HIGH);
}
void dash()
{
  digitalWrite(seg_a, HIGH);
  digitalWrite(seg_b, HIGH);
  digitalWrite(seg_c, HIGH);
  digitalWrite(seg_d, HIGH);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, LOW);
  digitalWrite(seg_g, HIGH);
  digitalWrite(seg_dp, HIGH);
}
void off(){
  digitalWrite(seg_a, HIGH);
  digitalWrite(seg_b, HIGH);
  digitalWrite(seg_c, HIGH);
  digitalWrite(seg_d, HIGH);
  digitalWrite(seg_e, HIGH);
  digitalWrite(seg_f, HIGH);
  digitalWrite(seg_g, HIGH);
  digitalWrite(seg_dp, HIGH);
}
void countdown()
{
  num9();
  delay(1000);
  num8();
  delay(1000);
  num7();
  delay(1000);
  num6();
  delay(1000);
  num5();
  delay(1000);
  num4();
  delay(1000);
  num3();
  delay(1000);
  num2();
  delay(1000);
  num1();
  delay(1000);
  dash();
  digitalWrite(ledPin, HIGH);
  digitalWrite(keyPin, HIGH);   // fire f5 key
  delay(100);                  // delay
  digitalWrite(keyPin, LOW);   //unfire f5 key

  delay(1000);
  off();
  digitalWrite(ledPin, LOW);
  primed=1;
}

Entry Filed under: museum tech

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Highlights

Categories

RSS RSS Subscription